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