diff --git a/ui/ui-widgets/src/components/PanelRenderer.tsx b/ui/ui-widgets/src/components/PanelRenderer.tsx index b5f7118e..99b5e933 100644 --- a/ui/ui-widgets/src/components/PanelRenderer.tsx +++ b/ui/ui-widgets/src/components/PanelRenderer.tsx @@ -11,6 +11,53 @@ export interface PanelRendererProps { isEditMode?: boolean; } +const PANEL_LAYOUT_CSS = ` +.panel-horizontal-grid { + display: grid; + width: 100%; + min-width: 0; + grid-template-columns: minmax(0, 1fr); + gap: 16px; +} +.panel-horizontal-grid > .panel-nested { + min-width: 0; + max-width: 100%; + position: relative; +} +.panel-horizontal-divider { + display: none; +} +.panel-widget-row { + display: flex; + flex-direction: column; + width: 100%; + min-width: 0; + gap: 0; +} +@media (min-width: 1024px) { + .panel-horizontal-grid { + grid-template-columns: repeat(var(--panel-columns, 1), minmax(0, 1fr)); + gap: 0; + } + .panel-horizontal-grid > .panel-nested { + grid-column: span var(--panel-span, 1); + } + .panel-horizontal-grid > .panel-nested.panel-nested-pad-left { + padding-left: 40px; + } + .panel-horizontal-grid > .panel-nested.panel-nested-pad-right { + padding-right: 40px; + } + .panel-horizontal-divider { + display: block; + } + .panel-widget-row { + flex-direction: row; + gap: 16px; + } +} +`; + export const PanelRenderer = ({ panel, dataSourceRequestHandler, @@ -21,9 +68,10 @@ export const PanelRenderer = ({ const orientation = panel['panel-orientation'] || 'vertical'; const nestedPanels = panel.panels || []; const widgets = panel.widgets || []; + const isHorizontalGrid = orientation === 'horizontal' && nestedPanels.length > 0; - const getContainerClassAndStyle = () => { - if (orientation === 'horizontal' && nestedPanels.length > 0) { + const getContainerClassAndStyle = (): { className: string; style: CSSProperties } => { + if (isHorizontalGrid) { let totalColumns = 0; nestedPanels.forEach((nestedPanel) => { const columnSpan = nestedPanel['panel-column-span'] || 1; @@ -33,15 +81,13 @@ export const PanelRenderer = ({ totalColumns = Math.max(totalColumns, nestedPanels.length); return { - className: 'grid', - style: { gridTemplateColumns: `repeat(${totalColumns}, minmax(200px, 1fr))` }, + className: 'panel-horizontal-grid', + style: { ['--panel-columns' as string]: String(totalColumns) }, }; } return { - className: orientation === 'horizontal' - ? 'flex flex-row' - : 'flex flex-col', - style: { gap: orientation === 'horizontal' ? '16px' : '0px' }, + className: orientation === 'horizontal' ? 'panel-widget-row' : 'flex flex-col', + style: {}, }; }; @@ -58,48 +104,28 @@ export const PanelRenderer = ({ {nestedPanels.map((nestedPanel, index) => { const isLastPanel = index === nestedPanels.length - 1; const isFirstPanel = index === 0; - const nestedOrientation = nestedPanel['panel-orientation'] || 'vertical'; - const columnSpan = nestedPanel['panel-column-span']; - - const getNestedPanelStyle = (): CSSProperties => { - if (orientation === 'horizontal') { - const baseStyle: CSSProperties = { - minWidth: '200px', - paddingRight: !isLastPanel ? '40px' : undefined, - paddingLeft: !isFirstPanel ? '40px' : undefined, - position: 'relative', - }; - - if (nestedOrientation === 'vertical' && columnSpan && columnSpan > 1) { - return { - ...baseStyle, - gridColumn: `span ${columnSpan}`, - minWidth: 'auto', - }; - } - - return baseStyle; - } + const columnSpan = nestedPanel['panel-column-span'] || 1; - if (columnSpan && columnSpan > 1) { - const width = columnSpan * 200; - return { - width: `${width}px`, - maxWidth: '100%', - flexShrink: 0, - }; - } - return { width: '100%' }; - }; + const nestedPanelStyle: CSSProperties = isHorizontalGrid + ? { ['--panel-span' as string]: String(columnSpan) } + : { width: '100%', maxWidth: '100%', minWidth: 0 }; - const nestedPanelStyle = getNestedPanelStyle(); + const nestedClassName = isHorizontalGrid + ? [ + 'panel-nested', + !isFirstPanel ? 'panel-nested-pad-left' : '', + !isLastPanel ? 'panel-nested-pad-right' : '', + ] + .filter(Boolean) + .join(' ') + : 'w-full min-w-0'; return (
1 ? columnSpan : undefined} > {orientation === 'horizontal' && !isLastPanel && (
+ {content}
); diff --git a/ui/ui-widgets/src/components/SectionBuilder/JSONEditorPanel.tsx b/ui/ui-widgets/src/components/SectionBuilder/JSONEditorPanel.tsx index bf974ba5..52bf765e 100644 --- a/ui/ui-widgets/src/components/SectionBuilder/JSONEditorPanel.tsx +++ b/ui/ui-widgets/src/components/SectionBuilder/JSONEditorPanel.tsx @@ -202,6 +202,7 @@ export const JSONEditorPanel: React.FC = ({ flex: '1 1 0%', width: '100%', minHeight: 0, + minWidth: 0, padding: '0 16px 16px', boxSizing: 'border-box', }} @@ -213,12 +214,24 @@ export const JSONEditorPanel: React.FC = ({ display: 'flex', justifyContent: 'space-between', alignItems: 'center', + flexWrap: 'wrap', flexShrink: 0, gap: '12px', }} > -
-
+
+
{t?.('sectionBuilder.jsonEditor') || 'JSON Editor'}
= ({ display: 'flex', alignItems: 'center', gap: '6px', + minWidth: 0, color: statusIsOk ? 'var(--owt-color-success)' : 'var(--owt-color-error)', }} > @@ -234,13 +248,25 @@ export const JSONEditorPanel: React.FC = ({ width: '12px', height: '12px', borderRadius: '50%', + flexShrink: 0, background: statusIsOk ? 'var(--owt-color-success)' : 'var(--owt-color-error)', }} /> - {statusLabel} + + {statusLabel} +
-
+
-
+
-
-
+
+
= ({
-
+
+
{collapsible ? (
-
+
-
+
{searchResults.length === 0 ? (

{searchText @@ -598,10 +554,13 @@ export const ParentLookupWidget = ({ isSelected ? 'owt-highlight' : 'owt-highlight-hover' }`} > - + {parentLabel(row) || '-'} - + {row.internal_record_id != null ? String(row.internal_record_id) : '-'} @@ -615,13 +574,9 @@ export const ParentLookupWidget = ({ )}

-
+
{totalCount !== null && ( - + {totalCount === 1 ? t?.('common.record', { count: totalCount, @@ -638,29 +593,29 @@ export const ParentLookupWidget = ({ )}`} )} -
- {totalCount !== null && ( - <> - - - - )} + {totalCount !== null && ( +
+ + +
+ )} +
{hasValue && (
- +
, + document.body, )}
); diff --git a/ui/ui-widgets/src/widgets/RegisterLookupWidget.tsx b/ui/ui-widgets/src/widgets/RegisterLookupWidget.tsx index b82b5439..fb658fab 100644 --- a/ui/ui-widgets/src/widgets/RegisterLookupWidget.tsx +++ b/ui/ui-widgets/src/widgets/RegisterLookupWidget.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { createPortal } from 'react-dom'; import { tSchema, toTitleCase } from '../utils/tSchema'; import { useBaseWidget } from '../hooks/useBaseWidget'; import { BaseWidgetConfig } from '../types'; @@ -75,13 +76,12 @@ const RecordDisplayPanel = ({ const column = (showDivider: boolean, isFirst: boolean, children: React.ReactNode) => (
{children} {showDivider && (
.text-base.owt-field-label, + .register-lookup-record-panel .DisplayFieldWidget > .text-base.owt-text-muted { + width: 100% !important; + min-width: 0 !important; + max-width: 100% !important; + white-space: normal !important; + overflow: visible !important; + text-overflow: unset !important; + } + .register-lookup-record-panel .DisplayFieldWidget > .flex-1 > .owt-text { + white-space: normal; + overflow: visible; + text-overflow: unset; + } + } `}
{column(true, true, ( <> @@ -189,7 +227,7 @@ const PaginationFooter = ({
@@ -199,7 +237,7 @@ const PaginationFooter = ({ : t?.('common.records', { count: totalCount, defaultValue: `${totalCount} records` })} {totalCount > 0 && ` ยท ${pageStart}-${pageEnd}`} -
+
) : null} - {!isReadonly && isOpen && ( - <> -
{ setIsOpen(false); onBlur(); }} - /> + {!isReadonly && isOpen && typeof document !== 'undefined' && createPortal( +
{ setIsOpen(false); onBlur(); }} + >
e.stopPropagation()} >
{ - e.preventDefault(); - isDragging.current = true; - dragOrigin.current = { mouseX: e.clientX, mouseY: e.clientY, posX: modalPos.x, posY: modalPos.y }; - }} - className="flex items-center justify-between px-5 py-4 flex-shrink-0 select-none border-b owt-border cursor-grab" + className="flex shrink-0 select-none items-center justify-between gap-3 border-b owt-border px-3 py-3 sm:px-5 sm:py-4" > -

+

{t?.('common.selectTitle', { label, defaultValue: `Select ${label}` })}

-
+
-
+
{searchResults.length === 0 ? (

{searchText @@ -671,11 +674,7 @@ export const RegisterLookupWidget = ({ config }: { config: BaseWidgetConfig }) = )}

-
+
{totalCount !== null && ( currentPage < totalPages && runSearch(searchText, currentPage + 1)} /> )} - +
+ +
- +
, + document.body, )}
); diff --git a/ui/ui-widgets/src/widgets/TableWidget.tsx b/ui/ui-widgets/src/widgets/TableWidget.tsx index c8683a9d..25be62cd 100644 --- a/ui/ui-widgets/src/widgets/TableWidget.tsx +++ b/ui/ui-widgets/src/widgets/TableWidget.tsx @@ -1107,27 +1107,29 @@ export const TableWidget = ({ config }: TableWidgetProps) => { const tableWidgetId = `table-widget-${widgetConfig['widget-id']}`; const columnSpan = widgetConfig['widget-column-span'] || 2; - const minWidth = columnSpan * 200; // Each column is 200px const actionsHeaderLabel = toTitleCase(t?.('common.actions') || 'Actions'); return ( <>
{confirmationState?.show && ( -
-
-

+
+
+

{t?.('table.confirm') || 'Confirm Action'}

-

+

{confirmationState.message}

-
+
)} {operations.add && !isReadonly && isEnabled && (isSectionEditMode || !isAnyRowEditing) && ( -
+
)} -
+