@openg2p/registry-widgets 1.0.2 → 1.1.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1676,6 +1676,158 @@ class WidgetEventBus {
1676
1676
  }
1677
1677
  }
1678
1678
 
1679
+ /**
1680
+ * Built-in default values (matches the original hardcoded colours).
1681
+ */
1682
+ const defaultTheme = {
1683
+ colors: {
1684
+ primary: '#F5BB1A',
1685
+ primaryDark: '#F07B1A',
1686
+ primaryLight: '#FBE6AA',
1687
+ primaryAccent: '#EE7C22',
1688
+ border: '#C4C4C4',
1689
+ borderLight: '#E4E4E4',
1690
+ background: '#FFFFFF',
1691
+ backgroundAlt: '#F6F6F6',
1692
+ text: '#011627',
1693
+ textMuted: '#727474',
1694
+ success: '#16A34A',
1695
+ successDark: '#047857',
1696
+ successLight: '#D1FAE5',
1697
+ error: '#B91C1C',
1698
+ errorLight: '#FEE2E2',
1699
+ warning: '#F59E0B',
1700
+ info: '#2563EB',
1701
+ },
1702
+ section: {
1703
+ borderRadius: '8px',
1704
+ borderColor: '#E4E4E4',
1705
+ backgroundColor: '#FFFFFF',
1706
+ titleColor: '#011627',
1707
+ dividerColor: '#F5BB1A',
1708
+ },
1709
+ panel: {
1710
+ dividerColor: '#C4C4C4',
1711
+ backgroundColor: 'transparent',
1712
+ },
1713
+ button: {
1714
+ primaryBg: '#FFFFFF',
1715
+ primaryColor: '#011627',
1716
+ primaryBorder: '#F07B1A',
1717
+ secondaryBg: '#FFFFFF',
1718
+ secondaryColor: '#011627',
1719
+ secondaryBorder: '#C4C4C4',
1720
+ borderRadius: '6px',
1721
+ },
1722
+ widget: {
1723
+ labelColor: '#011627',
1724
+ inputBorderColor: '#C4C4C4',
1725
+ inputFocusBorderColor: '#F5BB1A',
1726
+ inputBackground: '#FFFFFF',
1727
+ errorColor: '#B91C1C',
1728
+ helpTextColor: '#727474',
1729
+ tableHeaderBg: '#F6F6F6',
1730
+ tableHeaderColor: '#727474',
1731
+ tableBodyBg: '#FFFFFF',
1732
+ tableBorderColor: '#C4C4C4',
1733
+ tableRowDividerColor: '#E4E4E4',
1734
+ tableEditingRowBg: '#FBE6AA',
1735
+ tableDeletedRowBg: '#FEE2E2',
1736
+ tableEmptyTextColor: '#727474',
1737
+ tableBorderRadius: '15px',
1738
+ },
1739
+ };
1740
+ /**
1741
+ * Merge a user-supplied (partial) theme with the built-in defaults.
1742
+ */
1743
+ function resolveTheme(theme) {
1744
+ if (!theme)
1745
+ return defaultTheme;
1746
+ return {
1747
+ colors: { ...defaultTheme.colors, ...theme.colors },
1748
+ section: { ...defaultTheme.section, ...theme.section },
1749
+ panel: { ...defaultTheme.panel, ...theme.panel },
1750
+ button: { ...defaultTheme.button, ...theme.button },
1751
+ widget: { ...defaultTheme.widget, ...theme.widget },
1752
+ };
1753
+ }
1754
+ /**
1755
+ * Convert a resolved theme into a flat Record of CSS custom properties.
1756
+ * These are set on the provider wrapper element so every descendant can
1757
+ * reference them with `var(--owt-…)`.
1758
+ *
1759
+ * Prefix: `--owt-` (OpenG2P Widget Theme).
1760
+ */
1761
+ function themeToCSSVariables(resolved) {
1762
+ return {
1763
+ // --- colors ---
1764
+ '--owt-color-primary': resolved.colors.primary,
1765
+ '--owt-color-primary-dark': resolved.colors.primaryDark,
1766
+ '--owt-color-primary-light': resolved.colors.primaryLight,
1767
+ '--owt-color-primary-accent': resolved.colors.primaryAccent,
1768
+ '--owt-color-border': resolved.colors.border,
1769
+ '--owt-color-border-light': resolved.colors.borderLight,
1770
+ '--owt-color-bg': resolved.colors.background,
1771
+ '--owt-color-bg-alt': resolved.colors.backgroundAlt,
1772
+ '--owt-color-text': resolved.colors.text,
1773
+ '--owt-color-text-muted': resolved.colors.textMuted,
1774
+ '--owt-color-success': resolved.colors.success,
1775
+ '--owt-color-success-dark': resolved.colors.successDark,
1776
+ '--owt-color-success-light': resolved.colors.successLight,
1777
+ '--owt-color-error': resolved.colors.error,
1778
+ '--owt-color-error-light': resolved.colors.errorLight,
1779
+ '--owt-color-warning': resolved.colors.warning,
1780
+ '--owt-color-info': resolved.colors.info,
1781
+ // --- section ---
1782
+ '--owt-section-border-radius': resolved.section.borderRadius,
1783
+ '--owt-section-border-color': resolved.section.borderColor,
1784
+ '--owt-section-bg': resolved.section.backgroundColor,
1785
+ '--owt-section-title-color': resolved.section.titleColor,
1786
+ '--owt-section-divider-color': resolved.section.dividerColor,
1787
+ // --- panel ---
1788
+ '--owt-panel-divider-color': resolved.panel.dividerColor,
1789
+ '--owt-panel-bg': resolved.panel.backgroundColor,
1790
+ // --- button ---
1791
+ '--owt-btn-primary-bg': resolved.button.primaryBg,
1792
+ '--owt-btn-primary-color': resolved.button.primaryColor,
1793
+ '--owt-btn-primary-border': resolved.button.primaryBorder,
1794
+ '--owt-btn-secondary-bg': resolved.button.secondaryBg,
1795
+ '--owt-btn-secondary-color': resolved.button.secondaryColor,
1796
+ '--owt-btn-secondary-border': resolved.button.secondaryBorder,
1797
+ '--owt-btn-border-radius': resolved.button.borderRadius,
1798
+ // --- widget ---
1799
+ '--owt-widget-label-color': resolved.widget.labelColor,
1800
+ '--owt-widget-input-border': resolved.widget.inputBorderColor,
1801
+ '--owt-widget-input-focus-border': resolved.widget.inputFocusBorderColor,
1802
+ '--owt-widget-input-bg': resolved.widget.inputBackground,
1803
+ '--owt-widget-error-color': resolved.widget.errorColor,
1804
+ '--owt-widget-helptext-color': resolved.widget.helpTextColor,
1805
+ // --- widget / table ---
1806
+ '--owt-widget-table-header-bg': resolved.widget.tableHeaderBg,
1807
+ '--owt-widget-table-header-color': resolved.widget.tableHeaderColor,
1808
+ '--owt-widget-table-body-bg': resolved.widget.tableBodyBg,
1809
+ '--owt-widget-table-border-color': resolved.widget.tableBorderColor,
1810
+ '--owt-widget-table-row-divider': resolved.widget.tableRowDividerColor,
1811
+ '--owt-widget-table-editing-row-bg': resolved.widget.tableEditingRowBg,
1812
+ '--owt-widget-table-deleted-row-bg': resolved.widget.tableDeletedRowBg,
1813
+ '--owt-widget-table-empty-color': resolved.widget.tableEmptyTextColor,
1814
+ '--owt-widget-table-border-radius': resolved.widget.tableBorderRadius,
1815
+ };
1816
+ }
1817
+
1818
+ const ThemeContext = React.createContext(defaultTheme);
1819
+ /**
1820
+ * Access the resolved widget theme from any component inside `<WidgetProvider>`.
1821
+ *
1822
+ * ```tsx
1823
+ * const theme = useWidgetTheme();
1824
+ * // theme.colors.primary, theme.section.dividerColor, etc.
1825
+ * ```
1826
+ */
1827
+ function useWidgetTheme() {
1828
+ return React.useContext(ThemeContext);
1829
+ }
1830
+
1679
1831
  const WidgetContext = React.createContext({
1680
1832
  dataSourceRequestHandler: undefined,
1681
1833
  schemaData: undefined,
@@ -1684,10 +1836,13 @@ const WidgetContext = React.createContext({
1684
1836
  const useWidgetContext = () => {
1685
1837
  return React.useContext(WidgetContext);
1686
1838
  };
1687
- const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate, children, }) => {
1839
+ const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate, theme, children, }) => {
1688
1840
  const widgetStore = React.useMemo(() => store || createWidgetStore(), [store]);
1689
1841
  // Create event bus instance (one per provider)
1690
1842
  const eventBus = React.useMemo(() => new WidgetEventBus(), []);
1843
+ // Resolve theme: merge user-supplied overrides with defaults
1844
+ const resolvedTheme = React.useMemo(() => resolveTheme(theme), [theme]);
1845
+ const cssVariables = React.useMemo(() => themeToCSSVariables(resolvedTheme), [resolvedTheme]);
1691
1846
  // Memoize context value to prevent unnecessary re-renders
1692
1847
  const contextValue = React.useMemo(() => ({
1693
1848
  dataSourceRequestHandler,
@@ -1716,7 +1871,7 @@ const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate
1716
1871
  }
1717
1872
  // eslint-disable-next-line react-hooks/exhaustive-deps
1718
1873
  }, [schemaData, widgetStore]); // Only run on mount
1719
- const content = (jsxRuntimeExports.jsx(reactRedux.Provider, { store: widgetStore, children: jsxRuntimeExports.jsx(WidgetContext.Provider, { value: contextValue, children: jsxRuntimeExports.jsx(WidgetEventBusContext.Provider, { value: eventBus, children: children }) }) }));
1874
+ const content = (jsxRuntimeExports.jsx(reactRedux.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 }) }) }) }) }));
1720
1875
  return content;
1721
1876
  };
1722
1877
 
@@ -2736,7 +2891,7 @@ const PanelRenderer = ({ panel, dataSourceRequestHandler, schemaData, onValueCha
2736
2891
  top: 0,
2737
2892
  bottom: '5px',
2738
2893
  width: '1px',
2739
- backgroundColor: isEditMode ? '#F2BA1A' : '#D1D5DB',
2894
+ backgroundColor: isEditMode ? 'var(--owt-color-primary, #F5BB1A)' : 'var(--owt-panel-divider-color, #C4C4C4)',
2740
2895
  } }))] }) }, nestedPanel['panel-id'] || `panel-${index}`));
2741
2896
  }), widgets.map((widgetConfig, index) => {
2742
2897
  // Don't use readonly state in key - it causes remounting which resets userHasSetValueRef
@@ -3298,10 +3453,10 @@ const FileInputWidget = ({ config }) => {
3298
3453
  return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("button", { type: "button", onClick: (e) => {
3299
3454
  console.log('Button clicked!', file);
3300
3455
  handleFileClick(file, e);
3301
- }, 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 ? '#000000' : '#2563eb' }, title: "Click to preview", children: fileName })] }));
3456
+ }, 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 })] }));
3302
3457
  }
3303
3458
  else {
3304
- return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("span", { className: "text-sm", style: { color: isSupportingDocument ? '#000000' : '#4b5563' }, children: fileName })] }));
3459
+ 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 })] }));
3305
3460
  }
3306
3461
  }
3307
3462
  else {
@@ -3317,10 +3472,10 @@ const FileInputWidget = ({ config }) => {
3317
3472
  flexShrink: 0
3318
3473
  } }));
3319
3474
  if (canPreview) {
3320
- 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 ? '#000000' : '#2563eb' }, title: "Click to preview", children: fileName })] }, index));
3475
+ 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));
3321
3476
  }
3322
3477
  else {
3323
- return (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [fileIconElement, jsxRuntimeExports.jsx("span", { className: "text-sm", style: { color: isSupportingDocument ? '#000000' : '#4b5563' }, children: fileName })] }, index));
3478
+ 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));
3324
3479
  }
