@openg2p/registry-widgets 1.1.0-dev.0 → 1.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -25
- package/dist/index.d.ts +3 -16
- package/dist/index.esm.js +127 -168
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +127 -168
- package/dist/index.js.map +1 -1
- package/dist/widgets/ScoresDisplayWidget.d.ts +11 -17
- package/dist/widgets/ScoresDisplayWidget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9527,6 +9527,13 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
9527
9527
|
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display: imageUrl ? 'none' : 'flex' }, children: jsxRuntimeExports.jsx("img", { src: img$f, alt: "Profile Placeholder" }) })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-info", children: [displayName && jsxRuntimeExports.jsx("div", { className: "hdr-name", children: displayName }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx(Dot, { color: "#9CA3AF" }), jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('functionalId'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: functionalId || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx(Dot, { color: isReadonly ? statusColor : '#F59E0B' }), jsxRuntimeExports.jsx("span", { className: "hdr-field-label", children: getLabel('status') }), isReadonly ? (statusLabel ? (jsxRuntimeExports.jsx("span", { className: "hdr-status-badge", style: { backgroundColor: statusColor }, children: statusLabel })) : (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: "-" }))) : (jsxRuntimeExports.jsxs("select", { className: "hdr-select", value: statusValue, onChange: (e) => updateFieldValue('status', e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: getLabel('select') }), statusOptions.map((opt) => (jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, opt.value)))] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx(Dot, { color: isReadonly ? '#9CA3AF' : '#F59E0B' }), jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('statusReason'), " :"] }), isReadonly ? (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: statusReason || '-' })) : (jsxRuntimeExports.jsx("input", { type: "text", className: "hdr-input", value: statusReason, placeholder: getLabel('enterReason'), onChange: (e) => updateFieldValue('statusReason', e.target.value) }))] })] })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-right", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdAt || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedAt || '-' })] })] })] })] }));
|
|
9528
9528
|
};
|
|
9529
9529
|
|
|
9530
|
+
function getValueByPathOrKey(obj, path) {
|
|
9531
|
+
if (!obj || !path)
|
|
9532
|
+
return undefined;
|
|
9533
|
+
if (Object.prototype.hasOwnProperty.call(obj, path))
|
|
9534
|
+
return obj[path];
|
|
9535
|
+
return getValueByPath(obj, path);
|
|
9536
|
+
}
|
|
9530
9537
|
function tryFormatDateTime(value) {
|
|
9531
9538
|
if (typeof value !== 'string' || !value)
|
|
9532
9539
|
return value ? String(value) : '-';
|
|
@@ -9546,157 +9553,80 @@ function tryFormatDateTime(value) {
|
|
|
9546
9553
|
return value;
|
|
9547
9554
|
}
|
|
9548
9555
|
}
|
|
9549
|
-
function
|
|
9550
|
-
if (!scores || scores.length === 0)
|
|
9551
|
-
return null;
|
|
9556
|
+
function sortScores(scores) {
|
|
9552
9557
|
const withTime = scores
|
|
9553
|
-
.map((s) => {
|
|
9558
|
+
.map((s, idx) => {
|
|
9554
9559
|
const t = typeof s?.computed_at === 'string' ? new Date(s.computed_at).getTime() : NaN;
|
|
9555
|
-
return { s, t };
|
|
9560
|
+
return { s, t, idx };
|
|
9556
9561
|
})
|
|
9557
|
-
.
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
+
.sort((a, b) => {
|
|
9563
|
+
const aHas = !Number.isNaN(a.t);
|
|
9564
|
+
const bHas = !Number.isNaN(b.t);
|
|
9565
|
+
if (aHas && bHas)
|
|
9566
|
+
return b.t - a.t;
|
|
9567
|
+
if (aHas)
|
|
9568
|
+
return -1;
|
|
9569
|
+
if (bHas)
|
|
9570
|
+
return 1;
|
|
9571
|
+
return a.idx - b.idx;
|
|
9572
|
+
});
|
|
9573
|
+
return withTime.map((x) => x.s);
|
|
9562
9574
|
}
|
|
9563
9575
|
/**
|
|
9564
|
-
* Scores Display Widget - full-width, view-only widget
|
|
9576
|
+
* Scores Display Widget - full-width, view-only widget (list)
|
|
9565
9577
|
*
|
|
9566
9578
|
* Expected config (reference):
|
|
9567
9579
|
* {
|
|
9568
9580
|
* "widget": "scores-display",
|
|
9569
9581
|
* "widget-type": "group",
|
|
9570
9582
|
* "widget-id": "record-scores",
|
|
9571
|
-
* "widget-data-
|
|
9572
|
-
* "type": "api",
|
|
9573
|
-
* "service": "staff-portal-api",
|
|
9574
|
-
* "endpoint": "get_scores",
|
|
9575
|
-
* "method": "POST",
|
|
9576
|
-
* "params": { "internal_record_id_path": "internal_record_id" }
|
|
9577
|
-
* }
|
|
9583
|
+
* "widget-data-path": "scores"
|
|
9578
9584
|
* }
|
|
9579
|
-
*
|
|
9580
|
-
* The host's `dataSourceRequestHandler` is invoked with:
|
|
9581
|
-
* - service: config.widget-data-source.service
|
|
9582
|
-
* - endpoint: config.widget-data-source.endpoint
|
|
9583
|
-
* - method: config.widget-data-source.method (default POST)
|
|
9584
|
-
* - params: { internal_record_id: <resolved from internal_record_id_path> }
|
|
9585
9585
|
*/
|
|
9586
|
-
const ScoresDisplayWidget = ({ config,
|
|
9587
|
-
const {
|
|
9588
|
-
const
|
|
9589
|
-
const schemaData = propSchemaData || ctxSchemaData || {};
|
|
9586
|
+
const ScoresDisplayWidget = ({ config, schemaData: propSchemaData, }) => {
|
|
9587
|
+
const { schemaData: ctxSchemaData } = useWidgetContext();
|
|
9588
|
+
const schemaData = (propSchemaData || ctxSchemaData || {});
|
|
9590
9589
|
const values = reactRedux.useSelector((state) => state.widget.values);
|
|
9591
|
-
const
|
|
9592
|
-
const
|
|
9593
|
-
|
|
9594
|
-
const internalIdPath = React.useMemo(() => {
|
|
9595
|
-
if (!apiDs)
|
|
9596
|
-
return undefined;
|
|
9597
|
-
const p = apiDs.params || {};
|
|
9598
|
-
const fromParams = p.internal_record_id_path || p.internalRecordIdPath;
|
|
9599
|
-
const fromConfig = typeof config.internal_record_id_path === 'string'
|
|
9600
|
-
? config.internal_record_id_path
|
|
9601
|
-
: undefined;
|
|
9602
|
-
return fromParams || fromConfig;
|
|
9603
|
-
}, [apiDs, config]);
|
|
9604
|
-
const internalRecordId = React.useMemo(() => {
|
|
9605
|
-
if (!internalIdPath)
|
|
9590
|
+
const dataPath = config['widget-data-path'];
|
|
9591
|
+
const rawScores = React.useMemo(() => {
|
|
9592
|
+
if (!dataPath || typeof dataPath !== 'string')
|
|
9606
9593
|
return undefined;
|
|
9607
|
-
const
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
|
|
9612
|
-
|
|
9613
|
-
|
|
9594
|
+
const valuesObj = values;
|
|
9595
|
+
const tryResolve = (path) => {
|
|
9596
|
+
const fromValues = getValueByPathOrKey(valuesObj, path);
|
|
9597
|
+
if (fromValues !== undefined)
|
|
9598
|
+
return fromValues;
|
|
9599
|
+
return getValueByPathOrKey(schemaData, path);
|
|
9600
|
+
};
|
|
9601
|
+
// 1) Try exact path (works when schema/store is already namespaced)
|
|
9602
|
+
const direct = tryResolve(dataPath);
|
|
9603
|
+
if (direct !== undefined)
|
|
9604
|
+
return direct;
|
|
9605
|
+
// 2) If section/widget config has been namespaced (e.g. "rv-section-0.scores"),
|
|
9606
|
+
// fall back to the original path ("scores") so examples still work even when
|
|
9607
|
+
// schemaData/store are not namespaced.
|
|
9608
|
+
if (dataPath.includes('.')) {
|
|
9609
|
+
const unNamespaced = dataPath.split('.').slice(1).join('.');
|
|
9610
|
+
const fallback = tryResolve(unNamespaced);
|
|
9611
|
+
if (fallback !== undefined)
|
|
9612
|
+
return fallback;
|
|
9614
9613
|
}
|
|
9615
9614
|
return undefined;
|
|
9616
|
-
}, [
|
|
9617
|
-
const
|
|
9618
|
-
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
setResponse(null);
|
|
9631
|
-
return;
|
|
9632
|
-
}
|
|
9633
|
-
const service = apiDs.service;
|
|
9634
|
-
const endpoint = apiDs.endpoint;
|
|
9635
|
-
const method = apiDs.method || 'POST';
|
|
9636
|
-
if (!service || !endpoint) {
|
|
9637
|
-
setError('Scores widget API data source is missing service/endpoint.');
|
|
9638
|
-
setResponse(null);
|
|
9639
|
-
return;
|
|
9640
|
-
}
|
|
9641
|
-
if (!internalRecordId) {
|
|
9642
|
-
setError(null);
|
|
9643
|
-
setResponse(null);
|
|
9644
|
-
return;
|
|
9645
|
-
}
|
|
9646
|
-
try {
|
|
9647
|
-
setLoading(true);
|
|
9648
|
-
setError(null);
|
|
9649
|
-
const rawParams = apiDs.params || {};
|
|
9650
|
-
// Never pass the path helper through to the API.
|
|
9651
|
-
const { internal_record_id_path, internalRecordIdPath, ...rest } = rawParams;
|
|
9652
|
-
void internal_record_id_path;
|
|
9653
|
-
void internalRecordIdPath;
|
|
9654
|
-
const params = {
|
|
9655
|
-
...rest,
|
|
9656
|
-
internal_record_id: internalRecordId,
|
|
9657
|
-
};
|
|
9658
|
-
const res = await handler(service, endpoint, method, params, {
|
|
9659
|
-
headers: apiDs.headers,
|
|
9660
|
-
});
|
|
9661
|
-
if (cancelled)
|
|
9662
|
-
return;
|
|
9663
|
-
// Accept either direct payload or OpenG2P wrapper objects.
|
|
9664
|
-
const envelope = res && typeof res === 'object' ? res : null;
|
|
9665
|
-
const payload = envelope?.response_body?.response_payload ?? envelope?.data ?? res;
|
|
9666
|
-
if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
|
|
9667
|
-
setResponse(payload);
|
|
9668
|
-
}
|
|
9669
|
-
else {
|
|
9670
|
-
setResponse({ scores: Array.isArray(payload) ? payload : [] });
|
|
9671
|
-
}
|
|
9672
|
-
}
|
|
9673
|
-
catch (e) {
|
|
9674
|
-
if (cancelled)
|
|
9675
|
-
return;
|
|
9676
|
-
const maybeErr = e;
|
|
9677
|
-
const msg = maybeErr && typeof maybeErr === 'object' && typeof maybeErr.message === 'string'
|
|
9678
|
-
? maybeErr.message
|
|
9679
|
-
: 'Failed to load scores.';
|
|
9680
|
-
setError(msg);
|
|
9681
|
-
setResponse(null);
|
|
9682
|
-
}
|
|
9683
|
-
finally {
|
|
9684
|
-
if (!cancelled)
|
|
9685
|
-
setLoading(false);
|
|
9686
|
-
}
|
|
9687
|
-
};
|
|
9688
|
-
load();
|
|
9689
|
-
return () => {
|
|
9690
|
-
cancelled = true;
|
|
9691
|
-
};
|
|
9692
|
-
}, [apiDs, handler, internalRecordId]);
|
|
9693
|
-
const latest = React.useMemo(() => pickLatestScore(response?.scores), [response]);
|
|
9615
|
+
}, [dataPath, values, schemaData]);
|
|
9616
|
+
const scores = React.useMemo(() => {
|
|
9617
|
+
if (!rawScores)
|
|
9618
|
+
return [];
|
|
9619
|
+
if (Array.isArray(rawScores))
|
|
9620
|
+
return rawScores;
|
|
9621
|
+
if (typeof rawScores === 'object') {
|
|
9622
|
+
const maybe = rawScores.scores;
|
|
9623
|
+
if (Array.isArray(maybe))
|
|
9624
|
+
return maybe;
|
|
9625
|
+
}
|
|
9626
|
+
return [];
|
|
9627
|
+
}, [rawScores]);
|
|
9628
|
+
const sortedScores = React.useMemo(() => sortScores(scores), [scores]);
|
|
9694
9629
|
const cls = `scores-display-widget-${config['widget-id']}`;
|
|
9695
|
-
const scoreType = latest?.score_type ? String(latest.score_type) : '-';
|
|
9696
|
-
const scoreValue = latest?.computed_score !== undefined && latest?.computed_score !== null && String(latest.computed_score) !== ''
|
|
9697
|
-
? String(latest.computed_score)
|
|
9698
|
-
: '-';
|
|
9699
|
-
const computedAt = tryFormatDateTime(latest?.computed_at);
|
|
9700
9630
|
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { children: `
|
|
9701
9631
|
.${cls} {
|
|
9702
9632
|
width: 100%;
|
|
@@ -9713,66 +9643,95 @@ const ScoresDisplayWidget = ({ config, dataSourceRequestHandler: propHandler, sc
|
|
|
9713
9643
|
font-weight: 400;
|
|
9714
9644
|
}
|
|
9715
9645
|
|
|
9716
|
-
.${cls} .scores-
|
|
9646
|
+
.${cls} .scores-grid {
|
|
9717
9647
|
width: 100%;
|
|
9718
|
-
border: none;
|
|
9719
|
-
border-radius: 0;
|
|
9720
|
-
background: transparent;
|
|
9721
|
-
padding: 0;
|
|
9722
9648
|
display: grid;
|
|
9723
|
-
grid-template-columns:
|
|
9649
|
+
grid-template-columns: repeat(3, minmax(220px, 1fr));
|
|
9724
9650
|
gap: 16px;
|
|
9725
|
-
align-items: center;
|
|
9726
9651
|
}
|
|
9727
9652
|
|
|
9728
|
-
.${cls} .scores-
|
|
9729
|
-
|
|
9653
|
+
.${cls} .scores-card {
|
|
9654
|
+
border: 1px solid var(--owt-color-border-light, #E4E4E4);
|
|
9655
|
+
border-radius: 10px;
|
|
9656
|
+
background: var(--owt-color-bg, #FFFFFF);
|
|
9657
|
+
padding: 14px 14px;
|
|
9730
9658
|
display: flex;
|
|
9731
9659
|
flex-direction: column;
|
|
9732
|
-
gap:
|
|
9660
|
+
gap: 10px;
|
|
9661
|
+
min-width: 0;
|
|
9662
|
+
box-shadow: 0 1px 2px rgba(1, 22, 39, 0.06), 0 6px 16px rgba(1, 22, 39, 0.06);
|
|
9733
9663
|
}
|
|
9734
9664
|
|
|
9735
|
-
.${cls} .scores-
|
|
9736
|
-
font-size:
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
9665
|
+
.${cls} .scores-type {
|
|
9666
|
+
font-size: 16px;
|
|
9667
|
+
font-weight: 800;
|
|
9668
|
+
color: var(--owt-color-primary-dark, #F07B1A);
|
|
9669
|
+
line-height: 1.2;
|
|
9670
|
+
word-break: break-word;
|
|
9741
9671
|
}
|
|
9742
9672
|
|
|
9743
9673
|
.${cls} .scores-value {
|
|
9744
|
-
font-size:
|
|
9745
|
-
font-weight:
|
|
9674
|
+
font-size: 34px;
|
|
9675
|
+
font-weight: 800;
|
|
9746
9676
|
color: var(--owt-color-text, #011627);
|
|
9747
|
-
line-height: 1.
|
|
9748
|
-
|
|
9677
|
+
line-height: 1.05;
|
|
9678
|
+
letter-spacing: -0.25px;
|
|
9749
9679
|
}
|
|
9750
9680
|
|
|
9751
|
-
.${cls} .scores-
|
|
9752
|
-
|
|
9753
|
-
|
|
9681
|
+
.${cls} .scores-separator {
|
|
9682
|
+
height: 1px;
|
|
9683
|
+
width: 100%;
|
|
9684
|
+
background-color: var(--owt-color-border-light, #E4E4E4);
|
|
9685
|
+
border: none;
|
|
9686
|
+
margin: 2px 0;
|
|
9754
9687
|
}
|
|
9755
9688
|
|
|
9756
|
-
.${cls} .scores-value-
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9689
|
+
.${cls} .scores-value .scores-muted {
|
|
9690
|
+
font-size: 18px;
|
|
9691
|
+
font-weight: 600;
|
|
9692
|
+
color: var(--owt-color-text-muted, #727474);
|
|
9693
|
+
margin-left: 6px;
|
|
9761
9694
|
}
|
|
9762
9695
|
|
|
9763
|
-
.${cls} .scores-
|
|
9696
|
+
.${cls} .scores-meta {
|
|
9697
|
+
display: flex;
|
|
9698
|
+
flex-direction: column;
|
|
9699
|
+
gap: 4px;
|
|
9700
|
+
}
|
|
9764
9701
|
|
|
9765
|
-
.${cls} .scores-
|
|
9766
|
-
|
|
9767
|
-
|
|
9702
|
+
.${cls} .scores-meta-line {
|
|
9703
|
+
font-size: 13px;
|
|
9704
|
+
color: var(--owt-color-text-muted, #727474);
|
|
9705
|
+
font-weight: 500;
|
|
9768
9706
|
}
|
|
9769
9707
|
|
|
9770
|
-
|
|
9771
|
-
|
|
9708
|
+
.${cls} .scores-meta-line strong {
|
|
9709
|
+
color: var(--owt-color-text, #011627);
|
|
9710
|
+
font-weight: 700;
|
|
9711
|
+
}
|
|
9712
|
+
|
|
9713
|
+
@media (max-width: 1024px) {
|
|
9714
|
+
.${cls} .scores-grid {
|
|
9715
|
+
grid-template-columns: repeat(2, minmax(220px, 1fr));
|
|
9716
|
+
}
|
|
9717
|
+
}
|
|
9718
|
+
|
|
9719
|
+
@media (max-width: 640px) {
|
|
9720
|
+
.${cls} .scores-grid {
|
|
9772
9721
|
grid-template-columns: 1fr;
|
|
9773
9722
|
}
|
|
9774
9723
|
}
|
|
9775
|
-
` }), jsxRuntimeExports.jsx("div", { className: cls, children:
|
|
9724
|
+
` }), jsxRuntimeExports.jsx("div", { className: cls, children: sortedScores.length === 0 ? (jsxRuntimeExports.jsx("div", { className: "scores-subtle", children: "No scores available." })) : (jsxRuntimeExports.jsx("div", { className: "scores-grid", children: sortedScores.map((s, idx) => {
|
|
9725
|
+
const scoreType = s?.score_type ? String(s.score_type) : '-';
|
|
9726
|
+
const scoreValue = s?.computed_score !== undefined &&
|
|
9727
|
+
s?.computed_score !== null &&
|
|
9728
|
+
String(s.computed_score) !== ''
|
|
9729
|
+
? String(s.computed_score)
|
|
9730
|
+
: '-';
|
|
9731
|
+
const computedAt = tryFormatDateTime(s?.computed_at);
|
|
9732
|
+
const key = `${scoreType}-${String(s?.computed_at || '')}-${idx}`;
|
|
9733
|
+
return (jsxRuntimeExports.jsxs("div", { className: "scores-card", "aria-live": idx === 0 ? 'polite' : undefined, children: [jsxRuntimeExports.jsx("div", { className: "scores-type", children: scoreType }), jsxRuntimeExports.jsx("div", { className: "scores-value", children: scoreValue }), jsxRuntimeExports.jsx("hr", { className: "scores-separator" }), jsxRuntimeExports.jsx("div", { className: "scores-meta", children: jsxRuntimeExports.jsxs("div", { className: "scores-meta-line", children: ["Computed at: ", jsxRuntimeExports.jsx("strong", { children: computedAt })] }) })] }, key));
|
|
9734
|
+
}) })) })] }));
|
|
9776
9735
|
};
|
|
9777
9736
|
|
|
9778
9737
|
/**
|