@openg2p/registry-widgets 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/SectionRenderer.d.ts +1 -0
- package/dist/components/SectionRenderer.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +151 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +151 -11
- package/dist/index.js.map +1 -1
- package/dist/theme/index.d.ts +35 -9
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/widgets/DisplayWidget.d.ts.map +1 -1
- package/dist/widgets/HeaderSectionWidget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3516,6 +3516,39 @@ const sectionValidate = (section, currentSchemaData, dispatch) => {
|
|
|
3516
3516
|
return isValid;
|
|
3517
3517
|
};
|
|
3518
3518
|
|
|
3519
|
+
/** Root class on readonly label/value rows; SectionRenderer scopes overflow/ellipsis rules here. */
|
|
3520
|
+
const READONLY_VALUE_ROW_ROOT_CLASSES = [
|
|
3521
|
+
'TextDisplayWidget',
|
|
3522
|
+
'TextAreaDisplayWidget',
|
|
3523
|
+
'SelectDisplayWidget',
|
|
3524
|
+
'PhoneDisplayWidget',
|
|
3525
|
+
'NumberDisplayWidget',
|
|
3526
|
+
'CurrencyDisplayWidget',
|
|
3527
|
+
'RadioDisplayWidget',
|
|
3528
|
+
'DateDisplayWidget',
|
|
3529
|
+
'DateTimeDisplayWidget',
|
|
3530
|
+
'CheckboxDisplayWidget',
|
|
3531
|
+
'BooleanDisplayWidget',
|
|
3532
|
+
'FileDisplayWidget',
|
|
3533
|
+
'DisplayFieldWidget',
|
|
3534
|
+
];
|
|
3535
|
+
/** Rows whose value is one line in .flex-1 > .text-gray-900 (ellipsis; full string via title on the element). */
|
|
3536
|
+
const READONLY_SINGLE_LINE_VALUE_ROW_CLASSES = [
|
|
3537
|
+
'TextDisplayWidget',
|
|
3538
|
+
'SelectDisplayWidget',
|
|
3539
|
+
'PhoneDisplayWidget',
|
|
3540
|
+
'NumberDisplayWidget',
|
|
3541
|
+
'CurrencyDisplayWidget',
|
|
3542
|
+
'RadioDisplayWidget',
|
|
3543
|
+
'DateDisplayWidget',
|
|
3544
|
+
'DateTimeDisplayWidget',
|
|
3545
|
+
'CheckboxDisplayWidget',
|
|
3546
|
+
'BooleanDisplayWidget',
|
|
3547
|
+
'DisplayFieldWidget',
|
|
3548
|
+
];
|
|
3549
|
+
function scopedClassSelectors(sectionClassId, classNames) {
|
|
3550
|
+
return classNames.map((c) => `.${sectionClassId} .${c}`).join(',\n ');
|
|
3551
|
+
}
|
|
3519
3552
|
/**
|
|
3520
3553
|
* Renders a section with its panels
|
|
3521
3554
|
*
|
|
@@ -3580,6 +3613,9 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3580
3613
|
const sectionId = sectionToRender['section-id'];
|
|
3581
3614
|
const gridId = `section-panels-${sectionId}`;
|
|
3582
3615
|
const sectionClassId = `section-${sectionId}`;
|
|
3616
|
+
const readonlyValueRowRootsCss = React.useMemo(() => scopedClassSelectors(sectionClassId, READONLY_VALUE_ROW_ROOT_CLASSES), [sectionClassId]);
|
|
3617
|
+
const readonlyValueRowFlex1Css = React.useMemo(() => READONLY_VALUE_ROW_ROOT_CLASSES.map((c) => `.${sectionClassId} .${c} > .flex-1`).join(',\n '), [sectionClassId]);
|
|
3618
|
+
const readonlySingleLineValueTextCss = React.useMemo(() => READONLY_SINGLE_LINE_VALUE_ROW_CLASSES.map((c) => `.${sectionClassId} .${c} > .flex-1 > .text-gray-900`).join(',\n '), [sectionClassId]);
|
|
3583
3619
|
// IntakeForm mode: accordion expand/collapse state (supports toggle)
|
|
3584
3620
|
const [standaloneExpanded, setStandaloneExpanded] = React.useState(true); // For sectionIndex undefined (standalone use)
|
|
3585
3621
|
const isExpandedFromContainer = typeof sectionIndex === 'number' && expandedSectionIndex === sectionIndex;
|
|
@@ -4061,12 +4097,24 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4061
4097
|
});
|
|
4062
4098
|
}
|
|
4063
4099
|
if (JSON.stringify(oldSchemaData) !== JSON.stringify(newSchemaData)) {
|
|
4100
|
+
let profileImage = null;
|
|
4101
|
+
for (const record of newSchemaData) {
|
|
4102
|
+
if (typeof record === 'object' && record !== null) {
|
|
4103
|
+
for (const [key, value] of Object.entries(record)) {
|
|
4104
|
+
if (value instanceof File) {
|
|
4105
|
+
profileImage = value;
|
|
4106
|
+
record[key] = '';
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4064
4111
|
try {
|
|
4065
4112
|
const sectionchanges = {
|
|
4066
4113
|
section_id: dbSectionId ?? originalSection['section-id'],
|
|
4067
4114
|
section_register_id: sectionRegisterId,
|
|
4068
4115
|
records: [...newSchemaData],
|
|
4069
|
-
files: [...sectionFiles]
|
|
4116
|
+
files: [...sectionFiles],
|
|
4117
|
+
...(profileImage ? { image: profileImage } : {}),
|
|
4070
4118
|
};
|
|
4071
4119
|
await onSectionSave(sectionchanges);
|
|
4072
4120
|
}
|
|
@@ -4109,12 +4157,24 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4109
4157
|
});
|
|
4110
4158
|
}
|
|
4111
4159
|
if (JSON.stringify(oldSchemaData) !== JSON.stringify(newSchemaData)) {
|
|
4160
|
+
let profileImage = null;
|
|
4161
|
+
for (const record of newSchemaData) {
|
|
4162
|
+
if (typeof record === 'object' && record !== null) {
|
|
4163
|
+
for (const [key, value] of Object.entries(record)) {
|
|
4164
|
+
if (value instanceof File) {
|
|
4165
|
+
profileImage = value;
|
|
4166
|
+
record[key] = '';
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4112
4171
|
try {
|
|
4113
4172
|
await onSectionSave({
|
|
4114
4173
|
section_id: dbSectionId ?? originalSection['section-id'],
|
|
4115
4174
|
section_register_id: sectionRegisterId,
|
|
4116
4175
|
records: [...newSchemaData],
|
|
4117
4176
|
files: [...sectionFiles],
|
|
4177
|
+
...(profileImage ? { image: profileImage } : {}),
|
|
4118
4178
|
});
|
|
4119
4179
|
}
|
|
4120
4180
|
catch (error) {
|
|
@@ -4185,20 +4245,27 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4185
4245
|
white-space: nowrap !important;
|
|
4186
4246
|
}
|
|
4187
4247
|
/* Readonly: prevent flex row from overflowing panel */
|
|
4188
|
-
|
|
4248
|
+
${readonlyValueRowRootsCss} {
|
|
4189
4249
|
min-width: 0 !important;
|
|
4190
4250
|
overflow: hidden !important;
|
|
4191
4251
|
}
|
|
4192
|
-
|
|
4252
|
+
${readonlyValueRowFlex1Css} {
|
|
4193
4253
|
min-width: 0 !important;
|
|
4194
4254
|
overflow: hidden !important;
|
|
4195
4255
|
}
|
|
4196
|
-
/* Readonly value
|
|
4197
|
-
|
|
4256
|
+
/* Readonly value: single-line ellipsis; full value via title on the value node */
|
|
4257
|
+
${readonlySingleLineValueTextCss} {
|
|
4198
4258
|
overflow: hidden;
|
|
4199
4259
|
text-overflow: ellipsis;
|
|
4200
4260
|
white-space: nowrap;
|
|
4201
4261
|
}
|
|
4262
|
+
/* Readonly textarea: break unbroken long tokens; title on pre keeps full text on hover */
|
|
4263
|
+
.${sectionClassId} .TextAreaDisplayWidget > .flex-1 > pre {
|
|
4264
|
+
min-width: 0;
|
|
4265
|
+
max-width: 100%;
|
|
4266
|
+
overflow-wrap: anywhere;
|
|
4267
|
+
word-break: break-word;
|
|
4268
|
+
}
|
|
4202
4269
|
|
|
4203
4270
|
/* Only apply fixed height when in edit mode */
|
|
4204
4271
|
.${sectionClassId}[data-edit-mode="true"] {
|
|
@@ -8088,10 +8155,10 @@ const DisplayWidget = ({ config }) => {
|
|
|
8088
8155
|
const label = translateConfig(widgetConfig['widget-label']);
|
|
8089
8156
|
// If no label, render as paragraph text
|
|
8090
8157
|
if (!label || label.trim() === '') {
|
|
8091
|
-
return (jsxRuntimeExports.jsx("div", { className: "mb-3 text-base text-gray-700", title: String(displayValue ?? ''), children: displayValue }));
|
|
8158
|
+
return (jsxRuntimeExports.jsx("div", { className: "DisplayFieldWidget mb-3 min-w-0 w-full overflow-hidden text-ellipsis whitespace-nowrap text-base text-gray-700", title: String(displayValue ?? ''), children: displayValue }));
|
|
8092
8159
|
}
|
|
8093
|
-
// With label, render as key-value pair
|
|
8094
|
-
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 })] }));
|
|
8160
|
+
// With label, render as key-value pair (structure matches other readonly widgets for SectionRenderer ellipsis)
|
|
8161
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] DisplayFieldWidget flex flex-col sm:flex-row sm:items-start", children: [jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] }), jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntimeExports.jsx("div", { className: "text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue }) })] }));
|
|
8095
8162
|
};
|
|
8096
8163
|
|
|
8097
8164
|
const TableCellSelect = ({ config, value, onValueChange }) => {
|
|
@@ -9059,7 +9126,18 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9059
9126
|
result = searchIn(schemaData);
|
|
9060
9127
|
return result;
|
|
9061
9128
|
}, [paths, values, schemaData]);
|
|
9062
|
-
const
|
|
9129
|
+
const imageVal = findValue('image');
|
|
9130
|
+
const imageUrlVal = findValue('imageUrl');
|
|
9131
|
+
const [previewUrl, setPreviewUrl] = React.useState(null);
|
|
9132
|
+
React.useEffect(() => {
|
|
9133
|
+
if (imageVal instanceof File) {
|
|
9134
|
+
const url = URL.createObjectURL(imageVal);
|
|
9135
|
+
setPreviewUrl(url);
|
|
9136
|
+
return () => URL.revokeObjectURL(url);
|
|
9137
|
+
}
|
|
9138
|
+
setPreviewUrl(null);
|
|
9139
|
+
}, [imageVal]);
|
|
9140
|
+
const displayImageUrl = previewUrl || (typeof imageUrlVal === 'string' && imageUrlVal ? imageUrlVal : null);
|
|
9063
9141
|
const displayName = findValue('name') || '';
|
|
9064
9142
|
const functionalId = findValue('functionalId') || '';
|
|
9065
9143
|
const statusValue = findValue('status') || '';
|
|
@@ -9092,6 +9170,18 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9092
9170
|
return opt ? opt.label : String(statusValue);
|
|
9093
9171
|
}, [statusValue, statusOptions]);
|
|
9094
9172
|
const statusColor = statusColors[String(statusValue).toLowerCase()] || '#6B7280';
|
|
9173
|
+
// ── Image edit helpers ───────────────────────────────────────
|
|
9174
|
+
const fileInputRef = React.useRef(null);
|
|
9175
|
+
const handleImageUpload = React.useCallback((e) => {
|
|
9176
|
+
const file = e.target.files?.[0];
|
|
9177
|
+
if (!file)
|
|
9178
|
+
return;
|
|
9179
|
+
updateFieldValue('image', file);
|
|
9180
|
+
e.target.value = '';
|
|
9181
|
+
}, [updateFieldValue]);
|
|
9182
|
+
const handleImageDelete = React.useCallback(() => {
|
|
9183
|
+
updateFieldValue('image', '');
|
|
9184
|
+
}, [updateFieldValue]);
|
|
9095
9185
|
// ── Scoped class for CSS isolation ────────────────────────────
|
|
9096
9186
|
const cls = `header-section-widget-${widgetConfig['widget-id']}`;
|
|
9097
9187
|
// ── RENDER ────────────────────────────────────────────────────
|
|
@@ -9152,6 +9242,56 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9152
9242
|
border-radius: 8px;
|
|
9153
9243
|
}
|
|
9154
9244
|
|
|
9245
|
+
.${cls} .hdr-avatar-wrapper {
|
|
9246
|
+
position: relative;
|
|
9247
|
+
width: ${imageSize}px;
|
|
9248
|
+
height: ${imageSize}px;
|
|
9249
|
+
flex-shrink: 0;
|
|
9250
|
+
}
|
|
9251
|
+
|
|
9252
|
+
.${cls} .hdr-avatar-overlay {
|
|
9253
|
+
position: absolute;
|
|
9254
|
+
inset: 0;
|
|
9255
|
+
border-radius: 8px;
|
|
9256
|
+
background: rgba(0, 0, 0, 0.55);
|
|
9257
|
+
display: flex;
|
|
9258
|
+
flex-direction: column;
|
|
9259
|
+
align-items: center;
|
|
9260
|
+
justify-content: center;
|
|
9261
|
+
gap: 6px;
|
|
9262
|
+
opacity: 0;
|
|
9263
|
+
transition: opacity 0.2s;
|
|
9264
|
+
}
|
|
9265
|
+
|
|
9266
|
+
.${cls} .hdr-avatar-wrapper:hover .hdr-avatar-overlay {
|
|
9267
|
+
opacity: 1;
|
|
9268
|
+
}
|
|
9269
|
+
|
|
9270
|
+
.${cls} .hdr-avatar-action {
|
|
9271
|
+
display: flex;
|
|
9272
|
+
align-items: center;
|
|
9273
|
+
gap: 5px;
|
|
9274
|
+
padding: 5px 14px;
|
|
9275
|
+
border: none;
|
|
9276
|
+
border-radius: 4px;
|
|
9277
|
+
background: rgba(255, 255, 255, 0.92);
|
|
9278
|
+
color: #374151;
|
|
9279
|
+
font-size: 0.7rem;
|
|
9280
|
+
font-weight: 500;
|
|
9281
|
+
cursor: pointer;
|
|
9282
|
+
font-family: Roboto, sans-serif;
|
|
9283
|
+
transition: background 0.15s;
|
|
9284
|
+
white-space: nowrap;
|
|
9285
|
+
}
|
|
9286
|
+
|
|
9287
|
+
.${cls} .hdr-avatar-action:hover {
|
|
9288
|
+
background: #fff;
|
|
9289
|
+
}
|
|
9290
|
+
|
|
9291
|
+
.${cls} .hdr-avatar-action--delete {
|
|
9292
|
+
color: #DC2626;
|
|
9293
|
+
}
|
|
9294
|
+
|
|
9155
9295
|
.${cls} .hdr-info {
|
|
9156
9296
|
display: flex;
|
|
9157
9297
|
flex-direction: column;
|
|
@@ -9256,13 +9396,13 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9256
9396
|
min-width: 0;
|
|
9257
9397
|
}
|
|
9258
9398
|
}
|
|
9259
|
-
` }), jsxRuntimeExports.jsxs("div", { className: cls, children: [jsxRuntimeExports.jsxs("div", { className: "hdr-left", children: [jsxRuntimeExports.jsxs("div", { children: [
|
|
9399
|
+
` }), jsxRuntimeExports.jsxs("div", { className: cls, children: [jsxRuntimeExports.jsxs("div", { className: "hdr-left", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-wrapper", children: [displayImageUrl ? (jsxRuntimeExports.jsx("img", { src: displayImageUrl, alt: displayName || 'Profile', className: "hdr-avatar", onError: (e) => {
|
|
9260
9400
|
e.target.style.display = 'none';
|
|
9261
9401
|
const placeholder = e.target
|
|
9262
9402
|
.parentElement?.querySelector('.hdr-avatar-placeholder');
|
|
9263
9403
|
if (placeholder)
|
|
9264
9404
|
placeholder.style.display = 'flex';
|
|
9265
|
-
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display:
|
|
9405
|
+
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display: displayImageUrl ? 'none' : 'flex' }, children: jsxRuntimeExports.jsx("img", { src: img$f, alt: "Profile Placeholder" }) }), !isReadonly && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-overlay", children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action", onClick: () => fileInputRef.current?.click(), children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), jsxRuntimeExports.jsx("polyline", { points: "17 8 12 3 7 8" }), jsxRuntimeExports.jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })] }), "Upload"] }), jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action hdr-avatar-action--delete", onClick: handleImageDelete, children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("polyline", { points: "3 6 5 6 21 6" }), jsxRuntimeExports.jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })] }), "Delete"] })] }), jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: 'none' }, onChange: handleImageUpload })] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-info", children: [displayName && jsxRuntimeExports.jsx("div", { className: "hdr-name", children: displayName }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('functionalId'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: functionalId || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx("span", { className: "hdr-field-label", children: getLabel('status') }), isReadonly ? (statusLabel ? (jsxRuntimeExports.jsx("span", { className: "hdr-status-badge", style: { backgroundColor: statusColor }, children: statusLabel })) : (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: "-" }))) : (jsxRuntimeExports.jsxs("select", { className: "hdr-select", value: statusValue, onChange: (e) => updateFieldValue('status', e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: getLabel('select') }), statusOptions.map((opt) => (jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, opt.value)))] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('statusReason'), " :"] }), isReadonly ? (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: statusReason || '-' })) : (jsxRuntimeExports.jsx("input", { type: "text", className: "hdr-input", value: statusReason, placeholder: getLabel('enterReason'), onChange: (e) => updateFieldValue('statusReason', e.target.value) }))] })] })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-right", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdAt || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedAt || '-' })] })] })] })] }));
|
|
9266
9406
|
};
|
|
9267
9407
|
|
|
9268
9408
|
/**
|