3325
3480
  }) }));
3326
3481
  }
@@ -3516,39 +3671,6 @@ const sectionValidate = (section, currentSchemaData, dispatch) => {
3516
3671
  return isValid;
3517
3672
  };
3518
3673
 
3519
- /** Root class on readonly label/value rows; SectionRenderer scopes overflow/ellipsis rules here. */
3520
- const READONLY_VALUE_ROW_ROOT_CLASSES = [
3521
- 'TextDisplayWidget',
3522
- 'TextAreaDisplayWidget',
3523
- 'SelectDisplayWidget',
3524
- 'PhoneDisplayWidget',
3525
- 'NumberDisplayWidget',
3526
- 'CurrencyDisplayWidget',
3527
- 'RadioDisplayWidget',
3528
- 'DateDisplayWidget',
3529
- 'DateTimeDisplayWidget',
3530
- 'CheckboxDisplayWidget',
3531
- 'BooleanDisplayWidget',
3532
- 'FileDisplayWidget',
3533
- 'DisplayFieldWidget',
3534
- ];
3535
- /** Rows whose value is one line in .flex-1 > .text-gray-900 (ellipsis; full string via title on the element). */
3536
- const READONLY_SINGLE_LINE_VALUE_ROW_CLASSES = [
3537
- 'TextDisplayWidget',
3538
- 'SelectDisplayWidget',
3539
- 'PhoneDisplayWidget',
3540
- 'NumberDisplayWidget',
3541
- 'CurrencyDisplayWidget',
3542
- 'RadioDisplayWidget',
3543
- 'DateDisplayWidget',
3544
- 'DateTimeDisplayWidget',
3545
- 'CheckboxDisplayWidget',
3546
- 'BooleanDisplayWidget',
3547
- 'DisplayFieldWidget',
3548
- ];
3549
- function scopedClassSelectors(sectionClassId, classNames) {
3550
- return classNames.map((c) => `.${sectionClassId} .${c}`).join(',\n ');
3551
- }
3552
3674
  /**
3553
3675
  * Renders a section with its panels
3554
3676
  *
@@ -3559,6 +3681,8 @@ function scopedClassSelectors(sectionClassId, classNames) {
3559
3681
  */
3560
3682
  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, }) => {
3561
3683
  const { translateConfig, translate } = useWidgetTranslation();
3684
+ const resolvedTheme = useWidgetTheme();
3685
+ const portalCSSVariables = React.useMemo(() => themeToCSSVariables(resolvedTheme), [resolvedTheme]);
3562
3686
  const { schemaData: contextSchemaData, dataSourceRequestHandler: contextDataSourceRequestHandler } = useWidgetContext();
3563
3687
  const store = reactRedux.useStore();
3564
3688
  const dispatch = reactRedux.useDispatch();
@@ -3575,22 +3699,41 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
3575
3699
  }
3576
3700
  return section;
3577
3701
  }, [section, namespace]);
3578
- // Create namespaced schemaData if namespace is provided.
3579
- // Widgets with namespaced data-paths (e.g. "rv-section-0.a1a4d25a.birth_date")
3580
- // need a nested object at values[namespace] so getValueByPath can traverse it.
3702
+ // Create namespaced schemaData if namespace is provided
3703
+ // This ensures widgets can read initial values from schemaData at namespaced paths
3581
3704
  const namespacedSchemaData = React.useMemo(() => {
3582
3705
  if (!namespace || !currentSchemaData) {
3583
3706
  return schemaData;
3584
3707
  }
3585
- return { ...currentSchemaData, [namespace]: currentSchemaData };
3708
+ // Create a namespaced version of schemaData by copying values to namespaced paths
3709
+ const namespaced = { ...currentSchemaData };
3710
+ // Copy all top-level keys to namespaced paths
3711
+ Object.keys(currentSchemaData).forEach(key => {
3712
+ const namespacedKey = `${namespace}.${key}`;
3713
+ if (!(namespacedKey in namespaced)) {
3714
+ namespaced[namespacedKey] = currentSchemaData[key];
3715
+ }
3716
+ });
3717
+ // Also handle nested objects - copy nested values to namespaced paths
3718
+ const copyNestedValues = (obj, prefix = '') => {
3719
+ if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
3720
+ Object.keys(obj).forEach(key => {
3721
+ const fullPath = prefix ? `${prefix}.${key}` : key;
3722
+ const namespacedPath = `${namespace}.${fullPath}`;
3723
+ if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
3724
+ copyNestedValues(obj[key], fullPath);
3725
+ // Also set the nested object at the namespaced path
3726
+ setValueByPath(namespaced, namespacedPath, obj[key]);
3727
+ }
3728
+ else {
3729
+ setValueByPath(namespaced, namespacedPath, obj[key]);
3730
+ }
3731
+ });
3732
+ }
3733
+ };
3734
+ copyNestedValues(currentSchemaData);
3735
+ return namespaced;
3586
3736
  }, [namespace, schemaData, currentSchemaData]);
3587
- // Populate the store with namespaced schema data so that namespaced widgets
3588
- // can read their initial values via getValueByPath on the namespaced paths.
3589
- React.useEffect(() => {
3590
- if (namespace && namespacedSchemaData) {
3591
- dispatch(setValues(namespacedSchemaData));
3592
- }
3593
- }, [namespace, namespacedSchemaData, dispatch]);
3594
3737
  const crViewData = React.useMemo(() => {
3595
3738
  if (mode !== 'CRView')
3596
3739
  return null;
@@ -3613,9 +3756,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
3613
3756
  const sectionId = sectionToRender['section-id'];
3614
3757
  const gridId = `section-panels-${sectionId}`;
3615
3758
  const sectionClassId = `section-${sectionId}`;
3616
- const readonlyValueRowRootsCss = React.useMemo(() => scopedClassSelectors(sectionClassId, READONLY_VALUE_ROW_ROOT_CLASSES), [sectionClassId]);
3617
- const readonlyValueRowFlex1Css = React.useMemo(() => READONLY_VALUE_ROW_ROOT_CLASSES.map((c) => `.${sectionClassId} .${c} > .flex-1`).join(',\n '), [sectionClassId]);
3618
- const readonlySingleLineValueTextCss = React.useMemo(() => READONLY_SINGLE_LINE_VALUE_ROW_CLASSES.map((c) => `.${sectionClassId} .${c} > .flex-1 > .text-gray-900`).join(',\n '), [sectionClassId]);
3619
3759
  // IntakeForm mode: accordion expand/collapse state (supports toggle)
3620
3760
  const [standaloneExpanded, setStandaloneExpanded] = React.useState(true); // For sectionIndex undefined (standalone use)
3621
3761
  const isExpandedFromContainer = typeof sectionIndex === 'number' && expandedSectionIndex === sectionIndex;
@@ -3839,9 +3979,10 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
3839
3979
  top: 0;
3840
3980
  bottom: 5px;
3841
3981
  width: 1px;
3842
- background-color: #F2BA1A;
3982
+ background-color: var(--owt-color-primary, #F5BB1A);
3843
3983
  }
3844
3984
  ` }), jsxRuntimeExports.jsxs("div", { className: `section ${sectionClassId} ${sectionClassId}-edit px-4 sm:px-6 lg:px-8`, "data-section-id": `${sectionId}-edit`, style: {
3985
+ ...portalCSSVariables,
3845
3986
  position: 'absolute',
3846
3987
  top: `${editSectionPosition.top}px`,
3847
3988
  left: `${editSectionPosition.left}px`,
@@ -3851,10 +3992,22 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
3851
3992
  }, 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) => {
3852
3993
  const isLastPanel = index === editableSection.panels.length - 1;
3853
3994
  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}`));
3854
- }), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: '#F2BA1A', 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) => {
3995
+ }), 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) => {
3855
3996
  const docConfig = createDocumentWidgetConfig(doc, sectionId, index);
3856
3997
  return (jsxRuntimeExports.jsx("div", { className: "supporting-document-item", children: jsxRuntimeExports.jsx(FileInputWidget, { config: docConfig }) }, `${sectionId}-doc-${index}`));
3857
- }) }))] }) })), jsxRuntimeExports.jsx("hr", { className: "w-full", style: { height: '1px', backgroundColor: '#F2BA1A', 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: "bg-white hover:bg-gray-50 text-gray-900 text-sm font-medium px-6 py-2 transition-colors border border-gray-300", style: { fontFamily: 'Roboto, sans-serif', borderRadius: '10px' }, children: translate('common.cancel') || 'Cancel' }), jsxRuntimeExports.jsx("button", { onClick: handleSave, disabled: !isDirty, className: "bg-gray-900 hover:bg-gray-800 text-white text-sm font-medium px-6 py-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", style: { fontFamily: 'Roboto, sans-serif', borderRadius: '10px' }, children: translate('common.save') || 'Save' })] }) })] })] })] }), document.body);
3998
+ }) }))] }) })), 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: {
3999
+ fontFamily: 'Roboto, sans-serif',
4000
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
4001
+ border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
4002
+ backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
4003
+ color: 'var(--owt-btn-secondary-color, #011627)',
4004
+ }, 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: {
4005
+ fontFamily: 'Roboto, sans-serif',
4006
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
4007
+ border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
4008
+ backgroundColor: 'var(--owt-color-primary, #F5BB1A)',
4009
+ color: 'var(--owt-color-bg, #FFFFFF)',
4010
+ }, children: translate('common.save') || 'Save' })] }) })] })] })] }), document.body);
3858
4011
  };
