ui(deploy): extract MonitoringTab component
Pure presentational tab receiving MonitoringFormState via value/onChange. Also adds shared config-tab styles to AppDeploymentPage.module.css (configInline, toggleEnabled/Disabled, portPills, inputSizes, envVarsList/Row). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -94,3 +94,128 @@
|
|||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Config tab shared */
|
||||||
|
.configInline {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configHint {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-style: italic;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cellMeta {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggleEnabled {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggleDisabled {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fixed-width inputs */
|
||||||
|
.inputXs {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputSm {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputMd {
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputLg {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputXl {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Port pills */
|
||||||
|
.portPills {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portPill {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
background: var(--bg-raised);
|
||||||
|
color: var(--text-primary);
|
||||||
|
border: 1px solid var(--border-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
.portPillDelete {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-muted);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portPillDelete:hover {
|
||||||
|
color: var(--error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.portPillDelete:disabled {
|
||||||
|
opacity: 0.3;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portAddInput {
|
||||||
|
width: 70px;
|
||||||
|
padding: 3px 6px;
|
||||||
|
border: 1px dashed var(--border-subtle);
|
||||||
|
border-radius: 12px;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portAddInput::placeholder {
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.portAddInput:disabled {
|
||||||
|
opacity: 0.3;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Env vars list */
|
||||||
|
.envVarsList {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.envVarRow {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 2fr auto;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import { Select, Input, Toggle } from '@cameleer/design-system';
|
||||||
|
import type { MonitoringFormState } from '../hooks/useDeploymentPageState';
|
||||||
|
import styles from '../AppDeploymentPage.module.css';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
value: MonitoringFormState;
|
||||||
|
onChange: (next: MonitoringFormState) => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LOG_LEVELS = ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'].map((l) => ({ value: l, label: l }));
|
||||||
|
|
||||||
|
export function MonitoringTab({ value, onChange, disabled }: Props) {
|
||||||
|
const update = <K extends keyof MonitoringFormState>(key: K, v: MonitoringFormState[K]) =>
|
||||||
|
onChange({ ...value, [key]: v });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.configGrid}>
|
||||||
|
<span className={styles.configLabel}>Engine Level</span>
|
||||||
|
<Select
|
||||||
|
disabled={disabled}
|
||||||
|
value={value.engineLevel}
|
||||||
|
onChange={(e) => update('engineLevel', e.target.value)}
|
||||||
|
options={[
|
||||||
|
{ value: 'NONE', label: 'NONE' },
|
||||||
|
{ value: 'MINIMAL', label: 'MINIMAL' },
|
||||||
|
{ value: 'REGULAR', label: 'REGULAR' },
|
||||||
|
{ value: 'COMPLETE', label: 'COMPLETE' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className={styles.configLabel}>Payload Capture</span>
|
||||||
|
<Select
|
||||||
|
disabled={disabled}
|
||||||
|
value={value.payloadCaptureMode}
|
||||||
|
onChange={(e) => update('payloadCaptureMode', e.target.value)}
|
||||||
|
options={[
|
||||||
|
{ value: 'NONE', label: 'NONE' },
|
||||||
|
{ value: 'INPUT', label: 'INPUT' },
|
||||||
|
{ value: 'OUTPUT', label: 'OUTPUT' },
|
||||||
|
{ value: 'BOTH', label: 'BOTH' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className={styles.configLabel}>App Log Level</span>
|
||||||
|
<Select
|
||||||
|
disabled={disabled}
|
||||||
|
value={value.applicationLogLevel}
|
||||||
|
onChange={(e) => update('applicationLogLevel', e.target.value)}
|
||||||
|
options={LOG_LEVELS}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className={styles.configLabel}>Agent Log Level</span>
|
||||||
|
<Select
|
||||||
|
disabled={disabled}
|
||||||
|
value={value.agentLogLevel}
|
||||||
|
onChange={(e) => update('agentLogLevel', e.target.value)}
|
||||||
|
options={LOG_LEVELS}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className={styles.configLabel}>Metrics</span>
|
||||||
|
<div className={styles.configInline}>
|
||||||
|
<Toggle
|
||||||
|
checked={value.metricsEnabled}
|
||||||
|
onChange={() => !disabled && update('metricsEnabled', !value.metricsEnabled)}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
<span className={value.metricsEnabled ? styles.toggleEnabled : styles.toggleDisabled}>
|
||||||
|
{value.metricsEnabled ? 'Enabled' : 'Disabled'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className={styles.configLabel}>Sampling Rate</span>
|
||||||
|
<Input
|
||||||
|
disabled={disabled}
|
||||||
|
value={value.samplingRate}
|
||||||
|
onChange={(e) => update('samplingRate', e.target.value)}
|
||||||
|
className={styles.inputLg}
|
||||||
|
placeholder="1.0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className={styles.configLabel}>Compress Success</span>
|
||||||
|
<div className={styles.configInline}>
|
||||||
|
<Toggle
|
||||||
|
checked={value.compressSuccess}
|
||||||
|
onChange={() => !disabled && update('compressSuccess', !value.compressSuccess)}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
<span className={value.compressSuccess ? styles.toggleEnabled : styles.toggleDisabled}>
|
||||||
|
{value.compressSuccess ? 'Enabled' : 'Disabled'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user