@openg2p/registry-widgets 1.0.2 → 1.1.0-dev.1
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/README.md +42 -1
- package/dist/components/SectionBuilder/schemas.d.ts +4 -0
- package/dist/components/SectionBuilder/schemas.d.ts.map +1 -1
- package/dist/components/SectionRenderer.d.ts +0 -1
- package/dist/components/SectionRenderer.d.ts.map +1 -1
- package/dist/components/SectionsContainer.d.ts.map +1 -1
- package/dist/components/WidgetProvider.d.ts +4 -1
- package/dist/components/WidgetProvider.d.ts.map +1 -1
- package/dist/index.d.ts +155 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +669 -338
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +672 -337
- package/dist/index.js.map +1 -1
- package/dist/registry/defaultWidgets.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/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/dist/widgets/ProfileWidget.d.ts +2 -2
- package/dist/widgets/ScoresDisplayWidget.d.ts +26 -0
- package/dist/widgets/ScoresDisplayWidget.d.ts.map +1 -0
- package/dist/widgets/TableWidget.d.ts.map +1 -1
- package/dist/widgets/index.d.ts +1 -0
- package/dist/widgets/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1675,6 +1675,158 @@ class WidgetEventBus {
|
|
|
1675
1675
|
}
|
|
1676
1676
|
}
|
|
1677
1677
|
|
|
1678
|
+
/**
|
|
1679
|
+
* Built-in default values (matches the original hardcoded colours).
|
|
1680
|
+
*/
|
|
1681
|
+
const defaultTheme = {
|
|
1682
|
+
colors: {
|
|
1683
|
+
primary: '#F5BB1A',
|
|
1684
|
+
primaryDark: '#F07B1A',
|
|
1685
|
+
primaryLight: '#FBE6AA',
|
|
1686
|
+
primaryAccent: '#EE7C22',
|
|
1687
|
+
border: '#C4C4C4',
|
|
1688
|
+
borderLight: '#E4E4E4',
|
|
1689
|
+
background: '#FFFFFF',
|
|
1690
|
+
backgroundAlt: '#F6F6F6',
|
|
1691
|
+
text: '#011627',
|
|
1692
|
+
textMuted: '#727474',
|
|
1693
|
+
success: '#16A34A',
|
|
1694
|
+
successDark: '#047857',
|
|
1695
|
+
successLight: '#D1FAE5',
|
|
1696
|
+
error: '#B91C1C',
|
|
1697
|
+
errorLight: '#FEE2E2',
|
|
1698
|
+
warning: '#F59E0B',
|
|
1699
|
+
info: '#2563EB',
|
|
1700
|
+
},
|
|
1701
|
+
section: {
|
|
1702
|
+
borderRadius: '8px',
|
|
1703
|
+
borderColor: '#E4E4E4',
|
|
1704
|
+
backgroundColor: '#FFFFFF',
|
|
1705
|
+
titleColor: '#011627',
|
|
1706
|
+
dividerColor: '#F5BB1A',
|
|
1707
|
+
},
|
|
1708
|
+
panel: {
|
|
1709
|
+
dividerColor: '#C4C4C4',
|
|
1710
|
+
backgroundColor: 'transparent',
|
|
1711
|
+
},
|
|
1712
|
+
button: {
|
|
1713
|
+
primaryBg: '#FFFFFF',
|
|
1714
|
+
primaryColor: '#011627',
|
|
1715
|
+
primaryBorder: '#F07B1A',
|
|
1716
|
+
secondaryBg: '#FFFFFF',
|
|
1717
|
+
secondaryColor: '#011627',
|
|
1718
|
+
secondaryBorder: '#C4C4C4',
|
|
1719
|
+
borderRadius: '6px',
|
|
1720
|
+
},
|
|
1721
|
+
widget: {
|
|
1722
|
+
labelColor: '#011627',
|
|
1723
|
+
inputBorderColor: '#C4C4C4',
|
|
1724
|
+
inputFocusBorderColor: '#F5BB1A',
|
|
1725
|
+
inputBackground: '#FFFFFF',
|
|
1726
|
+
errorColor: '#B91C1C',
|
|
1727
|
+
helpTextColor: '#727474',
|
|
1728
|
+
tableHeaderBg: '#F6F6F6',
|
|
1729
|
+
tableHeaderColor: '#727474',
|
|
1730
|
+
tableBodyBg: '#FFFFFF',
|
|
1731
|
+
tableBorderColor: '#C4C4C4',
|
|
1732
|
+
tableRowDividerColor: '#E4E4E4',
|
|
1733
|
+
tableEditingRowBg: '#FBE6AA',
|
|
1734
|
+
tableDeletedRowBg: '#FEE2E2',
|
|
1735
|
+
tableEmptyTextColor: '#727474',
|
|
1736
|
+
tableBorderRadius: '15px',
|
|
1737
|
+
},
|
|
1738
|
+
};
|
|
1739
|
+
/**
|
|
1740
|
+
* Merge a user-supplied (partial) theme with the built-in defaults.
|
|
1741
|
+
*/
|
|
1742
|
+
function resolveTheme(theme) {
|
|
1743
|
+
if (!theme)
|
|
1744
|
+
return defaultTheme;
|
|
1745
|
+
return {
|
|
1746
|
+
colors: { ...defaultTheme.colors, ...theme.colors },
|
|
1747
|
+
section: { ...defaultTheme.section, ...theme.section },
|
|
1748
|
+
panel: { ...defaultTheme.panel, ...theme.panel },
|
|
1749
|
+
button: { ...defaultTheme.button, ...theme.button },
|
|
1750
|
+
widget: { ...defaultTheme.widget, ...theme.widget },
|
|
1751
|
+
};
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1754
|
+
* Convert a resolved theme into a flat Record of CSS custom properties.
|
|
1755
|
+
* These are set on the provider wrapper element so every descendant can
|
|
1756
|
+
* reference them with `var(--owt-…)`.
|
|
1757
|
+
*
|
|
1758
|
+
* Prefix: `--owt-` (OpenG2P Widget Theme).
|
|
1759
|
+
*/
|
|
1760
|
+
function themeToCSSVariables(resolved) {
|
|
1761
|
+
return {
|
|
1762
|
+
// --- colors ---
|
|
1763
|
+
'--owt-color-primary': resolved.colors.primary,
|
|
1764
|
+
'--owt-color-primary-dark': resolved.colors.primaryDark,
|
|
1765
|
+
'--owt-color-primary-light': resolved.colors.primaryLight,
|
|
1766
|
+
'--owt-color-primary-accent': resolved.colors.primaryAccent,
|
|
1767
|
+
'--owt-color-border': resolved.colors.border,
|
|
1768
|
+
'--owt-color-border-light': resolved.colors.borderLight,
|
|
1769
|
+
'--owt-color-bg': resolved.colors.background,
|
|
1770
|
+
'--owt-color-bg-alt': resolved.colors.backgroundAlt,
|
|
1771
|
+
'--owt-color-text': resolved.colors.text,
|
|
1772
|
+
'--owt-color-text-muted': resolved.colors.textMuted,
|
|
1773
|
+
'--owt-color-success': resolved.colors.success,
|
|
1774
|
+
'--owt-color-success-dark': resolved.colors.successDark,
|
|
1775
|
+
'--owt-color-success-light': resolved.colors.successLight,
|
|
1776
|
+
'--owt-color-error': resolved.colors.error,
|
|
1777
|
+
'--owt-color-error-light': resolved.colors.errorLight,
|
|
1778
|
+
'--owt-color-warning': resolved.colors.warning,
|
|
1779
|
+
'--owt-color-info': resolved.colors.info,
|
|
1780
|
+
// --- section ---
|
|
1781
|
+
'--owt-section-border-radius': resolved.section.borderRadius,
|
|
1782
|
+
'--owt-section-border-color': resolved.section.borderColor,
|
|
1783
|
+
'--owt-section-bg': resolved.section.backgroundColor,
|
|
1784
|
+
'--owt-section-title-color': resolved.section.titleColor,
|
|
1785
|
+
'--owt-section-divider-color': resolved.section.dividerColor,
|
|
1786
|
+
// --- panel ---
|
|
1787
|
+
'--owt-panel-divider-color': resolved.panel.dividerColor,
|
|
1788
|
+
'--owt-panel-bg': resolved.panel.backgroundColor,
|
|
1789
|
+
// --- button ---
|
|
1790
|
+
'--owt-btn-primary-bg': resolved.button.primaryBg,
|
|
1791
|
+
'--owt-btn-primary-color': resolved.button.primaryColor,
|
|
1792
|
+
'--owt-btn-primary-border': resolved.button.primaryBorder,
|
|
1793
|
+
'--owt-btn-secondary-bg': resolved.button.secondaryBg,
|
|
1794
|
+
'--owt-btn-secondary-color': resolved.button.secondaryColor,
|
|
1795
|
+
'--owt-btn-secondary-border': resolved.button.secondaryBorder,
|
|
1796
|
+
'--owt-btn-border-radius': resolved.button.borderRadius,
|
|
1797
|
+
// --- widget ---
|
|
1798
|
+
'--owt-widget-label-color': resolved.widget.labelColor,
|
|
1799
|
+
'--owt-widget-input-border': resolved.widget.inputBorderColor,
|
|
1800
|
+
'--owt-widget-input-focus-border': resolved.widget.inputFocusBorderColor,
|
|
1801
|
+
'--owt-widget-input-bg': resolved.widget.inputBackground,
|
|
1802
|
+
'--owt-widget-error-color': resolved.widget.errorColor,
|
|
1803
|
+
'--owt-widget-helptext-color': resolved.widget.helpTextColor,
|
|
1804
|
+
// --- widget / table ---
|
|
1805
|
+
'--owt-widget-table-header-bg': resolved.widget.tableHeaderBg,
|
|
1806
|
+
'--owt-widget-table-header-color': resolved.widget.tableHeaderColor,
|
|
1807
|
+
'--owt-widget-table-body-bg': resolved.widget.tableBodyBg,
|
|
1808
|
+
'--owt-widget-table-border-color': resolved.widget.tableBorderColor,
|
|
1809
|
+
'--owt-widget-table-row-divider': resolved.widget.tableRowDividerColor,
|
|
1810
|
+
'--owt-widget-table-editing-row-bg': resolved.widget.tableEditingRowBg,
|
|
1811
|
+
'--owt-widget-table-deleted-row-bg': resolved.widget.tableDeletedRowBg,
|
|
1812
|
+
'--owt-widget-table-empty-color': resolved.widget.tableEmptyTextColor,
|
|
1813
|
+
'--owt-widget-table-border-radius': resolved.widget.tableBorderRadius,
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
const ThemeContext = createContext(defaultTheme);
|
|
1818
|
+
/**
|
|
1819
|
+
* Access the resolved widget theme from any component inside `<WidgetProvider>`.
|
|
1820
|
+
*
|
|
1821
|
+
* ```tsx
|
|
1822
|
+
* const theme = useWidgetTheme();
|
|
1823
|
+
* // theme.colors.primary, theme.section.dividerColor, etc.
|
|
1824
|
+
* ```
|
|
1825
|
+
*/
|
|
1826
|
+
function useWidgetTheme() {
|
|
1827
|
+
return useContext(ThemeContext);
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1678
1830
|
const WidgetContext = createContext({
|
|
1679
1831
|
dataSourceRequestHandler: undefined,
|
|
1680
1832
|
schemaData: undefined,
|
|
@@ -1683,10 +1835,13 @@ const WidgetContext = createContext({
|
|
|
1683
1835
|
const useWidgetContext = () => {
|
|
1684
1836
|
return useContext(WidgetContext);
|
|
1685
1837
|
};
|
|
1686
|
-
const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate, children, }) => {
|
|
1838
|
+
const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate, theme, children, }) => {
|
|
1687
1839
|
const widgetStore = useMemo(() => store || createWidgetStore(), [store]);
|
|
1688
1840
|
// Create event bus instance (one per provider)
|
|
1689
1841
|
const eventBus = useMemo(() => new WidgetEventBus(), []);
|
|
1842
|
+
// Resolve theme: merge user-supplied overrides with defaults
|
|
1843
|
+
const resolvedTheme = useMemo(() => resolveTheme(theme), [theme]);
|
|
1844
|
+
const cssVariables = useMemo(() => themeToCSSVariables(resolvedTheme), [resolvedTheme]);
|
|
1690
1845
|
// Memoize context value to prevent unnecessary re-renders
|
|
1691
1846
|
const contextValue = useMemo(() => ({
|
|
1692
1847
|
dataSourceRequestHandler,
|
|
@@ -1715,7 +1870,7 @@ const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate
|
|
|
1715
1870
|
}
|
|
1716
1871
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1717
1872
|
}, [schemaData, widgetStore]); // Only run on mount
|
|
1718
|
-
const content = (jsxRuntimeExports.jsx(Provider, { store: widgetStore, children: jsxRuntimeExports.jsx(WidgetContext.Provider, { value: contextValue, children: jsxRuntimeExports.jsx(WidgetEventBusContext.Provider, { value: eventBus, children: children }) }) }));
|
|
1873
|
+
const content = (jsxRuntimeExports.jsx(Provider, { store: widgetStore, children: jsxRuntimeExports.jsx(ThemeContext.Provider, { value: resolvedTheme, children: jsxRuntimeExports.jsx(WidgetContext.Provider, { value: contextValue, children: jsxRuntimeExports.jsx(WidgetEventBusContext.Provider, { value: eventBus, children: jsxRuntimeExports.jsx("div", { className: "openg2p-widget-theme-root", style: cssVariables, children: children }) }) }) }) }));
|
|
1719
1874
|
return content;
|
|
1720
1875
|
};
|
|
1721
1876
|
|
|
@@ -2735,7 +2890,7 @@ const PanelRenderer = ({ panel, dataSourceRequestHandler, schemaData, onValueCha
|
|
|
2735
2890
|
top: 0,
|
|
2736
2891
|
bottom: '5px',
|
|
2737
2892
|
width: '1px',
|
|
2738
|
-
backgroundColor: isEditMode ? '#
|
|
2893
|
+
backgroundColor: isEditMode ? 'var(--owt-color-primary, #F5BB1A)' : 'var(--owt-panel-divider-color, #C4C4C4)',
|
|
2739
2894
|
} }))] }) }, nestedPanel['panel-id'] || `panel-${index}`));
|
|
2740
2895
|
}), widgets.map((widgetConfig, index) => {
|
|
2741
2896
|
// Don't use readonly state in key - it causes remounting which resets userHasSetValueRef
|
|
@@ -3297,10 +3452,10 @@ const FileInputWidget = ({ config }) => {
|
|
|
3297
3452
|
return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("button", { type: "button", onClick: (e) => {
|
|
3298
3453
|
console.log('Button clicked!', file);
|
|
3299
3454
|
handleFileClick(file, e);
|
|
3300
|
-
}, className: "text-sm hover:underline focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 rounded cursor-pointer", style: { color: isSupportingDocument ? '#
|
|
3455
|
+
}, className: "text-sm hover:underline focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 rounded cursor-pointer", style: { color: isSupportingDocument ? 'var(--owt-color-text, #011627)' : 'var(--owt-color-info, #2563eb)' }, title: "Click to preview", children: fileName })] }));
|
|
3301
3456
|
}
|
|
3302
3457
|
else {
|
|
3303
|
-
return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("span", { className: "text-sm", style: { color: isSupportingDocument ? '#
|
|
3458
|
+
return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("span", { className: "text-sm", style: { color: isSupportingDocument ? 'var(--owt-color-text, #011627)' : '#4b5563' }, children: fileName })] }));
|
|
3304
3459
|
}
|
|
3305
3460
|
}
|
|
3306
3461
|
else {
|
|
@@ -3316,10 +3471,10 @@ const FileInputWidget = ({ config }) => {
|
|
|
3316
3471
|
flexShrink: 0
|
|
3317
3472
|
} }));
|
|
3318
3473
|
if (canPreview) {
|
|
3319
|
-
return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("button", { type: "button", onClick: (e) => handleFileClick(file, e), className: "text-sm hover:underline focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 rounded cursor-pointer", style: { color: isSupportingDocument ? '#
|
|
3474
|
+
return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("button", { type: "button", onClick: (e) => handleFileClick(file, e), className: "text-sm hover:underline focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 rounded cursor-pointer", style: { color: isSupportingDocument ? 'var(--owt-color-text, #011627)' : 'var(--owt-color-info, #2563eb)' }, title: "Click to preview", children: fileName })] }, index));
|
|
3320
3475
|
}
|
|
3321
3476
|
else {
|
|
3322
|
-
return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("span", { className: "text-sm", style: { color: isSupportingDocument ? '#
|
|
3477
|
+
return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("span", { className: "text-sm", style: { color: isSupportingDocument ? 'var(--owt-color-text, #011627)' : '#4b5563' }, children: fileName })] }, index));
|
|
3323
3478
|
}
|
|
3324
3479
|
}) }));
|
|
3325
3480
|
}
|
|
@@ -3515,39 +3670,6 @@ const sectionValidate = (section, currentSchemaData, dispatch) => {
|
|
|
3515
3670
|
return isValid;
|
|
3516
3671
|
};
|
|
3517
3672
|
|
|
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
|
-
}
|
|
3551
3673
|
/**
|
|
3552
3674
|
* Renders a section with its panels
|
|
3553
3675
|
*
|
|
@@ -3558,6 +3680,8 @@ function scopedClassSelectors(sectionClassId, classNames) {
|
|
|
3558
3680
|
*/
|
|
3559
3681
|
const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, changeRequestType, showChangeRequestLabel = true, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, onEditModeChange, forceExitEdit, }) => {
|
|
3560
3682
|
const { translateConfig, translate } = useWidgetTranslation();
|
|
3683
|
+
const resolvedTheme = useWidgetTheme();
|
|
3684
|
+
const portalCSSVariables = useMemo(() => themeToCSSVariables(resolvedTheme), [resolvedTheme]);
|
|
3561
3685
|
const { schemaData: contextSchemaData, dataSourceRequestHandler: contextDataSourceRequestHandler } = useWidgetContext();
|
|
3562
3686
|
const store = useStore();
|
|
3563
3687
|
const dispatch = useDispatch();
|
|
@@ -3574,22 +3698,41 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3574
3698
|
}
|
|
3575
3699
|
return section;
|
|
3576
3700
|
}, [section, namespace]);
|
|
3577
|
-
// Create namespaced schemaData if namespace is provided
|
|
3578
|
-
//
|
|
3579
|
-
// need a nested object at values[namespace] so getValueByPath can traverse it.
|
|
3701
|
+
// Create namespaced schemaData if namespace is provided
|
|
3702
|
+
// This ensures widgets can read initial values from schemaData at namespaced paths
|
|
3580
3703
|
const namespacedSchemaData = useMemo(() => {
|
|
3581
3704
|
if (!namespace || !currentSchemaData) {
|
|
3582
3705
|
return schemaData;
|
|
3583
3706
|
}
|
|
3584
|
-
|
|
3707
|
+
// Create a namespaced version of schemaData by copying values to namespaced paths
|
|
3708
|
+
const namespaced = { ...currentSchemaData };
|
|
3709
|
+
// Copy all top-level keys to namespaced paths
|
|
3710
|
+
Object.keys(currentSchemaData).forEach(key => {
|
|
3711
|
+
const namespacedKey = `${namespace}.${key}`;
|
|
3712
|
+
if (!(namespacedKey in namespaced)) {
|
|
3713
|
+
namespaced[namespacedKey] = currentSchemaData[key];
|
|
3714
|
+
}
|
|
3715
|
+
});
|
|
3716
|
+
// Also handle nested objects - copy nested values to namespaced paths
|
|
3717
|
+
const copyNestedValues = (obj, prefix = '') => {
|
|
3718
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
3719
|
+
Object.keys(obj).forEach(key => {
|
|
3720
|
+
const fullPath = prefix ? `${prefix}.${key}` : key;
|
|
3721
|
+
const namespacedPath = `${namespace}.${fullPath}`;
|
|
3722
|
+
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
|
|
3723
|
+
copyNestedValues(obj[key], fullPath);
|
|
3724
|
+
// Also set the nested object at the namespaced path
|
|
3725
|
+
setValueByPath(namespaced, namespacedPath, obj[key]);
|
|
3726
|
+
}
|
|
3727
|
+
else {
|
|
3728
|
+
setValueByPath(namespaced, namespacedPath, obj[key]);
|
|
3729
|
+
}
|
|
3730
|
+
});
|
|
3731
|
+
}
|
|
3732
|
+
};
|
|
3733
|
+
copyNestedValues(currentSchemaData);
|
|
3734
|
+
return namespaced;
|
|
3585
3735
|
}, [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]);
|
|
3593
3736
|
const crViewData = useMemo(() => {
|
|
3594
3737
|
if (mode !== 'CRView')
|
|
3595
3738
|
return null;
|
|
@@ -3612,9 +3755,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3612
3755
|
const sectionId = sectionToRender['section-id'];
|
|
3613
3756
|
const gridId = `section-panels-${sectionId}`;
|
|
3614
3757
|
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]);
|
|
3618
3758
|
// IntakeForm mode: accordion expand/collapse state (supports toggle)
|
|
3619
3759
|
const [standaloneExpanded, setStandaloneExpanded] = useState(true); // For sectionIndex undefined (standalone use)
|
|
3620
3760
|
const isExpandedFromContainer = typeof sectionIndex === 'number' && expandedSectionIndex === sectionIndex;
|
|
@@ -3838,9 +3978,10 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3838
3978
|
top: 0;
|
|
3839
3979
|
bottom: 5px;
|
|
3840
3980
|
width: 1px;
|
|
3841
|
-
background-color: #
|
|
3981
|
+
background-color: var(--owt-color-primary, #F5BB1A);
|
|
3842
3982
|
}
|
|
3843
3983
|
` }), jsxRuntimeExports.jsxs("div", { className: `section ${sectionClassId} ${sectionClassId}-edit px-4 sm:px-6 lg:px-8`, "data-section-id": `${sectionId}-edit`, style: {
|
|
3984
|
+
...portalCSSVariables,
|
|
3844
3985
|
position: 'absolute',
|
|
3845
3986
|
top: `${editSectionPosition.top}px`,
|
|
3846
3987
|
left: `${editSectionPosition.left}px`,
|
|
@@ -3850,10 +3991,22 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3850
3991
|
}, children: [sectionToRender['section-title'] && (jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold mb-4", style: { fontFamily: 'Roboto, sans-serif', marginTop: '35px' }, children: translateConfig(sectionToRender['section-title']) })), jsxRuntimeExports.jsxs("div", { id: editGridId, className: "section-panels", children: [editableSection.panels.map((panel, index) => {
|
|
3851
3992
|
const isLastPanel = index === editableSection.panels.length - 1;
|
|
3852
3993
|
return (jsxRuntimeExports.jsx("div", { className: `panel-wrapper ${isLastPanel ? 'last-panel-wrapper' : ''}`, children: jsxRuntimeExports.jsx(PanelRenderer, { panel: panel, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: namespacedSchemaData, onValueChange: onValueChange, isEditMode: true }) }, panel['panel-id'] || `section-panel-${index}`));
|
|
3853
|
-
}), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: '#
|
|
3994
|
+
}), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: 'var(--owt-section-divider-color, #F5BB1A)', border: 'none', margin: '25px 0 0 0' } }), hasSupportingDocuments && (jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: jsxRuntimeExports.jsxs("div", { className: "supporting-documents-container", children: [jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => setIsDocumentsExpanded(!isDocumentsExpanded), className: "supporting-documents-title-button w-full flex items-center text-left", children: [jsxRuntimeExports.jsx("span", { className: "font-semibold", style: { fontFamily: 'Roboto, sans-serif', fontSize: '16px' }, children: translate('common.supportedDocuments') || 'Supported Documents' }), jsxRuntimeExports.jsx("img", { src: isDocumentsExpanded ? img$7 : img$6, alt: "Toggle Documents", className: "w-4 h-2.25 transition-transform ml-2" })] }), isDocumentsExpanded && (jsxRuntimeExports.jsx("div", { className: "supporting-documents-grid mt-4", children: supportingDocuments.map((doc, index) => {
|
|
3854
3995
|
const docConfig = createDocumentWidgetConfig(doc, sectionId, index);
|
|
3855
3996
|
return (jsxRuntimeExports.jsx("div", { className: "supporting-document-item", children: jsxRuntimeExports.jsx(FileInputWidget, { config: docConfig }) }, `${sectionId}-doc-${index}`));
|
|
3856
|
-
}) }))] }) })), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: '#
|
|
3997
|
+
}) }))] }) })), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: 'var(--owt-section-divider-color, #F5BB1A)', border: 'none', marginTop: hasSupportingDocuments ? '20px' : 0, marginBottom: '20px' } }), jsxRuntimeExports.jsx("div", { className: "edit-controls-container", style: { marginBottom: '20px' }, children: jsxRuntimeExports.jsxs("div", { className: "edit-controls-buttons", children: [jsxRuntimeExports.jsx("button", { onClick: handleCancel, className: "text-sm font-medium px-6 py-2 transition-colors", style: {
|
|
3998
|
+
fontFamily: 'Roboto, sans-serif',
|
|
3999
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
4000
|
+
border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
|
|
4001
|
+
backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
|
|
4002
|
+
color: 'var(--owt-btn-secondary-color, #011627)',
|
|
4003
|
+
}, children: translate('common.cancel') || 'Cancel' }), jsxRuntimeExports.jsx("button", { onClick: handleSave, disabled: !isDirty, className: "text-sm font-medium px-6 py-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", style: {
|
|
4004
|
+
fontFamily: 'Roboto, sans-serif',
|
|
4005
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
4006
|
+
border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
|
|
4007
|
+
backgroundColor: 'var(--owt-color-primary, #F5BB1A)',
|
|
4008
|
+
color: 'var(--owt-color-bg, #FFFFFF)',
|
|
4009
|
+
}, children: translate('common.save') || 'Save' })] }) })] })] })] }), document.body);
|
|
3857
4010
|
};
|
|
3858
4011
|
const trackSectionChages = (widgets, sourceData, pathPrefix) => {
|
|
3859
4012
|
if (!widgets || widgets.length === 0)
|
|
@@ -3954,8 +4107,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3954
4107
|
const baselineSnapshotRef = useRef(null);
|
|
3955
4108
|
// IntakeForm only: increment when baseline is updated after save - forces badge to update (refs don't trigger re-renders)
|
|
3956
4109
|
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);
|
|
3959
4110
|
// IntakeForm: treat as edit mode for dirty tracking when isDraft. RegistryView: use isEditMode.
|
|
3960
4111
|
const effectiveEditModeForDirty = mode === 'IntakeForm' ? (isDraft !== false) : isEditMode;
|
|
3961
4112
|
// Compute isDirty: compare current store state to baseline (only when in edit mode)
|
|
@@ -3998,68 +4149,18 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3998
4149
|
const intakeFormSectionStatus = useMemo(() => {
|
|
3999
4150
|
if (mode !== 'IntakeForm' || isDraft === false)
|
|
4000
4151
|
return null;
|
|
4152
|
+
const hasValue = (v) => v !== undefined && v !== null && (typeof v !== 'string' || v.trim().length > 0);
|
|
4153
|
+
const currentSnapshot = buildSectionSnapshot(storeValues, namespace);
|
|
4154
|
+
const record = currentSnapshot.records?.[0];
|
|
4155
|
+
const hasData = record &&
|
|
4156
|
+
typeof record === 'object' &&
|
|
4157
|
+
Object.values(record).some((v) => hasValue(v));
|
|
4001
4158
|
if (isDirty)
|
|
4002
4159
|
return 'modified';
|
|
4003
|
-
if (
|
|
4160
|
+
if (hasData)
|
|
4004
4161
|
return 'saved';
|
|
4005
4162
|
return null;
|
|
4006
|
-
}, [mode, isDirty,
|
|
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]);
|
|
4163
|
+
}, [mode, isDirty, storeValues, namespace, buildSectionSnapshot]);
|
|
4063
4164
|
// Handle save button click
|
|
4064
4165
|
const handleSave = async () => {
|
|
4065
4166
|
if (!store || !onSectionSave) {
|
|
@@ -4096,24 +4197,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4096
4197
|
});
|
|
4097
4198
|
}
|
|
4098
4199
|
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
|
-
}
|
|
4110
4200
|
try {
|
|
4111
4201
|
const sectionchanges = {
|
|
4112
4202
|
section_id: dbSectionId ?? originalSection['section-id'],
|
|
4113
4203
|
section_register_id: sectionRegisterId,
|
|
4114
4204
|
records: [...newSchemaData],
|
|
4115
|
-
files: [...sectionFiles]
|
|
4116
|
-
...(profileImage ? { image: profileImage } : {}),
|
|
4205
|
+
files: [...sectionFiles]
|
|
4117
4206
|
};
|
|
4118
4207
|
await onSectionSave(sectionchanges);
|
|
4119
4208
|
}
|
|
@@ -4121,12 +4210,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4121
4210
|
console.error('Section Changes Save failed', error);
|
|
4122
4211
|
}
|
|
4123
4212
|
}
|
|
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
|
-
}
|
|
4130
4213
|
setIsEditMode(false);
|
|
4131
4214
|
onEditModeChange?.(originalSectionId, false);
|
|
4132
4215
|
};
|
|
@@ -4156,24 +4239,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4156
4239
|
});
|
|
4157
4240
|
}
|
|
4158
4241
|
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
|
-
}
|
|
4170
4242
|
try {
|
|
4171
4243
|
await onSectionSave({
|
|
4172
4244
|
section_id: dbSectionId ?? originalSection['section-id'],
|
|
4173
4245
|
section_register_id: sectionRegisterId,
|
|
4174
4246
|
records: [...newSchemaData],
|
|
4175
4247
|
files: [...sectionFiles],
|
|
4176
|
-
...(profileImage ? { image: profileImage } : {}),
|
|
4177
4248
|
});
|
|
4178
4249
|
}
|
|
4179
4250
|
catch (error) {
|
|
@@ -4184,7 +4255,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4184
4255
|
if (mode === 'IntakeForm') {
|
|
4185
4256
|
baselineSnapshotRef.current = buildSectionSnapshot(currentSchemaData, namespace);
|
|
4186
4257
|
setIntakeFormBaselineTrigger((prev) => prev + 1);
|
|
4187
|
-
setHasBeenSavedByUser(true);
|
|
4188
4258
|
}
|
|
4189
4259
|
onSectionDirtyChange?.(sectionId, false);
|
|
4190
4260
|
}
|
|
@@ -4193,7 +4263,64 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4193
4263
|
}, [store, onSectionSave, onSectionSaveSuccess, sectionIndex, originalSection, schemaData, contextSchemaData, namespace, hasSupportingDocuments, dbSectionId, sectionRegisterId, dispatch, buildSectionSnapshot, sectionId, onSectionDirtyChange, mode, isDraft]);
|
|
4194
4264
|
// Handle cancel button click
|
|
4195
4265
|
const handleCancel = () => {
|
|
4196
|
-
|
|
4266
|
+
// Revert values in store to original schema data
|
|
4267
|
+
// Use original section (without namespace) for collecting widgets
|
|
4268
|
+
const sectionWidgets = collectWidgets(originalSection.panels);
|
|
4269
|
+
const oldSchemaData = schemaData || contextSchemaData;
|
|
4270
|
+
const currentStoreValues = store.getState().widget.values;
|
|
4271
|
+
let newStoreValues = currentStoreValues;
|
|
4272
|
+
sectionWidgets.forEach(widget => {
|
|
4273
|
+
const originalWidgetId = widget['widget-id'];
|
|
4274
|
+
// If namespace was used, we need to use namespaced widget ID and data path
|
|
4275
|
+
const namespacedWidgetId = namespace ? `${namespace}__${originalWidgetId}` : originalWidgetId;
|
|
4276
|
+
const widgetId = namespacedWidgetId;
|
|
4277
|
+
const originalDataPath = widget['widget-data-path'];
|
|
4278
|
+
// If namespace was used, data path in store is namespaced, but we read from original schema using original path
|
|
4279
|
+
const storeDataPath = namespace && originalDataPath
|
|
4280
|
+
? (typeof originalDataPath === 'string'
|
|
4281
|
+
? `${namespace}.${originalDataPath}`
|
|
4282
|
+
: Object.fromEntries(Object.entries(originalDataPath).map(([key, path]) => [key, `${namespace}.${path}`])))
|
|
4283
|
+
: originalDataPath;
|
|
4284
|
+
if (widgetId && originalDataPath) {
|
|
4285
|
+
// Handle multi-path (object) or single path (string)
|
|
4286
|
+
// Read from original schema data using original paths
|
|
4287
|
+
let oldValue;
|
|
4288
|
+
if (typeof originalDataPath === 'object') {
|
|
4289
|
+
// Multi-path: get values for each path
|
|
4290
|
+
oldValue = {};
|
|
4291
|
+
Object.entries(originalDataPath).forEach(([key, path]) => {
|
|
4292
|
+
if (typeof path === 'string') {
|
|
4293
|
+
oldValue[key] = getValueByPath(oldSchemaData, path);
|
|
4294
|
+
}
|
|
4295
|
+
});
|
|
4296
|
+
}
|
|
4297
|
+
else if (typeof originalDataPath === 'string') {
|
|
4298
|
+
oldValue = getValueByPath(oldSchemaData, originalDataPath);
|
|
4299
|
+
}
|
|
4300
|
+
// Set in store using namespaced data path (if namespace was used)
|
|
4301
|
+
if (oldValue !== undefined) {
|
|
4302
|
+
newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
});
|
|
4306
|
+
// Also revert supporting documents if any
|
|
4307
|
+
if (hasSupportingDocuments) {
|
|
4308
|
+
// Use original section's supporting documents to get original data paths
|
|
4309
|
+
const originalSupportingDocuments = originalSection['section-supporting-documents'] || [];
|
|
4310
|
+
originalSupportingDocuments.forEach((doc, index) => {
|
|
4311
|
+
const widgetId = `supporting-doc-${sectionId}-${index}`;
|
|
4312
|
+
const originalDataPath = doc['document-data-path'];
|
|
4313
|
+
// If namespace was used, data path in store is namespaced
|
|
4314
|
+
const storeDataPath = namespace && originalDataPath
|
|
4315
|
+
? `${namespace}.${originalDataPath}`
|
|
4316
|
+
: originalDataPath;
|
|
4317
|
+
const oldValue = getValueByPath(oldSchemaData, originalDataPath);
|
|
4318
|
+
newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
|
|
4319
|
+
});
|
|
4320
|
+
}
|
|
4321
|
+
if (newStoreValues !== currentStoreValues) {
|
|
4322
|
+
dispatch(setValues(newStoreValues));
|
|
4323
|
+
}
|
|
4197
4324
|
setIsEditMode(false);
|
|
4198
4325
|
onEditModeChange?.(originalSectionId, false);
|
|
4199
4326
|
};
|
|
@@ -4234,7 +4361,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4234
4361
|
.${sectionClassId} label.text-gray-700,
|
|
4235
4362
|
.${sectionClassId} .text-gray-600 {
|
|
4236
4363
|
font-weight: 400 !important;
|
|
4237
|
-
color:
|
|
4364
|
+
color: var(--owt-color-text-muted, #727474) !important;
|
|
4238
4365
|
width: 50% !important;
|
|
4239
4366
|
min-width: 50% !important;
|
|
4240
4367
|
max-width: 50% !important;
|
|
@@ -4244,27 +4371,20 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4244
4371
|
white-space: nowrap !important;
|
|
4245
4372
|
}
|
|
4246
4373
|
/* Readonly: prevent flex row from overflowing panel */
|
|
4247
|
-
|
|
4374
|
+
.${sectionClassId} .TextDisplayWidget {
|
|
4248
4375
|
min-width: 0 !important;
|
|
4249
4376
|
overflow: hidden !important;
|
|
4250
4377
|
}
|
|
4251
|
-
|
|
4378
|
+
.${sectionClassId} .TextDisplayWidget > .flex-1 {
|
|
4252
4379
|
min-width: 0 !important;
|
|
4253
4380
|
overflow: hidden !important;
|
|
4254
4381
|
}
|
|
4255
|
-
/* Readonly value
|
|
4256
|
-
|
|
4382
|
+
/* Readonly value text truncation */
|
|
4383
|
+
.${sectionClassId} .TextDisplayWidget > .flex-1 > .text-gray-900 {
|
|
4257
4384
|
overflow: hidden;
|
|
4258
4385
|
text-overflow: ellipsis;
|
|
4259
4386
|
white-space: nowrap;
|
|
4260
4387
|
}
|
|
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
|
-
}
|
|
4268
4388
|
|
|
4269
4389
|
/* Only apply fixed height when in edit mode */
|
|
4270
4390
|
.${sectionClassId}[data-edit-mode="true"] {
|
|
@@ -4286,11 +4406,11 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4286
4406
|
.${sectionClassId}-edit {
|
|
4287
4407
|
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.2),
|
|
4288
4408
|
0 8px 10px -6px rgba(0, 0, 0, 0.1);
|
|
4289
|
-
border-color: #
|
|
4409
|
+
border-color: var(--owt-color-primary-dark, #F07B1A);
|
|
4290
4410
|
border-style: dashed;
|
|
4291
4411
|
border-width: 1px;
|
|
4292
|
-
background-color: #
|
|
4293
|
-
border-radius: 10px;
|
|
4412
|
+
background-color: var(--owt-color-primary-light, #FBE6AA);
|
|
4413
|
+
border-radius: var(--owt-section-border-radius, 10px);
|
|
4294
4414
|
z-index: 10;
|
|
4295
4415
|
position: absolute;
|
|
4296
4416
|
}
|
|
@@ -4390,23 +4510,23 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4390
4510
|
|
|
4391
4511
|
/* IntakeForm accordion */
|
|
4392
4512
|
.${sectionClassId}.intake-form-accordion-item {
|
|
4393
|
-
border-color: #
|
|
4513
|
+
border-color: var(--owt-color-border-light, #E4E4E4);
|
|
4394
4514
|
transition: box-shadow 0.2s ease, border-color 0.2s ease;
|
|
4395
4515
|
}
|
|
4396
4516
|
.${sectionClassId}.intake-form-accordion-item:hover {
|
|
4397
|
-
border-color: #
|
|
4517
|
+
border-color: var(--owt-color-border, #C4C4C4);
|
|
4398
4518
|
}
|
|
4399
4519
|
.${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header {
|
|
4400
4520
|
transition: opacity 0.2s ease, background-color 0.2s ease;
|
|
4401
4521
|
}
|
|
4402
4522
|
.${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header h2 {
|
|
4403
|
-
color: #
|
|
4523
|
+
color: var(--owt-color-primary-dark, #F07B1A);
|
|
4404
4524
|
}
|
|
4405
4525
|
.${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header:hover {
|
|
4406
4526
|
opacity: 0.85;
|
|
4407
4527
|
}
|
|
4408
4528
|
.${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header:focus-visible {
|
|
4409
|
-
outline: 2px solid #
|
|
4529
|
+
outline: 2px solid var(--owt-color-primary, #F5BB1A);
|
|
4410
4530
|
outline-offset: 2px;
|
|
4411
4531
|
}
|
|
4412
4532
|
.${sectionClassId}.intake-form-accordion-item .intake-form-accordion-content {
|
|
@@ -4418,27 +4538,27 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4418
4538
|
width: 100%;
|
|
4419
4539
|
}
|
|
4420
4540
|
.${sectionClassId}.intake-form-accordion-item .intake-form-prev-btn {
|
|
4421
|
-
color:
|
|
4541
|
+
color: var(--owt-color-text-muted, #727474) !important;
|
|
4422
4542
|
}
|
|
4423
4543
|
.${sectionClassId}.intake-form-accordion-item .intake-form-prev-btn:disabled {
|
|
4424
|
-
color:
|
|
4544
|
+
color: var(--owt-color-border, #C4C4C4) !important;
|
|
4425
4545
|
}
|
|
4426
4546
|
.${sectionClassId}.intake-form-accordion-item .intake-form-prev-btn:hover:not(:disabled) {
|
|
4427
|
-
background-color: #
|
|
4428
|
-
border-color: #
|
|
4547
|
+
background-color: var(--owt-color-bg-alt, #F6F6F6);
|
|
4548
|
+
border-color: var(--owt-btn-primary-border, #F07B1A);
|
|
4429
4549
|
}
|
|
4430
4550
|
.${sectionClassId}.intake-form-accordion-item .intake-form-save-btn:hover:not(:disabled) {
|
|
4431
|
-
background-color: #
|
|
4551
|
+
background-color: var(--owt-color-border-light, #E4E4E4);
|
|
4432
4552
|
}
|
|
4433
|
-
` }), jsxRuntimeExports.jsx("div", { ref: sectionRef, className: `section ${sectionClassId} px-4 sm:px-6 lg:px-8 border-2
|
|
4553
|
+
` }), jsxRuntimeExports.jsx("div", { ref: sectionRef, className: `section ${sectionClassId} px-4 sm:px-6 lg:px-8 border-2 ${mode === 'IntakeForm' ? 'intake-form-accordion-item' : ''}`, "data-section-id": sectionId, "data-has-table": hasTableWidget ? 'true' : 'false', "data-has-explicit-span": hasExplicitTableSpan ? 'true' : 'false', "data-edit-mode": isEditMode ? 'true' : 'false', "data-section-dirty": isEditMode && isDirty ? 'true' : 'false', "data-column-span": columnSpan, "data-change-request-type": changeRequestType, "data-intake-form-expanded": mode === 'IntakeForm' ? (isExpanded ? 'true' : 'false') : undefined, style: {
|
|
4434
4554
|
gridColumn: `span ${columnSpan}`,
|
|
4435
4555
|
width: '100%',
|
|
4436
|
-
borderRadius: '10px',
|
|
4437
|
-
|
|
4556
|
+
borderRadius: 'var(--owt-section-border-radius, 10px)',
|
|
4557
|
+
borderColor: 'var(--owt-color-bg, #FFFFFF)',
|
|
4438
4558
|
...(mode === 'IntakeForm' && isExpanded
|
|
4439
|
-
? { backgroundColor: '#
|
|
4559
|
+
? { backgroundColor: 'var(--owt-color-primary-light, #FBE6AA)', border: '1px dashed var(--owt-color-primary-dark, #F07B1A)' }
|
|
4440
4560
|
: {
|
|
4441
|
-
backgroundColor: changeRequestType === 'old' ? '#
|
|
4561
|
+
backgroundColor: changeRequestType === 'old' ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-section-bg, #FFFFFF)',
|
|
4442
4562
|
opacity: changeRequestType === 'old' ? 0.95 : 1,
|
|
4443
4563
|
}),
|
|
4444
4564
|
...(isEditMode && sectionHeight ? {
|
|
@@ -4472,17 +4592,17 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4472
4592
|
borderRadius: '9999px',
|
|
4473
4593
|
fontSize: '12px',
|
|
4474
4594
|
fontWeight: 500,
|
|
4475
|
-
backgroundColor: '#D1FAE5',
|
|
4476
|
-
color: '#047857',
|
|
4595
|
+
backgroundColor: 'var(--owt-color-success-light, #D1FAE5)',
|
|
4596
|
+
color: 'var(--owt-color-success-dark, #047857)',
|
|
4477
4597
|
}, children: translate('common.sectionSaved') || 'Saved' })), intakeFormSectionStatus === 'modified' && (jsxRuntimeExports.jsx("span", { style: {
|
|
4478
4598
|
display: 'inline-block',
|
|
4479
4599
|
padding: '4px 10px',
|
|
4480
4600
|
borderRadius: '9999px',
|
|
4481
4601
|
fontSize: '12px',
|
|
4482
4602
|
fontWeight: 500,
|
|
4483
|
-
backgroundColor: '#FEE2E2',
|
|
4484
|
-
color: '#B91C1C',
|
|
4485
|
-
}, children: translate('common.sectionModified') || 'Modified and not saved' }))] }), jsxRuntimeExports.jsx("img", { src: isExpanded ? img$7 : img$6, alt: isExpanded ? 'Collapse' : 'Expand', className: "w-5 h-5 transition-transform", style: { flexShrink: 0, marginLeft: '12px' }, "aria-hidden": true })] }), isExpanded && (jsxRuntimeExports.jsx("div", { id: `intake-form-accordion-content-${sectionId}`, className: "intake-form-accordion-content", role: "region", "aria-labelledby": `intake-form-accordion-header-${sectionId}`, children: jsxRuntimeExports.jsxs("div", { id: gridId, className: "section-panels", style: { paddingTop: '8px' }, children: [editableSection.panels.map((panel, index) => (jsxRuntimeExports.jsx("div", { className: "panel-wrapper", children: jsxRuntimeExports.jsx(PanelRenderer, { panel: panel, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: namespacedSchemaData, onValueChange: onValueChange, isEditMode: isDraft !== false }) }, panel['panel-id'] || `section-panel-${index}`))), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: '#
|
|
4603
|
+
backgroundColor: 'var(--owt-color-error-light, #FEE2E2)',
|
|
4604
|
+
color: 'var(--owt-color-error, #B91C1C)',
|
|
4605
|
+
}, children: translate('common.sectionModified') || 'Modified and not saved' }))] }), jsxRuntimeExports.jsx("img", { src: isExpanded ? img$7 : img$6, alt: isExpanded ? 'Collapse' : 'Expand', className: "w-5 h-5 transition-transform", style: { flexShrink: 0, marginLeft: '12px' }, "aria-hidden": true })] }), isExpanded && (jsxRuntimeExports.jsx("div", { id: `intake-form-accordion-content-${sectionId}`, className: "intake-form-accordion-content", role: "region", "aria-labelledby": `intake-form-accordion-header-${sectionId}`, children: jsxRuntimeExports.jsxs("div", { id: gridId, className: "section-panels", style: { paddingTop: '8px' }, children: [editableSection.panels.map((panel, index) => (jsxRuntimeExports.jsx("div", { className: "panel-wrapper", children: jsxRuntimeExports.jsx(PanelRenderer, { panel: panel, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: namespacedSchemaData, onValueChange: onValueChange, isEditMode: isDraft !== false }) }, panel['panel-id'] || `section-panel-${index}`))), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: 'var(--owt-section-divider-color, #F5BB1A)', border: 'none', margin: '15px 0 0 0' } }), hasSupportingDocuments && (jsxRuntimeExports.jsxs("div", { className: "supporting-documents-container", children: [jsxRuntimeExports.jsx("span", { className: "font-semibold", style: { fontFamily: 'Roboto, sans-serif', fontSize: '16px' }, children: translate('common.supportedDocuments') || 'Supported Documents' }), jsxRuntimeExports.jsx("div", { className: "supporting-documents-grid mt-4", children: supportingDocuments.map((doc, docIndex) => {
|
|
4486
4606
|
const docConfig = createDocumentWidgetConfig(doc, sectionId, docIndex);
|
|
4487
4607
|
return (jsxRuntimeExports.jsx("div", { className: "supporting-document-item", children: jsxRuntimeExports.jsx(FileInputWidget, { config: docConfig }) }, `${sectionId}-doc-${docIndex}`));
|
|
4488
4608
|
}) })] })), jsxRuntimeExports.jsxs("div", { className: "intake-form-edit-controls", style: {
|
|
@@ -4498,10 +4618,10 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4498
4618
|
fontSize: '14px',
|
|
4499
4619
|
fontWeight: 400,
|
|
4500
4620
|
padding: '8px 24px',
|
|
4501
|
-
borderRadius: '10px',
|
|
4502
|
-
border: '1px solid #
|
|
4503
|
-
background: '#FFFFFF',
|
|
4504
|
-
color: '
|
|
4621
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
4622
|
+
border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
|
|
4623
|
+
background: 'var(--owt-btn-primary-bg, #FFFFFF)',
|
|
4624
|
+
color: 'var(--owt-color-text-muted, #727474)',
|
|
4505
4625
|
cursor: 'pointer',
|
|
4506
4626
|
display: 'inline-flex',
|
|
4507
4627
|
alignItems: 'center',
|
|
@@ -4511,10 +4631,10 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4511
4631
|
fontSize: '14px',
|
|
4512
4632
|
fontWeight: 400,
|
|
4513
4633
|
padding: '8px 24px',
|
|
4514
|
-
borderRadius: '10px',
|
|
4515
|
-
border: '1px solid #
|
|
4516
|
-
background: '#FFFFFF',
|
|
4517
|
-
color: '
|
|
4634
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
4635
|
+
border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
|
|
4636
|
+
background: 'var(--owt-btn-primary-bg, #FFFFFF)',
|
|
4637
|
+
color: 'var(--owt-color-text-muted, #727474)',
|
|
4518
4638
|
cursor: 'pointer',
|
|
4519
4639
|
display: 'inline-flex',
|
|
4520
4640
|
alignItems: 'center',
|
|
@@ -4537,11 +4657,11 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4537
4657
|
fontWeight: 600,
|
|
4538
4658
|
textTransform: 'uppercase',
|
|
4539
4659
|
letterSpacing: '0.5px',
|
|
4540
|
-
backgroundColor: changeRequestType === 'new' ? '#
|
|
4541
|
-
color: changeRequestType === 'new' ? '#FFFFFF' : '#
|
|
4660
|
+
backgroundColor: changeRequestType === 'new' ? 'var(--owt-color-success, #16A34A)' : 'var(--owt-color-error-light, #FEE2E2)',
|
|
4661
|
+
color: changeRequestType === 'new' ? 'var(--owt-color-bg, #FFFFFF)' : 'var(--owt-color-error, #B91C1C)',
|
|
4542
4662
|
whiteSpace: 'nowrap',
|
|
4543
4663
|
boxShadow: changeRequestType === 'new' ? '0 2px 4px rgba(40, 167, 69, 0.3)' : 'none',
|
|
4544
|
-
}, children: changeRequestType === 'new' ? 'New' : 'Old' }))] })), jsxRuntimeExports.jsxs("div", { id: gridId, className: "section-panels", style: mode === 'RegistryView' && hideEditButton ? { paddingBottom: '
|
|
4664
|
+
}, children: changeRequestType === 'new' ? 'New' : 'Old' }))] })), jsxRuntimeExports.jsxs("div", { id: gridId, className: "section-panels", style: mode === 'RegistryView' && hideEditButton ? { paddingBottom: '30px' } : {}, children: [editableSection.panels.map((panel, index) => (jsxRuntimeExports.jsx("div", { className: "panel-wrapper", children: jsxRuntimeExports.jsx(PanelRenderer, { panel: panel, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: namespacedSchemaData, onValueChange: onValueChange }) }, panel['panel-id'] || `section-panel-${index}`))), mode === 'CRView' && crViewData && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', marginTop: '20px', marginBottom: '0px', border: 'none', backgroundColor: 'var(--owt-color-border, #C4C4C4)' } }), jsxRuntimeExports.jsxs("div", { className: "cr-view-container", style: {
|
|
4545
4665
|
marginTop: '20px',
|
|
4546
4666
|
paddingBottom: '30px',
|
|
4547
4667
|
display: 'flex',
|
|
@@ -4556,17 +4676,17 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4556
4676
|
}, children: [jsxRuntimeExports.jsx("span", { style: {
|
|
4557
4677
|
fontFamily: 'Roboto, sans-serif',
|
|
4558
4678
|
fontSize: '14px',
|
|
4559
|
-
color: '#
|
|
4679
|
+
color: 'var(--owt-color-text, #011627)',
|
|
4560
4680
|
fontWeight: 'normal',
|
|
4561
4681
|
}, children: "Created by" }), jsxRuntimeExports.jsx("img", { src: img$a, alt: "Person", width: "16", height: "16", style: { filter: 'brightness(0) saturate(100%) invert(56%) sepia(45%) saturate(5139%) hue-rotate(348deg) brightness(96%) contrast(92%)' } }), crViewData?.createdBy && (jsxRuntimeExports.jsx("span", { style: {
|
|
4562
4682
|
fontFamily: 'Roboto, sans-serif',
|
|
4563
4683
|
fontSize: '14px',
|
|
4564
|
-
color: '#
|
|
4684
|
+
color: 'var(--owt-color-text, #011627)',
|
|
4565
4685
|
fontWeight: 'normal',
|
|
4566
4686
|
}, children: crViewData.createdBy })), jsxRuntimeExports.jsx("img", { src: img$9, alt: "Calendar", width: "16", height: "16", style: { marginLeft: '6px' } }), crViewData?.createdDate && (jsxRuntimeExports.jsx("span", { style: {
|
|
4567
4687
|
fontFamily: 'Roboto, sans-serif',
|
|
4568
4688
|
fontSize: '14px',
|
|
4569
|
-
color: '#
|
|
4689
|
+
color: 'var(--owt-color-text, #011627)',
|
|
4570
4690
|
fontWeight: 'normal',
|
|
4571
4691
|
}, children: crViewData.createdDate }))] }), jsxRuntimeExports.jsxs("div", { className: "approved-by-section", style: {
|
|
4572
4692
|
display: 'flex',
|
|
@@ -4577,22 +4697,22 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4577
4697
|
}, children: [jsxRuntimeExports.jsx("span", { style: {
|
|
4578
4698
|
fontFamily: 'Roboto, sans-serif',
|
|
4579
4699
|
fontSize: '14px',
|
|
4580
|
-
color: '#
|
|
4700
|
+
color: 'var(--owt-color-text, #011627)',
|
|
4581
4701
|
fontWeight: 'normal',
|
|
4582
4702
|
}, children: "Approved by" }), jsxRuntimeExports.jsx("img", { src: img$a, alt: "Person", width: "16", height: "16", style: { filter: 'brightness(0) saturate(100%) invert(56%) sepia(45%) saturate(5139%) hue-rotate(348deg) brightness(96%) contrast(92%)' } }), crViewData?.approvedBy && (jsxRuntimeExports.jsx("span", { style: {
|
|
4583
4703
|
fontFamily: 'Roboto, sans-serif',
|
|
4584
4704
|
fontSize: '14px',
|
|
4585
|
-
color: '#
|
|
4705
|
+
color: 'var(--owt-color-text, #011627)',
|
|
4586
4706
|
fontWeight: 'normal',
|
|
4587
4707
|
}, children: crViewData.approvedBy })), jsxRuntimeExports.jsx("img", { src: img$9, alt: "Calendar", width: "16", height: "16", style: { marginLeft: '6px' } }), crViewData?.approvedDate && (jsxRuntimeExports.jsx("span", { style: {
|
|
4588
4708
|
fontFamily: 'Roboto, sans-serif',
|
|
4589
4709
|
fontSize: '14px',
|
|
4590
|
-
color: '#
|
|
4710
|
+
color: 'var(--owt-color-text, #011627)',
|
|
4591
4711
|
fontWeight: 'normal',
|
|
4592
|
-
}, children: crViewData.approvedDate }))] })] })] })), mode === 'RegistryView' && !hideEditButton && (jsxRuntimeExports.jsx("hr", { className: "
|
|
4712
|
+
}, children: crViewData.approvedDate }))] })] })] })), mode === 'RegistryView' && !hideEditButton && (jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', marginTop: !isEditMode ? '10px' : 0, marginBottom: '14px', border: 'none', backgroundColor: 'var(--owt-color-border, #C4C4C4)' } })), mode === 'RegistryView' && !isEditMode && !hideEditButton && (jsxRuntimeExports.jsx("div", { className: "flex justify-center items-center", style: { marginBottom: '20px' }, children: jsxRuntimeExports.jsxs("button", { onClick: handleEdit, className: "font-normal inline-flex items-center gap-2 bg-transparent border-0 p-0 cursor-pointer hover:opacity-80", style: {
|
|
4593
4713
|
fontFamily: 'Roboto, sans-serif',
|
|
4594
4714
|
fontSize: '16px',
|
|
4595
|
-
color: '
|
|
4715
|
+
color: 'var(--owt-color-text-muted, #727474)'
|
|
4596
4716
|
}, children: [translate('common.editDetails') || 'Edit Details', jsxRuntimeExports.jsx("img", { src: img$8, alt: "right-arrow", className: "w-3.5 h-3.5 brightness-0 opacity-50" })] }) }))] })] })) })] }));
|
|
4597
4717
|
};
|
|
4598
4718
|
|
|
@@ -4766,9 +4886,6 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4766
4886
|
}, []);
|
|
4767
4887
|
const safeSections = sections ?? [];
|
|
4768
4888
|
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;
|
|
4772
4889
|
// Track dirty (unsaved changes) per section for form handle validation
|
|
4773
4890
|
const sectionDirtyMapRef = useRef({});
|
|
4774
4891
|
const handleSectionDirtyChange = useCallback((sectionId, isDirty) => {
|
|
@@ -4814,14 +4931,11 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4814
4931
|
// Form handle for onFormReady - allows host to validate and get all section data from its own Submit button
|
|
4815
4932
|
const formHandle = useMemo(() => {
|
|
4816
4933
|
const getValues = () => store.getState().widget?.values || {};
|
|
4817
|
-
const getNamespace = (section, index) =>
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
: ns(section['section-id'], index)
|
|
4823
|
-
: undefined;
|
|
4824
|
-
};
|
|
4934
|
+
const getNamespace = (section, index) => namespace
|
|
4935
|
+
? typeof namespace === 'string'
|
|
4936
|
+
? namespace
|
|
4937
|
+
: namespace(section['section-id'], index)
|
|
4938
|
+
: undefined;
|
|
4825
4939
|
const checkNoUnsavedChanges = () => {
|
|
4826
4940
|
const hasDirty = Object.values(sectionDirtyMapRef.current).some(Boolean);
|
|
4827
4941
|
if (hasDirty) {
|
|
@@ -4871,7 +4985,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4871
4985
|
return results;
|
|
4872
4986
|
},
|
|
4873
4987
|
};
|
|
4874
|
-
}, [store, dispatch, safeSections]);
|
|
4988
|
+
}, [store, dispatch, safeSections, namespace]);
|
|
4875
4989
|
// Call onFormReady when form is ready (sections loaded)
|
|
4876
4990
|
useEffect(() => {
|
|
4877
4991
|
if (onFormReady && safeSections.length > 0) {
|
|
@@ -4944,6 +5058,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4944
5058
|
const sectionNamespace = namespace
|
|
4945
5059
|
? (typeof namespace === 'string' ? namespace : namespace(section['section-id'], index))
|
|
4946
5060
|
: undefined;
|
|
5061
|
+
const hideEditForSection = hideEditButton || section['section-hide-edit-button'] === true;
|
|
4947
5062
|
// IntakeForm mode: pass accordion state and handlers
|
|
4948
5063
|
const intakeFormProps = mode === 'IntakeForm'
|
|
4949
5064
|
? {
|
|
@@ -4965,7 +5080,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4965
5080
|
: {};
|
|
4966
5081
|
// Check if section has explicit column span
|
|
4967
5082
|
if (section['section-column-span']) {
|
|
4968
|
-
return (jsxRuntimeExports.jsx(SectionRenderer, { section: section, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: schemaData, onValueChange: onValueChange, gridColumnSpan: section['section-column-span'], onSectionSave: onSectionSave, hideEditButton:
|
|
5083
|
+
return (jsxRuntimeExports.jsx(SectionRenderer, { section: section, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: schemaData, onValueChange: onValueChange, gridColumnSpan: section['section-column-span'], onSectionSave: onSectionSave, hideEditButton: hideEditForSection, mode: mode, namespace: sectionNamespace, onSectionDirtyChange: handleSectionDirtyChange, ...intakeFormProps, ...registryViewEditProps }, section['section-id']));
|
|
4969
5084
|
}
|
|
4970
5085
|
const verticalPanelsCount = countVerticalPanels(section.panels);
|
|
4971
5086
|
const tableWidgetColumnSpan = getTableWidgetColumnSpan(section.panels);
|
|
@@ -4973,7 +5088,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
4973
5088
|
const columnSpan = tableWidgetColumnSpan !== null
|
|
4974
5089
|
? tableWidgetColumnSpan
|
|
4975
5090
|
: (containsTable ? Math.max(verticalPanelsCount, 2) : verticalPanelsCount);
|
|
4976
|
-
return (jsxRuntimeExports.jsx(SectionRenderer, { section: section, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: schemaData, onValueChange: onValueChange, gridColumnSpan: columnSpan, onSectionSave: onSectionSave, hideEditButton:
|
|
5091
|
+
return (jsxRuntimeExports.jsx(SectionRenderer, { section: section, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: schemaData, onValueChange: onValueChange, gridColumnSpan: columnSpan, onSectionSave: onSectionSave, hideEditButton: hideEditForSection, mode: mode, namespace: sectionNamespace, onSectionDirtyChange: handleSectionDirtyChange, ...intakeFormProps, ...registryViewEditProps }, section['section-id']));
|
|
4977
5092
|
}) })] }));
|
|
4978
5093
|
};
|
|
4979
5094
|
|
|
@@ -8154,10 +8269,10 @@ const DisplayWidget = ({ config }) => {
|
|
|
8154
8269
|
const label = translateConfig(widgetConfig['widget-label']);
|
|
8155
8270
|
// If no label, render as paragraph text
|
|
8156
8271
|
if (!label || label.trim() === '') {
|
|
8157
|
-
return (jsxRuntimeExports.jsx("div", { className: "
|
|
8272
|
+
return (jsxRuntimeExports.jsx("div", { className: "mb-3 text-base text-gray-700", title: String(displayValue ?? ''), children: displayValue }));
|
|
8158
8273
|
}
|
|
8159
|
-
// With label, render as key-value pair
|
|
8160
|
-
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px]
|
|
8274
|
+
// With label, render as key-value pair
|
|
8275
|
+
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 })] }));
|
|
8161
8276
|
};
|
|
8162
8277
|
|
|
8163
8278
|
const TableCellSelect = ({ config, value, onValueChange }) => {
|
|
@@ -8165,7 +8280,11 @@ const TableCellSelect = ({ config, value, onValueChange }) => {
|
|
|
8165
8280
|
// Use useBaseWidget to get data source options (it handles loading)
|
|
8166
8281
|
const { dataSourceOptions, loading, config: widgetConfig, } = useBaseWidget({ config });
|
|
8167
8282
|
const isReadonly = config['widget-readonly'] || false;
|
|
8168
|
-
return (jsxRuntimeExports.jsxs("select", { value: value || '', onChange: (e) => onValueChange(e.target.value), disabled: isReadonly || loading, className: `w-full h-[28px] px-2 text-sm border focus:outline-none
|
|
8283
|
+
return (jsxRuntimeExports.jsxs("select", { value: value || '', onChange: (e) => onValueChange(e.target.value), disabled: isReadonly || loading, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly || loading ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8284
|
+
borderRadius: '10px',
|
|
8285
|
+
borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
8286
|
+
backgroundColor: isReadonly || loading ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
8287
|
+
}, children: [jsxRuntimeExports.jsx("option", { value: "", children: translate('common.select') || 'Select' }), dataSourceOptions.map((option) => (jsxRuntimeExports.jsx("option", { value: option.value, children: option.label }, option.value)))] }));
|
|
8169
8288
|
};
|
|
8170
8289
|
const SelectDisplayValue = ({ config, value }) => {
|
|
8171
8290
|
const { dataSourceOptions, loading } = useBaseWidget({ config });
|
|
@@ -8184,7 +8303,11 @@ const TableCellText = ({ config, value, onValueChange }) => {
|
|
|
8184
8303
|
config['widget-data-format'];
|
|
8185
8304
|
const maxLength = config['widget-data-validation']?.maxLength;
|
|
8186
8305
|
const displayValue = value !== null && value !== undefined ? String(value) : '';
|
|
8187
|
-
return (jsxRuntimeExports.jsx("input", { type: "text", value: displayValue, onChange: (e) => onValueChange(e.target.value), disabled: isReadonly, placeholder: placeholder, maxLength: maxLength, className: `w-full h-[28px] px-2 text-sm border focus:outline-none
|
|
8306
|
+
return (jsxRuntimeExports.jsx("input", { type: "text", value: displayValue, onChange: (e) => onValueChange(e.target.value), disabled: isReadonly, placeholder: placeholder, maxLength: maxLength, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8307
|
+
borderRadius: '10px',
|
|
8308
|
+
borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
8309
|
+
backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
8310
|
+
} }));
|
|
8188
8311
|
};
|
|
8189
8312
|
const TableCellNumber = ({ config, value, onValueChange }) => {
|
|
8190
8313
|
const isReadonly = config['widget-readonly'] || false;
|
|
@@ -8207,14 +8330,22 @@ const TableCellNumber = ({ config, value, onValueChange }) => {
|
|
|
8207
8330
|
onValueChange(inputValue);
|
|
8208
8331
|
}
|
|
8209
8332
|
};
|
|
8210
|
-
return (jsxRuntimeExports.jsx("input", { type: "number", value: displayValue, onChange: handleChange, disabled: isReadonly, placeholder: placeholder, min: validationConfig?.min, max: validationConfig?.max, step: formatConfig?.decimalPlaces ? Math.pow(0.1, formatConfig.decimalPlaces) : undefined, className: `w-full h-[28px] px-2 text-sm border focus:outline-none
|
|
8333
|
+
return (jsxRuntimeExports.jsx("input", { type: "number", value: displayValue, onChange: handleChange, disabled: isReadonly, placeholder: placeholder, min: validationConfig?.min, max: validationConfig?.max, step: formatConfig?.decimalPlaces ? Math.pow(0.1, formatConfig.decimalPlaces) : undefined, className: `w-full h-[28px] px-2 text-sm border focus:outline-none text-right ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8334
|
+
borderRadius: '10px',
|
|
8335
|
+
borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
8336
|
+
backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
8337
|
+
} }));
|
|
8211
8338
|
};
|
|
8212
8339
|
const TableCellDate = ({ config, value, onValueChange }) => {
|
|
8213
8340
|
const isReadonly = config['widget-readonly'] || false;
|
|
8214
8341
|
const placeholder = config['widget-data-placeholder'] || '';
|
|
8215
8342
|
// input type="date" requires YYYY-MM-DD format
|
|
8216
8343
|
const displayValue = value && typeof value === 'string' ? value.split('T')[0] : '';
|
|
8217
|
-
return (jsxRuntimeExports.jsx("input", { type: "date", value: displayValue, onChange: (e) => onValueChange(e.target.value), disabled: isReadonly, placeholder: placeholder, className: `w-full h-[28px] px-2 text-sm border focus:outline-none
|
|
8344
|
+
return (jsxRuntimeExports.jsx("input", { type: "date", value: displayValue, onChange: (e) => onValueChange(e.target.value), disabled: isReadonly, placeholder: placeholder, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8345
|
+
borderRadius: '10px',
|
|
8346
|
+
borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
8347
|
+
backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
8348
|
+
} }));
|
|
8218
8349
|
};
|
|
8219
8350
|
const TableWidget = ({ config }) => {
|
|
8220
8351
|
const { value, error, touched, isEnabled, onChange, config: widgetConfig, } = useBaseWidget({ config });
|
|
@@ -8621,13 +8752,13 @@ const TableWidget = ({ config }) => {
|
|
|
8621
8752
|
return {}; // No special styling when editing
|
|
8622
8753
|
const editAction = row?.edit_action;
|
|
8623
8754
|
if (editAction === 'ADD') {
|
|
8624
|
-
return { color: '#
|
|
8755
|
+
return { color: 'var(--owt-color-success, #16A34A)' };
|
|
8625
8756
|
}
|
|
8626
8757
|
else if (editAction === 'DELETE') {
|
|
8627
|
-
return { color: '#
|
|
8758
|
+
return { color: 'var(--owt-color-error, #B91C1C)', textDecoration: 'line-through' };
|
|
8628
8759
|
}
|
|
8629
8760
|
else if (editAction === 'UPDATE') {
|
|
8630
|
-
return { color: '#
|
|
8761
|
+
return { color: 'var(--owt-color-warning, #F59E0B)' };
|
|
8631
8762
|
}
|
|
8632
8763
|
return {};
|
|
8633
8764
|
};
|
|
@@ -8711,27 +8842,81 @@ const TableWidget = ({ config }) => {
|
|
|
8711
8842
|
.${tableWidgetId} button {
|
|
8712
8843
|
border-radius: 10px !important;
|
|
8713
8844
|
}
|
|
8714
|
-
|
|
8845
|
+
/* Focus ring for table cell inputs */
|
|
8846
|
+
.${tableWidgetId} .table-cell-input:focus {
|
|
8847
|
+
box-shadow: 0 0 0 1px var(--owt-widget-input-focus-border, #F07B1A);
|
|
8848
|
+
border-color: var(--owt-widget-input-focus-border, #F07B1A);
|
|
8849
|
+
}
|
|
8850
|
+
` }), jsxRuntimeExports.jsxs("div", { className: `table-widget-container ${tableWidgetId}`, children: [confirmationState?.show && (jsxRuntimeExports.jsx("div", { className: "fixed inset-0 flex items-center justify-center z-50", style: { backgroundColor: 'rgba(0,0,0,0.5)' }, children: jsxRuntimeExports.jsxs("div", { className: "rounded-lg p-6 max-w-md w-full mx-4", style: { backgroundColor: 'var(--owt-color-bg, #FFFFFF)' }, children: [jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: 'var(--owt-color-text, #011627)' }, children: translate('table.confirm') || 'Confirm Action' }), jsxRuntimeExports.jsx("p", { className: "mb-6", style: { color: 'var(--owt-color-text, #011627)' }, children: confirmationState.message }), jsxRuntimeExports.jsxs("div", { className: "flex justify-end gap-3", children: [jsxRuntimeExports.jsx("button", { onClick: confirmationState.onCancel, className: "px-4 py-2 text-sm font-medium", style: {
|
|
8851
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8852
|
+
border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
|
|
8853
|
+
backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
|
|
8854
|
+
color: 'var(--owt-btn-secondary-color, #011627)',
|
|
8855
|
+
}, children: translate('common.cancel') || 'Cancel' }), jsxRuntimeExports.jsx("button", { onClick: confirmationState.onConfirm, className: "px-4 py-2 text-sm font-medium", style: {
|
|
8856
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8857
|
+
border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
|
|
8858
|
+
backgroundColor: 'var(--owt-color-primary, #F5BB1A)',
|
|
8859
|
+
color: 'var(--owt-color-bg, #FFFFFF)',
|
|
8860
|
+
}, children: translate('table.discard') || 'Discard & Continue' })] })] }) })), operations.add && !isReadonly && isEnabled && (isSectionEditMode || !isAnyRowEditing) && (jsxRuntimeExports.jsx("div", { className: "flex justify-end mb-2", children: jsxRuntimeExports.jsx("button", { type: "button", onClick: startAdd, disabled: loadingRowIndex !== null, className: "px-3 py-1 text-sm disabled:opacity-50 disabled:cursor-not-allowed", style: {
|
|
8861
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8862
|
+
border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
|
|
8863
|
+
backgroundColor: 'var(--owt-color-primary, #F5BB1A)',
|
|
8864
|
+
color: 'var(--owt-color-bg, #FFFFFF)',
|
|
8865
|
+
}, children: translate('table.addRecord') || 'Add New Record' }) })), jsxRuntimeExports.jsx("div", { className: "overflow-x-auto border", style: { borderRadius: 'var(--owt-widget-table-border-radius, 15px)', borderColor: 'var(--owt-widget-table-border-color, #C4C4C4)' }, children: jsxRuntimeExports.jsxs("table", { className: "min-w-full", style: { borderCollapse: 'separate', borderSpacing: 0 }, children: [jsxRuntimeExports.jsx("thead", { style: { backgroundColor: 'var(--owt-widget-table-header-bg, #F6F6F6)' }, children: jsxRuntimeExports.jsxs("tr", { style: { borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)' }, children: [columns.map((col) => (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translateConfig(col['widget-label']) }, col['column-key']))), ((operations.edit || operations.remove) && !isReadonly) || isAnyRowEditing || isSectionEditMode ? (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translate('common.actions') || 'Actions' })) : null] }) }), jsxRuntimeExports.jsxs("tbody", { style: { backgroundColor: 'var(--owt-widget-table-body-bg, #FFFFFF)' }, children: [rows.length === 0 && !isAdding && (jsxRuntimeExports.jsx("tr", { children: jsxRuntimeExports.jsxs("td", { colSpan: columns.length + (((operations.edit || operations.remove) && !isReadonly) || isSectionEditMode ? 1 : 0), className: "px-4 py-6 text-center text-sm", style: { color: 'var(--owt-widget-table-empty-color, #727474)' }, children: [translate('table.noData') || 'No records available.', operations.add && !isReadonly && ` ${translate('table.clickToAdd') || 'Click "Add New Record" to add one.'}`] }) })), rows.map((row, rowIndex) => {
|
|
8715
8866
|
const isEditing = isRowEditing(rowIndex);
|
|
8716
8867
|
const isLoading = loadingRowIndex === rowIndex;
|
|
8717
|
-
return (jsxRuntimeExports.jsxs("tr", { className:
|
|
8868
|
+
return (jsxRuntimeExports.jsxs("tr", { className: isLoading ? 'opacity-50' : '', style: {
|
|
8869
|
+
borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)',
|
|
8870
|
+
backgroundColor: isEditing
|
|
8871
|
+
? 'var(--owt-widget-table-editing-row-bg, #FBE6AA)'
|
|
8872
|
+
: row.edit_action === 'DELETE'
|
|
8873
|
+
? 'var(--owt-widget-table-deleted-row-bg, #FEE2E2)'
|
|
8874
|
+
: undefined,
|
|
8875
|
+
}, children: [columns.map((col) => {
|
|
8718
8876
|
return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: renderCell(rowIndex, col, row) }, col['column-key']));
|
|
8719
8877
|
}), ((operations.edit || operations.remove) && !isReadonly) || isEditing || isSectionEditMode ? (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", style: { minWidth: '120px' }, children: isEditing ? (
|
|
8720
8878
|
// Show OK (Save)/Cancel buttons when row is being edited (works in both section edit mode and normal mode)
|
|
8721
|
-
jsxRuntimeExports.jsxs("div", { className: "flex flex-row gap-2 items-center", style: { width: '100%' }, children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: saveEdit, disabled: isLoading, className: "px-3 py-1 text-xs font-medium
|
|
8879
|
+
jsxRuntimeExports.jsxs("div", { className: "flex flex-row gap-2 items-center", style: { width: '100%' }, children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: saveEdit, disabled: isLoading, className: "px-3 py-1 text-xs font-medium disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap flex-shrink-0", style: {
|
|
8722
8880
|
display: 'inline-block',
|
|
8723
8881
|
minWidth: '60px',
|
|
8724
|
-
backgroundColor: '#
|
|
8725
|
-
color: '#
|
|
8882
|
+
backgroundColor: 'var(--owt-color-success, #16A34A)',
|
|
8883
|
+
color: 'var(--owt-color-bg, #FFFFFF)',
|
|
8726
8884
|
border: 'none',
|
|
8727
|
-
borderRadius: '
|
|
8728
|
-
}, children: translate('common.ok') || 'OK' }), jsxRuntimeExports.jsx("button", { type: "button", onClick: cancelEdit, disabled: isLoading, className: "px-3 py-1 text-xs font-medium
|
|
8885
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8886
|
+
}, children: translate('common.ok') || 'OK' }), jsxRuntimeExports.jsx("button", { type: "button", onClick: cancelEdit, disabled: isLoading, className: "px-3 py-1 text-xs font-medium disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap flex-shrink-0", style: {
|
|
8887
|
+
display: 'inline-block',
|
|
8888
|
+
minWidth: '60px',
|
|
8889
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8890
|
+
border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
|
|
8891
|
+
backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
|
|
8892
|
+
color: 'var(--owt-btn-secondary-color, #011627)',
|
|
8893
|
+
}, children: translate('common.cancel') || 'Cancel' })] })) : (
|
|
8729
8894
|
// Show Edit/Delete buttons when row is not being edited
|
|
8730
|
-
jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [operations.edit && (jsxRuntimeExports.jsx("button", { type: "button", onClick: () => startEdit(rowIndex), disabled: isAnyRowEditing || isLoading, className: "px-3 py-1 text-xs
|
|
8731
|
-
|
|
8895
|
+
jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [operations.edit && (jsxRuntimeExports.jsx("button", { type: "button", onClick: () => startEdit(rowIndex), disabled: isAnyRowEditing || isLoading, className: "px-3 py-1 text-xs disabled:opacity-50 disabled:cursor-not-allowed", style: {
|
|
8896
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8897
|
+
color: 'var(--owt-color-primary-dark, #F07B1A)',
|
|
8898
|
+
backgroundColor: 'transparent',
|
|
8899
|
+
border: 'none',
|
|
8900
|
+
}, children: translate('common.edit') || 'Edit' })), operations.remove && (jsxRuntimeExports.jsx("button", { type: "button", onClick: () => deleteRow(rowIndex), disabled: isAnyRowEditing || isLoading, className: "px-3 py-1 text-xs disabled:opacity-50 disabled:cursor-not-allowed", style: {
|
|
8901
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8902
|
+
color: 'var(--owt-color-error, #B91C1C)',
|
|
8903
|
+
backgroundColor: 'transparent',
|
|
8904
|
+
border: 'none',
|
|
8905
|
+
}, children: translate('common.remove') || 'Delete' }))] })) })) : null] }, rowIndex));
|
|
8906
|
+
}), isAdding && newRowData && (jsxRuntimeExports.jsxs("tr", { style: { backgroundColor: 'var(--owt-widget-table-editing-row-bg, #FBE6AA)' }, children: [columns.map((col) => (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: renderCell(rows.length, col, { ...newRowData, edit_action: 'ADD' }) }, col['column-key']))), jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: saveAdd, disabled: loadingRowIndex === -1, className: "px-3 py-1 text-xs disabled:opacity-50", style: {
|
|
8907
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8908
|
+
backgroundColor: 'var(--owt-color-success, #16A34A)',
|
|
8909
|
+
color: 'var(--owt-color-bg, #FFFFFF)',
|
|
8910
|
+
border: 'none',
|
|
8911
|
+
}, children: translate('common.save') || 'Save' }), jsxRuntimeExports.jsx("button", { type: "button", onClick: () => {
|
|
8732
8912
|
setIsAdding(false);
|
|
8733
8913
|
setNewRowData(null);
|
|
8734
|
-
}, disabled: loadingRowIndex === -1, className: "px-3 py-1 text-xs
|
|
8914
|
+
}, disabled: loadingRowIndex === -1, className: "px-3 py-1 text-xs disabled:opacity-50", style: {
|
|
8915
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
8916
|
+
border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
|
|
8917
|
+
backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
|
|
8918
|
+
color: 'var(--owt-btn-secondary-color, #011627)',
|
|
8919
|
+
}, children: translate('common.cancel') || 'Cancel' })] }) })] }))] })] }) }), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-sm mt-1", style: { color: 'var(--owt-widget-error-color, #B91C1C)' }, children: error[0] }))] })] }));
|
|
8735
8920
|
};
|
|
8736
8921
|
|
|
8737
8922
|
const ProfileWidget = ({ config }) => {
|
|
@@ -8820,7 +9005,7 @@ const ProfileWidget = ({ config }) => {
|
|
|
8820
9005
|
// Get format options (using index access for widget-specific properties)
|
|
8821
9006
|
const format = widgetConfig['widget-data-format'] || {};
|
|
8822
9007
|
const imageSize = format.imageSize || 80;
|
|
8823
|
-
const nameColor = format.nameColor || '#
|
|
9008
|
+
const nameColor = format.nameColor || 'var(--owt-color-primary-dark, #F07B1A)';
|
|
8824
9009
|
const showIdLabel = format.showIdLabel !== false; // Default to true
|
|
8825
9010
|
// Generate a unique class ID for this widget instance
|
|
8826
9011
|
const widgetClassId = `profile-widget-${config['widget-id']}`;
|
|
@@ -8843,8 +9028,8 @@ const ProfileWidget = ({ config }) => {
|
|
|
8843
9028
|
height: ${imageSize}px;
|
|
8844
9029
|
border-radius: 8px;
|
|
8845
9030
|
object-fit: cover;
|
|
8846
|
-
background-color: #e5e7eb;
|
|
8847
|
-
border: 2px solid #d1d5db;
|
|
9031
|
+
background-color: var(--owt-color-border-light, #e5e7eb);
|
|
9032
|
+
border: 2px solid var(--owt-color-border, #d1d5db);
|
|
8848
9033
|
flex-shrink: 0;
|
|
8849
9034
|
}
|
|
8850
9035
|
|
|
@@ -8852,8 +9037,8 @@ const ProfileWidget = ({ config }) => {
|
|
|
8852
9037
|
width: ${imageSize}px;
|
|
8853
9038
|
height: ${imageSize}px;
|
|
8854
9039
|
border-radius: 8px;
|
|
8855
|
-
background-color: #e5e7eb;
|
|
8856
|
-
border: 2px solid #d1d5db;
|
|
9040
|
+
background-color: var(--owt-color-border-light, #e5e7eb);
|
|
9041
|
+
border: 2px solid var(--owt-color-border, #d1d5db);
|
|
8857
9042
|
display: flex;
|
|
8858
9043
|
align-items: center;
|
|
8859
9044
|
justify-content: center;
|
|
@@ -8894,12 +9079,12 @@ const ProfileWidget = ({ config }) => {
|
|
|
8894
9079
|
}
|
|
8895
9080
|
|
|
8896
9081
|
.${widgetClassId} .profile-id-label {
|
|
8897
|
-
color: #6b7280;
|
|
9082
|
+
color: var(--owt-color-text-muted, #6b7280);
|
|
8898
9083
|
font-weight: 500;
|
|
8899
9084
|
}
|
|
8900
9085
|
|
|
8901
9086
|
.${widgetClassId} .profile-id-value {
|
|
8902
|
-
color: #111827;
|
|
9087
|
+
color: var(--owt-color-text, #111827);
|
|
8903
9088
|
font-weight: 400;
|
|
8904
9089
|
}
|
|
8905
9090
|
` }), jsxRuntimeExports.jsxs("div", { className: widgetClassId, children: [jsxRuntimeExports.jsxs("div", { className: "profile-avatar-container", children: [imageUrl ? (jsxRuntimeExports.jsx("img", { src: imageUrl, alt: displayName || 'Profile', className: "profile-avatar", onError: (e) => {
|
|
@@ -8990,7 +9175,7 @@ const TextAreaWidget = ({ config }) => {
|
|
|
8990
9175
|
minHeight: `${rows * 1.5 * 14 + 16}px`, // Approximate height based on rows
|
|
8991
9176
|
} }), showCharCounter && (jsxRuntimeExports.jsx("div", { className: "absolute bottom-2 right-2 text-xs px-1 rounded", style: {
|
|
8992
9177
|
fontFamily: 'Roboto, sans-serif',
|
|
8993
|
-
color: maxLength && currentLength > maxLength ? '#EF4444' : '#6B7280',
|
|
9178
|
+
color: maxLength && currentLength > maxLength ? 'var(--owt-widget-error-color, #EF4444)' : 'var(--owt-widget-helptext-color, #6B7280)',
|
|
8994
9179
|
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
8995
9180
|
}, children: charCounterText }))] }), hasError && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: errorMessage }))] })] }) }));
|
|
8996
9181
|
};
|
|
@@ -9125,18 +9310,7 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9125
9310
|
result = searchIn(schemaData);
|
|
9126
9311
|
return result;
|
|
9127
9312
|
}, [paths, values, schemaData]);
|
|
9128
|
-
const
|
|
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);
|
|
9313
|
+
const imageUrl = findValue('image') || null;
|
|
9140
9314
|
const displayName = findValue('name') || '';
|
|
9141
9315
|
const functionalId = findValue('functionalId') || '';
|
|
9142
9316
|
const statusValue = findValue('status') || '';
|
|
@@ -9148,7 +9322,7 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9148
9322
|
// ── Format options ────────────────────────────────────────────
|
|
9149
9323
|
const format = (widgetConfig['widget-data-format'] || {});
|
|
9150
9324
|
const imageSize = format.imageSize || 120;
|
|
9151
|
-
const nameColor = format.nameColor || '#
|
|
9325
|
+
const nameColor = format.nameColor || 'var(--owt-color-primary-dark, #F07B1A)';
|
|
9152
9326
|
const statusColors = {
|
|
9153
9327
|
...DEFAULT_STATUS_COLORS,
|
|
9154
9328
|
...(format.statusColors || {}),
|
|
@@ -9168,21 +9342,19 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9168
9342
|
const opt = statusOptions.find((o) => String(o.value).toLowerCase() === String(statusValue).toLowerCase());
|
|
9169
9343
|
return opt ? opt.label : String(statusValue);
|
|
9170
9344
|
}, [statusValue, statusOptions]);
|
|
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]);
|
|
9345
|
+
const statusColor = statusColors[String(statusValue).toLowerCase()] || 'var(--owt-color-text-muted, #6B7280)';
|
|
9184
9346
|
// ── Scoped class for CSS isolation ────────────────────────────
|
|
9185
9347
|
const cls = `header-section-widget-${widgetConfig['widget-id']}`;
|
|
9348
|
+
// ── Indicator dot component ───────────────────────────────────
|
|
9349
|
+
const Dot = ({ color }) => (jsxRuntimeExports.jsx("span", { style: {
|
|
9350
|
+
display: 'inline-block',
|
|
9351
|
+
width: 8,
|
|
9352
|
+
height: 8,
|
|
9353
|
+
borderRadius: '50%',
|
|
9354
|
+
backgroundColor: color,
|
|
9355
|
+
flexShrink: 0,
|
|
9356
|
+
marginTop: 6,
|
|
9357
|
+
} }));
|
|
9186
9358
|
// ── RENDER ────────────────────────────────────────────────────
|
|
9187
9359
|
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { children: `
|
|
9188
9360
|
.${cls} {
|
|
@@ -9216,8 +9388,8 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9216
9388
|
height: ${imageSize}px;
|
|
9217
9389
|
border-radius: 8px;
|
|
9218
9390
|
object-fit: cover;
|
|
9219
|
-
background-color: #e5e7eb;
|
|
9220
|
-
border: 2px solid #d1d5db;
|
|
9391
|
+
background-color: var(--owt-color-border-light, #e5e7eb);
|
|
9392
|
+
border: 2px solid var(--owt-color-border, #d1d5db);
|
|
9221
9393
|
flex-shrink: 0;
|
|
9222
9394
|
}
|
|
9223
9395
|
|
|
@@ -9225,8 +9397,8 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9225
9397
|
width: ${imageSize}px;
|
|
9226
9398
|
height: ${imageSize}px;
|
|
9227
9399
|
border-radius: 8px;
|
|
9228
|
-
background-color: #e5e7eb;
|
|
9229
|
-
border: 2px solid #d1d5db;
|
|
9400
|
+
background-color: var(--owt-color-border-light, #e5e7eb);
|
|
9401
|
+
border: 2px solid var(--owt-color-border, #d1d5db);
|
|
9230
9402
|
display: flex;
|
|
9231
9403
|
align-items: center;
|
|
9232
9404
|
justify-content: center;
|
|
@@ -9241,56 +9413,6 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9241
9413
|
border-radius: 8px;
|
|
9242
9414
|
}
|
|
9243
9415
|
|
|
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
|
-
|
|
9294
9416
|
.${cls} .hdr-info {
|
|
9295
9417
|
display: flex;
|
|
9296
9418
|
flex-direction: column;
|
|
@@ -9322,7 +9444,7 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9322
9444
|
}
|
|
9323
9445
|
|
|
9324
9446
|
.${cls} .hdr-field-value {
|
|
9325
|
-
color: #111827;
|
|
9447
|
+
color: var(--owt-color-text, #111827);
|
|
9326
9448
|
font-weight: 500;
|
|
9327
9449
|
}
|
|
9328
9450
|
|
|
@@ -9349,41 +9471,41 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9349
9471
|
}
|
|
9350
9472
|
|
|
9351
9473
|
.${cls} .hdr-meta-value {
|
|
9352
|
-
color: #111827;
|
|
9474
|
+
color: var(--owt-color-text, #111827);
|
|
9353
9475
|
font-weight: 500;
|
|
9354
9476
|
}
|
|
9355
9477
|
|
|
9356
9478
|
.${cls} .hdr-select {
|
|
9357
9479
|
height: 32px;
|
|
9358
9480
|
padding: 0 8px;
|
|
9359
|
-
border: 1px solid #d1d5db;
|
|
9481
|
+
border: 1px solid var(--owt-widget-input-border, #d1d5db);
|
|
9360
9482
|
border-radius: 6px;
|
|
9361
9483
|
font-size: 0.875rem;
|
|
9362
9484
|
font-family: Roboto, sans-serif;
|
|
9363
|
-
background: #fff;
|
|
9485
|
+
background: var(--owt-widget-input-bg, #fff);
|
|
9364
9486
|
min-width: 140px;
|
|
9365
|
-
color: #374151;
|
|
9487
|
+
color: var(--owt-btn-primary-color, #374151);
|
|
9366
9488
|
}
|
|
9367
9489
|
.${cls} .hdr-select:focus {
|
|
9368
9490
|
outline: none;
|
|
9369
|
-
border-color: #
|
|
9491
|
+
border-color: var(--owt-widget-input-focus-border, #F07B1A);
|
|
9370
9492
|
box-shadow: 0 0 0 2px rgba(237, 124, 34, 0.15);
|
|
9371
9493
|
}
|
|
9372
9494
|
|
|
9373
9495
|
.${cls} .hdr-input {
|
|
9374
9496
|
height: 32px;
|
|
9375
9497
|
padding: 0 8px;
|
|
9376
|
-
border: 1px solid #d1d5db;
|
|
9498
|
+
border: 1px solid var(--owt-widget-input-border, #d1d5db);
|
|
9377
9499
|
border-radius: 6px;
|
|
9378
9500
|
font-size: 0.875rem;
|
|
9379
9501
|
font-family: Roboto, sans-serif;
|
|
9380
|
-
background: #fff;
|
|
9502
|
+
background: var(--owt-widget-input-bg, #fff);
|
|
9381
9503
|
min-width: 140px;
|
|
9382
|
-
color: #374151;
|
|
9504
|
+
color: var(--owt-btn-primary-color, #374151);
|
|
9383
9505
|
}
|
|
9384
9506
|
.${cls} .hdr-input:focus {
|
|
9385
9507
|
outline: none;
|
|
9386
|
-
border-color: #
|
|
9508
|
+
border-color: var(--owt-widget-input-focus-border, #F07B1A);
|
|
9387
9509
|
box-shadow: 0 0 0 2px rgba(237, 124, 34, 0.15);
|
|
9388
9510
|
}
|
|
9389
9511
|
|
|
@@ -9395,13 +9517,220 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9395
9517
|
min-width: 0;
|
|
9396
9518
|
}
|
|
9397
9519
|
}
|
|
9398
|
-
` }), jsxRuntimeExports.jsxs("div", { className: cls, children: [jsxRuntimeExports.jsxs("div", { className: "hdr-left", children: [jsxRuntimeExports.jsxs("div", {
|
|
9520
|
+
` }), jsxRuntimeExports.jsxs("div", { className: cls, children: [jsxRuntimeExports.jsxs("div", { className: "hdr-left", children: [jsxRuntimeExports.jsxs("div", { children: [imageUrl ? (jsxRuntimeExports.jsx("img", { src: imageUrl, alt: displayName || 'Profile', className: "hdr-avatar", onError: (e) => {
|
|
9399
9521
|
e.target.style.display = 'none';
|
|
9400
9522
|
const placeholder = e.target
|
|
9401
9523
|
.parentElement?.querySelector('.hdr-avatar-placeholder');
|
|
9402
9524
|
if (placeholder)
|
|
9403
9525
|
placeholder.style.display = 'flex';
|
|
9404
|
-
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display:
|
|
9526
|
+
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display: imageUrl ? 'none' : 'flex' }, children: jsxRuntimeExports.jsx("img", { src: img$f, alt: "Profile Placeholder" }) })] }), 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.jsx(Dot, { color: "#9CA3AF" }), 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(Dot, { color: isReadonly ? statusColor : '#F59E0B' }), 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.jsx(Dot, { color: isReadonly ? '#9CA3AF' : '#F59E0B' }), 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 || '-' })] })] })] })] }));
|
|
9527
|
+
};
|
|
9528
|
+
|
|
9529
|
+
function getValueByPathOrKey(obj, path) {
|
|
9530
|
+
if (!obj || !path)
|
|
9531
|
+
return undefined;
|
|
9532
|
+
if (Object.prototype.hasOwnProperty.call(obj, path))
|
|
9533
|
+
return obj[path];
|
|
9534
|
+
return getValueByPath(obj, path);
|
|
9535
|
+
}
|
|
9536
|
+
function tryFormatDateTime(value) {
|
|
9537
|
+
if (typeof value !== 'string' || !value)
|
|
9538
|
+
return value ? String(value) : '-';
|
|
9539
|
+
const d = new Date(value);
|
|
9540
|
+
if (Number.isNaN(d.getTime()))
|
|
9541
|
+
return value;
|
|
9542
|
+
try {
|
|
9543
|
+
return d.toLocaleString(undefined, {
|
|
9544
|
+
year: 'numeric',
|
|
9545
|
+
month: 'short',
|
|
9546
|
+
day: '2-digit',
|
|
9547
|
+
hour: '2-digit',
|
|
9548
|
+
minute: '2-digit',
|
|
9549
|
+
});
|
|
9550
|
+
}
|
|
9551
|
+
catch {
|
|
9552
|
+
return value;
|
|
9553
|
+
}
|
|
9554
|
+
}
|
|
9555
|
+
function sortScores(scores) {
|
|
9556
|
+
const withTime = scores
|
|
9557
|
+
.map((s, idx) => {
|
|
9558
|
+
const t = typeof s?.computed_at === 'string' ? new Date(s.computed_at).getTime() : NaN;
|
|
9559
|
+
return { s, t, idx };
|
|
9560
|
+
})
|
|
9561
|
+
.sort((a, b) => {
|
|
9562
|
+
const aHas = !Number.isNaN(a.t);
|
|
9563
|
+
const bHas = !Number.isNaN(b.t);
|
|
9564
|
+
if (aHas && bHas)
|
|
9565
|
+
return b.t - a.t;
|
|
9566
|
+
if (aHas)
|
|
9567
|
+
return -1;
|
|
9568
|
+
if (bHas)
|
|
9569
|
+
return 1;
|
|
9570
|
+
return a.idx - b.idx;
|
|
9571
|
+
});
|
|
9572
|
+
return withTime.map((x) => x.s);
|
|
9573
|
+
}
|
|
9574
|
+
/**
|
|
9575
|
+
* Scores Display Widget - full-width, view-only widget (list)
|
|
9576
|
+
*
|
|
9577
|
+
* Expected config (reference):
|
|
9578
|
+
* {
|
|
9579
|
+
* "widget": "scores-display",
|
|
9580
|
+
* "widget-type": "group",
|
|
9581
|
+
* "widget-id": "record-scores",
|
|
9582
|
+
* "widget-data-path": "scores"
|
|
9583
|
+
* }
|
|
9584
|
+
*/
|
|
9585
|
+
const ScoresDisplayWidget = ({ config, schemaData: propSchemaData, }) => {
|
|
9586
|
+
const { schemaData: ctxSchemaData } = useWidgetContext();
|
|
9587
|
+
const schemaData = (propSchemaData || ctxSchemaData || {});
|
|
9588
|
+
const values = useSelector((state) => state.widget.values);
|
|
9589
|
+
const dataPath = config['widget-data-path'];
|
|
9590
|
+
const rawScores = useMemo(() => {
|
|
9591
|
+
if (!dataPath || typeof dataPath !== 'string')
|
|
9592
|
+
return undefined;
|
|
9593
|
+
const valuesObj = values;
|
|
9594
|
+
const tryResolve = (path) => {
|
|
9595
|
+
const fromValues = getValueByPathOrKey(valuesObj, path);
|
|
9596
|
+
if (fromValues !== undefined)
|
|
9597
|
+
return fromValues;
|
|
9598
|
+
return getValueByPathOrKey(schemaData, path);
|
|
9599
|
+
};
|
|
9600
|
+
// 1) Try exact path (works when schema/store is already namespaced)
|
|
9601
|
+
const direct = tryResolve(dataPath);
|
|
9602
|
+
if (direct !== undefined)
|
|
9603
|
+
return direct;
|
|
9604
|
+
// 2) If section/widget config has been namespaced (e.g. "rv-section-0.scores"),
|
|
9605
|
+
// fall back to the original path ("scores") so examples still work even when
|
|
9606
|
+
// schemaData/store are not namespaced.
|
|
9607
|
+
if (dataPath.includes('.')) {
|
|
9608
|
+
const unNamespaced = dataPath.split('.').slice(1).join('.');
|
|
9609
|
+
const fallback = tryResolve(unNamespaced);
|
|
9610
|
+
if (fallback !== undefined)
|
|
9611
|
+
return fallback;
|
|
9612
|
+
}
|
|
9613
|
+
return undefined;
|
|
9614
|
+
}, [dataPath, values, schemaData]);
|
|
9615
|
+
const scores = useMemo(() => {
|
|
9616
|
+
if (!rawScores)
|
|
9617
|
+
return [];
|
|
9618
|
+
if (Array.isArray(rawScores))
|
|
9619
|
+
return rawScores;
|
|
9620
|
+
if (typeof rawScores === 'object') {
|
|
9621
|
+
const maybe = rawScores.scores;
|
|
9622
|
+
if (Array.isArray(maybe))
|
|
9623
|
+
return maybe;
|
|
9624
|
+
}
|
|
9625
|
+
return [];
|
|
9626
|
+
}, [rawScores]);
|
|
9627
|
+
const sortedScores = useMemo(() => sortScores(scores), [scores]);
|
|
9628
|
+
const cls = `scores-display-widget-${config['widget-id']}`;
|
|
9629
|
+
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { children: `
|
|
9630
|
+
.${cls} {
|
|
9631
|
+
width: 100%;
|
|
9632
|
+
font-family: Roboto, sans-serif;
|
|
9633
|
+
padding: 0;
|
|
9634
|
+
display: flex;
|
|
9635
|
+
flex-direction: column;
|
|
9636
|
+
gap: 8px;
|
|
9637
|
+
}
|
|
9638
|
+
|
|
9639
|
+
.${cls} .scores-subtle {
|
|
9640
|
+
font-size: 13px;
|
|
9641
|
+
color: var(--owt-color-text-muted, #727474);
|
|
9642
|
+
font-weight: 400;
|
|
9643
|
+
}
|
|
9644
|
+
|
|
9645
|
+
.${cls} .scores-grid {
|
|
9646
|
+
width: 100%;
|
|
9647
|
+
display: grid;
|
|
9648
|
+
grid-template-columns: repeat(3, minmax(220px, 1fr));
|
|
9649
|
+
gap: 16px;
|
|
9650
|
+
}
|
|
9651
|
+
|
|
9652
|
+
.${cls} .scores-card {
|
|
9653
|
+
border: 1px solid var(--owt-color-border-light, #E4E4E4);
|
|
9654
|
+
border-radius: 10px;
|
|
9655
|
+
background: var(--owt-color-bg, #FFFFFF);
|
|
9656
|
+
padding: 14px 14px;
|
|
9657
|
+
display: flex;
|
|
9658
|
+
flex-direction: column;
|
|
9659
|
+
gap: 10px;
|
|
9660
|
+
min-width: 0;
|
|
9661
|
+
box-shadow: 0 1px 2px rgba(1, 22, 39, 0.06), 0 6px 16px rgba(1, 22, 39, 0.06);
|
|
9662
|
+
}
|
|
9663
|
+
|
|
9664
|
+
.${cls} .scores-type {
|
|
9665
|
+
font-size: 16px;
|
|
9666
|
+
font-weight: 800;
|
|
9667
|
+
color: var(--owt-color-primary-dark, #F07B1A);
|
|
9668
|
+
line-height: 1.2;
|
|
9669
|
+
word-break: break-word;
|
|
9670
|
+
}
|
|
9671
|
+
|
|
9672
|
+
.${cls} .scores-value {
|
|
9673
|
+
font-size: 34px;
|
|
9674
|
+
font-weight: 800;
|
|
9675
|
+
color: var(--owt-color-text, #011627);
|
|
9676
|
+
line-height: 1.05;
|
|
9677
|
+
letter-spacing: -0.25px;
|
|
9678
|
+
}
|
|
9679
|
+
|
|
9680
|
+
.${cls} .scores-separator {
|
|
9681
|
+
height: 1px;
|
|
9682
|
+
width: 100%;
|
|
9683
|
+
background-color: var(--owt-color-border-light, #E4E4E4);
|
|
9684
|
+
border: none;
|
|
9685
|
+
margin: 2px 0;
|
|
9686
|
+
}
|
|
9687
|
+
|
|
9688
|
+
.${cls} .scores-value .scores-muted {
|
|
9689
|
+
font-size: 18px;
|
|
9690
|
+
font-weight: 600;
|
|
9691
|
+
color: var(--owt-color-text-muted, #727474);
|
|
9692
|
+
margin-left: 6px;
|
|
9693
|
+
}
|
|
9694
|
+
|
|
9695
|
+
.${cls} .scores-meta {
|
|
9696
|
+
display: flex;
|
|
9697
|
+
flex-direction: column;
|
|
9698
|
+
gap: 4px;
|
|
9699
|
+
}
|
|
9700
|
+
|
|
9701
|
+
.${cls} .scores-meta-line {
|
|
9702
|
+
font-size: 13px;
|
|
9703
|
+
color: var(--owt-color-text-muted, #727474);
|
|
9704
|
+
font-weight: 500;
|
|
9705
|
+
}
|
|
9706
|
+
|
|
9707
|
+
.${cls} .scores-meta-line strong {
|
|
9708
|
+
color: var(--owt-color-text, #011627);
|
|
9709
|
+
font-weight: 700;
|
|
9710
|
+
}
|
|
9711
|
+
|
|
9712
|
+
@media (max-width: 1024px) {
|
|
9713
|
+
.${cls} .scores-grid {
|
|
9714
|
+
grid-template-columns: repeat(2, minmax(220px, 1fr));
|
|
9715
|
+
}
|
|
9716
|
+
}
|
|
9717
|
+
|
|
9718
|
+
@media (max-width: 640px) {
|
|
9719
|
+
.${cls} .scores-grid {
|
|
9720
|
+
grid-template-columns: 1fr;
|
|
9721
|
+
}
|
|
9722
|
+
}
|
|
9723
|
+
` }), jsxRuntimeExports.jsx("div", { className: cls, children: sortedScores.length === 0 ? (jsxRuntimeExports.jsx("div", { className: "scores-subtle", children: "No scores available." })) : (jsxRuntimeExports.jsx("div", { className: "scores-grid", children: sortedScores.map((s, idx) => {
|
|
9724
|
+
const scoreType = s?.score_type ? String(s.score_type) : '-';
|
|
9725
|
+
const scoreValue = s?.computed_score !== undefined &&
|
|
9726
|
+
s?.computed_score !== null &&
|
|
9727
|
+
String(s.computed_score) !== ''
|
|
9728
|
+
? String(s.computed_score)
|
|
9729
|
+
: '-';
|
|
9730
|
+
const computedAt = tryFormatDateTime(s?.computed_at);
|
|
9731
|
+
const key = `${scoreType}-${String(s?.computed_at || '')}-${idx}`;
|
|
9732
|
+
return (jsxRuntimeExports.jsxs("div", { className: "scores-card", "aria-live": idx === 0 ? 'polite' : undefined, children: [jsxRuntimeExports.jsx("div", { className: "scores-type", children: scoreType }), jsxRuntimeExports.jsx("div", { className: "scores-value", children: scoreValue }), jsxRuntimeExports.jsx("hr", { className: "scores-separator" }), jsxRuntimeExports.jsx("div", { className: "scores-meta", children: jsxRuntimeExports.jsxs("div", { className: "scores-meta-line", children: ["Computed at: ", jsxRuntimeExports.jsx("strong", { children: computedAt })] }) })] }, key));
|
|
9733
|
+
}) })) })] }));
|
|
9405
9734
|
};
|
|
9406
9735
|
|
|
9407
9736
|
/**
|
|
@@ -9445,6 +9774,8 @@ const registerDefaultWidgets = () => {
|
|
|
9445
9774
|
widgetRegistry.register({ widget: 'profile', component: ProfileWidget });
|
|
9446
9775
|
// Header section widget for full-width registry header with profile, status, and metadata
|
|
9447
9776
|
widgetRegistry.register({ widget: 'header-section', component: HeaderSectionWidget });
|
|
9777
|
+
// Scores display widget for full-width computed scores display (view-only)
|
|
9778
|
+
widgetRegistry.register({ widget: 'scores-display', component: ScoresDisplayWidget });
|
|
9448
9779
|
};
|
|
9449
9780
|
// Auto-register on import
|
|
9450
9781
|
registerDefaultWidgets();
|
|
@@ -9806,5 +10137,5 @@ const translateUISchema = (schema, translate) => {
|
|
|
9806
10137
|
};
|
|
9807
10138
|
};
|
|
9808
10139
|
|
|
9809
|
-
export { ArrayWidget, BooleanWidget, CheckboxWidget, CurrencyInputWidget, DateInputWidget, DateTimeInputWidget, DisplayWidget, FileInputWidget, HeaderSectionWidget, IterableAccordionWidget, JSONEditorPanel, NumberInputWidget, PanelRenderer, PhoneInputWidget, ProfileWidget, PropertyEditor, RadioWidget, SectionBuilder, SectionRenderer, SectionTree, SectionsContainer, SelectWidget, SimpleTableWidget, TableWidget, TextAreaWidget, TextInputWidget, VisualBuilderPanel, WidgetEventBus, WidgetProvider, WidgetRenderer, applyCaseControl, applyDecimalPrecision, applyMask, createWidgetStore, createZodSchema, evaluateCondition, filterByCharacterType, formatCurrency, formatDate, formatNumber, formatPhone, formatValue, geoHierarchyBuilder, getApiDataSource, getFormattedNumberLength, getSchemaDataSource, getStaticDataSource, getValueByPath, getWidgetValue, initI18n, isAllowedKey, parseDataPath, parseNumber, registerDefaultWidgets, removeMask, resetAll, resetWidget, setDataSource, setError, setLoading, setTouched, setValue, setValueByPath, setValues, setWidgetValue, shouldEnableWidget, shouldShowWidget, transformDataSourceOptions, translatePanelConfig, translateUISchema, translateWidgetConfig, useBaseWidget, useGeoWidgetCascade, useWidgetCascade, useWidgetContext, useWidgetEventBus, useWidgetTranslation, validateNumericValue, validateWidget, widgetRegistry };
|
|
10140
|
+
export { ArrayWidget, BooleanWidget, CheckboxWidget, CurrencyInputWidget, DateInputWidget, DateTimeInputWidget, DisplayWidget, FileInputWidget, HeaderSectionWidget, IterableAccordionWidget, JSONEditorPanel, NumberInputWidget, PanelRenderer, PhoneInputWidget, ProfileWidget, PropertyEditor, RadioWidget, ScoresDisplayWidget, SectionBuilder, SectionRenderer, SectionTree, SectionsContainer, SelectWidget, SimpleTableWidget, TableWidget, TextAreaWidget, TextInputWidget, VisualBuilderPanel, WidgetEventBus, WidgetProvider, WidgetRenderer, applyCaseControl, applyDecimalPrecision, applyMask, createWidgetStore, createZodSchema, defaultTheme, evaluateCondition, filterByCharacterType, formatCurrency, formatDate, formatNumber, formatPhone, formatValue, geoHierarchyBuilder, getApiDataSource, getFormattedNumberLength, getSchemaDataSource, getStaticDataSource, getValueByPath, getWidgetValue, initI18n, isAllowedKey, parseDataPath, parseNumber, registerDefaultWidgets, removeMask, resetAll, resetWidget, resolveTheme, setDataSource, setError, setLoading, setTouched, setValue, setValueByPath, setValues, setWidgetValue, shouldEnableWidget, shouldShowWidget, transformDataSourceOptions, translatePanelConfig, translateUISchema, translateWidgetConfig, useBaseWidget, useGeoWidgetCascade, useWidgetCascade, useWidgetContext, useWidgetEventBus, useWidgetTheme, useWidgetTranslation, validateNumericValue, validateWidget, widgetRegistry };
|
|
9810
10141
|
//# sourceMappingURL=index.esm.js.map
|