3859
4012
  const trackSectionChages = (widgets, sourceData, pathPrefix) => {
3860
4013
  if (!widgets || widgets.length === 0)
@@ -3955,8 +4108,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
3955
4108
  const baselineSnapshotRef = React.useRef(null);
3956
4109
  // IntakeForm only: increment when baseline is updated after save - forces badge to update (refs don't trigger re-renders)
3957
4110
  const [intakeFormBaselineTrigger, setIntakeFormBaselineTrigger] = React.useState(0);
3958
- // IntakeForm only: tracks whether the user has actually saved this section (prevents "Saved" badge on initial load)
3959
- const [hasBeenSavedByUser, setHasBeenSavedByUser] = React.useState(false);
3960
4111
  // IntakeForm: treat as edit mode for dirty tracking when isDraft. RegistryView: use isEditMode.
3961
4112
  const effectiveEditModeForDirty = mode === 'IntakeForm' ? (isDraft !== false) : isEditMode;
3962
4113
  // Compute isDirty: compare current store state to baseline (only when in edit mode)
@@ -3999,68 +4150,18 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
3999
4150
  const intakeFormSectionStatus = React.useMemo(() => {
4000
4151
  if (mode !== 'IntakeForm' || isDraft === false)
4001
4152
  return null;
4153
+ const hasValue = (v) => v !== undefined && v !== null && (typeof v !== 'string' || v.trim().length > 0);
4154
+ const currentSnapshot = buildSectionSnapshot(storeValues, namespace);
4155
+ const record = currentSnapshot.records?.[0];
4156
+ const hasData = record &&
4157
+ typeof record === 'object' &&
4158
+ Object.values(record).some((v) => hasValue(v));
4002
4159
  if (isDirty)
4003
4160
  return 'modified';
4004
- if (hasBeenSavedByUser)
4161
+ if (hasData)
4005
4162
  return 'saved';
4006
4163
  return null;
4007
- }, [mode, isDirty, hasBeenSavedByUser]);
4008
- // Revert store values to the original schemaData for this section's widgets.
4009
- // Used by both handleSave (RegistryView raises a CR, so values should not persist)
4010
- // and handleCancel.
4011
- const revertToOriginalValues = React.useCallback(() => {
4012
- const sectionWidgets = collectWidgets(originalSection.panels);
4013
- const oldSchemaData = schemaData || contextSchemaData;
4014
- const currentStoreValues = store.getState().widget.values;
4015
- let newStoreValues = currentStoreValues;
4016
- sectionWidgets.forEach(widget => {
4017
- const originalWidgetId = widget['widget-id'];
4018
- const namespacedWidgetId = namespace ? `${namespace}__${originalWidgetId}` : originalWidgetId;
4019
- const widgetId = namespacedWidgetId;
4020
- const originalDataPath = widget['widget-data-path'];
4021
- const storeDataPath = namespace && originalDataPath
4022
- ? (typeof originalDataPath === 'string'
4023
- ? `${namespace}.${originalDataPath}`
4024
- : Object.fromEntries(Object.entries(originalDataPath).map(([key, path]) => [key, `${namespace}.${path}`])))
4025
- : originalDataPath;
4026
- if (widgetId && originalDataPath) {
4027
- let oldValue;
4028
- if (typeof originalDataPath === 'object') {
4029
- oldValue = {};
4030
- Object.entries(originalDataPath).forEach(([key, path]) => {
4031
- if (typeof path === 'string') {
4032
- oldValue[key] = getValueByPath(oldSchemaData, path);
4033
- }
4034
- });
4035
- }
4036
- else if (typeof originalDataPath === 'string') {
4037
- oldValue = getValueByPath(oldSchemaData, originalDataPath);
4038
- }
4039
- if (oldValue !== undefined) {
4040
- newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
4041
- // Also revert the widgetId-based entry — useBaseWidget.handleChange
4042
- // sets values[widgetId] during editing, and useBaseWidget.currentValue
4043
- // reads values[widgetId] first before falling through to the dataPath.
4044
- newStoreValues = { ...newStoreValues, [widgetId]: oldValue };
4045
- }
4046
- }
4047
- });
4048
- if (hasSupportingDocuments) {
4049
- const originalSupportingDocuments = originalSection['section-supporting-documents'] || [];
4050
- originalSupportingDocuments.forEach((doc, index) => {
4051
- const widgetId = `supporting-doc-${sectionId}-${index}`;
4052
- const originalDataPath = doc['document-data-path'];
4053
- const storeDataPath = namespace && originalDataPath
4054
- ? `${namespace}.${originalDataPath}`
4055
- : originalDataPath;
4056
- const oldValue = getValueByPath(oldSchemaData, originalDataPath);
4057
- newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
4058
- });
4059
- }
4060
- if (newStoreValues !== currentStoreValues) {
4061
- dispatch(setValues(newStoreValues));
4062
- }
4063
- }, [originalSection, schemaData, contextSchemaData, store, namespace, hasSupportingDocuments, sectionId, dispatch]);
4164
+ }, [mode, isDirty, storeValues, namespace, buildSectionSnapshot]);
4064
4165
  // Handle save button click
4065
4166
  const handleSave = async () => {
4066
4167
  if (!store || !onSectionSave) {
@@ -4097,24 +4198,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4097
4198
  });
4098
4199
  }
4099
4200
  if (JSON.stringify(oldSchemaData) !== JSON.stringify(newSchemaData)) {
4100
- let profileImage = null;
4101
- for (const record of newSchemaData) {
4102
- if (typeof record === 'object' && record !== null) {
4103
- for (const [key, value] of Object.entries(record)) {
4104
- if (value instanceof File) {
4105
- profileImage = value;
4106
- record[key] = '';
4107
- }
4108
- }
4109
- }
4110
- }
4111
4201
  try {
4112
4202
  const sectionchanges = {
4113
4203
  section_id: dbSectionId ?? originalSection['section-id'],
4114
4204
  section_register_id: sectionRegisterId,
4115
4205
  records: [...newSchemaData],
4116
- files: [...sectionFiles],
4117
- ...(profileImage ? { image: profileImage } : {}),
4206
+ files: [...sectionFiles]
4118
4207
  };
4119
4208
  await onSectionSave(sectionchanges);
4120
4209
  }
@@ -4122,12 +4211,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4122
4211
  console.error('Section Changes Save failed', error);
4123
4212
  }
4124
4213
  }
4125
- // In RegistryView, save raises a CR — the actual data update follows a
4126
- // separate approval workflow, so revert the displayed values to the
4127
- // originals so the view doesn't show unapproved edits.
4128
- if (mode === 'RegistryView') {
4129
- revertToOriginalValues();
4130
- }
4131
4214
  setIsEditMode(false);
4132
4215
  onEditModeChange?.(originalSectionId, false);
4133
4216
  };
@@ -4157,24 +4240,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4157
4240
  });
4158
4241
  }
4159
4242
  if (JSON.stringify(oldSchemaData) !== JSON.stringify(newSchemaData)) {
4160
- let profileImage = null;
4161
- for (const record of newSchemaData) {
4162
- if (typeof record === 'object' && record !== null) {
4163
- for (const [key, value] of Object.entries(record)) {
4164
- if (value instanceof File) {
4165
- profileImage = value;
4166
- record[key] = '';
4167
- }
4168
- }
4169
- }
4170
- }
4171
4243
  try {
4172
4244
  await onSectionSave({
4173
4245
  section_id: dbSectionId ?? originalSection['section-id'],
4174
4246
  section_register_id: sectionRegisterId,
4175
4247
  records: [...newSchemaData],
4176
4248
  files: [...sectionFiles],
4177
- ...(profileImage ? { image: profileImage } : {}),
4178
4249
  });
4179
4250
  }
4180
4251
  catch (error) {
@@ -4185,7 +4256,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4185
4256
  if (mode === 'IntakeForm') {
4186
4257
  baselineSnapshotRef.current = buildSectionSnapshot(currentSchemaData, namespace);
4187
4258
  setIntakeFormBaselineTrigger((prev) => prev + 1);
4188
- setHasBeenSavedByUser(true);
4189
4259
  }
4190
4260
  onSectionDirtyChange?.(sectionId, false);
4191
4261
  }
@@ -4194,7 +4264,64 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4194
4264
  }, [store, onSectionSave, onSectionSaveSuccess, sectionIndex, originalSection, schemaData, contextSchemaData, namespace, hasSupportingDocuments, dbSectionId, sectionRegisterId, dispatch, buildSectionSnapshot, sectionId, onSectionDirtyChange, mode, isDraft]);
4195
4265
  // Handle cancel button click
4196
4266
  const handleCancel = () => {
4197
- revertToOriginalValues();
4267
+ // Revert values in store to original schema data
4268
+ // Use original section (without namespace) for collecting widgets
4269
+ const sectionWidgets = collectWidgets(originalSection.panels);
4270
+ const oldSchemaData = schemaData || contextSchemaData;
4271
+ const currentStoreValues = store.getState().widget.values;
4272
+ let newStoreValues = currentStoreValues;
4273
+ sectionWidgets.forEach(widget => {
4274
+ const originalWidgetId = widget['widget-id'];
4275
+ // If namespace was used, we need to use namespaced widget ID and data path
4276
+ const namespacedWidgetId = namespace ? `${namespace}__${originalWidgetId}` : originalWidgetId;
4277
+ const widgetId = namespacedWidgetId;
4278
+ const originalDataPath = widget['widget-data-path'];
4279
+ // If namespace was used, data path in store is namespaced, but we read from original schema using original path
4280
+ const storeDataPath = namespace && originalDataPath
4281
+ ? (typeof originalDataPath === 'string'
4282
+ ? `${namespace}.${originalDataPath}`
4283
+ : Object.fromEntries(Object.entries(originalDataPath).map(([key, path]) => [key, `${namespace}.${path}`])))
4284
+ : originalDataPath;
4285
+ if (widgetId && originalDataPath) {
4286
+ // Handle multi-path (object) or single path (string)
4287
+ // Read from original schema data using original paths
4288
+ let oldValue;
4289
+ if (typeof originalDataPath === 'object') {
4290
+ // Multi-path: get values for each path
4291
+ oldValue = {};
4292
+ Object.entries(originalDataPath).forEach(([key, path]) => {
4293
+ if (typeof path === 'string') {
4294
+ oldValue[key] = getValueByPath(oldSchemaData, path);
4295
+ }
4296
+ });
4297
+ }
4298
+ else if (typeof originalDataPath === 'string') {
4299
+ oldValue = getValueByPath(oldSchemaData, originalDataPath);
4300
+ }
4301
+ // Set in store using namespaced data path (if namespace was used)
4302
+ if (oldValue !== undefined) {
4303
+ newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
4304
+ }
4305
+ }
4306
+ });
4307
+ // Also revert supporting documents if any
4308
+ if (hasSupportingDocuments) {
4309
+ // Use original section's supporting documents to get original data paths
4310
+ const originalSupportingDocuments = originalSection['section-supporting-documents'] || [];
4311
+ originalSupportingDocuments.forEach((doc, index) => {
4312
+ const widgetId = `supporting-doc-${sectionId}-${index}`;
4313
+ const originalDataPath = doc['document-data-path'];
4314
+ // If namespace was used, data path in store is namespaced
4315
+ const storeDataPath = namespace && originalDataPath
4316
+ ? `${namespace}.${originalDataPath}`
4317
+ : originalDataPath;
4318
+ const oldValue = getValueByPath(oldSchemaData, originalDataPath);
4319
+ newStoreValues = setWidgetValue(newStoreValues, storeDataPath, widgetId, oldValue);
4320
+ });
4321
+ }
4322
+ if (newStoreValues !== currentStoreValues) {
4323
+ dispatch(setValues(newStoreValues));
4324
+ }
4198
4325
  setIsEditMode(false);
4199
4326
  onEditModeChange?.(originalSectionId, false);
4200
4327
  };
@@ -4235,7 +4362,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4235
4362
  .${sectionClassId} label.text-gray-700,
