@wipco/sdui 0.13.1 → 0.14.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/dist/{chunk-WJEGCCPY.js → chunk-4NPTFNAL.js} +1 -1
- package/dist/{chunk-4CZJF5PR.js → chunk-5C4SIRSW.js} +1 -1
- package/dist/{chunk-JWYBFODH.js → chunk-5YVXVGQ2.js} +1 -1
- package/dist/{chunk-PBGYAVQZ.js → chunk-6NAJ2D4A.js} +2 -2
- package/dist/{chunk-7AHNAX6T.js → chunk-BOSSWJTN.js} +1 -1
- package/dist/{chunk-X3DGYP4W.js → chunk-BS4LGGQV.js} +30 -6
- package/dist/{chunk-WMPSOKNI.js → chunk-CXZYC7IN.js} +1 -1
- package/dist/{chunk-BT4HC3WR.js → chunk-F2MKI3W5.js} +1 -1
- package/dist/{chunk-QIDMPWZH.js → chunk-FC2F37QH.js} +2 -2
- package/dist/{chunk-VK6KWB65.js → chunk-G4QIJHEP.js} +1 -1
- package/dist/{chunk-5A7BWIGN.js → chunk-HINKJD6C.js} +1 -1
- package/dist/{chunk-VV73LOAE.js → chunk-JND5NXUT.js} +9 -6
- package/dist/{chunk-TMAVD3WL.js → chunk-K55ODWRY.js} +16 -3
- package/dist/{chunk-UA5CT24N.js → chunk-K5ZJTLFP.js} +2 -2
- package/dist/{chunk-B5JTXYDB.js → chunk-LMHIRQZ6.js} +1 -0
- package/dist/{chunk-4IRLQWQC.js → chunk-LN6IOMCK.js} +1 -1
- package/dist/{chunk-3PYMVHL3.js → chunk-R3IK6EPA.js} +1 -1
- package/dist/{chunk-YFUQUWWH.js → chunk-VBCUIM7N.js} +2 -2
- package/dist/{chunk-FDVI3PWQ.js → chunk-X5X3FKCQ.js} +1 -1
- package/dist/{chunk-WLWWN5LW.js → chunk-YGSU34B3.js} +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +63 -10
- package/dist/meta.d.ts +1 -1
- package/dist/meta.js +70 -3
- package/dist/rich.js +3 -3
- package/dist/{types-DO8_hC6A.d.ts → types-CeUhMB9Q.d.ts} +18 -0
- package/dist/widgets/AutocompleteField.js +3 -3
- package/dist/widgets/ColumnBoard.js +2 -2
- package/dist/widgets/DiffView.js +2 -2
- package/dist/widgets/Disclosure.js +2 -2
- package/dist/widgets/EventCalendar.js +2 -2
- package/dist/widgets/ImageLightbox.js +2 -2
- package/dist/widgets/InlineEdit.js +2 -2
- package/dist/widgets/JsonField.js +2 -2
- package/dist/widgets/OrgChart.js +2 -2
- package/dist/widgets/PeriodFilter.js +2 -2
- package/dist/widgets/PrintSheet.js +2 -2
- package/dist/widgets/SearchableMultiPicker.js +3 -3
- package/dist/widgets/SecureScreen.js +2 -2
- package/dist/widgets/TagMultiSelect.d.ts +9 -1
- package/dist/widgets/TagMultiSelect.js +2 -2
- package/dist/widgets/Timeline.js +3 -3
- package/dist/widgets/TreePicker.d.ts +7 -2
- package/dist/widgets/TreePicker.js +4 -3
- package/dist/widgets/TreeView.d.ts +27 -2
- package/dist/widgets/TreeView.js +3 -2
- package/dist/widgets/index.d.ts +1 -1
- package/dist/widgets/index.js +35 -35
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SegmentedControl, Select, Input } from './chunk-
|
|
1
|
+
import { SegmentedControl, Select, Input } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
3
|
import { useState, useMemo } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { includesLooseSearch } from './chunk-
|
|
2
|
-
import { Icon, Button, Input, Spinner } from './chunk-
|
|
1
|
+
import { includesLooseSearch } from './chunk-FC2F37QH.js';
|
|
2
|
+
import { Icon, Button, Input, Spinner } from './chunk-LMHIRQZ6.js';
|
|
3
3
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
4
4
|
import { useId, useRef, useState, useEffect, useMemo } from 'react';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IconButton, Input } from './chunk-
|
|
1
|
+
import { IconButton, Input } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
3
|
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildCascadingTree } from './chunk-FC2F37QH.js';
|
|
2
|
+
import { Input, IconButton, EmptyState, Icon, Badge } from './chunk-LMHIRQZ6.js';
|
|
2
3
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
|
-
import React, { useState,
|
|
4
|
+
import React, { useMemo, useState, useRef, useEffect } from 'react';
|
|
4
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
var INDENT = 24;
|
|
@@ -12,6 +13,20 @@ var TREE_CSS = `
|
|
|
12
13
|
.erp-treeview__row[aria-current='true'],
|
|
13
14
|
.erp-treeview__row[aria-current='true']:hover{background:var(--wp-surface-selected);}
|
|
14
15
|
`;
|
|
16
|
+
function toTreeNodes(options) {
|
|
17
|
+
return options.map((option) => ({
|
|
18
|
+
id: option.value,
|
|
19
|
+
label: option.label,
|
|
20
|
+
...option.children ? { children: toTreeNodes(option.children) } : null
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
function buildTreeNodes(rows, tree) {
|
|
24
|
+
return toTreeNodes(buildCascadingTree(rows, tree));
|
|
25
|
+
}
|
|
26
|
+
function resolveTreeNodes(nodes, rows, tree) {
|
|
27
|
+
if (Array.isArray(rows) && rows.length > 0 && tree) return buildTreeNodes(rows, tree);
|
|
28
|
+
return nodes ?? [];
|
|
29
|
+
}
|
|
15
30
|
function pruneExcluded(nodes, excluded) {
|
|
16
31
|
if (excluded.size === 0) return nodes;
|
|
17
32
|
const out = [];
|
|
@@ -59,6 +74,8 @@ function toggled(prev, id) {
|
|
|
59
74
|
}
|
|
60
75
|
function TreeViewImpl({
|
|
61
76
|
nodes,
|
|
77
|
+
rows,
|
|
78
|
+
tree,
|
|
62
79
|
selectedId,
|
|
63
80
|
onSelect,
|
|
64
81
|
searchable = false,
|
|
@@ -66,18 +83,25 @@ function TreeViewImpl({
|
|
|
66
83
|
excludeIds,
|
|
67
84
|
maxHeight
|
|
68
85
|
}) {
|
|
69
|
-
const
|
|
86
|
+
const sourceNodes = useMemo(() => resolveTreeNodes(nodes, rows, tree), [nodes, rows, tree]);
|
|
87
|
+
const [expanded, setExpanded] = useState(() => collectExpandedIds(sourceNodes, defaultExpandedDepth));
|
|
70
88
|
const [searchCollapsed, setSearchCollapsed] = useState(() => /* @__PURE__ */ new Set());
|
|
71
89
|
const [query, setQuery] = useState("");
|
|
72
90
|
const [innerSelected, setInnerSelected] = useState(null);
|
|
91
|
+
const hadRows = useRef(Array.isArray(rows) && rows.length > 0);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
const hasRows = Array.isArray(rows) && rows.length > 0;
|
|
94
|
+
if (hasRows && !hadRows.current) setExpanded(collectExpandedIds(sourceNodes, defaultExpandedDepth));
|
|
95
|
+
hadRows.current = hasRows;
|
|
96
|
+
}, [rows, sourceNodes, defaultExpandedDepth]);
|
|
73
97
|
const isControlled = selectedId !== void 0;
|
|
74
98
|
const currentSelected = isControlled ? selectedId : innerSelected;
|
|
75
99
|
const trimmedQuery = query.trim().toLowerCase();
|
|
76
100
|
const searching = trimmedQuery.length > 0;
|
|
77
101
|
const visibleNodes = useMemo(() => {
|
|
78
|
-
const pruned = pruneExcluded(
|
|
102
|
+
const pruned = pruneExcluded(sourceNodes, new Set(excludeIds ?? []));
|
|
79
103
|
return searching ? filterTree(pruned, trimmedQuery) : pruned;
|
|
80
|
-
}, [
|
|
104
|
+
}, [sourceNodes, excludeIds, searching, trimmedQuery]);
|
|
81
105
|
const isOpen = (id) => searching ? !searchCollapsed.has(id) : expanded.has(id);
|
|
82
106
|
const toggleNode = (id) => {
|
|
83
107
|
if (searching) setSearchCollapsed((prev) => toggled(prev, id));
|
|
@@ -259,4 +283,4 @@ function TreeViewImpl({
|
|
|
259
283
|
}
|
|
260
284
|
var TreeView = boxed(TreeViewImpl, "TreeView");
|
|
261
285
|
|
|
262
|
-
export { TreeView };
|
|
286
|
+
export { TreeView, buildTreeNodes, pruneExcluded, resolveTreeNodes };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SegmentedControl, IconButton, Button, Tag, EmptyState, Icon, Badge } from './chunk-
|
|
1
|
+
import { SegmentedControl, IconButton, Button, Tag, EmptyState, Icon, Badge } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
3
|
import { useState, useMemo } from 'react';
|
|
4
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IconButton, Badge } from './chunk-
|
|
1
|
+
import { IconButton, Badge } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
3
|
import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Input, Button, IconButton, Tag, Field, Checkbox } from './chunk-
|
|
1
|
+
import { Input, Button, IconButton, Tag, Field, Checkbox } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { useRef, useEffect, useState, useMemo } from 'react';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -623,4 +623,4 @@ function CascadingLevelSelect({
|
|
|
623
623
|
);
|
|
624
624
|
}
|
|
625
625
|
|
|
626
|
-
export { Popover, SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchFields, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue };
|
|
626
|
+
export { Popover, SearchToolbar, buildCascadingTree, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchFields, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Badge, Checkbox, IconButton, Icon } from './chunk-
|
|
1
|
+
import { Badge, Checkbox, IconButton, Icon } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
3
|
import { useState, useEffect } from 'react';
|
|
4
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Icon } from './chunk-
|
|
1
|
+
import { Icon } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
3
|
import { createContext, useState, useRef, useMemo, useCallback, useEffect, useLayoutEffect, useContext } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { TreeView } from './chunk-
|
|
2
|
-
import { Field, Dialog, Icon, Button, Input } from './chunk-
|
|
1
|
+
import { resolveTreeNodes, TreeView } from './chunk-BS4LGGQV.js';
|
|
2
|
+
import { Field, Dialog, Icon, Button, Input } from './chunk-LMHIRQZ6.js';
|
|
3
3
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
4
|
-
import { useState, useEffect } from 'react';
|
|
4
|
+
import { useState, useMemo, useEffect } from 'react';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
var PICKER_CSS = `
|
|
@@ -23,6 +23,8 @@ function findNode(nodes, id) {
|
|
|
23
23
|
}
|
|
24
24
|
function TreePickerImpl({
|
|
25
25
|
nodes,
|
|
26
|
+
rows,
|
|
27
|
+
tree,
|
|
26
28
|
value,
|
|
27
29
|
valueLabel,
|
|
28
30
|
onChange,
|
|
@@ -35,9 +37,10 @@ function TreePickerImpl({
|
|
|
35
37
|
const [open, setOpen] = useState(false);
|
|
36
38
|
const [pendingId, setPendingId] = useState(null);
|
|
37
39
|
const [innerValue, setInnerValue] = useState(null);
|
|
40
|
+
const sourceNodes = useMemo(() => resolveTreeNodes(nodes, rows, tree), [nodes, rows, tree]);
|
|
38
41
|
const isControlled = value !== void 0;
|
|
39
42
|
const current = isControlled ? value : innerValue;
|
|
40
|
-
const currentNode = current != null ? findNode(
|
|
43
|
+
const currentNode = current != null ? findNode(sourceNodes, current) : void 0;
|
|
41
44
|
const displayLabel = current == null ? "" : currentNode?.label ?? valueLabel ?? current;
|
|
42
45
|
const openDialog = () => {
|
|
43
46
|
if (disabled) return;
|
|
@@ -46,7 +49,7 @@ function TreePickerImpl({
|
|
|
46
49
|
};
|
|
47
50
|
const closeDialog = () => setOpen(false);
|
|
48
51
|
const commit = () => {
|
|
49
|
-
const node = pendingId != null ? findNode(
|
|
52
|
+
const node = pendingId != null ? findNode(sourceNodes, pendingId) : void 0;
|
|
50
53
|
if (!isControlled) setInnerValue(pendingId);
|
|
51
54
|
onChange?.(pendingId, node);
|
|
52
55
|
setOpen(false);
|
|
@@ -175,7 +178,7 @@ function TreePickerImpl({
|
|
|
175
178
|
/* @__PURE__ */ jsx(
|
|
176
179
|
TreeView,
|
|
177
180
|
{
|
|
178
|
-
nodes,
|
|
181
|
+
nodes: sourceNodes,
|
|
179
182
|
selectedId: pendingId,
|
|
180
183
|
onSelect: (id) => setPendingId(id),
|
|
181
184
|
searchable: true,
|
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
import { Badge, Tag } from './chunk-
|
|
1
|
+
import { Badge, Tag } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo, useState } from 'react';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
+
function foldOptions(options, valueKey, labelKey) {
|
|
7
|
+
if (!Array.isArray(options)) return [];
|
|
8
|
+
return options.flatMap((raw) => {
|
|
9
|
+
if (raw === null || typeof raw !== "object") return [];
|
|
10
|
+
const row = raw;
|
|
11
|
+
const value = (valueKey ? row[valueKey] : void 0) ?? row.value;
|
|
12
|
+
if (value === void 0 || value === null) return [];
|
|
13
|
+
const label = (labelKey ? row[labelKey] : void 0) ?? row.label ?? value;
|
|
14
|
+
return [{ value: String(value), label: String(label) }];
|
|
15
|
+
});
|
|
16
|
+
}
|
|
6
17
|
function TagMultiSelectImpl({
|
|
7
18
|
options,
|
|
19
|
+
valueKey,
|
|
20
|
+
labelKey,
|
|
8
21
|
values,
|
|
9
22
|
onChange,
|
|
10
23
|
disabled = false,
|
|
11
24
|
emptyText = "\uC120\uD0DD\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
12
25
|
}) {
|
|
13
|
-
const safeOptions = options
|
|
26
|
+
const safeOptions = useMemo(() => foldOptions(options, valueKey, labelKey), [options, valueKey, labelKey]);
|
|
14
27
|
const isControlled = values !== void 0 && typeof onChange === "function";
|
|
15
28
|
const [internalValues, setInternalValues] = useState(values ?? []);
|
|
16
29
|
const current = isControlled ? values : internalValues;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { includesLooseSearch } from './chunk-
|
|
2
|
-
import { Button, Dialog, Input, Tag, Checkbox } from './chunk-
|
|
1
|
+
import { includesLooseSearch } from './chunk-FC2F37QH.js';
|
|
2
|
+
import { Button, Dialog, Input, Tag, Checkbox } from './chunk-LMHIRQZ6.js';
|
|
3
3
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
4
4
|
import React, { useMemo, useState, useEffect } from 'react';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -750,6 +750,7 @@ function Button({
|
|
|
750
750
|
style: mergeStyle(containerLayoutStyle({ justify }), style),
|
|
751
751
|
disabled: Tag2 === "button" ? disabled || loading : void 0,
|
|
752
752
|
"aria-disabled": disabled || void 0,
|
|
753
|
+
type: Tag2 === "button" ? "button" : void 0,
|
|
753
754
|
...rest,
|
|
754
755
|
children: [
|
|
755
756
|
icon ? /* @__PURE__ */ jsx(Icon, { name: icon, size: iconSize }) : null,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Disclosure } from './chunk-
|
|
2
|
-
import { Icon } from './chunk-
|
|
1
|
+
import { Disclosure } from './chunk-YGSU34B3.js';
|
|
2
|
+
import { Icon } from './chunk-LMHIRQZ6.js';
|
|
3
3
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
4
4
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Textarea, Icon } from './chunk-
|
|
1
|
+
import { Textarea, Icon } from './chunk-LMHIRQZ6.js';
|
|
2
2
|
import { boxed } from './chunk-SAN4IX6N.js';
|
|
3
3
|
import { useState, useRef, useId, useEffect, useCallback } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { CSSProperties, ReactNode, ComponentType } from 'react';
|
|
3
|
-
import { S as SduiAction, a as SduiPropValue, b as SduiRule, c as SduiPage } from './types-
|
|
4
|
-
export { d as SduiCalcRef, e as SduiChild, f as SduiIndexRef, g as SduiItemRef, h as SduiNode, i as SduiPageQuery, j as SduiScalar, k as SduiStateRef } from './types-
|
|
3
|
+
import { S as SduiAction, a as SduiPropValue, b as SduiRule, c as SduiPage } from './types-CeUhMB9Q.js';
|
|
4
|
+
export { d as SduiCalcRef, e as SduiChild, f as SduiIndexRef, g as SduiItemRef, h as SduiNode, i as SduiPageQuery, j as SduiScalar, k as SduiStateRef } from './types-CeUhMB9Q.js';
|
|
5
5
|
import { S as SduiBoxProps, a as SduiContainerLayoutProps, b as SduiColumnsScale, c as SduiGapScale, d as SduiWeightScale, e as SduiTextAlignScale } from './layout-B1QrIBm6.js';
|
|
6
6
|
export { C as CHILD_LAYOUT_PROPS, L as LAYOUT_CSS, f as SduiAlignScale, g as SduiChildLayoutProps, h as SduiSizeScale, i as SduiSpanScale, j as childLayoutFrom, k as columnsClass, l as containerLayoutStyle, m as joinClass, n as mergeStyle, t as typographyStyle } from './layout-B1QrIBm6.js';
|
|
7
7
|
import { D as DatePickerProps, a as DateRangePickerProps } from './DatePicker-BndreCPl.js';
|
|
@@ -448,6 +448,12 @@ interface SduiTextCell {
|
|
|
448
448
|
interface SduiBadgeCell {
|
|
449
449
|
type: 'badge';
|
|
450
450
|
toneMap?: Record<string, BadgeTone>;
|
|
451
|
+
/**
|
|
452
|
+
* 값 → 표시 텍스트(생략 시 값 그대로) — Table 컬럼 badge와 같은 의미론.
|
|
453
|
+
* 톤 조회 키는 여전히 **원래 값**이다. labelMap이 조회 키까지 바꾸면 기존 스펙의
|
|
454
|
+
* toneMap(enum 키)이 전부 neutral로 떨어진다.
|
|
455
|
+
*/
|
|
456
|
+
labelMap?: Record<string, string>;
|
|
451
457
|
}
|
|
452
458
|
/** 값을 태그로. 선행 점 색은 값별 매핑(CSS 색상 문자열). */
|
|
453
459
|
interface SduiTagCell {
|
|
@@ -550,9 +556,11 @@ interface SduiGridCardAction {
|
|
|
550
556
|
interface SduiGridCard {
|
|
551
557
|
titleKey: string;
|
|
552
558
|
subtitleKey?: string;
|
|
559
|
+
/** 카드 우상단 배지 — labelMap은 표시 텍스트만 바꾸고 톤 조회 키는 원래 값이다(셀 badge와 같은 규칙) */
|
|
553
560
|
badge?: {
|
|
554
561
|
key: string;
|
|
555
562
|
toneMap?: Record<string, BadgeTone>;
|
|
563
|
+
labelMap?: Record<string, string>;
|
|
556
564
|
};
|
|
557
565
|
/** 한 열로 쌓는 행 */
|
|
558
566
|
rows?: SduiGridCardRow[];
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DEV, HoistedStyle, isSafeNavigationTarget, useSduiAdapter, hostFetchOf, DateRangePicker, DatePicker, useSduiSandbox, resolveAdapter, assetResolverOf, SduiAdapterContext } from './chunk-
|
|
2
|
-
export { DatePicker, DateRangePicker, defaultAdapter, useSduiAssetResolver, useSduiSandbox } from './chunk-
|
|
3
|
-
import { normalizeSearchFields, searchValuesFromParams, splitMultiValue, includesLooseSearch, cascadingValuePaths, SearchToolbar, searchFieldKeys, Popover } from './chunk-
|
|
4
|
-
export { SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue } from './chunk-
|
|
5
|
-
import { EmptyState, Button, Checkbox, SegmentedControl, Spinner, Select, Pagination, Icon, Card, Badge, ProgressBar, Tag, Toast, Textarea, Tabs, Table, Switch, StatCard, Input, IconButton, Field, Alert, warnOnce, Dialog } from './chunk-
|
|
6
|
-
export { Alert, Avatar, Badge, Breadcrumb, Button, Card, Checkbox, Dialog, EmptyState, Field, Icon, IconButton, Input, Pagination, ProgressBar, Radio, SegmentedControl, Select, SidebarNav, Spinner, StatCard, Switch, Table, Tabs, Tag, Textarea, Toast, Tooltip } from './chunk-
|
|
1
|
+
import { DEV, HoistedStyle, isSafeNavigationTarget, useSduiAdapter, hostFetchOf, DateRangePicker, DatePicker, useSduiSandbox, resolveAdapter, assetResolverOf, SduiAdapterContext } from './chunk-HINKJD6C.js';
|
|
2
|
+
export { DatePicker, DateRangePicker, defaultAdapter, useSduiAssetResolver, useSduiSandbox } from './chunk-HINKJD6C.js';
|
|
3
|
+
import { normalizeSearchFields, searchValuesFromParams, splitMultiValue, includesLooseSearch, cascadingValuePaths, SearchToolbar, searchFieldKeys, Popover } from './chunk-FC2F37QH.js';
|
|
4
|
+
export { SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue } from './chunk-FC2F37QH.js';
|
|
5
|
+
import { EmptyState, Button, Checkbox, SegmentedControl, Spinner, Select, Pagination, Icon, Card, Badge, ProgressBar, Tag, Toast, Textarea, Tabs, Table, Switch, StatCard, Input, IconButton, Field, Alert, warnOnce, Dialog } from './chunk-LMHIRQZ6.js';
|
|
6
|
+
export { Alert, Avatar, Badge, Breadcrumb, Button, Card, Checkbox, Dialog, EmptyState, Field, Icon, IconButton, Input, Pagination, ProgressBar, Radio, SegmentedControl, Select, SidebarNav, Spinner, StatCard, Switch, Table, Tabs, Tag, Textarea, Toast, Tooltip } from './chunk-LMHIRQZ6.js';
|
|
7
7
|
import { boxed, mergeStyle, containerLayoutStyle, joinClass, columnsClass, typographyStyle, LAYOUT_CSS, childLayoutFrom, CHILD_LAYOUT_PROPS } from './chunk-SAN4IX6N.js';
|
|
8
8
|
export { CHILD_LAYOUT_PROPS, LAYOUT_CSS, boxed, childLayoutFrom, columnsClass, containerLayoutStyle, joinClass, mergeStyle, typographyStyle } from './chunk-SAN4IX6N.js';
|
|
9
9
|
import React, { createContext, useState, useMemo, useContext, useRef, useEffect, useCallback } from 'react';
|
|
@@ -347,7 +347,7 @@ function cellRenderer(cell, key, dispatch) {
|
|
|
347
347
|
return (row) => {
|
|
348
348
|
const value = String(row[key] ?? "");
|
|
349
349
|
if (!value) return null;
|
|
350
|
-
return /* @__PURE__ */ jsx(Badge, { tone: cell.toneMap?.[value] ?? "neutral", children: value });
|
|
350
|
+
return /* @__PURE__ */ jsx(Badge, { tone: cell.toneMap?.[value] ?? "neutral", children: cell.labelMap?.[value] ?? value });
|
|
351
351
|
};
|
|
352
352
|
case "tag":
|
|
353
353
|
return (row) => {
|
|
@@ -1111,7 +1111,10 @@ function mapGridCard(gridCard, dispatch) {
|
|
|
1111
1111
|
badge: gridCard.badge ? (row) => {
|
|
1112
1112
|
const value = String(row[gridCard.badge.key] ?? "");
|
|
1113
1113
|
if (!value) return null;
|
|
1114
|
-
return {
|
|
1114
|
+
return {
|
|
1115
|
+
text: gridCard.badge.labelMap?.[value] ?? value,
|
|
1116
|
+
variant: gridCard.badge.toneMap?.[value] ?? "neutral"
|
|
1117
|
+
};
|
|
1115
1118
|
} : void 0,
|
|
1116
1119
|
rows: mapCardRows(gridCard.rows, dispatch),
|
|
1117
1120
|
leftRows: mapCardRows(gridCard.leftRows, dispatch),
|
|
@@ -1711,6 +1714,33 @@ function createRegistry(extensions) {
|
|
|
1711
1714
|
return { ...defaultRegistry, ...extensions };
|
|
1712
1715
|
}
|
|
1713
1716
|
|
|
1717
|
+
// src/request-action.ts
|
|
1718
|
+
function deferChainEntry(container, key) {
|
|
1719
|
+
return typeof container.action === "string" && (key === "onSuccess" || key === "onError");
|
|
1720
|
+
}
|
|
1721
|
+
async function runRequestAction(action, deps) {
|
|
1722
|
+
try {
|
|
1723
|
+
if (typeof action.endpoint !== "string" || action.endpoint === "") {
|
|
1724
|
+
throw new Error("request \uC561\uC158\uC758 endpoint\uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 \u2014 $state \uCC38\uC870\uC5D0 \uC544\uC9C1 \uAC12\uC774 \uC5C6\uB294\uC9C0 \uD655\uC778\uD558\uC138\uC694");
|
|
1725
|
+
}
|
|
1726
|
+
const response = await deps.fetch(action.endpoint, {
|
|
1727
|
+
method: action.method ?? "POST",
|
|
1728
|
+
...action.body === void 0 ? {} : { body: action.body }
|
|
1729
|
+
});
|
|
1730
|
+
if (typeof action.invalidate === "string" && action.invalidate !== "") {
|
|
1731
|
+
deps.dispatch({ action: "invalidate", prefix: action.invalidate });
|
|
1732
|
+
}
|
|
1733
|
+
(action.onSuccess ?? []).forEach((a) => deps.dispatch(a, response));
|
|
1734
|
+
} catch (error) {
|
|
1735
|
+
const message = error instanceof Error ? error.message : "\uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4";
|
|
1736
|
+
if (action.onError?.length) {
|
|
1737
|
+
action.onError.forEach((a) => deps.dispatch(a, message));
|
|
1738
|
+
} else {
|
|
1739
|
+
deps.toast({ tone: "danger", title: "\uC694\uCCAD \uC2E4\uD328", message });
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1714
1744
|
// src/validate.ts
|
|
1715
1745
|
var ACTION_NAMES = /* @__PURE__ */ new Set([
|
|
1716
1746
|
"navigate",
|
|
@@ -1719,6 +1749,7 @@ var ACTION_NAMES = /* @__PURE__ */ new Set([
|
|
|
1719
1749
|
"close",
|
|
1720
1750
|
"toast",
|
|
1721
1751
|
"submitForm",
|
|
1752
|
+
"request",
|
|
1722
1753
|
"invalidate",
|
|
1723
1754
|
"refresh",
|
|
1724
1755
|
"download",
|
|
@@ -2004,6 +2035,15 @@ function pickPath(source, path) {
|
|
|
2004
2035
|
}
|
|
2005
2036
|
return value;
|
|
2006
2037
|
}
|
|
2038
|
+
function planStamp(plan, epochs) {
|
|
2039
|
+
return `${plan.endpoint}#${epochs[plan.key] ?? 0}`;
|
|
2040
|
+
}
|
|
2041
|
+
function revertUnsettledStamps(fetched, runnable, epochs, settled) {
|
|
2042
|
+
for (const plan of runnable) {
|
|
2043
|
+
if (settled.has(plan.key)) continue;
|
|
2044
|
+
if (fetched.get(plan.key) === planStamp(plan, epochs)) fetched.delete(plan.key);
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2007
2047
|
function isPlainObject3(v) {
|
|
2008
2048
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2009
2049
|
}
|
|
@@ -2442,7 +2482,9 @@ function SduiRenderer({
|
|
|
2442
2482
|
if (Array.isArray(value)) return value.map((v) => resolveValue(v, scope));
|
|
2443
2483
|
if (isPlainObject3(value)) {
|
|
2444
2484
|
const out = {};
|
|
2445
|
-
for (const [k, v] of Object.entries(value))
|
|
2485
|
+
for (const [k, v] of Object.entries(value)) {
|
|
2486
|
+
out[k] = deferChainEntry(value, k) ? v : resolveValue(v, scope);
|
|
2487
|
+
}
|
|
2446
2488
|
return out;
|
|
2447
2489
|
}
|
|
2448
2490
|
return value;
|
|
@@ -2465,7 +2507,7 @@ function SduiRenderer({
|
|
|
2465
2507
|
useEffect(() => {
|
|
2466
2508
|
const epochs = dataEpochsRef.current;
|
|
2467
2509
|
const runnable = runnablePlans(dataPlanRef.current).filter((plan) => {
|
|
2468
|
-
const stamp =
|
|
2510
|
+
const stamp = planStamp(plan, epochs);
|
|
2469
2511
|
if (fetchedRef.current.get(plan.key) === stamp) return false;
|
|
2470
2512
|
fetchedRef.current.set(plan.key, stamp);
|
|
2471
2513
|
return true;
|
|
@@ -2474,6 +2516,7 @@ function SduiRenderer({
|
|
|
2474
2516
|
const controller = new AbortController();
|
|
2475
2517
|
let cancelled = false;
|
|
2476
2518
|
const timers = [];
|
|
2519
|
+
const settled = /* @__PURE__ */ new Set();
|
|
2477
2520
|
setEntries(
|
|
2478
2521
|
Object.fromEntries(runnable.map((plan) => [`${plan.key}.$loading`, true]))
|
|
2479
2522
|
);
|
|
@@ -2497,6 +2540,7 @@ function SduiRenderer({
|
|
|
2497
2540
|
`[sdui] page.data.${plan.key}: \uC751\uB2F5\uC5D0 "${plan.select}" \uACBD\uB85C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uAC12 \uC5C6\uC74C\uC73C\uB85C \uB461\uB2C8\uB2E4 (${plan.endpoint})`
|
|
2498
2541
|
);
|
|
2499
2542
|
}
|
|
2543
|
+
settled.add(plan.key);
|
|
2500
2544
|
setEntries({
|
|
2501
2545
|
[plan.key]: picked,
|
|
2502
2546
|
[`${plan.key}.$loading`]: false,
|
|
@@ -2506,6 +2550,7 @@ function SduiRenderer({
|
|
|
2506
2550
|
if (cancelled || controller.signal.aborted) return;
|
|
2507
2551
|
const message = error instanceof Error ? error.message : "\uC870\uD68C\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4";
|
|
2508
2552
|
warnOnce2(`data:${plan.key}:${plan.endpoint}`, `[sdui] page.data.${plan.key} \uC870\uD68C \uC2E4\uD328 (${plan.endpoint}): ${message}`);
|
|
2553
|
+
settled.add(plan.key);
|
|
2509
2554
|
setEntries({
|
|
2510
2555
|
[plan.key]: plan.fallback ?? void 0,
|
|
2511
2556
|
[`${plan.key}.$loading`]: false,
|
|
@@ -2518,6 +2563,7 @@ function SduiRenderer({
|
|
|
2518
2563
|
cancelled = true;
|
|
2519
2564
|
controller.abort();
|
|
2520
2565
|
timers.forEach(clearTimeout);
|
|
2566
|
+
revertUnsettledStamps(fetchedRef.current, runnable, epochs, settled);
|
|
2521
2567
|
};
|
|
2522
2568
|
}, [dataPlanKey, dataEpochKey, setEntries]);
|
|
2523
2569
|
const dispatchRef = useRef(() => {
|
|
@@ -2646,6 +2692,13 @@ function SduiRenderer({
|
|
|
2646
2692
|
})();
|
|
2647
2693
|
break;
|
|
2648
2694
|
}
|
|
2695
|
+
case "request":
|
|
2696
|
+
void runRequestAction(action, {
|
|
2697
|
+
fetch: (path, init) => hostRef.current.fetch(path, init),
|
|
2698
|
+
dispatch: (a, value) => dispatchRef.current(a, value),
|
|
2699
|
+
toast: pushToast
|
|
2700
|
+
});
|
|
2701
|
+
break;
|
|
2649
2702
|
case "invalidate": {
|
|
2650
2703
|
hostRef.current.invalidate?.(action.prefix, action.exact ?? false);
|
|
2651
2704
|
const prefix = typeof action.prefix === "string" ? action.prefix : "";
|
package/dist/meta.d.ts
CHANGED
package/dist/meta.js
CHANGED
|
@@ -1806,6 +1806,12 @@ var searchCellFields = [
|
|
|
1806
1806
|
]
|
|
1807
1807
|
},
|
|
1808
1808
|
{ name: "toneMap", kind: "object", label: "\uAC12 \u2192 \uD1A4", description: "type=badge (\uC5C6\uB294 \uAC12\uC740 neutral)" },
|
|
1809
|
+
{
|
|
1810
|
+
name: "labelMap",
|
|
1811
|
+
kind: "object",
|
|
1812
|
+
label: "\uAC12 \u2192 \uD45C\uC2DC \uBB38\uAD6C",
|
|
1813
|
+
description: "type=badge (\uC5C6\uB294 \uAC12\uC740 \uC6D0\uBB38 \uADF8\uB300\uB85C, \uD1A4 \uC870\uD68C \uD0A4\uB294 \uC6D0\uB798 \uAC12)"
|
|
1814
|
+
},
|
|
1809
1815
|
{ name: "colorMap", kind: "object", label: "\uAC12 \u2192 \uC810 \uC0C9", description: "type=tag" },
|
|
1810
1816
|
{ name: "filled", kind: "boolean", label: "\uCC44\uC6B4 \uD0DC\uADF8", description: "type=tag" },
|
|
1811
1817
|
{
|
|
@@ -1955,7 +1961,7 @@ var searchCommonProps = [
|
|
|
1955
1961
|
fields: [
|
|
1956
1962
|
{ name: "titleKey", kind: "string", label: "\uC81C\uBAA9 \uD544\uB4DC", required: true },
|
|
1957
1963
|
{ name: "subtitleKey", kind: "string", label: "\uBD80\uC81C \uD544\uB4DC" },
|
|
1958
|
-
{ name: "badge", kind: "object", label: "\uBC30\uC9C0", description: "{ key, toneMap }" },
|
|
1964
|
+
{ name: "badge", kind: "object", label: "\uBC30\uC9C0", description: "{ key, toneMap, labelMap } \u2014 labelMap\uC740 \uD45C\uC2DC \uBB38\uAD6C\uB9CC \uBC14\uAFBC\uB2E4" },
|
|
1959
1965
|
{ name: "rows", kind: "array", label: "\uD589", item: searchCardRowFields },
|
|
1960
1966
|
{
|
|
1961
1967
|
name: "leftRows",
|
|
@@ -3493,12 +3499,29 @@ var TagMultiSelectMeta = {
|
|
|
3493
3499
|
label: "\uC635\uC158",
|
|
3494
3500
|
required: true,
|
|
3495
3501
|
bindable: true,
|
|
3502
|
+
description: "\uAE30\uBCF8\uC740 \uC544\uB798 \uD589 \uD3B8\uC9D1\uAE30\uC758 {\uAC12, \uD45C\uC2DC} \uBAA8\uC591\uC774\uB2E4. \uB3C4\uBA54\uC778 \uD589 \uBAA9\uB85D\uC744 \uADF8\uB300\uB85C \uBB3C\uB9B4 \uAC70\uBA74(\uC608: /employees\uC758 {id, name}) \uAC12 \uD0A4\xB7\uB77C\uBCA8 \uD0A4\uB85C \uC77D\uC744 \uC790\uB9AC\uB97C \uC54C\uB824 \uC900\uB2E4.",
|
|
3496
3503
|
group: "data",
|
|
3497
3504
|
item: [
|
|
3498
3505
|
{ name: "value", kind: "string", label: "\uAC12", required: true },
|
|
3499
3506
|
{ name: "label", kind: "string", label: "\uD45C\uC2DC", required: true }
|
|
3500
3507
|
]
|
|
3501
3508
|
},
|
|
3509
|
+
{
|
|
3510
|
+
name: "valueKey",
|
|
3511
|
+
kind: "string",
|
|
3512
|
+
label: "\uAC12 \uD0A4",
|
|
3513
|
+
default: "value",
|
|
3514
|
+
description: "\uC635\uC158\uC5D0\uC11C \uAC12\uC744 \uC77D\uC744 \uD0A4. Select\uC758 \uAC19\uC740 \uC774\uB984 \uD504\uB86D\uACFC \uB73B\uC774 \uAC19\uB2E4.",
|
|
3515
|
+
group: "data"
|
|
3516
|
+
},
|
|
3517
|
+
{
|
|
3518
|
+
name: "labelKey",
|
|
3519
|
+
kind: "string",
|
|
3520
|
+
label: "\uB77C\uBCA8 \uD0A4",
|
|
3521
|
+
default: "label",
|
|
3522
|
+
description: "\uC635\uC158\uC5D0\uC11C \uD45C\uC2DC \uB77C\uBCA8\uC744 \uC77D\uC744 \uD0A4. \uADF8 \uC790\uB9AC\uAC00 \uBE44\uBA74 \uAC12\uC73C\uB85C \uB300\uC2E0 \uADF8\uB9B0\uB2E4.",
|
|
3523
|
+
group: "data"
|
|
3524
|
+
},
|
|
3502
3525
|
{
|
|
3503
3526
|
name: "values",
|
|
3504
3527
|
kind: "array",
|
|
@@ -3541,11 +3564,33 @@ var TreePickerMeta = {
|
|
|
3541
3564
|
name: "nodes",
|
|
3542
3565
|
kind: "array",
|
|
3543
3566
|
label: "\uD2B8\uB9AC",
|
|
3544
|
-
required: true,
|
|
3545
3567
|
bindable: true,
|
|
3568
|
+
description: "rows\uAC00 \uBE44\uC5B4 \uC788\uC744 \uB54C\uC758 \uD3F4\uBC31 \u2014 \uCE94\uBC84\uC2A4 \uB370\uBAA8\uB294 \uC5EC\uAE30 \uB454\uB2E4.",
|
|
3546
3569
|
group: "data",
|
|
3547
3570
|
item: treeNodeItem
|
|
3548
3571
|
},
|
|
3572
|
+
{
|
|
3573
|
+
name: "rows",
|
|
3574
|
+
kind: "array",
|
|
3575
|
+
label: "\uD3C9\uBA74 \uD589",
|
|
3576
|
+
bindable: true,
|
|
3577
|
+
description: "{id, parent_id, name} \uAC19\uC740 \uD3C9\uBA74 \uBAA9\uB85D. \uBE44\uC5B4\uC788\uC9C0 \uC54A\uC73C\uBA74 tree \uB9E4\uD551\uC73C\uB85C \uACC4\uCE35\uC744 \uC138\uC6B4\uB2E4 \u2014 /categories\uCC98\uB7FC \uD3C9\uBA74\uC73C\uB85C \uC8FC\uB294 API\uB97C \uADF8\uB300\uB85C \uBC14\uC778\uB529\uD55C\uB2E4.",
|
|
3578
|
+
group: "data",
|
|
3579
|
+
item: [],
|
|
3580
|
+
itemKind: "object"
|
|
3581
|
+
},
|
|
3582
|
+
{
|
|
3583
|
+
name: "tree",
|
|
3584
|
+
kind: "object",
|
|
3585
|
+
label: "\uD589 \u2192 \uD2B8\uB9AC \uB9E4\uD551",
|
|
3586
|
+
description: "\uD3C9\uBA74 \uD589\uC5D0\uC11C \uC77D\uC744 \uD0A4 \uC774\uB984. \uC0C1\uC138\uAC80\uC0C9 cascading\uC758 tree\uC640 \uAC19\uC740 \uACC4\uC57D\uC774\uB2E4.",
|
|
3587
|
+
group: "data",
|
|
3588
|
+
fields: [
|
|
3589
|
+
{ name: "idKey", kind: "string", label: "id \uD0A4", required: true },
|
|
3590
|
+
{ name: "parentIdKey", kind: "string", label: "\uBD80\uBAA8 id \uD0A4", required: true },
|
|
3591
|
+
{ name: "labelKey", kind: "string", label: "\uB77C\uBCA8 \uD0A4", required: true }
|
|
3592
|
+
]
|
|
3593
|
+
},
|
|
3549
3594
|
{
|
|
3550
3595
|
name: "value",
|
|
3551
3596
|
kind: "string",
|
|
@@ -4198,11 +4243,33 @@ var TreeViewMeta = {
|
|
|
4198
4243
|
name: "nodes",
|
|
4199
4244
|
kind: "array",
|
|
4200
4245
|
label: "\uD2B8\uB9AC",
|
|
4201
|
-
required: true,
|
|
4202
4246
|
bindable: true,
|
|
4247
|
+
description: "rows\uAC00 \uBE44\uC5B4 \uC788\uC744 \uB54C\uC758 \uD3F4\uBC31 \u2014 \uCE94\uBC84\uC2A4 \uB370\uBAA8\uB294 \uC5EC\uAE30 \uB454\uB2E4.",
|
|
4203
4248
|
group: "data",
|
|
4204
4249
|
item: treeNodeItem
|
|
4205
4250
|
},
|
|
4251
|
+
{
|
|
4252
|
+
name: "rows",
|
|
4253
|
+
kind: "array",
|
|
4254
|
+
label: "\uD3C9\uBA74 \uD589",
|
|
4255
|
+
bindable: true,
|
|
4256
|
+
description: "{id, parent_id, name} \uAC19\uC740 \uD3C9\uBA74 \uBAA9\uB85D. \uBE44\uC5B4\uC788\uC9C0 \uC54A\uC73C\uBA74 tree \uB9E4\uD551\uC73C\uB85C \uACC4\uCE35\uC744 \uC138\uC6B4\uB2E4 \u2014 /categories\uCC98\uB7FC \uD3C9\uBA74\uC73C\uB85C \uC8FC\uB294 API\uB97C \uADF8\uB300\uB85C \uBC14\uC778\uB529\uD55C\uB2E4.",
|
|
4257
|
+
group: "data",
|
|
4258
|
+
item: [],
|
|
4259
|
+
itemKind: "object"
|
|
4260
|
+
},
|
|
4261
|
+
{
|
|
4262
|
+
name: "tree",
|
|
4263
|
+
kind: "object",
|
|
4264
|
+
label: "\uD589 \u2192 \uD2B8\uB9AC \uB9E4\uD551",
|
|
4265
|
+
description: "\uD3C9\uBA74 \uD589\uC5D0\uC11C \uC77D\uC744 \uD0A4 \uC774\uB984. \uC0C1\uC138\uAC80\uC0C9 cascading\uC758 tree\uC640 \uAC19\uC740 \uACC4\uC57D\uC774\uB2E4.",
|
|
4266
|
+
group: "data",
|
|
4267
|
+
fields: [
|
|
4268
|
+
{ name: "idKey", kind: "string", label: "id \uD0A4", required: true },
|
|
4269
|
+
{ name: "parentIdKey", kind: "string", label: "\uBD80\uBAA8 id \uD0A4", required: true },
|
|
4270
|
+
{ name: "labelKey", kind: "string", label: "\uB77C\uBCA8 \uD0A4", required: true }
|
|
4271
|
+
]
|
|
4272
|
+
},
|
|
4206
4273
|
{
|
|
4207
4274
|
name: "selectedId",
|
|
4208
4275
|
kind: "string",
|
package/dist/rich.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useSduiAssetResolver, HoistedStyle } from './chunk-
|
|
2
|
-
export { DatePicker, DateRangePicker } from './chunk-
|
|
3
|
-
import { Spinner, EmptyState } from './chunk-
|
|
1
|
+
import { useSduiAssetResolver, HoistedStyle } from './chunk-HINKJD6C.js';
|
|
2
|
+
export { DatePicker, DateRangePicker } from './chunk-HINKJD6C.js';
|
|
3
|
+
import { Spinner, EmptyState } from './chunk-LMHIRQZ6.js';
|
|
4
4
|
import './chunk-SAN4IX6N.js';
|
|
5
5
|
import { useRef, useCallback, useMemo, useState, useEffect, useLayoutEffect } from 'react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -134,6 +134,24 @@ type SduiAction = {
|
|
|
134
134
|
/** 실패 시 순차 실행 (이벤트 값 = 에러 메시지). 생략하면 danger 토스트 */
|
|
135
135
|
onError?: SduiAction[];
|
|
136
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* 단발 API 호출 — submitForm에서 폼 수집·검증을 뺀 것. 서버의 2단계 커밋 계약
|
|
139
|
+
* (본체 POST 후 `POST /{entity}/{id}/attachments`)을 submitForm의 onSuccess 안에서
|
|
140
|
+
* 잇는 자리다. endpoint·body는 디스패치 시점에 해석되므로 같은 체인의 setState를 본다.
|
|
141
|
+
*/
|
|
142
|
+
| {
|
|
143
|
+
action: 'request';
|
|
144
|
+
endpoint: string;
|
|
145
|
+
/** 생략하면 POST. GET은 page.data의 몫이다 — 본문 실린 GET은 브라우저가 막는다. */
|
|
146
|
+
method?: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
147
|
+
body?: SduiPropValue;
|
|
148
|
+
/** 성공 시 순차 실행 (이벤트 값 = 응답 JSON) */
|
|
149
|
+
onSuccess?: SduiAction[];
|
|
150
|
+
/** 실패 시 순차 실행 (이벤트 값 = 에러 메시지). 생략하면 danger 토스트 */
|
|
151
|
+
onError?: SduiAction[];
|
|
152
|
+
/** 성공 시 무효화할 조회 prefix — onSuccess의 invalidate 액션 단축 */
|
|
153
|
+
invalidate?: string;
|
|
154
|
+
}
|
|
137
155
|
/** 클라이언트 조회 캐시 무효화 — 어댑터의 invalidate로 위임 */
|
|
138
156
|
| {
|
|
139
157
|
action: 'invalidate';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AutocompleteField, toAutocompleteOptions } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { AutocompleteField, toAutocompleteOptions } from '../chunk-6NAJ2D4A.js';
|
|
2
|
+
import '../chunk-FC2F37QH.js';
|
|
3
|
+
import '../chunk-LMHIRQZ6.js';
|
|
4
4
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { ColumnBoard } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { ColumnBoard } from '../chunk-G4QIJHEP.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
package/dist/widgets/DiffView.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { DiffView } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { DiffView } from '../chunk-LN6IOMCK.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Disclosure } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { Disclosure } from '../chunk-YGSU34B3.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { EventCalendar } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { EventCalendar } from '../chunk-CXZYC7IN.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { ImageLightbox } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { ImageLightbox } from '../chunk-R3IK6EPA.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { InlineEdit } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { InlineEdit } from '../chunk-BOSSWJTN.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { JsonField } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { JsonField } from '../chunk-X5X3FKCQ.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
package/dist/widgets/OrgChart.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { OrgChart } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { OrgChart } from '../chunk-F2MKI3W5.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { PeriodFilter } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { PeriodFilter } from '../chunk-4NPTFNAL.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { PrintSheet } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { PrintSheet } from '../chunk-5YVXVGQ2.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { SearchableMultiPicker } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { SearchableMultiPicker } from '../chunk-K5ZJTLFP.js';
|
|
2
|
+
import '../chunk-FC2F37QH.js';
|
|
3
|
+
import '../chunk-LMHIRQZ6.js';
|
|
4
4
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { SecureScreen } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { SecureScreen } from '../chunk-5C4SIRSW.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -14,7 +14,15 @@ interface TagMultiSelectOption {
|
|
|
14
14
|
label: string;
|
|
15
15
|
}
|
|
16
16
|
interface TagMultiSelectProps {
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* 기본은 `{value, label}`이고, 도메인 행(`{id, name, …}`)을 그대로 넘길 거면
|
|
19
|
+
* `valueKey`/`labelKey`로 읽을 키를 알려 준다 — Select 0.7.0과 같은 계약.
|
|
20
|
+
*/
|
|
21
|
+
options: Array<TagMultiSelectOption | Record<string, unknown>>;
|
|
22
|
+
/** 옵션에서 값을 읽을 키. 기본 'value'. */
|
|
23
|
+
valueKey?: string;
|
|
24
|
+
/** 옵션에서 표시 라벨을 읽을 키. 기본 'label'. */
|
|
25
|
+
labelKey?: string;
|
|
18
26
|
values: string[];
|
|
19
27
|
onChange: (values: string[]) => void;
|
|
20
28
|
disabled?: boolean;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { TagMultiSelect } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { TagMultiSelect } from '../chunk-K55ODWRY.js';
|
|
2
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
3
|
import '../chunk-SAN4IX6N.js';
|
package/dist/widgets/Timeline.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Timeline } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { Timeline } from '../chunk-VBCUIM7N.js';
|
|
2
|
+
import '../chunk-YGSU34B3.js';
|
|
3
|
+
import '../chunk-LMHIRQZ6.js';
|
|
4
4
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { S as SduiBoxProps } from '../layout-B1QrIBm6.js';
|
|
3
|
-
import { TreeNode } from './TreeView.js';
|
|
3
|
+
import { TreeNode, TreeRowsMapping } from './TreeView.js';
|
|
4
4
|
|
|
5
5
|
interface TreePickerProps {
|
|
6
|
-
|
|
6
|
+
/** 정적 트리. `rows`가 비어 있을 때의 폴백이기도 하다 — 캔버스 데모는 여기 둔다. */
|
|
7
|
+
nodes?: TreeNode[];
|
|
8
|
+
/** 평면 행. 비어있지 않으면 `tree` 매핑으로 계층을 세운다 — {@link TreeViewProps.rows}와 같은 계약. */
|
|
9
|
+
rows?: unknown[];
|
|
10
|
+
/** 평면 행에서 읽을 키 이름. 없으면 `rows`는 무시된다. */
|
|
11
|
+
tree?: TreeRowsMapping;
|
|
7
12
|
/** 지정하면 controlled — 내부 커밋 상태를 쓰지 않는다. null = 선택 없음. */
|
|
8
13
|
value?: string | null;
|
|
9
14
|
/** 트리에서 노드를 찾지 못할 때 표시할 라벨(controlled 보조). */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { TreePicker } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { TreePicker } from '../chunk-JND5NXUT.js';
|
|
2
|
+
import '../chunk-BS4LGGQV.js';
|
|
3
|
+
import '../chunk-FC2F37QH.js';
|
|
4
|
+
import '../chunk-LMHIRQZ6.js';
|
|
4
5
|
import '../chunk-SAN4IX6N.js';
|
|
@@ -8,8 +8,25 @@ interface TreeNode {
|
|
|
8
8
|
meta?: string;
|
|
9
9
|
children?: TreeNode[];
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* `rows` → 트리 매핑 계약. 상세검색 cascading의 `tree`(SearchToolbar)와 같은 모양이다 —
|
|
13
|
+
* 스펙 작성자가 한 어휘를 두 자리에서 그대로 쓴다.
|
|
14
|
+
*/
|
|
15
|
+
interface TreeRowsMapping {
|
|
16
|
+
idKey: string;
|
|
17
|
+
parentIdKey: string;
|
|
18
|
+
labelKey: string;
|
|
19
|
+
}
|
|
11
20
|
interface TreeViewProps {
|
|
12
|
-
|
|
21
|
+
/** 정적 트리. `rows`가 비어 있을 때의 폴백이기도 하다 — 캔버스 데모는 여기 둔다. */
|
|
22
|
+
nodes?: TreeNode[];
|
|
23
|
+
/**
|
|
24
|
+
* 평면 행(/categories 모양 — {id, parent_id, name}). 비어있지 않으면 `tree` 매핑으로
|
|
25
|
+
* 계층을 세우고, 아니면 `nodes` 폴백 — AutocompleteField의 데모 options 유지와 같은 관례.
|
|
26
|
+
*/
|
|
27
|
+
rows?: unknown[];
|
|
28
|
+
/** 평면 행에서 읽을 키 이름. 없으면 `rows`는 무시된다. */
|
|
29
|
+
tree?: TreeRowsMapping;
|
|
13
30
|
/** 지정하면 controlled — 내부 선택 상태를 쓰지 않는다. */
|
|
14
31
|
selectedId?: string | null;
|
|
15
32
|
onSelect?: (id: string, node: TreeNode) => void;
|
|
@@ -22,10 +39,18 @@ interface TreeViewProps {
|
|
|
22
39
|
/** 스크롤 컨테이너 최대 높이 (예: "320px"). */
|
|
23
40
|
maxHeight?: string;
|
|
24
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* 평면 행을 TreeNode 계층으로 세운다. 고아 행(부모가 목록에 없음)을 루트로 올리는 것까지
|
|
44
|
+
* `buildCascadingTree`와 동작이 같다 — 알고리즘은 그쪽 한 벌뿐이고 여기는 노드 모양만 바꾼다.
|
|
45
|
+
*/
|
|
46
|
+
declare function buildTreeNodes(rows: unknown[] | undefined, tree: TreeRowsMapping): TreeNode[];
|
|
47
|
+
/** rows가 비어있지 않고 매핑이 있으면 파생 트리, 아니면 nodes 폴백. TreePicker도 이 판을 쓴다. */
|
|
48
|
+
declare function resolveTreeNodes(nodes: TreeNode[] | undefined, rows: unknown[] | undefined, tree: TreeRowsMapping | undefined): TreeNode[];
|
|
49
|
+
declare function pruneExcluded(nodes: TreeNode[], excluded: ReadonlySet<string>): TreeNode[];
|
|
25
50
|
/**
|
|
26
51
|
* 바깥에서 온 `style`·`className`을 뿌리에 얹어 내보낸다 — 자식 축(`grow`·`width` …)이
|
|
27
52
|
* 이 컴포넌트에서도 동작하게 하는 유일한 통로다. 까닭은 {@link ../boxed.tsx}에 있다.
|
|
28
53
|
*/
|
|
29
54
|
declare const TreeView: React__default.FC<TreeViewProps & SduiBoxProps>;
|
|
30
55
|
|
|
31
|
-
export { type TreeNode, TreeView, type TreeViewProps };
|
|
56
|
+
export { type TreeNode, type TreeRowsMapping, TreeView, type TreeViewProps, buildTreeNodes, pruneExcluded, resolveTreeNodes };
|
package/dist/widgets/TreeView.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { TreeView } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { TreeView, buildTreeNodes, pruneExcluded, resolveTreeNodes } from '../chunk-BS4LGGQV.js';
|
|
2
|
+
import '../chunk-FC2F37QH.js';
|
|
3
|
+
import '../chunk-LMHIRQZ6.js';
|
|
3
4
|
import '../chunk-SAN4IX6N.js';
|
package/dist/widgets/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TreeViewProps } from './TreeView.js';
|
|
2
|
-
export { TreeNode, TreeView } from './TreeView.js';
|
|
2
|
+
export { TreeNode, TreeRowsMapping, TreeView, buildTreeNodes } from './TreeView.js';
|
|
3
3
|
import { TreePickerProps } from './TreePicker.js';
|
|
4
4
|
export { TreePicker } from './TreePicker.js';
|
|
5
5
|
import { TimelineProps } from './Timeline.js';
|
package/dist/widgets/index.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import { SearchableMultiPicker } from '../chunk-
|
|
2
|
-
export { SearchableMultiPicker } from '../chunk-
|
|
3
|
-
import { SecureScreen } from '../chunk-
|
|
4
|
-
export { SecureScreen } from '../chunk-
|
|
1
|
+
import { SearchableMultiPicker } from '../chunk-K5ZJTLFP.js';
|
|
2
|
+
export { SearchableMultiPicker } from '../chunk-K5ZJTLFP.js';
|
|
3
|
+
import { SecureScreen } from '../chunk-5C4SIRSW.js';
|
|
4
|
+
export { SecureScreen } from '../chunk-5C4SIRSW.js';
|
|
5
5
|
import { StackedMeter } from '../chunk-BMZKZGJF.js';
|
|
6
6
|
export { StackedMeter } from '../chunk-BMZKZGJF.js';
|
|
7
7
|
import { Strip } from '../chunk-ZH5MLOZS.js';
|
|
8
8
|
export { Strip } from '../chunk-ZH5MLOZS.js';
|
|
9
9
|
import { SummaryTable } from '../chunk-O4U7Y3XL.js';
|
|
10
10
|
export { SummaryTable } from '../chunk-O4U7Y3XL.js';
|
|
11
|
-
import { TagMultiSelect } from '../chunk-
|
|
12
|
-
export { TagMultiSelect } from '../chunk-
|
|
13
|
-
import { Timeline } from '../chunk-
|
|
14
|
-
export { Timeline } from '../chunk-
|
|
15
|
-
import { TreePicker } from '../chunk-
|
|
16
|
-
export { TreePicker } from '../chunk-
|
|
17
|
-
import { TreeView } from '../chunk-
|
|
18
|
-
export { TreeView } from '../chunk-
|
|
19
|
-
import { EventCalendar } from '../chunk-
|
|
20
|
-
export { EventCalendar } from '../chunk-
|
|
21
|
-
import { ImageLightbox } from '../chunk-
|
|
22
|
-
export { ImageLightbox } from '../chunk-
|
|
23
|
-
import { InlineEdit } from '../chunk-
|
|
24
|
-
export { InlineEdit } from '../chunk-
|
|
25
|
-
import { JsonField } from '../chunk-
|
|
26
|
-
export { JsonField } from '../chunk-
|
|
11
|
+
import { TagMultiSelect } from '../chunk-K55ODWRY.js';
|
|
12
|
+
export { TagMultiSelect } from '../chunk-K55ODWRY.js';
|
|
13
|
+
import { Timeline } from '../chunk-VBCUIM7N.js';
|
|
14
|
+
export { Timeline } from '../chunk-VBCUIM7N.js';
|
|
15
|
+
import { TreePicker } from '../chunk-JND5NXUT.js';
|
|
16
|
+
export { TreePicker } from '../chunk-JND5NXUT.js';
|
|
17
|
+
import { TreeView } from '../chunk-BS4LGGQV.js';
|
|
18
|
+
export { TreeView, buildTreeNodes } from '../chunk-BS4LGGQV.js';
|
|
19
|
+
import { EventCalendar } from '../chunk-CXZYC7IN.js';
|
|
20
|
+
export { EventCalendar } from '../chunk-CXZYC7IN.js';
|
|
21
|
+
import { ImageLightbox } from '../chunk-R3IK6EPA.js';
|
|
22
|
+
export { ImageLightbox } from '../chunk-R3IK6EPA.js';
|
|
23
|
+
import { InlineEdit } from '../chunk-BOSSWJTN.js';
|
|
24
|
+
export { InlineEdit } from '../chunk-BOSSWJTN.js';
|
|
25
|
+
import { JsonField } from '../chunk-X5X3FKCQ.js';
|
|
26
|
+
export { JsonField } from '../chunk-X5X3FKCQ.js';
|
|
27
27
|
import { LiveClock } from '../chunk-Z3WGIFJP.js';
|
|
28
28
|
export { LiveClock } from '../chunk-Z3WGIFJP.js';
|
|
29
|
-
import { OrgChart } from '../chunk-
|
|
30
|
-
export { OrgChart } from '../chunk-
|
|
31
|
-
import { PeriodFilter } from '../chunk-
|
|
32
|
-
export { PeriodFilter } from '../chunk-
|
|
33
|
-
import { PrintSheet } from '../chunk-
|
|
34
|
-
export { PrintSheet } from '../chunk-
|
|
35
|
-
export { AutocompleteField, toAutocompleteOptions } from '../chunk-
|
|
36
|
-
import '../chunk-
|
|
37
|
-
import { ColumnBoard } from '../chunk-
|
|
38
|
-
export { ColumnBoard } from '../chunk-
|
|
39
|
-
import { DiffView } from '../chunk-
|
|
40
|
-
export { DiffView } from '../chunk-
|
|
41
|
-
import { Disclosure } from '../chunk-
|
|
42
|
-
export { Disclosure } from '../chunk-
|
|
43
|
-
import '../chunk-
|
|
29
|
+
import { OrgChart } from '../chunk-F2MKI3W5.js';
|
|
30
|
+
export { OrgChart } from '../chunk-F2MKI3W5.js';
|
|
31
|
+
import { PeriodFilter } from '../chunk-4NPTFNAL.js';
|
|
32
|
+
export { PeriodFilter } from '../chunk-4NPTFNAL.js';
|
|
33
|
+
import { PrintSheet } from '../chunk-5YVXVGQ2.js';
|
|
34
|
+
export { PrintSheet } from '../chunk-5YVXVGQ2.js';
|
|
35
|
+
export { AutocompleteField, toAutocompleteOptions } from '../chunk-6NAJ2D4A.js';
|
|
36
|
+
import '../chunk-FC2F37QH.js';
|
|
37
|
+
import { ColumnBoard } from '../chunk-G4QIJHEP.js';
|
|
38
|
+
export { ColumnBoard } from '../chunk-G4QIJHEP.js';
|
|
39
|
+
import { DiffView } from '../chunk-LN6IOMCK.js';
|
|
40
|
+
export { DiffView } from '../chunk-LN6IOMCK.js';
|
|
41
|
+
import { Disclosure } from '../chunk-YGSU34B3.js';
|
|
42
|
+
export { Disclosure } from '../chunk-YGSU34B3.js';
|
|
43
|
+
import '../chunk-LMHIRQZ6.js';
|
|
44
44
|
import '../chunk-SAN4IX6N.js';
|
|
45
45
|
|
|
46
46
|
// src/widgets/index.ts
|