@openg2p/registry-widgets 1.0.0 → 1.0.2
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/components/SectionRenderer.d.ts +1 -0
- package/dist/components/SectionRenderer.d.ts.map +1 -1
- package/dist/components/SectionsContainer.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +242 -123
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +242 -123
- package/dist/index.js.map +1 -1
- package/dist/theme/index.d.ts +35 -9
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/widgets/DisplayWidget.d.ts.map +1 -1
- package/dist/widgets/HeaderSectionWidget.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionRenderer.d.ts","sourceRoot":"","sources":["../../src/components/SectionRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAM9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"SectionRenderer.d.ts","sourceRoot":"","sources":["../../src/components/SectionRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAM9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA0ClD,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,wBAAwB,CAAC,EAAE,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAClC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAGjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,2GAA2G;IAC3G,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAErE,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oGAAoG;IACpG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,uGAAuG;IACvG,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,0HAA0H;IAC1H,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,iGAAiG;IACjG,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAGD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,wZAwB7B,oBAAoB,4CAm8CtB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionsContainer.d.ts","sourceRoot":"","sources":["../../src/components/SectionsContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAmB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOpE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnE,uHAAuH;AACvH,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,qEAAqE;IACrE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,qFAAqF;IACrF,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAClD;;;OAGG;IACD,iBAAiB,IAAI,cAAc,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAEpE,wHAAwH;IACxH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrE,0JAA0J;IAC1J,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACpD;AA4ED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,yMAa/B,sBAAsB,
|
|
1
|
+
{"version":3,"file":"SectionsContainer.d.ts","sourceRoot":"","sources":["../../src/components/SectionsContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAmB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOpE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnE,uHAAuH;AACvH,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,qEAAqE;IACrE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,qFAAqF;IACrF,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAClD;;;OAGG;IACD,iBAAiB,IAAI,cAAc,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAEpE,wHAAwH;IACxH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrE,0JAA0J;IAC1J,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACpD;AA4ED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,yMAa/B,sBAAsB,4CAqSxB,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -3515,6 +3515,39 @@ const sectionValidate = (section, currentSchemaData, dispatch) => {
|
|
|
3515
3515
|
return isValid;
|
|
3516
3516
|
};
|
|
3517
3517
|
|
|
3518
|
+
/** Root class on readonly label/value rows; SectionRenderer scopes overflow/ellipsis rules here. */
|
|
3519
|
+
const READONLY_VALUE_ROW_ROOT_CLASSES = [
|
|
3520
|
+
'TextDisplayWidget',
|
|
3521
|
+
'TextAreaDisplayWidget',
|
|
3522
|
+
'SelectDisplayWidget',
|
|
3523
|
+
'PhoneDisplayWidget',
|
|
3524
|
+
'NumberDisplayWidget',
|
|
3525
|
+
'CurrencyDisplayWidget',
|
|
3526
|
+
'RadioDisplayWidget',
|
|
3527
|
+
'DateDisplayWidget',
|
|
3528
|
+
'DateTimeDisplayWidget',
|
|
3529
|
+
'CheckboxDisplayWidget',
|
|
3530
|
+
'BooleanDisplayWidget',
|
|
3531
|
+
'FileDisplayWidget',
|
|
3532
|
+
'DisplayFieldWidget',
|
|
3533
|
+
];
|
|
3534
|
+
/** Rows whose value is one line in .flex-1 > .text-gray-900 (ellipsis; full string via title on the element). */
|
|
3535
|
+
const READONLY_SINGLE_LINE_VALUE_ROW_CLASSES = [
|
|
3536
|
+
'TextDisplayWidget',
|
|
3537
|
+
'SelectDisplayWidget',
|
|
3538
|
+
'PhoneDisplayWidget',
|
|
3539
|
+
'NumberDisplayWidget',
|
|
3540
|
+
'CurrencyDisplayWidget',
|
|
3541
|
+
'RadioDisplayWidget',
|
|
3542
|
+
'DateDisplayWidget',
|
|
3543
|
+
'DateTimeDisplayWidget',
|
|
3544
|
+
'CheckboxDisplayWidget',
|
|
3545
|
+
'BooleanDisplayWidget',
|
|
3546
|
+
'DisplayFieldWidget',
|
|
3547
|
+
];
|
|
3548
|
+
function scopedClassSelectors(sectionClassId, classNames) {
|
|
3549
|
+
return classNames.map((c) => `.${sectionClassId} .${c}`).join(',\n ');
|
|
3550
|
+
}
|
|
3518
3551
|
/**
|
|
3519
3552
|
* Renders a section with its panels
|
|
3520
3553
|
*
|
|
@@ -3541,41 +3574,22 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3541
3574
|
}
|
|
3542
3575
|
return section;
|
|
3543
3576
|
}, [section, namespace]);
|
|
3544
|
-
// Create namespaced schemaData if namespace is provided
|
|
3545
|
-
//
|
|
3577
|
+
// Create namespaced schemaData if namespace is provided.
|
|
3578
|
+
// Widgets with namespaced data-paths (e.g. "rv-section-0.a1a4d25a.birth_date")
|
|
3579
|
+
// need a nested object at values[namespace] so getValueByPath can traverse it.
|
|
3546
3580
|
const namespacedSchemaData = useMemo(() => {
|
|
3547
3581
|
if (!namespace || !currentSchemaData) {
|
|
3548
3582
|
return schemaData;
|
|
3549
3583
|
}
|
|
3550
|
-
|
|
3551
|
-
const namespaced = { ...currentSchemaData };
|
|
3552
|
-
// Copy all top-level keys to namespaced paths
|
|
3553
|
-
Object.keys(currentSchemaData).forEach(key => {
|
|
3554
|
-
const namespacedKey = `${namespace}.${key}`;
|
|
3555
|
-
if (!(namespacedKey in namespaced)) {
|
|
3556
|
-
namespaced[namespacedKey] = currentSchemaData[key];
|
|
3557
|
-
}
|
|
3558
|
-
});
|
|
3559
|
-
// Also handle nested objects - copy nested values to namespaced paths
|
|
3560
|
-
const copyNestedValues = (obj, prefix = '') => {
|
|
3561
|
-
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
3562
|
-
Object.keys(obj).forEach(key => {
|
|
3563
|
-
const fullPath = prefix ? `${prefix}.${key}` : key;
|
|
3564
|
-
const namespacedPath = `${namespace}.${fullPath}`;
|
|
3565
|
-
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
|
|
3566
|
-
copyNestedValues(obj[key], fullPath);
|
|
3567
|
-
// Also set the nested object at the namespaced path
|
|
3568
|
-
setValueByPath(namespaced, namespacedPath, obj[key]);
|
|
3569
|
-
}
|
|
3570
|
-
else {
|
|
3571
|
-
setValueByPath(namespaced, namespacedPath, obj[key]);
|
|
3572
|
-
}
|
|
3573
|
-
});
|
|
3574
|
-
}
|
|
3575
|
-
};
|
|
3576
|
-
copyNestedValues(currentSchemaData);
|
|
3577
|
-
return namespaced;
|
|
3584
|
+
return { ...currentSchemaData, [namespace]: currentSchemaData };
|
|
3578
3585
|
}, [namespace, schemaData, currentSchemaData]);
|
|
3586
|
+
// Populate the store with namespaced schema data so that namespaced widgets
|
|
3587
|
+
// can read their initial values via getValueByPath on the namespaced paths.
|
|
3588
|
+
useEffect(() => {
|
|
3589
|
+
if (namespace && namespacedSchemaData) {
|
|
3590
|
+
dispatch(setValues(namespacedSchemaData));
|
|
3591
|
+
}
|
|
3592
|
+
}, [namespace, namespacedSchemaData, dispatch]);
|
|
3579
3593
|
const crViewData = useMemo(() => {
|
|
3580
3594
|
if (mode !== 'CRView')
|
|
3581
3595
|
return null;
|
|
@@ -3598,6 +3612,9 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3598
3612
|
const sectionId = sectionToRender['section-id'];
|
|
3599
3613
|
const gridId = `section-panels-${sectionId}`;
|
|
3600
3614
|
const sectionClassId = `section-${sectionId}`;
|
|
3615
|
+
const readonlyValueRowRootsCss = useMemo(() => scopedClassSelectors(sectionClassId, READONLY_VALUE_ROW_ROOT_CLASSES), [sectionClassId]);
|
|
3616
|
+
const readonlyValueRowFlex1Css = useMemo(() => READONLY_VALUE_ROW_ROOT_CLASSES.map((c) => `.${sectionClassId} .${c} > .flex-1`).join(',\n '), [sectionClassId]);
|
|
3617
|
+
const readonlySingleLineValueTextCss = useMemo(() => READONLY_SINGLE_LINE_VALUE_ROW_CLASSES.map((c) => `.${sectionClassId} .${c} > .flex-1 > .text-gray-900`).join(',\n '), [sectionClassId]);
|
|
3601
3618
|
// IntakeForm mode: accordion expand/collapse state (supports toggle)
|
|
3602
3619
|
const [standaloneExpanded, setStandaloneExpanded] = useState(true); // For sectionIndex undefined (standalone use)
|
|
3603
3620
|
const isExpandedFromContainer = typeof sectionIndex === 'number' && expandedSectionIndex === sectionIndex;
|
|
@@ -3937,6 +3954,8 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3937
3954
|
const baselineSnapshotRef = useRef(null);
|
|
3938
3955
|
// IntakeForm only: increment when baseline is updated after save - forces badge to update (refs don't trigger re-renders)
|
|
3939
3956
|
const [intakeFormBaselineTrigger, setIntakeFormBaselineTrigger] = useState(0);
|
|
3957
|
+
// IntakeForm only: tracks whether the user has actually saved this section (prevents "Saved" badge on initial load)
|
|
3958
|
+
const [hasBeenSavedByUser, setHasBeenSavedByUser] = useState(false);
|
|
3940
3959
|
// IntakeForm: treat as edit mode for dirty tracking when isDraft. RegistryView: use isEditMode.
|
|
3941
3960
|
const effectiveEditModeForDirty = mode === 'IntakeForm' ? (isDraft !== false) : isEditMode;
|
|
3942
3961
|
// Compute isDirty: compare current store state to baseline (only when in edit mode)
|
|
@@ -3979,18 +3998,68 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3979
3998
|
const intakeFormSectionStatus = useMemo(() => {
|
|
3980
3999
|
if (mode !== 'IntakeForm' || isDraft === false)
|
|
3981
4000
|
return null;
|
|
3982
|
-
const hasValue = (v) => v !== undefined && v !== null && (typeof v !== 'string' || v.trim().length > 0);
|
|
3983
|
-
const currentSnapshot = buildSectionSnapshot(storeValues, namespace);
|
|
3984
|
-
const record = currentSnapshot.records?.[0];
|
|
3985
|
-
const hasData = record &&
|
|
3986
|
-
typeof record === 'object' &&
|
|
3987
|
-
Object.values(record).some((v) => hasValue(v));
|
|
3988
4001
|
if (isDirty)
|
|
3989
4002
|
return 'modified';
|
|
3990
|
-
if (
|
|
4003
|
+
if (hasBeenSavedByUser)
|
|
3991
4004
|
return 'saved';
|
|
3992
4005
|
return null;
|
|
3993
|
-
}, [mode, isDirty,
|
|
4006
|
+
}, [mode, isDirty, hasBeenSavedByUser]);
|
|
4007
|
+
// Revert store values to the original schemaData for this section's widgets.
|
|
4008
|
+
// Used by both handleSave (RegistryView raises a CR, so values should not persist)
|
|
4009
|
+
// and handleCancel.
|
|
4010
|
+
const revertToOriginalValues = useCallback(() => {
|
|
4011
|
+
const sectionWidgets = collectWidgets(originalSection.panels);
|
|
4012
|
+
const oldSchemaData = schemaData || contextSchemaData;
|
|
4013
|
+
const currentStoreValues = store.getState().widget.values;
|
|
4014
|
+
let newStoreValues = currentStoreValues;
|
|
4015
|
+
sectionWidgets.forEach(widget => {
|
|
4016
|
+
const originalWidgetId = widget['widget-id'];
|
|
4017
|
+
const namespacedWidgetId = namespace ? `${namespace}__${originalWidgetId}` : originalWidgetId;
|
|
4018
|
+
const widgetId = namespacedWidgetId;
|
|
4019
|
+
const originalDataPath = widget['widget-data-path'];
|
|
4020
|
+
const storeDataPath = namespace && originalDataPath
|
|
4021
|
+
? (typeof originalDataPath === 'string'
|
|
4022
|
+
? `${namespace}.${originalDataPath}`
|
|
4023
|
+
: Object.fromEntries(Object.entries(originalDataPath).map(([key, path]) => [key, `${namespace}.${path}`])))
|
|
4024
|
+
: originalDataPath;
|
|
4025
|
+
if (widgetId && originalDataPath) {
|
|
4026
|
+
let oldValue;
|
|
4027
|
+
if (typeof originalDataPath === 'object') {
|
|
4028
|
+
oldValue = {};
|
|
4029
|
+
Object.entries(originalDataPath).forEach(([key, path]) => {
|
|
4030
|
+
if (typeof path === 'string') {
|
|
4031
|
+
oldValue[key] = getValueByPath(oldSchemaData, path);
|
|
4032
|
+
}
|
|
4033
|
+
});
|
|
4034
|
+
}
|
|
4035
|
+
else if (typeof originalDataPath === 'string') {
|
|
4036
|
+
oldValue = getValueByPath(oldSchemaData, originalDataPath);
|
|
4037
|
+
}
|
|
4038
|
+
if (oldValue !== undefined) {
|
|
4039
|
+
newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
|
|
4040
|
+
// Also revert the widgetId-based entry — useBaseWidget.handleChange
|
|
4041
|
+
// sets values[widgetId] during editing, and useBaseWidget.currentValue
|
|
4042
|
+
// reads values[widgetId] first before falling through to the dataPath.
|
|
4043
|
+
newStoreValues = { ...newStoreValues, [widgetId]: oldValue };
|
|
4044
|
+
}
|
|
4045
|
+
}
|
|
4046
|
+
});
|
|
4047
|
+
if (hasSupportingDocuments) {
|
|
4048
|
+
const originalSupportingDocuments = originalSection['section-supporting-documents'] || [];
|
|
4049
|
+
originalSupportingDocuments.forEach((doc, index) => {
|
|
4050
|
+
const widgetId = `supporting-doc-${sectionId}-${index}`;
|
|
4051
|
+
const originalDataPath = doc['document-data-path'];
|
|
4052
|
+
const storeDataPath = namespace && originalDataPath
|
|
4053
|
+
? `${namespace}.${originalDataPath}`
|
|
4054
|
+
: originalDataPath;
|
|
4055
|
+
const oldValue = getValueByPath(oldSchemaData, originalDataPath);
|
|
4056
|
+
newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
|
|
4057
|
+
});
|
|
4058
|
+
}
|
|
4059
|
+
if (newStoreValues !== currentStoreValues) {
|
|
4060
|
+
dispatch(setValues(newStoreValues));
|
|
4061
|
+
}
|
|
4062
|
+
}, [originalSection, schemaData, contextSchemaData, store, namespace, hasSupportingDocuments, sectionId, dispatch]);
|
|
3994
4063
|
// Handle save button click
|
|
3995
4064
|
const handleSave = async () => {
|
|
3996
4065
|
if (!store || !onSectionSave) {
|
|
@@ -4027,12 +4096,24 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4027
4096
|
});
|
|
4028
4097
|
}
|
|
4029
4098
|
if (JSON.stringify(oldSchemaData) !== JSON.stringify(newSchemaData)) {
|
|
4099
|
+
let profileImage = null;
|
|
4100
|
+
for (const record of newSchemaData) {
|
|
4101
|
+
if (typeof record === 'object' && record !== null) {
|
|
4102
|
+
for (const [key, value] of Object.entries(record)) {
|
|
4103
|
+
if (value instanceof File) {
|
|
4104
|
+
profileImage = value;
|
|
4105
|
+
record[key] = '';
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4030
4110
|
try {
|
|
4031
4111
|
const sectionchanges = {
|
|
4032
4112
|
section_id: dbSectionId ?? originalSection['section-id'],
|
|
4033
4113
|
section_register_id: sectionRegisterId,
|
|
4034
4114
|
records: [...newSchemaData],
|
|
4035
|
-
files: [...sectionFiles]
|
|
4115
|
+
files: [...sectionFiles],
|
|
4116
|
+
...(profileImage ? { image: profileImage } : {}),
|
|
4036
4117
|
};
|
|
4037
4118
|
await onSectionSave(sectionchanges);
|
|
4038
4119
|
}
|
|
@@ -4040,6 +4121,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4040
4121
|
console.error('Section Changes Save failed', error);
|
|
4041
4122
|
}
|
|
4042
4123
|
}
|
|
4124
|
+
// In RegistryView, save raises a CR — the actual data update follows a
|
|
4125
|
+
// separate approval workflow, so revert the displayed values to the
|
|
4126
|
+
// originals so the view doesn't show unapproved edits.
|
|
4127
|
+
if (mode === 'RegistryView') {
|
|
4128
|
+
revertToOriginalValues();
|
|
4129
|
+
}
|
|
4043
4130
|
setIsEditMode(false);
|
|
4044
4131
|
onEditModeChange?.(originalSectionId, false);
|
|
4045
4132
|
};
|
|
@@ -4069,12 +4156,24 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4069
4156
|
});
|
|
4070
4157
|
}
|
|
4071
4158
|
if (JSON.stringify(oldSchemaData) !== JSON.stringify(newSchemaData)) {
|
|
4159
|
+
let profileImage = null;
|
|
4160
|
+
for (const record of newSchemaData) {
|
|
4161
|
+
if (typeof record === 'object' && record !== null) {
|
|
4162
|
+
for (const [key, value] of Object.entries(record)) {
|
|
4163
|
+
if (value instanceof File) {
|
|
4164
|
+
profileImage = value;
|
|
4165
|
+
record[key] = '';
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4072
4170
|
try {
|
|
4073
4171
|
await onSectionSave({
|
|
4074
4172
|
section_id: dbSectionId ?? originalSection['section-id'],
|
|
4075
4173
|
section_register_id: sectionRegisterId,
|
|
4076
4174
|
records: [...newSchemaData],
|
|
4077
4175
|
files: [...sectionFiles],
|
|
4176
|
+
...(profileImage ? { image: profileImage } : {}),
|
|
4078
4177
|
});
|
|
4079
4178
|
}
|
|
4080
4179
|
catch (error) {
|
|
@@ -4085,6 +4184,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4085
4184
|
if (mode === 'IntakeForm') {
|
|
4086
4185
|
baselineSnapshotRef.current = buildSectionSnapshot(currentSchemaData, namespace);
|
|
4087
4186
|
setIntakeFormBaselineTrigger((prev) => prev + 1);
|
|
4187
|
+
setHasBeenSavedByUser(true);
|
|
4088
4188
|
}
|
|
4089
4189
|
onSectionDirtyChange?.(sectionId, false);
|
|
4090
4190
|
}
|
|
@@ -4093,64 +4193,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4093
4193
|
}, [store, onSectionSave, onSectionSaveSuccess, sectionIndex, originalSection, schemaData, contextSchemaData, namespace, hasSupportingDocuments, dbSectionId, sectionRegisterId, dispatch, buildSectionSnapshot, sectionId, onSectionDirtyChange, mode, isDraft]);
|
|
4094
4194
|
// Handle cancel button click
|
|
4095
4195
|
const handleCancel = () => {
|
|
4096
|
-
|
|
4097
|
-
// Use original section (without namespace) for collecting widgets
|
|
4098
|
-
const sectionWidgets = collectWidgets(originalSection.panels);
|
|
4099
|
-
const oldSchemaData = schemaData || contextSchemaData;
|
|
4100
|
-
const currentStoreValues = store.getState().widget.values;
|
|
4101
|
-
let newStoreValues = currentStoreValues;
|
|
4102
|
-
sectionWidgets.forEach(widget => {
|
|
4103
|
-
const originalWidgetId = widget['widget-id'];
|
|
4104
|
-
// If namespace was used, we need to use namespaced widget ID and data path
|
|
4105
|
-
const namespacedWidgetId = namespace ? `${namespace}__${originalWidgetId}` : originalWidgetId;
|
|
4106
|
-
const widgetId = namespacedWidgetId;
|
|
4107
|
-
const originalDataPath = widget['widget-data-path'];
|
|
4108
|
-
// If namespace was used, data path in store is namespaced, but we read from original schema using original path
|
|
4109
|
-
const storeDataPath = namespace && originalDataPath
|
|
4110
|
-
? (typeof originalDataPath === 'string'
|
|
4111
|
-
? `${namespace}.${originalDataPath}`
|
|
4112
|
-
: Object.fromEntries(Object.entries(originalDataPath).map(([key, path]) => [key, `${namespace}.${path}`])))
|
|
4113
|
-
: originalDataPath;
|
|
4114
|
-
if (widgetId && originalDataPath) {
|
|
4115
|
-
// Handle multi-path (object) or single path (string)
|
|
4116
|
-
// Read from original schema data using original paths
|
|
4117
|
-
let oldValue;
|
|
4118
|
-
if (typeof originalDataPath === 'object') {
|
|
4119
|
-
// Multi-path: get values for each path
|
|
4120
|
-
oldValue = {};
|
|
4121
|
-
Object.entries(originalDataPath).forEach(([key, path]) => {
|
|
4122
|
-
if (typeof path === 'string') {
|
|
4123
|
-
oldValue[key] = getValueByPath(oldSchemaData, path);
|
|
4124
|
-
}
|
|
4125
|
-
});
|
|
4126
|
-
}
|
|
4127
|
-
else if (typeof originalDataPath === 'string') {
|
|
4128
|
-
oldValue = getValueByPath(oldSchemaData, originalDataPath);
|
|
4129
|
-
}
|
|
4130
|
-
// Set in store using namespaced data path (if namespace was used)
|
|
4131
|
-
if (oldValue !== undefined) {
|
|
4132
|
-
newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
|
|
4133
|
-
}
|
|
4134
|
-
}
|
|
4135
|
-
});
|
|
4136
|
-
// Also revert supporting documents if any
|
|
4137
|
-
if (hasSupportingDocuments) {
|
|
4138
|
-
// Use original section's supporting documents to get original data paths
|
|
4139
|
-
const originalSupportingDocuments = originalSection['section-supporting-documents'] || [];
|
|
4140
|
-
originalSupportingDocuments.forEach((doc, index) => {
|
|
4141
|
-
const widgetId = `supporting-doc-${sectionId}-${index}`;
|
|
4142
|
-
const originalDataPath = doc['document-data-path'];
|
|
4143
|
-
// If namespace was used, data path in store is namespaced
|
|
4144
|
-
const storeDataPath = namespace && originalDataPath
|
|
4145
|
-
? `${namespace}.${originalDataPath}`
|
|
4146
|
-
: originalDataPath;
|
|
4147
|
-
const oldValue = getValueByPath(oldSchemaData, originalDataPath);
|
|
4148
|
-
newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
|
|
4149
|
-
});
|
|
4150
|
-
}
|
|
4151
|
-
if (newStoreValues !== currentStoreValues) {
|
|
4152
|
-
dispatch(setValues(newStoreValues));
|
|
4153
|
-
}
|
|
4196
|
+
revertToOriginalValues();
|
|
4154
4197
|
setIsEditMode(false);
|
|
4155
4198
|
onEditModeChange?.(originalSectionId, false);
|
|
4156
4199
|
};
|
|
@@ -4201,20 +4244,27 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4201
4244
|
white-space: nowrap !important;
|
|
4202
4245
|
}
|
|
4203
4246
|
/* Readonly: prevent flex row from overflowing panel */
|
|
4204
|
-
|
|
4247
|
+
${readonlyValueRowRootsCss} {
|
|
4205
4248
|
min-width: 0 !important;
|
|
4206
4249
|
overflow: hidden !important;
|
|
4207
4250
|
}
|
|
4208
|
-
|
|
4251
|
+
${readonlyValueRowFlex1Css} {
|
|
4209
4252
|
min-width: 0 !important;
|
|
4210
4253
|
overflow: hidden !important;
|
|
4211
4254
|
}
|
|
4212
|
-
/* Readonly value
|
|
4213
|
-
|
|
4255
|
+
/* Readonly value: single-line ellipsis; full value via title on the value node */
|
|
4256
|
+
${readonlySingleLineValueTextCss} {
|
|
4214
4257
|
overflow: hidden;
|
|
4215
4258
|
text-overflow: ellipsis;
|
|
4216
4259
|
white-space: nowrap;
|
|
4217
4260
|
}
|
|
4261
|
+
/* Readonly textarea: break unbroken long tokens; title on pre keeps full text on hover */
|
|
4262
|
+
.${sectionClassId} .TextAreaDisplayWidget > .flex-1 > pre {
|
|
4263
|
+
min-width: 0;
|
|
4264
|
+
max-width: 100%;
|
|
4265
|
+
overflow-wrap: anywhere;
|
|
4266
|
+
word-break: break-word;
|
|
4267
|
+
}
|
|
4218
4268
|
|
|
4219
4269
|
/* Only apply fixed height when in edit mode */
|
|
4220
4270
|
.${sectionClassId}[data-edit-mode="true"] {
|
|
@@ -4716,6 +4766,9 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4716
4766
|
}, []);
|
|
4717
4767
|
const safeSections = sections ?? [];
|
|
4718
4768
|
const prevSectionsLengthRef = useRef(safeSections.length);
|
|
4769
|
+
// Stable ref for namespace so formHandle useMemo doesn't depend on the (possibly inline) function identity
|
|
4770
|
+
const namespaceRef = useRef(namespace);
|
|
4771
|
+
namespaceRef.current = namespace;
|
|
4719
4772
|
// Track dirty (unsaved changes) per section for form handle validation
|
|
4720
4773
|
const sectionDirtyMapRef = useRef({});
|
|
4721
4774
|
const handleSectionDirtyChange = useCallback((sectionId, isDirty) => {
|
|
@@ -4761,11 +4814,14 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4761
4814
|
// Form handle for onFormReady - allows host to validate and get all section data from its own Submit button
|
|
4762
4815
|
const formHandle = useMemo(() => {
|
|
4763
4816
|
const getValues = () => store.getState().widget?.values || {};
|
|
4764
|
-
const getNamespace = (section, index) =>
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4817
|
+
const getNamespace = (section, index) => {
|
|
4818
|
+
const ns = namespaceRef.current;
|
|
4819
|
+
return ns
|
|
4820
|
+
? typeof ns === 'string'
|
|
4821
|
+
? ns
|
|
4822
|
+
: ns(section['section-id'], index)
|
|
4823
|
+
: undefined;
|
|
4824
|
+
};
|
|
4769
4825
|
const checkNoUnsavedChanges = () => {
|
|
4770
4826
|
const hasDirty = Object.values(sectionDirtyMapRef.current).some(Boolean);
|
|
4771
4827
|
if (hasDirty) {
|
|
@@ -4815,7 +4871,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4815
4871
|
return results;
|
|
4816
4872
|
},
|
|
4817
4873
|
};
|
|
4818
|
-
}, [store, dispatch, safeSections
|
|
4874
|
+
}, [store, dispatch, safeSections]);
|
|
4819
4875
|
// Call onFormReady when form is ready (sections loaded)
|
|
4820
4876
|
useEffect(() => {
|
|
4821
4877
|
if (onFormReady && safeSections.length > 0) {
|
|
@@ -8098,10 +8154,10 @@ const DisplayWidget = ({ config }) => {
|
|
|
8098
8154
|
const label = translateConfig(widgetConfig['widget-label']);
|
|
8099
8155
|
// If no label, render as paragraph text
|
|
8100
8156
|
if (!label || label.trim() === '') {
|
|
8101
|
-
return (jsxRuntimeExports.jsx("div", { className: "mb-3 text-base text-gray-700", title: String(displayValue ?? ''), children: displayValue }));
|
|
8157
|
+
return (jsxRuntimeExports.jsx("div", { className: "DisplayFieldWidget mb-3 min-w-0 w-full overflow-hidden text-ellipsis whitespace-nowrap text-base text-gray-700", title: String(displayValue ?? ''), children: displayValue }));
|
|
8102
8158
|
}
|
|
8103
|
-
// With label, render as key-value pair
|
|
8104
|
-
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] flex flex-col sm:flex-row sm:items-start", children: [jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] }), jsxRuntimeExports.jsx("div", { className: "flex-1 text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue })] }));
|
|
8159
|
+
// With label, render as key-value pair (structure matches other readonly widgets for SectionRenderer ellipsis)
|
|
8160
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] DisplayFieldWidget flex flex-col sm:flex-row sm:items-start", children: [jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] }), jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntimeExports.jsx("div", { className: "text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue }) })] }));
|
|
8105
8161
|
};
|
|
8106
8162
|
|
|
8107
8163
|
const TableCellSelect = ({ config, value, onValueChange }) => {
|
|
@@ -9069,7 +9125,18 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9069
9125
|
result = searchIn(schemaData);
|
|
9070
9126
|
return result;
|
|
9071
9127
|
}, [paths, values, schemaData]);
|
|
9072
|
-
const
|
|
9128
|
+
const imageVal = findValue('image');
|
|
9129
|
+
const imageUrlVal = findValue('imageUrl');
|
|
9130
|
+
const [previewUrl, setPreviewUrl] = useState(null);
|
|
9131
|
+
useEffect(() => {
|
|
9132
|
+
if (imageVal instanceof File) {
|
|
9133
|
+
const url = URL.createObjectURL(imageVal);
|
|
9134
|
+
setPreviewUrl(url);
|
|
9135
|
+
return () => URL.revokeObjectURL(url);
|
|
9136
|
+
}
|
|
9137
|
+
setPreviewUrl(null);
|
|
9138
|
+
}, [imageVal]);
|
|
9139
|
+
const displayImageUrl = previewUrl || (typeof imageUrlVal === 'string' && imageUrlVal ? imageUrlVal : null);
|
|
9073
9140
|
const displayName = findValue('name') || '';
|
|
9074
9141
|
const functionalId = findValue('functionalId') || '';
|
|
9075
9142
|
const statusValue = findValue('status') || '';
|
|
@@ -9102,18 +9169,20 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9102
9169
|
return opt ? opt.label : String(statusValue);
|
|
9103
9170
|
}, [statusValue, statusOptions]);
|
|
9104
9171
|
const statusColor = statusColors[String(statusValue).toLowerCase()] || '#6B7280';
|
|
9172
|
+
// ── Image edit helpers ───────────────────────────────────────
|
|
9173
|
+
const fileInputRef = useRef(null);
|
|
9174
|
+
const handleImageUpload = useCallback((e) => {
|
|
9175
|
+
const file = e.target.files?.[0];
|
|
9176
|
+
if (!file)
|
|
9177
|
+
return;
|
|
9178
|
+
updateFieldValue('image', file);
|
|
9179
|
+
e.target.value = '';
|
|
9180
|
+
}, [updateFieldValue]);
|
|
9181
|
+
const handleImageDelete = useCallback(() => {
|
|
9182
|
+
updateFieldValue('image', '');
|
|
9183
|
+
}, [updateFieldValue]);
|
|
9105
9184
|
// ── Scoped class for CSS isolation ────────────────────────────
|
|
9106
9185
|
const cls = `header-section-widget-${widgetConfig['widget-id']}`;
|
|
9107
|
-
// ── Indicator dot component ───────────────────────────────────
|
|
9108
|
-
const Dot = ({ color }) => (jsxRuntimeExports.jsx("span", { style: {
|
|
9109
|
-
display: 'inline-block',
|
|
9110
|
-
width: 8,
|
|
9111
|
-
height: 8,
|
|
9112
|
-
borderRadius: '50%',
|
|
9113
|
-
backgroundColor: color,
|
|
9114
|
-
flexShrink: 0,
|
|
9115
|
-
marginTop: 6,
|
|
9116
|
-
} }));
|
|
9117
9186
|
// ── RENDER ────────────────────────────────────────────────────
|
|
9118
9187
|
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { children: `
|
|
9119
9188
|
.${cls} {
|
|
@@ -9172,6 +9241,56 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9172
9241
|
border-radius: 8px;
|
|
9173
9242
|
}
|
|
9174
9243
|
|
|
9244
|
+
.${cls} .hdr-avatar-wrapper {
|
|
9245
|
+
position: relative;
|
|
9246
|
+
width: ${imageSize}px;
|
|
9247
|
+
height: ${imageSize}px;
|
|
9248
|
+
flex-shrink: 0;
|
|
9249
|
+
}
|
|
9250
|
+
|
|
9251
|
+
.${cls} .hdr-avatar-overlay {
|
|
9252
|
+
position: absolute;
|
|
9253
|
+
inset: 0;
|
|
9254
|
+
border-radius: 8px;
|
|
9255
|
+
background: rgba(0, 0, 0, 0.55);
|
|
9256
|
+
display: flex;
|
|
9257
|
+
flex-direction: column;
|
|
9258
|
+
align-items: center;
|
|
9259
|
+
justify-content: center;
|
|
9260
|
+
gap: 6px;
|
|
9261
|
+
opacity: 0;
|
|
9262
|
+
transition: opacity 0.2s;
|
|
9263
|
+
}
|
|
9264
|
+
|
|
9265
|
+
.${cls} .hdr-avatar-wrapper:hover .hdr-avatar-overlay {
|
|
9266
|
+
opacity: 1;
|
|
9267
|
+
}
|
|
9268
|
+
|
|
9269
|
+
.${cls} .hdr-avatar-action {
|
|
9270
|
+
display: flex;
|
|
9271
|
+
align-items: center;
|
|
9272
|
+
gap: 5px;
|
|
9273
|
+
padding: 5px 14px;
|
|
9274
|
+
border: none;
|
|
9275
|
+
border-radius: 4px;
|
|
9276
|
+
background: rgba(255, 255, 255, 0.92);
|
|
9277
|
+
color: #374151;
|
|
9278
|
+
font-size: 0.7rem;
|
|
9279
|
+
font-weight: 500;
|
|
9280
|
+
cursor: pointer;
|
|
9281
|
+
font-family: Roboto, sans-serif;
|
|
9282
|
+
transition: background 0.15s;
|
|
9283
|
+
white-space: nowrap;
|
|
9284
|
+
}
|
|
9285
|
+
|
|
9286
|
+
.${cls} .hdr-avatar-action:hover {
|
|
9287
|
+
background: #fff;
|
|
9288
|
+
}
|
|
9289
|
+
|
|
9290
|
+
.${cls} .hdr-avatar-action--delete {
|
|
9291
|
+
color: #DC2626;
|
|
9292
|
+
}
|
|
9293
|
+
|
|
9175
9294
|
.${cls} .hdr-info {
|
|
9176
9295
|
display: flex;
|
|
9177
9296
|
flex-direction: column;
|
|
@@ -9276,13 +9395,13 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9276
9395
|
min-width: 0;
|
|
9277
9396
|
}
|
|
9278
9397
|
}
|
|
9279
|
-
` }), jsxRuntimeExports.jsxs("div", { className: cls, children: [jsxRuntimeExports.jsxs("div", { className: "hdr-left", children: [jsxRuntimeExports.jsxs("div", { children: [
|
|
9398
|
+
` }), jsxRuntimeExports.jsxs("div", { className: cls, children: [jsxRuntimeExports.jsxs("div", { className: "hdr-left", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-wrapper", children: [displayImageUrl ? (jsxRuntimeExports.jsx("img", { src: displayImageUrl, alt: displayName || 'Profile', className: "hdr-avatar", onError: (e) => {
|
|
9280
9399
|
e.target.style.display = 'none';
|
|
9281
9400
|
const placeholder = e.target
|
|
9282
9401
|
.parentElement?.querySelector('.hdr-avatar-placeholder');
|
|
9283
9402
|
if (placeholder)
|
|
9284
9403
|
placeholder.style.display = 'flex';
|
|
9285
|
-
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display:
|
|
9404
|
+
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display: displayImageUrl ? 'none' : 'flex' }, children: jsxRuntimeExports.jsx("img", { src: img$f, alt: "Profile Placeholder" }) }), !isReadonly && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-overlay", children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action", onClick: () => fileInputRef.current?.click(), children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), jsxRuntimeExports.jsx("polyline", { points: "17 8 12 3 7 8" }), jsxRuntimeExports.jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })] }), "Upload"] }), jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action hdr-avatar-action--delete", onClick: handleImageDelete, children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("polyline", { points: "3 6 5 6 21 6" }), jsxRuntimeExports.jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })] }), "Delete"] })] }), jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: 'none' }, onChange: handleImageUpload })] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-info", children: [displayName && jsxRuntimeExports.jsx("div", { className: "hdr-name", children: displayName }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('functionalId'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: functionalId || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx("span", { className: "hdr-field-label", children: getLabel('status') }), isReadonly ? (statusLabel ? (jsxRuntimeExports.jsx("span", { className: "hdr-status-badge", style: { backgroundColor: statusColor }, children: statusLabel })) : (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: "-" }))) : (jsxRuntimeExports.jsxs("select", { className: "hdr-select", value: statusValue, onChange: (e) => updateFieldValue('status', e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: getLabel('select') }), statusOptions.map((opt) => (jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, opt.value)))] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('statusReason'), " :"] }), isReadonly ? (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: statusReason || '-' })) : (jsxRuntimeExports.jsx("input", { type: "text", className: "hdr-input", value: statusReason, placeholder: getLabel('enterReason'), onChange: (e) => updateFieldValue('statusReason', e.target.value) }))] })] })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-right", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdAt || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedAt || '-' })] })] })] })] }));
|
|
9286
9405
|
};
|
|
9287
9406
|
|
|
9288
9407
|
/**
|