4236
4363
  .${sectionClassId} .text-gray-600 {
4237
4364
  font-weight: 400 !important;
4238
- color: rgba(0, 0, 0, 0.5) !important;
4365
+ color: var(--owt-color-text-muted, #727474) !important;
4239
4366
  width: 50% !important;
4240
4367
  min-width: 50% !important;
4241
4368
  max-width: 50% !important;
@@ -4245,27 +4372,20 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4245
4372
  white-space: nowrap !important;
4246
4373
  }
4247
4374
  /* Readonly: prevent flex row from overflowing panel */
4248
- ${readonlyValueRowRootsCss} {
4375
+ .${sectionClassId} .TextDisplayWidget {
4249
4376
  min-width: 0 !important;
4250
4377
  overflow: hidden !important;
4251
4378
  }
4252
- ${readonlyValueRowFlex1Css} {
4379
+ .${sectionClassId} .TextDisplayWidget > .flex-1 {
4253
4380
  min-width: 0 !important;
4254
4381
  overflow: hidden !important;
4255
4382
  }
4256
- /* Readonly value: single-line ellipsis; full value via title on the value node */
4257
- ${readonlySingleLineValueTextCss} {
4383
+ /* Readonly value text truncation */
4384
+ .${sectionClassId} .TextDisplayWidget > .flex-1 > .text-gray-900 {
4258
4385
  overflow: hidden;
4259
4386
  text-overflow: ellipsis;
4260
4387
  white-space: nowrap;
4261
4388
  }
4262
- /* Readonly textarea: break unbroken long tokens; title on pre keeps full text on hover */
4263
- .${sectionClassId} .TextAreaDisplayWidget > .flex-1 > pre {
4264
- min-width: 0;
4265
- max-width: 100%;
4266
- overflow-wrap: anywhere;
4267
- word-break: break-word;
4268
- }
4269
4389
 
4270
4390
  /* Only apply fixed height when in edit mode */
4271
4391
  .${sectionClassId}[data-edit-mode="true"] {
@@ -4287,11 +4407,11 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4287
4407
  .${sectionClassId}-edit {
4288
4408
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.2),
4289
4409
  0 8px 10px -6px rgba(0, 0, 0, 0.1);
4290
- border-color: #ED7C22;
4410
+ border-color: var(--owt-color-primary-dark, #F07B1A);
4291
4411
  border-style: dashed;
4292
4412
  border-width: 1px;
4293
- background-color: #F3E6BC;
4294
- border-radius: 10px;
4413
+ background-color: var(--owt-color-primary-light, #FBE6AA);
4414
+ border-radius: var(--owt-section-border-radius, 10px);
4295
4415
  z-index: 10;
4296
4416
  position: absolute;
4297
4417
  }
@@ -4391,23 +4511,23 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4391
4511
 
4392
4512
  /* IntakeForm accordion */
4393
4513
  .${sectionClassId}.intake-form-accordion-item {
4394
- border-color: #E5E7EB;
4514
+ border-color: var(--owt-color-border-light, #E4E4E4);
4395
4515
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
4396
4516
  }
4397
4517
  .${sectionClassId}.intake-form-accordion-item:hover {
4398
- border-color: #D1D5DB;
4518
+ border-color: var(--owt-color-border, #C4C4C4);
4399
4519
  }
4400
4520
  .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header {
4401
4521
  transition: opacity 0.2s ease, background-color 0.2s ease;
4402
4522
  }
4403
4523
  .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header h2 {
4404
- color: #ED7C22;
4524
+ color: var(--owt-color-primary-dark, #F07B1A);
4405
4525
  }
4406
4526
  .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header:hover {
4407
4527
  opacity: 0.85;
4408
4528
  }
4409
4529
  .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header:focus-visible {
4410
- outline: 2px solid #F2BA1A;
4530
+ outline: 2px solid var(--owt-color-primary, #F5BB1A);
4411
4531
  outline-offset: 2px;
4412
4532
  }
4413
4533
  .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-content {
@@ -4419,27 +4539,27 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4419
4539
  width: 100%;
4420
4540
  }
4421
4541
  .${sectionClassId}.intake-form-accordion-item .intake-form-prev-btn {
4422
- color: rgba(0, 0, 0, 0.5) !important;
4542
+ color: var(--owt-color-text-muted, #727474) !important;
4423
4543
  }
4424
4544
  .${sectionClassId}.intake-form-accordion-item .intake-form-prev-btn:disabled {
4425
- color: rgba(0, 0, 0, 0.3) !important;
4545
+ color: var(--owt-color-border, #C4C4C4) !important;
4426
4546
  }
4427
4547
  .${sectionClassId}.intake-form-accordion-item .intake-form-prev-btn:hover:not(:disabled) {
4428
- background-color: #F3F4F6;
4429
- border-color: #FD8C3E;
4548
+ background-color: var(--owt-color-bg-alt, #F6F6F6);
4549
+ border-color: var(--owt-btn-primary-border, #F07B1A);
4430
4550
  }
4431
4551
  .${sectionClassId}.intake-form-accordion-item .intake-form-save-btn:hover:not(:disabled) {
4432
- background-color: #E5E7EB;
4552
+ background-color: var(--owt-color-border-light, #E4E4E4);
4433
4553
  }
4434
- ` }), jsxRuntimeExports.jsx("div", { ref: sectionRef, className: `section ${sectionClassId} px-4 sm:px-6 lg:px-8 border-2 border-white ${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: {
4554
+ ` }), 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: {
4435
4555
  gridColumn: `span ${columnSpan}`,
4436
4556
  width: '100%',
4437
- borderRadius: '10px',
4438
- // IntakeForm expanded: edit-mode colors. Others: normal or faded for old CR
4557
+ borderRadius: 'var(--owt-section-border-radius, 10px)',
4558
+ borderColor: 'var(--owt-color-bg, #FFFFFF)',
4439
4559
  ...(mode === 'IntakeForm' && isExpanded
4440
- ? { backgroundColor: '#F3E6BC', border: '1px dashed #ED7C22' }
4560
+ ? { backgroundColor: 'var(--owt-color-primary-light, #FBE6AA)', border: '1px dashed var(--owt-color-primary-dark, #F07B1A)' }
4441
4561
  : {
4442
- backgroundColor: changeRequestType === 'old' ? '#F9F9F9' : '#FFFFFF',
4562
+ backgroundColor: changeRequestType === 'old' ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-section-bg, #FFFFFF)',
4443
4563
  opacity: changeRequestType === 'old' ? 0.95 : 1,
4444
4564
  }),
4445
4565
  ...(isEditMode && sectionHeight ? {
@@ -4473,17 +4593,17 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4473
4593
  borderRadius: '9999px',
4474
4594
  fontSize: '12px',
4475
4595
  fontWeight: 500,
4476
- backgroundColor: '#D1FAE5',
4477
- color: '#047857',
4596
+ backgroundColor: 'var(--owt-color-success-light, #D1FAE5)',
4597
+ color: 'var(--owt-color-success-dark, #047857)',
4478
4598
  }, children: translate('common.sectionSaved') || 'Saved' })), intakeFormSectionStatus === 'modified' && (jsxRuntimeExports.jsx("span", { style: {
4479
4599
  display: 'inline-block',
4480
4600
  padding: '4px 10px',
4481
4601
  borderRadius: '9999px',
4482
4602
  fontSize: '12px',
4483
4603
  fontWeight: 500,
4484
- backgroundColor: '#FEE2E2',
4485
- color: '#B91C1C',
4486
- }, 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: '#F2BA1A', 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) => {
4604
+ backgroundColor: 'var(--owt-color-error-light, #FEE2E2)',
4605
+ color: 'var(--owt-color-error, #B91C1C)',
4606
+ }, 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) => {
4487
4607
  const docConfig = createDocumentWidgetConfig(doc, sectionId, docIndex);
4488
4608
  return (jsxRuntimeExports.jsx("div", { className: "supporting-document-item", children: jsxRuntimeExports.jsx(FileInputWidget, { config: docConfig }) }, `${sectionId}-doc-${docIndex}`));
4489
4609
  }) })] })), jsxRuntimeExports.jsxs("div", { className: "intake-form-edit-controls", style: {
@@ -4499,10 +4619,10 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4499
4619
  fontSize: '14px',
4500
4620
  fontWeight: 400,
4501
4621
  padding: '8px 24px',
4502
- borderRadius: '10px',
4503
- border: '1px solid #FD8C3E',
4504
- background: '#FFFFFF',
4505
- color: 'rgba(0, 0, 0, 0.5)',
4622
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
4623
+ border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
4624
+ background: 'var(--owt-btn-primary-bg, #FFFFFF)',
4625
+ color: 'var(--owt-color-text-muted, #727474)',
4506
4626
  cursor: 'pointer',
4507
4627
  display: 'inline-flex',
4508
4628
  alignItems: 'center',
@@ -4512,10 +4632,10 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4512
4632
  fontSize: '14px',
4513
4633
  fontWeight: 400,
4514
4634
  padding: '8px 24px',
4515
- borderRadius: '10px',
4516
- border: '1px solid #FD8C3E',
4517
- background: '#FFFFFF',
4518
- color: 'rgba(0, 0, 0, 0.5)',
4635
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
4636
+ border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
4637
+ background: 'var(--owt-btn-primary-bg, #FFFFFF)',
4638
+ color: 'var(--owt-color-text-muted, #727474)',
4519
4639
  cursor: 'pointer',
4520
4640
  display: 'inline-flex',
4521
4641
  alignItems: 'center',
@@ -4538,11 +4658,11 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4538
4658
  fontWeight: 600,
4539
4659
  textTransform: 'uppercase',
4540
4660
  letterSpacing: '0.5px',
4541
- backgroundColor: changeRequestType === 'new' ? '#28a745' : '#ffcccc', // Green for new, faded red for old
4542
- color: changeRequestType === 'new' ? '#FFFFFF' : '#cc0000',
4661
+ backgroundColor: changeRequestType === 'new' ? 'var(--owt-color-success, #16A34A)' : 'var(--owt-color-error-light, #FEE2E2)',
4662
+ color: changeRequestType === 'new' ? 'var(--owt-color-bg, #FFFFFF)' : 'var(--owt-color-error, #B91C1C)',
4543
4663
  whiteSpace: 'nowrap',
4544
4664
  boxShadow: changeRequestType === 'new' ? '0 2px 4px rgba(40, 167, 69, 0.3)' : 'none',
4545
- }, children: changeRequestType === 'new' ? 'New' : 'Old' }))] })), jsxRuntimeExports.jsxs("div", { id: gridId, className: "section-panels", style: mode === 'RegistryView' && hideEditButton ? { paddingBottom: '40px' } : {}, 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: "border-gray-300 w-full", style: { height: '1px', marginTop: '20px', marginBottom: '0px' } }), jsxRuntimeExports.jsxs("div", { className: "cr-view-container", style: {
4665
+ }, 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: {
4546
4666
  marginTop: '20px',
4547
4667
  paddingBottom: '30px',
4548
4668
  display: 'flex',
@@ -4557,17 +4677,17 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4557
4677
  }, children: [jsxRuntimeExports.jsx("span", { style: {
4558
4678
  fontFamily: 'Roboto, sans-serif',
4559
4679
  fontSize: '14px',
4560
- color: '#000000',
4680
+ color: 'var(--owt-color-text, #011627)',
4561
4681
  fontWeight: 'normal',
4562
4682
  }, 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: {
4563
4683
  fontFamily: 'Roboto, sans-serif',
4564
4684
  fontSize: '14px',
4565
- color: '#000000',
4685
+ color: 'var(--owt-color-text, #011627)',
4566
4686
  fontWeight: 'normal',
4567
4687
  }, children: crViewData.createdBy })), jsxRuntimeExports.jsx("img", { src: img$9, alt: "Calendar", width: "16", height: "16", style: { marginLeft: '6px' } }), crViewData?.createdDate && (jsxRuntimeExports.jsx("span", { style: {
4568
4688
  fontFamily: 'Roboto, sans-serif',
4569
4689
  fontSize: '14px',
4570
- color: '#000000',
4690
+ color: 'var(--owt-color-text, #011627)',
4571
4691
  fontWeight: 'normal',
4572
4692
  }, children: crViewData.createdDate }))] }), jsxRuntimeExports.jsxs("div", { className: "approved-by-section", style: {
4573
4693
  display: 'flex',
@@ -4578,22 +4698,22 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4578
4698
  }, children: [jsxRuntimeExports.jsx("span", { style: {
4579
4699
  fontFamily: 'Roboto, sans-serif',
4580
4700
  fontSize: '14px',
4581
- color: '#000000',
4701
+ color: 'var(--owt-color-text, #011627)',
4582
4702
  fontWeight: 'normal',
4583
4703
  }, 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: {
4584
4704
  fontFamily: 'Roboto, sans-serif',
4585
4705
  fontSize: '14px',
4586
- color: '#000000',
4706
+ color: 'var(--owt-color-text, #011627)',
4587
4707
  fontWeight: 'normal',
4588
4708
  }, children: crViewData.approvedBy })), jsxRuntimeExports.jsx("img", { src: img$9, alt: "Calendar", width: "16", height: "16", style: { marginLeft: '6px' } }), crViewData?.approvedDate && (jsxRuntimeExports.jsx("span", { style: {
4589
4709
  fontFamily: 'Roboto, sans-serif',
4590
4710
  fontSize: '14px',
4591
- color: '#000000',
4711
+ color: 'var(--owt-color-text, #011627)',
4592
4712
  fontWeight: 'normal',
4593
- }, children: crViewData.approvedDate }))] })] })] })), mode === 'RegistryView' && !hideEditButton && (jsxRuntimeExports.jsx("hr", { className: "border-gray-300 w-full", style: { height: '1px', marginTop: !isEditMode ? '10px' : 0, marginBottom: '14px' } })), 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: {
4713
+ }, 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: {
4594
4714
  fontFamily: 'Roboto, sans-serif',
4595
4715
  fontSize: '16px',
4596
- color: 'rgba(0, 0, 0, 0.50)'
4716
+ color: 'var(--owt-color-text-muted, #727474)'
4597
4717
  }, 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" })] }) }))] })] })) })] }));
4598
4718
  };
4599
4719
 
@@ -4767,9 +4887,6 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
4767
4887
  }, []);
4768
4888
  const safeSections = sections ?? [];
4769
4889
  const prevSectionsLengthRef = React.useRef(safeSections.length);
4770
- // Stable ref for namespace so formHandle useMemo doesn't depend on the (possibly inline) function identity
4771
- const namespaceRef = React.useRef(namespace);
4772
- namespaceRef.current = namespace;
4773
4890
  // Track dirty (unsaved changes) per section for form handle validation
4774
4891
  const sectionDirtyMapRef = React.useRef({});
4775
4892
  const handleSectionDirtyChange = React.useCallback((sectionId, isDirty) => {
@@ -4815,14 +4932,11 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
4815
4932
  // Form handle for onFormReady - allows host to validate and get all section data from its own Submit button
4816
4933
  const formHandle = React.useMemo(() => {
4817
4934
  const getValues = () => store.getState().widget?.values || {};
4818
- const getNamespace = (section, index) => {
4819
- const ns = namespaceRef.current;
4820
- return ns
4821
- ? typeof ns === 'string'
4822
- ? ns
4823
- : ns(section['section-id'], index)
4824
- : undefined;
4825
- };
4935
+ const getNamespace = (section, index) => namespace
4936
+ ? typeof namespace === 'string'
4937
+ ? namespace
4938
+ : namespace(section['section-id'], index)
4939
+ : undefined;
4826
4940
  const checkNoUnsavedChanges = () => {
4827
4941
  const hasDirty = Object.values(sectionDirtyMapRef.current).some(Boolean);
4828
4942
  if (hasDirty) {
@@ -4872,7 +4986,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
4872
4986
  return results;
4873
4987
  },
4874
4988
  };
4875
- }, [store, dispatch, safeSections]);
4989
+ }, [store, dispatch, safeSections, namespace]);
4876
4990
  // Call onFormReady when form is ready (sections loaded)
4877
4991
  React.useEffect(() => {
4878
4992
  if (onFormReady && safeSections.length > 0) {
@@ -4945,6 +5059,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
4945
5059
  const sectionNamespace = namespace
4946
5060
  ? (typeof namespace === 'string' ? namespace : namespace(section['section-id'], index))
4947
5061
  : undefined;
5062
+ const hideEditForSection = hideEditButton || section['section-hide-edit-button'] === true;
4948
5063
  // IntakeForm mode: pass accordion state and handlers
4949
5064
  const intakeFormProps = mode === 'IntakeForm'
4950
5065
  ? {
@@ -4966,7 +5081,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
4966
5081
  : {};
4967
5082
  // Check if section has explicit column span
4968
5083
  if (section['section-column-span']) {
4969
- return (jsxRuntimeExports.jsx(SectionRenderer, { section: section, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: schemaData, onValueChange: onValueChange, gridColumnSpan: section['section-column-span'], onSectionSave: onSectionSave, hideEditButton: hideEditButton, mode: mode, namespace: sectionNamespace, onSectionDirtyChange: handleSectionDirtyChange, ...intakeFormProps, ...registryViewEditProps }, section['section-id']));
5084
+ 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']));
4970
5085
  }
4971
5086
  const verticalPanelsCount = countVerticalPanels(section.panels);
4972
5087
  const tableWidgetColumnSpan = getTableWidgetColumnSpan(section.panels);
@@ -4974,7 +5089,7 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
4974
5089
  const columnSpan = tableWidgetColumnSpan !== null
4975
5090
  ? tableWidgetColumnSpan
4976
5091
  : (containsTable ? Math.max(verticalPanelsCount, 2) : verticalPanelsCount);
4977
- return (jsxRuntimeExports.jsx(SectionRenderer, { section: section, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: schemaData, onValueChange: onValueChange, gridColumnSpan: columnSpan, onSectionSave: onSectionSave, hideEditButton: hideEditButton, mode: mode, namespace: sectionNamespace, onSectionDirtyChange: handleSectionDirtyChange, ...intakeFormProps, ...registryViewEditProps }, section['section-id']));
5092
+ 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']));
4978
5093
  }) })] }));
4979
5094
  };
4980
5095
 
@@ -8155,10 +8270,10 @@ const DisplayWidget = ({ config }) => {
8155
8270
  const label = translateConfig(widgetConfig['widget-label']);
8156
8271
  // If no label, render as paragraph text
8157
8272
  if (!label || label.trim() === '') {
8158
- return (jsxRuntimeExports.jsx("div", { className: "DisplayFieldWidget mb-3 min-w-0 w-full overflow-hidden text-ellipsis whitespace-nowrap text-base text-gray-700", title: String(displayValue ?? ''), children: displayValue }));
8273
+ return (jsxRuntimeExports.jsx("div", { className: "mb-3 text-base text-gray-700", title: String(displayValue ?? ''), children: displayValue }));
8159
8274
  }
8160
- // With label, render as key-value pair (structure matches other readonly widgets for SectionRenderer ellipsis)
8161
- return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] DisplayFieldWidget flex flex-col sm:flex-row sm:items-start", children: [jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] }), jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntimeExports.jsx("div", { className: "text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue }) })] }));
8275
+ // With label, render as key-value pair
8276
+ 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 })] }));
8162
8277
  };
8163
8278
 
8164
8279
  const TableCellSelect = ({ config, value, onValueChange }) => {
@@ -8166,7 +8281,11 @@ const TableCellSelect = ({ config, value, onValueChange }) => {
8166
8281
  // Use useBaseWidget to get data source options (it handles loading)
8167
8282
  const { dataSourceOptions, loading, config: widgetConfig, } = useBaseWidget({ config });
8168
8283
  const isReadonly = config['widget-readonly'] || false;
8169
- 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 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 ${isReadonly || loading ? 'bg-gray-100 cursor-not-allowed' : 'bg-white'} border-gray-300`, style: { borderRadius: '10px' }, children: [jsxRuntimeExports.jsx("option", { value: "", children: translate('common.select') || 'Select' }), dataSourceOptions.map((option) => (jsxRuntimeExports.jsx("option", { value: option.value, children: option.label }, option.value)))] }));
8284
+ 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: {
8285
+ borderRadius: '10px',
8286
+ borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
8287
+ backgroundColor: isReadonly || loading ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
8288
+ }, children: [jsxRuntimeExports.jsx("option", { value: "", children: translate('common.select') || 'Select' }), dataSourceOptions.map((option) => (jsxRuntimeExports.jsx("option", { value: option.value, children: option.label }, option.value)))] }));
8170
8289
  };
8171
8290
  const SelectDisplayValue = ({ config, value }) => {
8172
8291
  const { dataSourceOptions, loading } = useBaseWidget({ config });
@@ -8185,7 +8304,11 @@ const TableCellText = ({ config, value, onValueChange }) => {
8185
8304
  config['widget-data-format'];
8186
8305
  const maxLength = config['widget-data-validation']?.maxLength;
8187
8306
  const displayValue = value !== null && value !== undefined ? String(value) : '';
8188
- 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 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 ${isReadonly ? 'bg-gray-100 cursor-not-allowed' : 'bg-white'} border-gray-300`, style: { borderRadius: '10px' } }));
8307
+ 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: {
8308
+ borderRadius: '10px',
8309
+ borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
8310
+ backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
8311
+ } }));
8189
8312
  };
8190
8313
  const TableCellNumber = ({ config, value, onValueChange }) => {
8191
8314
  const isReadonly = config['widget-readonly'] || false;
@@ -8208,14 +8331,22 @@ const TableCellNumber = ({ config, value, onValueChange }) => {
8208
8331
  onValueChange(inputValue);
8209
8332
  }
8210
8333
  };
8211
- 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 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 text-right ${isReadonly ? 'bg-gray-100 cursor-not-allowed' : 'bg-white'} border-gray-300`, style: { borderRadius: '10px' } }));
8334
+ 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: {
8335
+ borderRadius: '10px',
8336
+ borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
8337
+ backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
8338
+ } }));
8212
8339
  };
8213
8340
  const TableCellDate = ({ config, value, onValueChange }) => {
8214
8341
  const isReadonly = config['widget-readonly'] || false;
8215
8342
  const placeholder = config['widget-data-placeholder'] || '';
8216
8343
  // input type="date" requires YYYY-MM-DD format
8217
8344
  const displayValue = value && typeof value === 'string' ? value.split('T')[0] : '';
8218
- 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 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 ${isReadonly ? 'bg-gray-100 cursor-not-allowed' : 'bg-white'} border-gray-300`, style: { borderRadius: '10px' } }));
8345
+ 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: {
8346
+ borderRadius: '10px',
8347
+ borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
8348
+ backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
8349
+ } }));
8219
8350
  };
8220
8351
  const TableWidget = ({ config }) => {
8221
8352
  const { value, error, touched, isEnabled, onChange, config: widgetConfig, } = useBaseWidget({ config });
@@ -8622,13 +8753,13 @@ const TableWidget = ({ config }) => {
8622
8753
  return {}; // No special styling when editing
8623
8754
  const editAction = row?.edit_action;
8624
8755
  if (editAction === 'ADD') {
8625
- return { color: '#16a34a' }; // green-600
8756
+ return { color: 'var(--owt-color-success, #16A34A)' };
8626
8757
  }
8627
8758
  else if (editAction === 'DELETE') {
8628
- return { color: '#dc2626', textDecoration: 'line-through' }; // red-600 with strikethrough
8759
+ return { color: 'var(--owt-color-error, #B91C1C)', textDecoration: 'line-through' };
8629
8760
  }
8630
8761
  else if (editAction === 'UPDATE') {
8631
- return { color: '#ea580c' }; // orange-600
8762
+ return { color: 'var(--owt-color-warning, #F59E0B)' };
8632
8763
  }
8633
8764
  return {};
8634
8765
  };
@@ -8712,27 +8843,81 @@ const TableWidget = ({ config }) => {
8712
8843
  .${tableWidgetId} button {
8713
8844
  border-radius: 10px !important;
8714
8845
  }
8715
- ` }), jsxRuntimeExports.jsxs("div", { className: `table-widget-container ${tableWidgetId}`, children: [confirmationState?.show && (jsxRuntimeExports.jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: jsxRuntimeExports.jsxs("div", { className: "bg-white rounded-lg p-6 max-w-md w-full mx-4", children: [jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold mb-4", children: translate('table.confirm') || 'Confirm Action' }), jsxRuntimeExports.jsx("p", { className: "text-gray-700 mb-6", 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 text-gray-700 bg-gray-200 hover:bg-gray-300", style: { borderRadius: '15px' }, children: translate('common.cancel') || 'Cancel' }), jsxRuntimeExports.jsx("button", { onClick: confirmationState.onConfirm, className: "px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700", style: { borderRadius: '15px' }, 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 bg-blue-500 text-white hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed", style: { borderRadius: '15px' }, children: translate('table.addRecord') || 'Add New Record' }) })), rows.length === 0 && !isAdding ? (jsxRuntimeExports.jsxs("div", { className: "text-gray-500 text-sm py-4 text-center border border-gray-300", style: { borderRadius: '15px' }, children: [translate('table.noData') || 'No records available.', operations.add && !isReadonly && ` ${translate('table.clickToAdd') || 'Click "Add New Record" to add one.'}`] })) : (jsxRuntimeExports.jsx("div", { className: "overflow-x-auto border border-gray-300", style: { borderRadius: '15px' }, children: jsxRuntimeExports.jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [jsxRuntimeExports.jsx("thead", { className: "bg-gray-50", children: jsxRuntimeExports.jsxs("tr", { children: [columns.map((col) => (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", 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 text-gray-500 uppercase tracking-wider", children: translate('common.actions') || 'Actions' })) : null] }) }), jsxRuntimeExports.jsxs("tbody", { className: "bg-white divide-y divide-gray-200", children: [rows.map((row, rowIndex) => {
8846
+ /* Focus ring for table cell inputs */
8847
+ .${tableWidgetId} .table-cell-input:focus {
8848
+ box-shadow: 0 0 0 1px var(--owt-widget-input-focus-border, #F07B1A);
8849
+ border-color: var(--owt-widget-input-focus-border, #F07B1A);
8850
+ }
8851
+ ` }), 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: {
8852
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8853
+ border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
8854
+ backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
8855
+ color: 'var(--owt-btn-secondary-color, #011627)',
8856
+ }, children: translate('common.cancel') || 'Cancel' }), jsxRuntimeExports.jsx("button", { onClick: confirmationState.onConfirm, className: "px-4 py-2 text-sm font-medium", style: {
8857
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8858
+ border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
8859
+ backgroundColor: 'var(--owt-color-primary, #F5BB1A)',
8860
+ color: 'var(--owt-color-bg, #FFFFFF)',
8861
+ }, 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: {
8862
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8863
+ border: '1px solid var(--owt-btn-primary-border, #F07B1A)',
8864
+ backgroundColor: 'var(--owt-color-primary, #F5BB1A)',
8865
+ color: 'var(--owt-color-bg, #FFFFFF)',
8866
+ }, 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) => {
8716
8867
  const isEditing = isRowEditing(rowIndex);
8717
8868
  const isLoading = loadingRowIndex === rowIndex;
8718
- return (jsxRuntimeExports.jsxs("tr", { className: isEditing ? 'bg-blue-50' : isLoading ? 'opacity-50' : row.edit_action === 'DELETE' ? 'bg-red-50' : '', children: [columns.map((col) => {
8869
+ return (jsxRuntimeExports.jsxs("tr", { className: isLoading ? 'opacity-50' : '', style: {
8870
+ borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)',
8871
+ backgroundColor: isEditing
8872
+ ? 'var(--owt-widget-table-editing-row-bg, #FBE6AA)'
8873
+ : row.edit_action === 'DELETE'
8874
+ ? 'var(--owt-widget-table-deleted-row-bg, #FEE2E2)'
8875
+ : undefined,
8876
+ }, children: [columns.map((col) => {
8719
8877
  return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: renderCell(rowIndex, col, row) }, col['column-key']));
8720
8878
  }), ((operations.edit || operations.remove) && !isReadonly) || isEditing || isSectionEditMode ? (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", style: { minWidth: '120px' }, children: isEditing ? (
8721
8879
  // Show OK (Save)/Cancel buttons when row is being edited (works in both section edit mode and normal mode)
8722
- 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 hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap flex-shrink-0", style: {
8880
+ 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: {
8723
8881
  display: 'inline-block',
8724
8882
  minWidth: '60px',
8725
- backgroundColor: '#16a34a', // green-600
8726
- color: '#ffffff', // white text
8883
+ backgroundColor: 'var(--owt-color-success, #16A34A)',
8884
+ color: 'var(--owt-color-bg, #FFFFFF)',
8727
8885
  border: 'none',
8728
- borderRadius: '15px'
8729
- }, children: translate('common.ok') || 'OK' }), jsxRuntimeExports.jsx("button", { type: "button", onClick: cancelEdit, disabled: isLoading, className: "px-3 py-1 text-xs font-medium bg-gray-200 text-gray-700 hover:bg-gray-300 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap flex-shrink-0", style: { display: 'inline-block', minWidth: '60px', borderRadius: '15px' }, children: translate('common.cancel') || 'Cancel' })] })) : (
8886
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8887
+ }, 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: {
8888
+ display: 'inline-block',
8889
+ minWidth: '60px',
8890
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8891
+ border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
8892
+ backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
8893
+ color: 'var(--owt-btn-secondary-color, #011627)',
8894
+ }, children: translate('common.cancel') || 'Cancel' })] })) : (
8730
8895
  // Show Edit/Delete buttons when row is not being edited
8731
- 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 text-blue-600 hover:text-blue-800 hover:bg-blue-50 disabled:opacity-50 disabled:cursor-not-allowed", style: { borderRadius: '15px' }, 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 text-red-600 hover:text-red-800 hover:bg-red-50 disabled:opacity-50 disabled:cursor-not-allowed", style: { borderRadius: '15px' }, children: translate('common.remove') || 'Delete' }))] })) })) : null] }, rowIndex));
8732
- }), isAdding && newRowData && (jsxRuntimeExports.jsxs("tr", { className: "bg-blue-50", 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 bg-green-600 text-white hover:bg-green-700 disabled:opacity-50", style: { borderRadius: '15px' }, children: translate('common.save') || 'Save' }), jsxRuntimeExports.jsx("button", { type: "button", onClick: () => {
8896
+ 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: {
8897
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8898
+ color: 'var(--owt-color-primary-dark, #F07B1A)',
8899
+ backgroundColor: 'transparent',
8900
+ border: 'none',
8901
+ }, 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: {
8902
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8903
+ color: 'var(--owt-color-error, #B91C1C)',
8904
+ backgroundColor: 'transparent',
8905
+ border: 'none',
8906
+ }, children: translate('common.remove') || 'Delete' }))] })) })) : null] }, rowIndex));
8907
+ }), 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: {
8908
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8909
+ backgroundColor: 'var(--owt-color-success, #16A34A)',
8910
+ color: 'var(--owt-color-bg, #FFFFFF)',
8911
+ border: 'none',
8912
+ }, children: translate('common.save') || 'Save' }), jsxRuntimeExports.jsx("button", { type: "button", onClick: () => {
8733
8913
  setIsAdding(false);
8734
8914
  setNewRowData(null);
8735
- }, disabled: loadingRowIndex === -1, className: "px-3 py-1 text-xs bg-gray-200 text-gray-700 hover:bg-gray-300 disabled:opacity-50", style: { borderRadius: '15px' }, children: translate('common.cancel') || 'Cancel' })] }) })] }))] })] }) })), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: error[0] }))] })] }));
8915
+ }, disabled: loadingRowIndex === -1, className: "px-3 py-1 text-xs disabled:opacity-50", style: {
8916
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
8917
+ border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
8918
+ backgroundColor: 'var(--owt-btn-secondary-bg, #FFFFFF)',
8919
+ color: 'var(--owt-btn-secondary-color, #011627)',
8920
+ }, 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] }))] })] }));
8736
8921
  };
8737
8922
 
8738
8923
  const ProfileWidget = ({ config }) => {
@@ -8821,7 +9006,7 @@ const ProfileWidget = ({ config }) => {
8821
9006
  // Get format options (using index access for widget-specific properties)
8822
9007
  const format = widgetConfig['widget-data-format'] || {};
8823
9008
  const imageSize = format.imageSize || 80;
8824
- const nameColor = format.nameColor || '#ED7C22';
9009
+ const nameColor = format.nameColor || 'var(--owt-color-primary-dark, #F07B1A)';
8825
9010
  const showIdLabel = format.showIdLabel !== false; // Default to true
8826
9011
  // Generate a unique class ID for this widget instance
8827
9012
  const widgetClassId = `profile-widget-${config['widget-id']}`;
@@ -8844,8 +9029,8 @@ const ProfileWidget = ({ config }) => {
8844
9029
  height: ${imageSize}px;
8845
9030
  border-radius: 8px;
8846
9031
  object-fit: cover;
8847
- background-color: #e5e7eb;
8848
- border: 2px solid #d1d5db;
9032
+ background-color: var(--owt-color-border-light, #e5e7eb);
9033
+ border: 2px solid var(--owt-color-border, #d1d5db);
8849
9034
  flex-shrink: 0;
8850
9035
  }
8851
9036
 
@@ -8853,8 +9038,8 @@ const ProfileWidget = ({ config }) => {
8853
9038
  width: ${imageSize}px;
8854
9039
  height: ${imageSize}px;
8855
9040
  border-radius: 8px;
8856
- background-color: #e5e7eb;
8857
- border: 2px solid #d1d5db;
9041
+ background-color: var(--owt-color-border-light, #e5e7eb);
9042
+ border: 2px solid var(--owt-color-border, #d1d5db);
8858
9043
  display: flex;
8859
9044
  align-items: center;
8860
9045
  justify-content: center;
@@ -8895,12 +9080,12 @@ const ProfileWidget = ({ config }) => {
8895
9080
  }
8896
9081
 
8897
9082
  .${widgetClassId} .profile-id-label {
8898
- color: #6b7280;
9083
+ color: var(--owt-color-text-muted, #6b7280);
8899
9084
  font-weight: 500;
8900
9085
  }
8901
9086
 
8902
9087
  .${widgetClassId} .profile-id-value {
8903
- color: #111827;
9088
+ color: var(--owt-color-text, #111827);
8904
9089
  font-weight: 400;
8905
9090
  }
8906
9091
  ` }), 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) => {
@@ -8991,7 +9176,7 @@ const TextAreaWidget = ({ config }) => {
8991
9176
  minHeight: `${rows * 1.5 * 14 + 16}px`, // Approximate height based on rows
8992
9177
  } }), showCharCounter && (jsxRuntimeExports.jsx("div", { className: "absolute bottom-2 right-2 text-xs px-1 rounded", style: {
8993
9178
  fontFamily: 'Roboto, sans-serif',
8994
- color: maxLength && currentLength > maxLength ? '#EF4444' : '#6B7280',
9179
+ color: maxLength && currentLength > maxLength ? 'var(--owt-widget-error-color, #EF4444)' : 'var(--owt-widget-helptext-color, #6B7280)',
8995
9180
  backgroundColor: 'rgba(255, 255, 255, 0.9)',
8996
9181
  }, children: charCounterText }))] }), hasError && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: errorMessage }))] })] }) }));
