@adcops/autocore-react 3.3.89 → 3.3.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/JogXNeg.d.ts +4 -0
- package/dist/assets/JogXNeg.d.ts.map +1 -0
- package/dist/assets/JogXNeg.js +1 -0
- package/dist/assets/JogXPos.d.ts +4 -0
- package/dist/assets/JogXPos.d.ts.map +1 -0
- package/dist/assets/JogXPos.js +1 -0
- package/dist/assets/JogYNeg.d.ts +4 -0
- package/dist/assets/JogYNeg.d.ts.map +1 -0
- package/dist/assets/JogYNeg.js +1 -0
- package/dist/assets/JogYPos.d.ts +4 -0
- package/dist/assets/JogYPos.d.ts.map +1 -0
- package/dist/assets/JogYPos.js +1 -0
- package/dist/assets/JogZNeg.d.ts +4 -0
- package/dist/assets/JogZNeg.d.ts.map +1 -0
- package/dist/assets/JogZNeg.js +1 -0
- package/dist/assets/JogZPos.d.ts +4 -0
- package/dist/assets/JogZPos.d.ts.map +1 -0
- package/dist/assets/JogZPos.js +1 -0
- package/dist/assets/Off.d.ts +4 -0
- package/dist/assets/Off.d.ts.map +1 -0
- package/dist/assets/Off.js +1 -0
- package/dist/assets/On.d.ts +4 -0
- package/dist/assets/On.d.ts.map +1 -0
- package/dist/assets/On.js +1 -0
- package/dist/assets/index.d.ts +8 -0
- package/dist/assets/index.d.ts.map +1 -1
- package/dist/assets/index.js +1 -1
- package/dist/assets/svg/off.svg +2 -0
- package/dist/assets/svg/on.svg +11 -0
- package/dist/components/JogPanel.d.ts +2 -2
- package/dist/components/JogPanel.d.ts.map +1 -1
- package/dist/components/JogPanel.js +1 -1
- package/dist/components/ams/AssetDetailView.js +1 -1
- package/dist/components/ams/AssetEditDialog.d.ts.map +1 -1
- package/dist/components/ams/AssetEditDialog.js +1 -1
- package/dist/components/ams/AssetRegistryTable.css +12 -0
- package/dist/components/ams/AssetRegistryTable.d.ts +1 -0
- package/dist/components/ams/AssetRegistryTable.d.ts.map +1 -1
- package/dist/components/ams/AssetRegistryTable.js +1 -1
- package/dist/components/tis/ConfigurationDialog.d.ts +21 -0
- package/dist/components/tis/ConfigurationDialog.d.ts.map +1 -0
- package/dist/components/tis/ConfigurationDialog.js +1 -0
- package/dist/components/tis/ResultHistoryTable.js +1 -1
- package/dist/components/tis/TestDataView.d.ts +47 -0
- package/dist/components/tis/TestDataView.d.ts.map +1 -1
- package/dist/components/tis/TestDataView.js +1 -1
- package/dist/components/tis/TestSetupForm.d.ts +37 -0
- package/dist/components/tis/TestSetupForm.d.ts.map +1 -1
- package/dist/components/tis/TestSetupForm.js +1 -1
- package/dist/components/tis/TisProvider.d.ts +25 -0
- package/dist/components/tis/TisProvider.d.ts.map +1 -1
- package/dist/components/tis/TisProvider.js +1 -1
- package/dist/components/tis/useRawCycleData.d.ts.map +1 -1
- package/dist/components/tis/useRawCycleData.js +1 -1
- package/dist/components/tis-editor/TisConfigEditor.css +20 -0
- package/dist/components/tis-editor/editor/ConfigurationsEditor.d.ts +19 -0
- package/dist/components/tis-editor/editor/ConfigurationsEditor.d.ts.map +1 -0
- package/dist/components/tis-editor/editor/ConfigurationsEditor.js +1 -0
- package/dist/components/tis-editor/editor/MethodFormEditor.d.ts.map +1 -1
- package/dist/components/tis-editor/editor/MethodFormEditor.js +1 -1
- package/dist/components/tis-editor/types.d.ts +13 -0
- package/dist/components/tis-editor/types.d.ts.map +1 -1
- package/dist/components/tis-editor/validation.d.ts.map +1 -1
- package/dist/components/tis-editor/validation.js +1 -1
- package/dist/themes/adc-dark/blue/theme.css +17 -2
- package/dist/themes/adc-dark/blue/theme.css.map +1 -1
- package/package.json +2 -1
- package/src/assets/JogXNeg.tsx +30 -0
- package/src/assets/JogXPos.tsx +30 -0
- package/src/assets/JogYNeg.tsx +30 -0
- package/src/assets/JogYPos.tsx +30 -0
- package/src/assets/JogZNeg.tsx +30 -0
- package/src/assets/JogZPos.tsx +30 -0
- package/src/assets/Off.tsx +14 -0
- package/src/assets/On.tsx +26 -0
- package/src/assets/index.ts +8 -0
- package/src/assets/svg/off.svg +2 -0
- package/src/assets/svg/on.svg +11 -0
- package/src/components/JogPanel.tsx +18 -28
- package/src/components/ams/AssetDetailView.tsx +1 -1
- package/src/components/ams/AssetEditDialog.tsx +25 -10
- package/src/components/ams/AssetRegistryTable.css +12 -0
- package/src/components/ams/AssetRegistryTable.tsx +15 -4
- package/src/components/tis/ConfigurationDialog.tsx +128 -0
- package/src/components/tis/ResultHistoryTable.tsx +2 -2
- package/src/components/tis/TestDataView.tsx +270 -12
- package/src/components/tis/TestSetupForm.tsx +167 -10
- package/src/components/tis/TisProvider.tsx +53 -0
- package/src/components/tis/useRawCycleData.ts +22 -3
- package/src/components/tis-editor/TisConfigEditor.css +20 -0
- package/src/components/tis-editor/editor/ConfigurationsEditor.tsx +242 -0
- package/src/components/tis-editor/editor/MethodFormEditor.tsx +4 -0
- package/src/components/tis-editor/types.ts +14 -0
- package/src/components/tis-editor/validation.ts +29 -0
- package/src/themes/adc-dark/_extensions.scss +20 -0
- package/src/themes/theme-base/components/panel/_fieldset.scss +2 -2
|
@@ -19,6 +19,7 @@ import { Distance, JogShort, JogMedium, JogLong } from '../assets';
|
|
|
19
19
|
import { Speed, SpeedSlow, SpeedMedium, SpeedFast } from '../assets';
|
|
20
20
|
import { RotationCcwA, RotationCcwB, RotationCcwC } from '../assets';
|
|
21
21
|
import { RotationCwA, RotationCwB, RotationCwC } from '../assets';
|
|
22
|
+
import { JogXPos, JogXNeg, JogYPos, JogYNeg, JogZPos, JogZNeg } from '../assets';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Enumerates the source button or action when an event occurs.
|
|
@@ -125,9 +126,9 @@ interface JogPanelState {
|
|
|
125
126
|
* A default jog button configuration for linear 3D motion.
|
|
126
127
|
*/
|
|
127
128
|
export const DefaultLinearJogButtons : (JogPanelButtonDefinition | undefined)[][] = [
|
|
128
|
-
[{ icon: "pi pi-arrow-up
|
|
129
|
+
[undefined, { icon: "pi pi-arrow-up", action: JogPanelAction.zPositive, alt: "Z Positive" }, { icon: "pi pi-arrow-down-left", action: JogPanelAction.yNegative, alt: "Y Negative" }],
|
|
129
130
|
[{ icon: "pi pi-arrow-left", action: JogPanelAction.xNegative, alt: "X Negative" }, undefined, { icon: "pi pi-arrow-right", action: JogPanelAction.xPositive, alt: "X Positive" }],
|
|
130
|
-
[
|
|
131
|
+
[{ icon: "pi pi-arrow-up-right", action: JogPanelAction.yPositive, alt: "Y Positive" }, { icon: "pi pi-arrow-down", action: JogPanelAction.zNegative, alt: "Z Negative" }, undefined],
|
|
131
132
|
];
|
|
132
133
|
|
|
133
134
|
/**
|
|
@@ -156,9 +157,9 @@ export const DefaultRotationJogButtons : (JogPanelButtonDefinition | undefined)[
|
|
|
156
157
|
* Example:
|
|
157
158
|
* ```
|
|
158
159
|
* export const kDefaultButtonDefinitions : (JogPanelButtonDefinition | undefined)[][] = [
|
|
159
|
-
* [{ icon: "pi pi-arrow-up
|
|
160
|
+
* [undefined, { icon: "pi pi-arrow-up", action: JogPanelAction.zPositive, alt: "Z Positive" }, { icon: "pi pi-arrow-down-left", action: JogPanelAction.yNegative, alt: "Y Negative" }],
|
|
160
161
|
* [{ icon: "pi pi-arrow-left", action: JogPanelAction.xNegative, alt: "X Negative" }, undefined, { icon: "pi pi-arrow-right", action: JogPanelAction.xPositive, alt: "X Positive" }],
|
|
161
|
-
* [
|
|
162
|
+
* [{ icon: "pi pi-arrow-up-right", action: JogPanelAction.yPositive, alt: "Y Positive" }, { icon: "pi pi-arrow-down", action: JogPanelAction.zNegative, alt: "Z Negative" }, undefined],
|
|
162
163
|
* ];
|
|
163
164
|
* ```
|
|
164
165
|
*
|
|
@@ -249,22 +250,22 @@ export class JogPanel extends React.Component<JogPanelProps, JogPanelState> {
|
|
|
249
250
|
return <i/>
|
|
250
251
|
}
|
|
251
252
|
else if (action == JogPanelAction.xNegative) {
|
|
252
|
-
return <
|
|
253
|
+
return <JogXNeg />
|
|
253
254
|
}
|
|
254
255
|
else if (action == JogPanelAction.xPositive) {
|
|
255
|
-
return <
|
|
256
|
+
return <JogXPos />
|
|
256
257
|
}
|
|
257
258
|
else if (action == JogPanelAction.yNegative) {
|
|
258
|
-
return <
|
|
259
|
+
return <JogYNeg />
|
|
259
260
|
}
|
|
260
261
|
else if (action == JogPanelAction.yPositive) {
|
|
261
|
-
return <
|
|
262
|
+
return <JogYPos />
|
|
262
263
|
}
|
|
263
264
|
else if (action == JogPanelAction.zNegative) {
|
|
264
|
-
return <
|
|
265
|
+
return <JogZNeg />
|
|
265
266
|
}
|
|
266
267
|
else if (action == JogPanelAction.zPositive) {
|
|
267
|
-
return <
|
|
268
|
+
return <JogZPos />
|
|
268
269
|
}
|
|
269
270
|
else if (action == JogPanelAction.aNegative) {
|
|
270
271
|
return <RotationCcwA />
|
|
@@ -299,24 +300,13 @@ export class JogPanel extends React.Component<JogPanelProps, JogPanelState> {
|
|
|
299
300
|
|
|
300
301
|
const action = this.props.buttonDefinitions[row][col]?.action;
|
|
301
302
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
/>
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
return <Button
|
|
313
|
-
key={`${row}-${col}`}
|
|
314
|
-
tooltip={this.props.buttonDefinitions[row][col]?.alt}
|
|
315
|
-
onClick={() => this.handleClicked(action)}
|
|
316
|
-
className="button-item"
|
|
317
|
-
icon={() => this.actionToIcon(action)}/>
|
|
318
|
-
}
|
|
319
|
-
|
|
303
|
+
return <Button
|
|
304
|
+
key={`${row}-${col}`}
|
|
305
|
+
tooltip={this.props.buttonDefinitions[row][col]?.alt}
|
|
306
|
+
onClick={() => this.handleClicked(action)}
|
|
307
|
+
className="button-item"
|
|
308
|
+
icon={() => this.actionToIcon(action)}/>
|
|
309
|
+
|
|
320
310
|
}
|
|
321
311
|
else {
|
|
322
312
|
return <Button icon="pi" key={`${row}-${col}`} disabled={true} className="button-item empty-slot" />
|
|
@@ -235,7 +235,7 @@ export const AssetDetailView: React.FC = () => {
|
|
|
235
235
|
<Button label="Edit" icon="pi pi-pencil"
|
|
236
236
|
outlined
|
|
237
237
|
onClick={() => setEditDialogOpen(true)}
|
|
238
|
-
tooltip="Edit role, nameplate, and per-axis values. Type
|
|
238
|
+
tooltip="Edit serial, role, nameplate, and per-axis values. Type and install date are immutable."
|
|
239
239
|
tooltipOptions={{ position: 'left' }}
|
|
240
240
|
/>
|
|
241
241
|
{asset.status === 'active' && (
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
* `asset.current_calibration_id` is non-null. Posts via
|
|
10
10
|
* `ams.update_calibration` (server enforces "current only"). Tab
|
|
11
11
|
* is hidden entirely for assets that never had a calibration —
|
|
12
|
-
* "
|
|
12
|
+
* "Calibration" on <AssetDetailView> is the path to add one.
|
|
13
13
|
*
|
|
14
|
-
* The server treats `asset_id`, `asset_type`, `
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* The server treats `asset_id`, `asset_type`, and `install_date` as
|
|
15
|
+
* immutable; the read-only header strip mirrors that. `serial` is
|
|
16
|
+
* editable (free-form traceability metadata) so a mis-keyed serial can
|
|
17
|
+
* be corrected here. Status stays out of this dialog because the Retire
|
|
18
|
+
* button on <AssetDetailView> already owns that transition.
|
|
18
19
|
*
|
|
19
20
|
* Save commits the Asset tab first, then (if a calibration is loaded)
|
|
20
21
|
* the Calibration tab. Either failure surfaces inline and stops; the
|
|
@@ -175,6 +176,7 @@ export const AssetEditDialog: React.FC<AssetEditDialogProps> = ({
|
|
|
175
176
|
// effect below.
|
|
176
177
|
const [roleSelection, setRoleSelection] = useState<string>('');
|
|
177
178
|
const [location, setLocation] = useState<string>('');
|
|
179
|
+
const [serial, setSerial] = useState<string>('');
|
|
178
180
|
const [customFields, setCustomFields] =
|
|
179
181
|
useState<Record<string, string>>({});
|
|
180
182
|
const [subLocationFields, setSubLocationFields] =
|
|
@@ -215,6 +217,9 @@ export const AssetEditDialog: React.FC<AssetEditDialogProps> = ({
|
|
|
215
217
|
setSubmitting(false);
|
|
216
218
|
setActiveTab(0);
|
|
217
219
|
|
|
220
|
+
// Serial: free-form, editable so operators can correct a typo.
|
|
221
|
+
setSerial(typeof asset.serial === 'string' ? asset.serial : '');
|
|
222
|
+
|
|
218
223
|
// Role: pick the dropdown option when the asset's location
|
|
219
224
|
// matches a declared role; otherwise route into ROLE_OTHER so
|
|
220
225
|
// the operator can keep the current custom string.
|
|
@@ -365,6 +370,7 @@ export const AssetEditDialog: React.FC<AssetEditDialogProps> = ({
|
|
|
365
370
|
const payload: any = {
|
|
366
371
|
asset_id: asset.asset_id,
|
|
367
372
|
location,
|
|
373
|
+
serial,
|
|
368
374
|
custom,
|
|
369
375
|
};
|
|
370
376
|
if (subLocations) payload.sub_locations = subLocations;
|
|
@@ -481,10 +487,11 @@ export const AssetEditDialog: React.FC<AssetEditDialogProps> = ({
|
|
|
481
487
|
</>
|
|
482
488
|
}
|
|
483
489
|
>
|
|
484
|
-
{/* Read-only context strip — type,
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
490
|
+
{/* Read-only context strip — type, install_date. The server
|
|
491
|
+
treats these as immutable; surfacing them here keeps the
|
|
492
|
+
operator oriented without inviting an edit that would
|
|
493
|
+
silently no-op. Serial moved into the editable Asset tab
|
|
494
|
+
below so operators can correct a mis-entered serial. */}
|
|
488
495
|
<div style={{ display: 'grid',
|
|
489
496
|
gridTemplateColumns: 'auto 1fr',
|
|
490
497
|
gap: '0.25rem 1rem',
|
|
@@ -492,7 +499,6 @@ export const AssetEditDialog: React.FC<AssetEditDialogProps> = ({
|
|
|
492
499
|
color: 'var(--text-secondary-color)',
|
|
493
500
|
marginBottom: '0.75rem' }}>
|
|
494
501
|
<span>Type</span> <span>{typeLabel}</span>
|
|
495
|
-
<span>Serial</span> <span>{asset.serial || <em>(none)</em>}</span>
|
|
496
502
|
{asset.install_date && (
|
|
497
503
|
<>
|
|
498
504
|
<span>Installed</span>
|
|
@@ -507,6 +513,15 @@ export const AssetEditDialog: React.FC<AssetEditDialogProps> = ({
|
|
|
507
513
|
gridTemplateColumns: 'auto 1fr',
|
|
508
514
|
gap: '0.5rem 1rem',
|
|
509
515
|
alignItems: 'center' }}>
|
|
516
|
+
{/* Serial — free-form manufacturer metadata. Editable so
|
|
517
|
+
a mis-entered serial can be corrected after the fact. */}
|
|
518
|
+
<label>Serial</label>
|
|
519
|
+
<InputText
|
|
520
|
+
value={serial}
|
|
521
|
+
placeholder="(none)"
|
|
522
|
+
onChange={(e) => setSerial(e.target.value)}
|
|
523
|
+
/>
|
|
524
|
+
|
|
510
525
|
{/* Role field. Asset types referenced only by_id_field
|
|
511
526
|
(no by_location asset_ref) come back with an empty
|
|
512
527
|
role list — we hide the row entirely so the operator
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Touch-friendly row sizing for the AMS asset list.
|
|
3
|
+
*
|
|
4
|
+
* The shop-floor HMI is a touchscreen and operators were mis-tapping
|
|
5
|
+
* the dense default DataTable rows. Adding vertical padding to each
|
|
6
|
+
* body cell enlarges the per-row touch target without changing the
|
|
7
|
+
* column layout or text size.
|
|
8
|
+
*/
|
|
9
|
+
.ams-asset-table .p-datatable-tbody > tr > td {
|
|
10
|
+
padding-top: 0.9rem;
|
|
11
|
+
padding-bottom: 0.9rem;
|
|
12
|
+
}
|
|
@@ -15,6 +15,7 @@ import { Dialog } from 'primereact/dialog';
|
|
|
15
15
|
import { EventEmitterContext } from '../../core/EventEmitterContext';
|
|
16
16
|
import { MessageType } from '../../hub/CommandMessage';
|
|
17
17
|
import { useAms, type AmsAssetEntry, type AmsRole } from './AmsProvider';
|
|
18
|
+
import './AssetRegistryTable.css';
|
|
18
19
|
|
|
19
20
|
// Sentinel value for the "Other..." dropdown option, which lets the
|
|
20
21
|
// operator type a free-form role for the rare case (custom builds,
|
|
@@ -433,8 +434,11 @@ export const AssetRegistryTable: React.FC = () => {
|
|
|
433
434
|
? 'AMS not enabled in this project (no asset_types declared).'
|
|
434
435
|
: 'No assets registered yet.'
|
|
435
436
|
}
|
|
436
|
-
size="small"
|
|
437
437
|
stripedRows
|
|
438
|
+
/* Extra vertical padding on body cells (see the CSS) enlarges
|
|
439
|
+
the touch target for each row — operators on the shop-floor
|
|
440
|
+
touchscreen were mis-tapping the dense default rows. */
|
|
441
|
+
className="ams-asset-table"
|
|
438
442
|
>
|
|
439
443
|
<Column field="asset_id" header="Asset ID" />
|
|
440
444
|
<Column field="asset_type" header="Type"
|
|
@@ -481,9 +485,16 @@ export const AssetRegistryTable: React.FC = () => {
|
|
|
481
485
|
onChange={(e) => onAssetTypeChange(e.value)}
|
|
482
486
|
placeholder="Choose asset type"
|
|
483
487
|
/>
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
488
|
+
{/* Serial: hidden until a type is chosen. Showing it
|
|
489
|
+
before the type led operators to fill it in for a
|
|
490
|
+
not-yet-selected asset, which read as confusing. */}
|
|
491
|
+
{addState.assetType && (
|
|
492
|
+
<>
|
|
493
|
+
<label>Serial</label>
|
|
494
|
+
<InputText value={addState.serial}
|
|
495
|
+
onChange={(e) => setAddState(s => ({ ...s, serial: e.target.value }))} />
|
|
496
|
+
</>
|
|
497
|
+
)}
|
|
487
498
|
|
|
488
499
|
{/* Role field: only shown when this asset_type has at
|
|
489
500
|
least one declared role in project.json. Asset
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2026 Automated Design Corp. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* <ConfigurationDialog> — picker UI for choosing a method's named
|
|
5
|
+
* configuration (see `TestMethod.configurations`). Mirrors
|
|
6
|
+
* <TestMethodDialog>: a dropdown of the configurations declared on the
|
|
7
|
+
* active method plus the long-form description for whichever entry is
|
|
8
|
+
* highlighted. OK applies the choice via the supplied callback (which
|
|
9
|
+
* writes the configuration's `defaults` into the config_fields); Cancel
|
|
10
|
+
* discards.
|
|
11
|
+
*
|
|
12
|
+
* Only mounted by <TestSetupForm> when the active method declares one or
|
|
13
|
+
* more configurations, so the empty case is informational only.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
17
|
+
import { Button } from 'primereact/button';
|
|
18
|
+
import { Dialog } from 'primereact/dialog';
|
|
19
|
+
import { Dropdown } from 'primereact/dropdown';
|
|
20
|
+
import type { TestConfiguration } from './TestSetupForm';
|
|
21
|
+
|
|
22
|
+
/** Display name for one configuration: prefer `label`, fall back to `name`. */
|
|
23
|
+
export const configLabelOf = (cfg: TestConfiguration | undefined): string =>
|
|
24
|
+
(cfg?.label && cfg.label.length > 0) ? cfg.label : (cfg?.name ?? '');
|
|
25
|
+
|
|
26
|
+
export interface ConfigurationDialogProps {
|
|
27
|
+
visible: boolean;
|
|
28
|
+
onHide: () => void;
|
|
29
|
+
/** Configurations declared on the active method. */
|
|
30
|
+
configurations: TestConfiguration[];
|
|
31
|
+
/** `name` of the configuration currently applied on the form. The
|
|
32
|
+
* dropdown opens pointing at this so the dialog reflects state. */
|
|
33
|
+
currentConfigName: string;
|
|
34
|
+
/**
|
|
35
|
+
* Called with the chosen configuration `name` when the operator
|
|
36
|
+
* clicks OK. Cancel does not fire this. The parent applies the
|
|
37
|
+
* configuration's defaults to the fields.
|
|
38
|
+
*/
|
|
39
|
+
onSelected: (configName: string) => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const ConfigurationDialog: React.FC<ConfigurationDialogProps> = ({
|
|
43
|
+
visible, onHide, configurations, currentConfigName, onSelected,
|
|
44
|
+
}) => {
|
|
45
|
+
// Local "draft" selection — the dropdown writes here; OK applies it,
|
|
46
|
+
// so a Cancel really cancels (matches <TestMethodDialog>).
|
|
47
|
+
const [draftName, setDraftName] = useState<string>(currentConfigName);
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (visible) setDraftName(currentConfigName);
|
|
51
|
+
}, [visible, currentConfigName]);
|
|
52
|
+
|
|
53
|
+
const options = useMemo(
|
|
54
|
+
() => configurations.map(cfg => ({ label: configLabelOf(cfg), value: cfg.name })),
|
|
55
|
+
[configurations],
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const draftCfg = configurations.find(c => c.name === draftName);
|
|
59
|
+
const draftDescription =
|
|
60
|
+
(draftCfg?.description && draftCfg.description.length > 0)
|
|
61
|
+
? draftCfg.description
|
|
62
|
+
: null;
|
|
63
|
+
|
|
64
|
+
const handleOk = () => {
|
|
65
|
+
if (draftName && draftName !== currentConfigName) {
|
|
66
|
+
onSelected(draftName);
|
|
67
|
+
}
|
|
68
|
+
onHide();
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const footer = (
|
|
72
|
+
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: '0.5rem' }}>
|
|
73
|
+
<Button label="Cancel" icon="pi pi-times" onClick={onHide} text />
|
|
74
|
+
<Button label="OK" icon="pi pi-check" onClick={handleOk} disabled={!draftName} />
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<Dialog
|
|
80
|
+
header="Select Configuration"
|
|
81
|
+
visible={visible}
|
|
82
|
+
onHide={onHide}
|
|
83
|
+
footer={footer}
|
|
84
|
+
modal
|
|
85
|
+
style={{ width: 'min(560px, 90vw)' }}
|
|
86
|
+
>
|
|
87
|
+
{options.length === 0 ? (
|
|
88
|
+
<p style={{ color: 'var(--text-secondary-color)' }}>
|
|
89
|
+
This test method declares no configurations.
|
|
90
|
+
</p>
|
|
91
|
+
) : (
|
|
92
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
|
93
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
|
|
94
|
+
<label htmlFor="acConfigurationDropdown" style={{ flexShrink: 0 }}>
|
|
95
|
+
Configuration:
|
|
96
|
+
</label>
|
|
97
|
+
<Dropdown
|
|
98
|
+
inputId="acConfigurationDropdown"
|
|
99
|
+
value={draftName}
|
|
100
|
+
options={options}
|
|
101
|
+
onChange={(e) => setDraftName(e.value)}
|
|
102
|
+
placeholder="Select a configuration"
|
|
103
|
+
style={{ flex: 1 }}
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
106
|
+
{/* Stable-height description region, matching
|
|
107
|
+
<TestMethodDialog>: render a muted placeholder
|
|
108
|
+
rather than collapsing the dialog. */}
|
|
109
|
+
<div
|
|
110
|
+
style={{
|
|
111
|
+
padding: '0.75rem 1rem',
|
|
112
|
+
background: 'var(--surface-100)',
|
|
113
|
+
borderRadius: '6px',
|
|
114
|
+
minHeight: '4.5rem',
|
|
115
|
+
color: draftDescription
|
|
116
|
+
? 'var(--text-color)'
|
|
117
|
+
: 'var(--text-secondary-color)',
|
|
118
|
+
fontStyle: draftDescription ? 'normal' : 'italic',
|
|
119
|
+
whiteSpace: 'pre-wrap',
|
|
120
|
+
}}
|
|
121
|
+
>
|
|
122
|
+
{draftDescription ?? 'No description provided for this configuration.'}
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
)}
|
|
126
|
+
</Dialog>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
@@ -300,7 +300,7 @@ export const ResultHistoryTable: React.FC<ResultHistoryTableProps> = (props) =>
|
|
|
300
300
|
<div style={{ display: 'flex', gap: '0.4rem' }}>
|
|
301
301
|
<Button
|
|
302
302
|
icon={isDataBusy ? 'pi pi-spin pi-spinner' : 'pi pi-download'}
|
|
303
|
-
label="
|
|
303
|
+
label="Raw"
|
|
304
304
|
size="small"
|
|
305
305
|
outlined
|
|
306
306
|
disabled={anyBusy}
|
|
@@ -310,7 +310,7 @@ export const ResultHistoryTable: React.FC<ResultHistoryTableProps> = (props) =>
|
|
|
310
310
|
/>
|
|
311
311
|
<Button
|
|
312
312
|
icon={isReportBusy ? 'pi pi-spin pi-spinner' : 'pi pi-file'}
|
|
313
|
-
label="
|
|
313
|
+
label="Results"
|
|
314
314
|
size="small"
|
|
315
315
|
outlined
|
|
316
316
|
disabled={anyBusy}
|