8997
9182
  };
@@ -9126,18 +9311,7 @@ const HeaderSectionWidget = ({ config }) => {
9126
9311
  result = searchIn(schemaData);
9127
9312
  return result;
9128
9313
  }, [paths, values, schemaData]);
9129
- const imageVal = findValue('image');
9130
- const imageUrlVal = findValue('imageUrl');
9131
- const [previewUrl, setPreviewUrl] = React.useState(null);
9132
- React.useEffect(() => {
9133
- if (imageVal instanceof File) {
9134
- const url = URL.createObjectURL(imageVal);
9135
- setPreviewUrl(url);
9136
- return () => URL.revokeObjectURL(url);
9137
- }
9138
- setPreviewUrl(null);
9139
- }, [imageVal]);
9140
- const displayImageUrl = previewUrl || (typeof imageUrlVal === 'string' && imageUrlVal ? imageUrlVal : null);
9314
+ const imageUrl = findValue('image') || null;
9141
9315
  const displayName = findValue('name') || '';
9142
9316
  const functionalId = findValue('functionalId') || '';
9143
9317
  const statusValue = findValue('status') || '';
@@ -9149,7 +9323,7 @@ const HeaderSectionWidget = ({ config }) => {
9149
9323
  // ── Format options ────────────────────────────────────────────
9150
9324
  const format = (widgetConfig['widget-data-format'] || {});
9151
9325
  const imageSize = format.imageSize || 120;
9152
- const nameColor = format.nameColor || '#ED7C22';
9326
+ const nameColor = format.nameColor || 'var(--owt-color-primary-dark, #F07B1A)';
9153
9327
  const statusColors = {
9154
9328
  ...DEFAULT_STATUS_COLORS,
9155
9329
  ...(format.statusColors || {}),
@@ -9169,21 +9343,19 @@ const HeaderSectionWidget = ({ config }) => {
9169
9343
  const opt = statusOptions.find((o) => String(o.value).toLowerCase() === String(statusValue).toLowerCase());
9170
9344
  return opt ? opt.label : String(statusValue);
9171
9345
  }, [statusValue, statusOptions]);
9172
- const statusColor = statusColors[String(statusValue).toLowerCase()] || '#6B7280';
9173
- // ── Image edit helpers ───────────────────────────────────────
9174
- const fileInputRef = React.useRef(null);
9175
- const handleImageUpload = React.useCallback((e) => {
9176
- const file = e.target.files?.[0];
9177
- if (!file)
9178
- return;
9179
- updateFieldValue('image', file);
9180
- e.target.value = '';
9181
- }, [updateFieldValue]);
9182
- const handleImageDelete = React.useCallback(() => {
9183
- updateFieldValue('image', '');
9184
- }, [updateFieldValue]);
9346
+ const statusColor = statusColors[String(statusValue).toLowerCase()] || 'var(--owt-color-text-muted, #6B7280)';
9185
9347
  // ── Scoped class for CSS isolation ────────────────────────────
9186
9348
  const cls = `header-section-widget-${widgetConfig['widget-id']}`;
9349
+ // ── Indicator dot component ───────────────────────────────────
9350
+ const Dot = ({ color }) => (jsxRuntimeExports.jsx("span", { style: {
9351
+ display: 'inline-block',
9352
+ width: 8,
9353
+ height: 8,
9354
+ borderRadius: '50%',
9355
+ backgroundColor: color,
9356
+ flexShrink: 0,
9357
+ marginTop: 6,
9358
+ } }));
9187
9359
  // ── RENDER ────────────────────────────────────────────────────
9188
9360
  return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { children: `
9189
9361
  .${cls} {
@@ -9217,8 +9389,8 @@ const HeaderSectionWidget = ({ config }) => {
9217
9389
  height: ${imageSize}px;
9218
9390
  border-radius: 8px;
9219
9391
  object-fit: cover;
9220
- background-color: #e5e7eb;
9221
- border: 2px solid #d1d5db;
9392
+ background-color: var(--owt-color-border-light, #e5e7eb);
9393
+ border: 2px solid var(--owt-color-border, #d1d5db);
9222
9394
  flex-shrink: 0;
9223
9395
  }
9224
9396
 
@@ -9226,8 +9398,8 @@ const HeaderSectionWidget = ({ config }) => {
9226
9398
  width: ${imageSize}px;
9227
9399
  height: ${imageSize}px;
9228
9400
  border-radius: 8px;
9229
- background-color: #e5e7eb;
9230
- border: 2px solid #d1d5db;
9401
+ background-color: var(--owt-color-border-light, #e5e7eb);
9402
+ border: 2px solid var(--owt-color-border, #d1d5db);
9231
9403
  display: flex;
9232
9404
  align-items: center;
9233
9405
  justify-content: center;
@@ -9242,56 +9414,6 @@ const HeaderSectionWidget = ({ config }) => {
9242
9414
  border-radius: 8px;
9243
9415
  }
9244
9416
 
9245
- .${cls} .hdr-avatar-wrapper {
9246
- position: relative;
9247
- width: ${imageSize}px;
9248
- height: ${imageSize}px;
9249
- flex-shrink: 0;
9250
- }
9251
-
9252
- .${cls} .hdr-avatar-overlay {
9253
- position: absolute;
9254
- inset: 0;
9255
- border-radius: 8px;
9256
- background: rgba(0, 0, 0, 0.55);
9257
- display: flex;
9258
- flex-direction: column;
9259
- align-items: center;
9260
- justify-content: center;
9261
- gap: 6px;
9262
- opacity: 0;
9263
- transition: opacity 0.2s;
9264
- }
9265
-
9266
- .${cls} .hdr-avatar-wrapper:hover .hdr-avatar-overlay {
9267
- opacity: 1;
9268
- }
9269
-
9270
- .${cls} .hdr-avatar-action {
9271
- display: flex;
9272
- align-items: center;
9273
- gap: 5px;
9274
- padding: 5px 14px;
9275
- border: none;
9276
- border-radius: 4px;
9277
- background: rgba(255, 255, 255, 0.92);
9278
- color: #374151;
9279
- font-size: 0.7rem;
9280
- font-weight: 500;
9281
- cursor: pointer;
9282
- font-family: Roboto, sans-serif;
9283
- transition: background 0.15s;
9284
- white-space: nowrap;
9285
- }
9286
-
9287
- .${cls} .hdr-avatar-action:hover {
9288
- background: #fff;
9289
- }
9290
-
9291
- .${cls} .hdr-avatar-action--delete {
9292
- color: #DC2626;
9293
- }
9294
-
9295
9417
  .${cls} .hdr-info {
9296
9418
  display: flex;
9297
9419
  flex-direction: column;
@@ -9323,7 +9445,7 @@ const HeaderSectionWidget = ({ config }) => {
9323
9445
  }
9324
9446
 
9325
9447
  .${cls} .hdr-field-value {
9326
- color: #111827;
9448
+ color: var(--owt-color-text, #111827);
9327
9449
  font-weight: 500;
9328
9450
  }
9329
9451
 
@@ -9350,41 +9472,41 @@ const HeaderSectionWidget = ({ config }) => {
9350
9472
  }
9351
9473
 
9352
9474
  .${cls} .hdr-meta-value {
9353
- color: #111827;
9475
+ color: var(--owt-color-text, #111827);
9354
9476
  font-weight: 500;
9355
9477
  }
9356
9478
 
9357
9479
  .${cls} .hdr-select {
9358
9480
  height: 32px;
9359
9481
  padding: 0 8px;
9360
- border: 1px solid #d1d5db;
9482
+ border: 1px solid var(--owt-widget-input-border, #d1d5db);
9361
9483
  border-radius: 6px;
9362
9484
  font-size: 0.875rem;
9363
9485
  font-family: Roboto, sans-serif;
9364
- background: #fff;
9486
+ background: var(--owt-widget-input-bg, #fff);
9365
9487
  min-width: 140px;
9366
- color: #374151;
9488
+ color: var(--owt-btn-primary-color, #374151);
9367
9489
  }
9368
9490
  .${cls} .hdr-select:focus {
9369
9491
  outline: none;
9370
- border-color: #ED7C22;
9492
+ border-color: var(--owt-widget-input-focus-border, #F07B1A);
9371
9493
  box-shadow: 0 0 0 2px rgba(237, 124, 34, 0.15);
9372
9494
  }
9373
9495
 
9374
9496
  .${cls} .hdr-input {
9375
9497
  height: 32px;
9376
9498
  padding: 0 8px;
9377
- border: 1px solid #d1d5db;
9499
+ border: 1px solid var(--owt-widget-input-border, #d1d5db);
9378
9500
  border-radius: 6px;
9379
9501
  font-size: 0.875rem;
9380
9502
  font-family: Roboto, sans-serif;
9381
- background: #fff;
9503
+ background: var(--owt-widget-input-bg, #fff);
9382
9504
  min-width: 140px;
9383
- color: #374151;
9505
+ color: var(--owt-btn-primary-color, #374151);
9384
9506
  }
9385
9507
  .${cls} .hdr-input:focus {
9386
9508
  outline: none;
9387
- border-color: #ED7C22;
9509
+ border-color: var(--owt-widget-input-focus-border, #F07B1A);
9388
9510
  box-shadow: 0 0 0 2px rgba(237, 124, 34, 0.15);
9389
9511
  }
9390
9512
 
@@ -9396,13 +9518,261 @@ const HeaderSectionWidget = ({ config }) => {
9396
9518
  min-width: 0;
9397
9519
  }
9398
9520
  }
9399
- ` }), jsxRuntimeExports.jsxs("div", { className: cls, children: [jsxRuntimeExports.jsxs("div", { className: "hdr-left", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-wrapper", children: [displayImageUrl ? (jsxRuntimeExports.jsx("img", { src: displayImageUrl, alt: displayName || 'Profile', className: "hdr-avatar", onError: (e) => {
9521
+ ` }), 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) => {
9400
9522
  e.target.style.display = 'none';
9401
9523
  const placeholder = e.target
9402
9524
  .parentElement?.querySelector('.hdr-avatar-placeholder');
9403
9525
  if (placeholder)
9404
9526
  placeholder.style.display = 'flex';
9405
- } })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display: displayImageUrl ? 'none' : 'flex' }, children: jsxRuntimeExports.jsx("img", { src: img$f, alt: "Profile Placeholder" }) }), !isReadonly && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-overlay", children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action", onClick: () => fileInputRef.current?.click(), children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), jsxRuntimeExports.jsx("polyline", { points: "17 8 12 3 7 8" }), jsxRuntimeExports.jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })] }), "Upload"] }), jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action hdr-avatar-action--delete", onClick: handleImageDelete, children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("polyline", { points: "3 6 5 6 21 6" }), jsxRuntimeExports.jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })] }), "Delete"] })] }), jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: 'none' }, onChange: handleImageUpload })] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-info", children: [displayName && jsxRuntimeExports.jsx("div", { className: "hdr-name", children: displayName }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('functionalId'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: functionalId || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx("span", { className: "hdr-field-label", children: getLabel('status') }), isReadonly ? (statusLabel ? (jsxRuntimeExports.jsx("span", { className: "hdr-status-badge", style: { backgroundColor: statusColor }, children: statusLabel })) : (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: "-" }))) : (jsxRuntimeExports.jsxs("select", { className: "hdr-select", value: statusValue, onChange: (e) => updateFieldValue('status', e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: getLabel('select') }), statusOptions.map((opt) => (jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, opt.value)))] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('statusReason'), " :"] }), isReadonly ? (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: statusReason || '-' })) : (jsxRuntimeExports.jsx("input", { type: "text", className: "hdr-input", value: statusReason, placeholder: getLabel('enterReason'), onChange: (e) => updateFieldValue('statusReason', e.target.value) }))] })] })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-right", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdAt || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedAt || '-' })] })] })] })] }));
9527
+ } })) : 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 || '-' })] })] })] })] }));
9528
+ };
9529
+
9530
+ function tryFormatDateTime(value) {
9531
+ if (typeof value !== 'string' || !value)
9532
+ return value ? String(value) : '-';
9533
+ const d = new Date(value);
9534
+ if (Number.isNaN(d.getTime()))
9535
+ return value;
9536
+ try {
9537
+ return d.toLocaleString(undefined, {
9538
+ year: 'numeric',
9539
+ month: 'short',
9540
+ day: '2-digit',
9541
+ hour: '2-digit',
9542
+ minute: '2-digit',
9543
+ });
9544
+ }
9545
+ catch {
9546
+ return value;
9547
+ }
9548
+ }
9549
+ function pickLatestScore(scores) {
9550
+ if (!scores || scores.length === 0)
9551
+ return null;
9552
+ const withTime = scores
9553
+ .map((s) => {
9554
+ const t = typeof s?.computed_at === 'string' ? new Date(s.computed_at).getTime() : NaN;
9555
+ return { s, t };
9556
+ })
9557
+ .filter((x) => !Number.isNaN(x.t));
9558
+ if (withTime.length === 0)
9559
+ return scores[0] || null;
9560
+ withTime.sort((a, b) => b.t - a.t);
9561
+ return withTime[0]?.s || null;
9562
+ }
9563
+ /**
9564
+ * Scores Display Widget - full-width, view-only widget
9565
+ *
9566
+ * Expected config (reference):
9567
+ * {
9568
+ * "widget": "scores-display",
9569
+ * "widget-type": "group",
9570
+ * "widget-id": "record-scores",
9571
+ * "widget-data-source": {
9572
+ * "type": "api",
9573
+ * "service": "staff-portal-api",
9574
+ * "endpoint": "get_scores",
9575
+ * "method": "POST",
9576
+ * "params": { "internal_record_id_path": "internal_record_id" }
9577
+ * }
9578
+ * }
9579
+ *
9580
+ * The host's `dataSourceRequestHandler` is invoked with:
9581
+ * - service: config.widget-data-source.service
9582
+ * - endpoint: config.widget-data-source.endpoint
9583
+ * - method: config.widget-data-source.method (default POST)
9584
+ * - params: { internal_record_id: <resolved from internal_record_id_path> }
9585
+ */
9586
+ const ScoresDisplayWidget = ({ config, dataSourceRequestHandler: propHandler, schemaData: propSchemaData, }) => {
9587
+ const { dataSourceRequestHandler: ctxHandler, schemaData: ctxSchemaData } = useWidgetContext();
9588
+ const handler = propHandler || ctxHandler;
9589
+ const schemaData = propSchemaData || ctxSchemaData || {};
9590
+ const values = reactRedux.useSelector((state) => state.widget.values);
9591
+ const api = config['widget-data-source'];
9592
+ const isApi = api?.type === 'api';
9593
+ const apiDs = isApi ? api : null;
9594
+ const internalIdPath = React.useMemo(() => {
9595
+ if (!apiDs)
9596
+ return undefined;
9597
+ const p = apiDs.params || {};
9598
+ const fromParams = p.internal_record_id_path || p.internalRecordIdPath;
9599
+ const fromConfig = typeof config.internal_record_id_path === 'string'
9600
+ ? config.internal_record_id_path
9601
+ : undefined;
9602
+ return fromParams || fromConfig;
9603
+ }, [apiDs, config]);
9604
+ const internalRecordId = React.useMemo(() => {
9605
+ if (!internalIdPath)
9606
+ return undefined;
9607
+ const fromValues = getValueByPath(values || {}, internalIdPath);
9608
+ if (fromValues !== undefined && fromValues !== null && String(fromValues).trim() !== '') {
9609
+ return String(fromValues);
9610
+ }
9611
+ const fromSchema = getValueByPath(schemaData || {}, internalIdPath);
9612
+ if (fromSchema !== undefined && fromSchema !== null && String(fromSchema).trim() !== '') {
9613
+ return String(fromSchema);
9614
+ }
9615
+ return undefined;
9616
+ }, [internalIdPath, values, schemaData]);
9617
+ const [loading, setLoading] = React.useState(false);
9618
+ const [error, setError] = React.useState(null);
9619
+ const [response, setResponse] = React.useState(null);
9620
+ React.useEffect(() => {
9621
+ let cancelled = false;
9622
+ const load = async () => {
9623
+ if (!apiDs) {
9624
+ setError('Scores widget requires an API data source.');
9625
+ setResponse(null);
9626
+ return;
9627
+ }
9628
+ if (!handler) {
9629
+ setError(null);
9630
+ setResponse(null);
9631
+ return;
9632
+ }
9633
+ const service = apiDs.service;
9634
+ const endpoint = apiDs.endpoint;
9635
+ const method = apiDs.method || 'POST';
9636
+ if (!service || !endpoint) {
9637
+ setError('Scores widget API data source is missing service/endpoint.');
9638
+ setResponse(null);
9639
+ return;
9640
+ }
9641
+ if (!internalRecordId) {
9642
+ setError(null);
9643
+ setResponse(null);
9644
+ return;
9645
+ }
9646
+ try {
9647
+ setLoading(true);
9648
+ setError(null);
9649
+ const rawParams = apiDs.params || {};
9650
+ // Never pass the path helper through to the API.
9651
+ const { internal_record_id_path, internalRecordIdPath, ...rest } = rawParams;
9652
+ void internal_record_id_path;
9653
+ void internalRecordIdPath;
9654
+ const params = {
9655
+ ...rest,
9656
+ internal_record_id: internalRecordId,
9657
+ };
9658
+ const res = await handler(service, endpoint, method, params, {
9659
+ headers: apiDs.headers,
9660
+ });
9661
+ if (cancelled)
9662
+ return;
9663
+ // Accept either direct payload or OpenG2P wrapper objects.
9664
+ const envelope = res && typeof res === 'object' ? res : null;
9665
+ const payload = envelope?.response_body?.response_payload ?? envelope?.data ?? res;
9666
+ if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
9667
+ setResponse(payload);
9668
+ }
9669
+ else {
9670
+ setResponse({ scores: Array.isArray(payload) ? payload : [] });
9671
+ }
9672
+ }
9673
+ catch (e) {
9674
+ if (cancelled)
9675
+ return;
9676
+ const maybeErr = e;
9677
+ const msg = maybeErr && typeof maybeErr === 'object' && typeof maybeErr.message === 'string'
9678
+ ? maybeErr.message
9679
+ : 'Failed to load scores.';
9680
+ setError(msg);
9681
+ setResponse(null);
9682
+ }
9683
+ finally {
9684
+ if (!cancelled)
9685
+ setLoading(false);
9686
+ }
9687
+ };
9688
+ load();
9689
+ return () => {
9690
+ cancelled = true;
9691
+ };
9692
+ }, [apiDs, handler, internalRecordId]);
9693
+ const latest = React.useMemo(() => pickLatestScore(response?.scores), [response]);
9694
+ const cls = `scores-display-widget-${config['widget-id']}`;
9695
+ const scoreType = latest?.score_type ? String(latest.score_type) : '-';
9696
+ const scoreValue = latest?.computed_score !== undefined && latest?.computed_score !== null && String(latest.computed_score) !== ''
9697
+ ? String(latest.computed_score)
9698
+ : '-';
9699
+ const computedAt = tryFormatDateTime(latest?.computed_at);
9700
+ return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { children: `
9701
+ .${cls} {
9702
+ width: 100%;
9703
+ font-family: Roboto, sans-serif;
9704
+ padding: 0;
9705
+ display: flex;
9706
+ flex-direction: column;
9707
+ gap: 8px;
9708
+ }
9709
+
9710
+ .${cls} .scores-subtle {
9711
+ font-size: 13px;
9712
+ color: var(--owt-color-text-muted, #727474);
9713
+ font-weight: 400;
9714
+ }
9715
+
9716
+ .${cls} .scores-card {
9717
+ width: 100%;
9718
+ border: none;
9719
+ border-radius: 0;
9720
+ background: transparent;
9721
+ padding: 0;
9722
+ display: grid;
9723
+ grid-template-columns: 1fr 1fr 1fr;
9724
+ gap: 16px;
9725
+ align-items: center;
9726
+ }
9727
+
9728
+ .${cls} .scores-col {
9729
+ min-width: 0;
9730
+ display: flex;
9731
+ flex-direction: column;
9732
+ gap: 6px;
9733
+ }
9734
+
9735
+ .${cls} .scores-label {
9736
+ font-size: 12px;
9737
+ color: var(--owt-color-text-muted, #727474);
9738
+ font-weight: 600;
9739
+ letter-spacing: 0.25px;
9740
+ text-transform: uppercase;
9741
+ }
9742
+
9743
+ .${cls} .scores-value {
9744
+ font-size: 16px;
9745
+ font-weight: 600;
9746
+ color: var(--owt-color-text, #011627);
9747
+ line-height: 1.25;
9748
+ word-break: break-word;
9749
+ }
9750
+
9751
+ .${cls} .scores-value--highlight {
9752
+ font-weight: 800;
9753
+ color: var(--owt-color-primary-dark, #F07B1A);
9754
+ }
9755
+
9756
+ .${cls} .scores-value-wrap {
9757
+ display: inline-flex;
9758
+ align-items: baseline;
9759
+ gap: 10px;
9760
+ flex-wrap: wrap;
9761
+ }
9762
+
9763
+ .${cls} .scores-value-badge { display: inline; }
9764
+
9765
+ .${cls} .scores-statusline {
9766
+ grid-column: 1 / -1;
9767
+ margin-top: 2px;
9768
+ }
9769
+
9770
+ @media (max-width: 768px) {
9771
+ .${cls} .scores-card {
9772
+ grid-template-columns: 1fr;
9773
+ }
9774
+ }
9775
+ ` }), jsxRuntimeExports.jsx("div", { className: cls, children: jsxRuntimeExports.jsxs("div", { className: "scores-card", children: [jsxRuntimeExports.jsxs("div", { className: "scores-col", "aria-live": "polite", children: [jsxRuntimeExports.jsx("div", { className: "scores-label", children: "Score Type" }), jsxRuntimeExports.jsx("div", { className: "scores-value-wrap", children: jsxRuntimeExports.jsx("span", { className: "scores-value-badge", children: jsxRuntimeExports.jsx("span", { className: "scores-value scores-value--highlight", children: scoreType }) }) })] }), jsxRuntimeExports.jsxs("div", { className: "scores-col", children: [jsxRuntimeExports.jsx("div", { className: "scores-label", children: "Score" }), jsxRuntimeExports.jsx("div", { className: "scores-value-wrap", children: jsxRuntimeExports.jsx("span", { className: "scores-value-badge", children: jsxRuntimeExports.jsx("span", { className: "scores-value scores-value--highlight", children: scoreValue }) }) })] }), jsxRuntimeExports.jsxs("div", { className: "scores-col", children: [jsxRuntimeExports.jsx("div", { className: "scores-label", children: "Computed at" }), jsxRuntimeExports.jsx("div", { className: "scores-value", children: computedAt })] }), jsxRuntimeExports.jsx("div", { className: "scores-statusline", children: loading ? (jsxRuntimeExports.jsx("div", { className: "scores-subtle", children: "Loading scores\u2026" })) : error ? (jsxRuntimeExports.jsx("div", { className: "scores-subtle", style: { color: 'var(--owt-color-error, #B91C1C)' }, children: error })) : !latest ? (jsxRuntimeExports.jsx("div", { className: "scores-subtle", children: "No scores available." })) : null })] }) })] }));
9406
9776
  };
9407
9777
 
9408
9778
  /**
@@ -9446,6 +9816,8 @@ const registerDefaultWidgets = () => {
9446
9816
  widgetRegistry.register({ widget: 'profile', component: ProfileWidget });
9447
9817
  // Header section widget for full-width registry header with profile, status, and metadata
9448
9818
  widgetRegistry.register({ widget: 'header-section', component: HeaderSectionWidget });
9819
+ // Scores display widget for full-width computed scores display (view-only)
9820
+ widgetRegistry.register({ widget: 'scores-display', component: ScoresDisplayWidget });
9449
9821
  };
9450
9822
  // Auto-register on import
9451
9823
  registerDefaultWidgets();
@@ -9825,6 +10197,7 @@ exports.PhoneInputWidget = PhoneInputWidget;
9825
10197
  exports.ProfileWidget = ProfileWidget;
9826
10198
  exports.PropertyEditor = PropertyEditor;
9827
10199
  exports.RadioWidget = RadioWidget;
10200
+ exports.ScoresDisplayWidget = ScoresDisplayWidget;
9828
10201
  exports.SectionBuilder = SectionBuilder;
9829
10202
  exports.SectionRenderer = SectionRenderer;
9830
10203
  exports.SectionTree = SectionTree;
@@ -9843,6 +10216,7 @@ exports.applyDecimalPrecision = applyDecimalPrecision;
9843
10216
  exports.applyMask = applyMask;
9844
10217
  exports.createWidgetStore = createWidgetStore;
9845
10218
  exports.createZodSchema = createZodSchema;
10219
+ exports.defaultTheme = defaultTheme;
9846
10220
  exports.evaluateCondition = evaluateCondition;
9847
10221
  exports.filterByCharacterType = filterByCharacterType;
9848
10222
  exports.formatCurrency = formatCurrency;
@@ -9865,6 +10239,7 @@ exports.registerDefaultWidgets = registerDefaultWidgets;
9865
10239
  exports.removeMask = removeMask;
9866
10240
  exports.resetAll = resetAll;
9867
10241
  exports.resetWidget = resetWidget;
10242
+ exports.resolveTheme = resolveTheme;
9868
10243
  exports.setDataSource = setDataSource;
9869
10244
  exports.setError = setError;
9870
10245
  exports.setLoading = setLoading;
@@ -9884,6 +10259,7 @@ exports.useGeoWidgetCascade = useGeoWidgetCascade;
9884
10259
  exports.useWidgetCascade = useWidgetCascade;
9885
10260
  exports.useWidgetContext = useWidgetContext;
9886
10261
  exports.useWidgetEventBus = useWidgetEventBus;
10262
+ exports.useWidgetTheme = useWidgetTheme;
9887
10263
  exports.useWidgetTranslation = useWidgetTranslation;
9888
10264
  exports.validateNumericValue = validateNumericValue;
9889
10265
  exports.validateWidget = validateWidget;