@wipco/sdui 0.50.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DatePicker-BK_jsV7i.d.ts → DatePicker-C_TT_SOw.d.ts} +25 -0
- package/dist/{chunk-OEWTVLPZ.js → chunk-2HLXCKK7.js} +2 -2
- package/dist/{chunk-PWVHAUJC.js → chunk-2YP5N4VV.js} +6 -4
- package/dist/{chunk-QTHYLNJW.js → chunk-37SFFW37.js} +2 -13
- package/dist/{chunk-YQOMSWW5.js → chunk-5WW4MBRO.js} +1 -1
- package/dist/{chunk-LIOS3PF2.js → chunk-5XPZ3RSA.js} +3 -4
- package/dist/{chunk-ZD3VNVRF.js → chunk-7BGDSSAN.js} +5 -13
- package/dist/{chunk-Y2LIEWQX.js → chunk-7FZTUI6U.js} +6 -5
- package/dist/{chunk-HJ5VSXR4.js → chunk-7P7N43JV.js} +2 -2
- package/dist/{chunk-55VB6SDU.js → chunk-A5XQOEVH.js} +23 -20
- package/dist/{chunk-77LKJCMM.js → chunk-A6LAIGUS.js} +20 -108
- package/dist/{chunk-YXS5FXVS.js → chunk-AC5TI3BE.js} +7 -16
- package/dist/{chunk-AIOJYVJ2.js → chunk-AXGF4M57.js} +1 -1
- package/dist/{chunk-5MPK3NZK.js → chunk-B6WMC2AN.js} +3 -3
- package/dist/{chunk-C6ZV4VBN.js → chunk-C37U3GCC.js} +4 -4
- package/dist/{chunk-265YPW4W.js → chunk-DMLDKW7K.js} +1 -1
- package/dist/{chunk-FZ72IDVF.js → chunk-E6ISNQK3.js} +2 -2
- package/dist/{chunk-STX2AX6Y.js → chunk-FLAN7CV3.js} +7 -39
- package/dist/{chunk-IV5YTVHR.js → chunk-GE6BYNQJ.js} +18 -33
- package/dist/{chunk-ZX36LKJ7.js → chunk-GTGS2QRL.js} +7 -6
- package/dist/{chunk-NL3I6F2I.js → chunk-HBBTENSV.js} +3 -3
- package/dist/{chunk-RUU7WBGR.js → chunk-I45EUZC6.js} +19 -9
- package/dist/{chunk-JBKNIALK.js → chunk-I5SD7XRA.js} +9 -6
- package/dist/{chunk-X7GHY2RI.js → chunk-IFKYGJXP.js} +14 -42
- package/dist/{chunk-J3YMUR6R.js → chunk-IZ3JA2BR.js} +3 -3
- package/dist/{chunk-AUW5RP24.js → chunk-JIV4YHCZ.js} +7 -6
- package/dist/{chunk-M6KM3FJS.js → chunk-JYAR7D5U.js} +2 -2
- package/dist/{chunk-DKPNFEVU.js → chunk-KO6OEY3G.js} +19 -6
- package/dist/{chunk-JHHMFL5D.js → chunk-LFEJLOFN.js} +28 -16
- package/dist/chunk-MMIGOPO5.js +111 -0
- package/dist/{chunk-YSSNP6JM.js → chunk-N25YP7ID.js} +6 -21
- package/dist/{chunk-F2W2FWOT.js → chunk-N5RKM6IC.js} +7 -7
- package/dist/{chunk-C4HYWZML.js → chunk-O4IISNE7.js} +1 -1
- package/dist/chunk-Q4SWUINA.js +51 -0
- package/dist/{chunk-TUOG7EEI.js → chunk-RNOUXUBO.js} +418 -22
- package/dist/{chunk-4VZI3PLI.js → chunk-RYHEV5E3.js} +15 -39
- package/dist/{chunk-AVRNQOB5.js → chunk-SAPBDJJQ.js} +14 -13
- package/dist/{chunk-OPJ4DYNI.js → chunk-SJ3737RA.js} +156 -158
- package/dist/{chunk-UMANGYRD.js → chunk-TFGNKFL2.js} +1 -1
- package/dist/{chunk-KYGSMUUU.js → chunk-VY7MVBSE.js} +2 -2
- package/dist/{chunk-VDBUXYEB.js → chunk-WOYMEEPH.js} +8 -8
- package/dist/{chunk-I5Z2RVDF.js → chunk-WSLT32Q4.js} +278 -30
- package/dist/{chunk-NYUHSMUU.js → chunk-XGFDY43I.js} +2 -2
- package/dist/{chunk-ODKZF4IT.js → chunk-YOZN35HD.js} +17 -9
- package/dist/{chunk-EKP6Z3G6.js → chunk-YVTV4ZV6.js} +1 -1
- package/dist/{chunk-6BCWFPNJ.js → chunk-YWUDBLO6.js} +2 -2
- package/dist/chunk-Z4PYMTTS.js +41 -0
- package/dist/{chunk-WXIQLWIX.js → chunk-ZFNFPXPR.js} +2 -2
- package/dist/{chunk-7GOWOSX6.js → chunk-ZORQPB6B.js} +11 -5
- package/dist/index.d.ts +1118 -943
- package/dist/index.js +369 -610
- package/dist/meta.d.ts +13 -12
- package/dist/meta.js +84 -16
- package/dist/rich/ExcelUploadCard.d.ts +7 -0
- package/dist/rich/ExcelUploadCard.js +17 -13
- package/dist/rich.d.ts +1 -1
- package/dist/rich.js +25 -12
- package/dist/styles.css +10 -2
- package/dist/{types-D14eqLpf.d.ts → types-C7y9CpgF.d.ts} +7 -5
- package/dist/widgets/ApprovalLineEditor.js +7 -6
- package/dist/widgets/ApprovalOverridesEditor.d.ts +11 -1
- package/dist/widgets/ApprovalOverridesEditor.js +9 -8
- package/dist/widgets/ApprovalStepper.js +3 -3
- package/dist/widgets/AutocompleteField.d.ts +1 -0
- package/dist/widgets/AutocompleteField.js +7 -6
- package/dist/widgets/ColumnBoard.js +3 -3
- package/dist/widgets/DiffView.js +3 -3
- package/dist/widgets/Disclosure.js +3 -3
- package/dist/widgets/EventCalendar.d.ts +16 -1
- package/dist/widgets/EventCalendar.js +3 -3
- package/dist/widgets/FileDropzone.js +7 -6
- package/dist/widgets/ImageLightbox.js +5 -4
- package/dist/widgets/InlineEdit.js +3 -3
- package/dist/widgets/JsonField.js +3 -3
- package/dist/widgets/LiveClock.js +2 -2
- package/dist/widgets/OptionSchemaEditor.js +4 -4
- package/dist/widgets/OptionValueFields.d.ts +5 -0
- package/dist/widgets/OptionValueFields.js +4 -4
- package/dist/widgets/OrgChart.js +4 -3
- package/dist/widgets/OrgChartBoard.d.ts +93 -4
- package/dist/widgets/OrgChartBoard.js +9 -6
- package/dist/widgets/PeriodFilter.js +4 -4
- package/dist/widgets/PermissionMatrixEditor.d.ts +16 -0
- package/dist/widgets/PermissionMatrixEditor.js +4 -4
- package/dist/widgets/PositionSelect.d.ts +6 -1
- package/dist/widgets/PositionSelect.js +5 -4
- package/dist/widgets/PrintSheet.js +3 -3
- package/dist/widgets/ProfileEditDiffCard.d.ts +6 -0
- package/dist/widgets/ProfileEditDiffCard.js +4 -4
- package/dist/widgets/QRDisplay.js +4 -4
- package/dist/widgets/RankBoard.d.ts +6 -0
- package/dist/widgets/RankBoard.js +6 -5
- package/dist/widgets/RecordSheet.js +2 -2
- package/dist/widgets/RoleMemberPicker.d.ts +11 -5
- package/dist/widgets/RoleMemberPicker.js +5 -4
- package/dist/widgets/SearchableMultiPicker.js +5 -5
- package/dist/widgets/SecureScreen.d.ts +12 -0
- package/dist/widgets/SecureScreen.js +3 -3
- package/dist/widgets/StackedMeter.js +2 -2
- package/dist/widgets/StagePeriodEditor.js +4 -5
- package/dist/widgets/Strip.js +2 -2
- package/dist/widgets/SummaryTable.js +2 -2
- package/dist/widgets/TagMultiSelect.d.ts +0 -1
- package/dist/widgets/TagMultiSelect.js +4 -4
- package/dist/widgets/Timeline.js +4 -4
- package/dist/widgets/TreePicker.js +6 -6
- package/dist/widgets/TreeView.js +5 -5
- package/dist/widgets/index.d.ts +3 -3
- package/dist/widgets/index.js +81 -79
- package/package.json +1 -1
- package/dist/chunk-EKVA7T7P.js +0 -198
|
@@ -15,10 +15,31 @@ interface TimePickerProps {
|
|
|
15
15
|
invalid?: boolean;
|
|
16
16
|
disabled?: boolean;
|
|
17
17
|
size?: 'sm' | 'md' | 'lg';
|
|
18
|
+
/**
|
|
19
|
+
* 목록(listbox)의 낭독 라벨. 값 계약(HH:MM)은 로캘과 무관하고 이 문구만 한국어라,
|
|
20
|
+
* 한국어권 밖 소비 프로젝트가 여기 하나만 갈아 끼우면 된다.
|
|
21
|
+
*/
|
|
22
|
+
listLabel?: string;
|
|
18
23
|
}
|
|
19
24
|
/** 바깥에서 온 `style`·`className`을 뿌리에 얹어 내보낸다. 까닭은 {@link ./boxed.tsx}에 있다. */
|
|
20
25
|
declare const TimePicker: React__default.FC<TimePickerProps & SduiBoxProps>;
|
|
21
26
|
|
|
27
|
+
interface DatePickerLocale {
|
|
28
|
+
/** 요일 머리글 — **일요일부터** 7개. 주 시작이 달라도 이 순서로 주면 내부에서 돌린다. */
|
|
29
|
+
weekdays?: readonly string[];
|
|
30
|
+
/** 주 시작 요일 (0=일 … 6=토). */
|
|
31
|
+
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
32
|
+
/** 달력 위 연월 캡션 (month는 1–12). */
|
|
33
|
+
formatCaption?: (year: number, month: number) => string;
|
|
34
|
+
/** 이전/다음 달 버튼의 낭독 라벨 */
|
|
35
|
+
prevMonthLabel?: string;
|
|
36
|
+
nextMonthLabel?: string;
|
|
37
|
+
/** 달력 패널의 낭독 라벨 */
|
|
38
|
+
calendarLabel?: string;
|
|
39
|
+
/** 기간 달력에서 시작·종료 칸의 낭독 라벨 (DateRangePicker) */
|
|
40
|
+
startLabel?: string;
|
|
41
|
+
endLabel?: string;
|
|
42
|
+
}
|
|
22
43
|
interface DatePickerProps {
|
|
23
44
|
/** 선택된 날짜 (YYYY-MM-DD, `withTime`이면 YYYY-MM-DDTHH:mm). 주어지면 controlled로 동작. */
|
|
24
45
|
value?: string;
|
|
@@ -36,6 +57,8 @@ interface DatePickerProps {
|
|
|
36
57
|
* 같은 모양이라 서버로 가는 문자열은 그대로다). 칸에는 `2026-08-18 14:30`으로 보인다.
|
|
37
58
|
*/
|
|
38
59
|
withTime?: boolean;
|
|
60
|
+
/** 표시 로캘(요일·캡션·낭독 라벨·주 시작 요일). 기본 한국어·일요일 시작. 값 계약은 불변. */
|
|
61
|
+
locale?: DatePickerLocale;
|
|
39
62
|
}
|
|
40
63
|
interface DateRangeValue {
|
|
41
64
|
from?: string;
|
|
@@ -57,6 +80,8 @@ interface DateRangePickerProps {
|
|
|
57
80
|
invalid?: boolean;
|
|
58
81
|
disabled?: boolean;
|
|
59
82
|
size?: 'sm' | 'md' | 'lg';
|
|
83
|
+
/** 표시 로캘(요일·캡션·낭독 라벨·주 시작 요일). 기본 한국어·일요일 시작. 값 계약은 불변. */
|
|
84
|
+
locale?: DatePickerLocale;
|
|
60
85
|
}
|
|
61
86
|
/** 바깥에서 온 `style`·`className`을 뿌리에 얹어 내보낸다. 까닭은 {@link ./boxed.tsx}에 있다. */
|
|
62
87
|
declare const DatePicker: React__default.FC<DatePickerProps & SduiBoxProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Icon } from './chunk-
|
|
2
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { Icon } from './chunk-RNOUXUBO.js';
|
|
2
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
3
3
|
import { useState, useId, useCallback } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
var SUMMARY_TABLE_CSS = `
|
|
@@ -18,11 +18,13 @@ function cellClass(column) {
|
|
|
18
18
|
return classes.length > 0 ? classes.join(" ") : void 0;
|
|
19
19
|
}
|
|
20
20
|
function SummaryTableImpl({ columns, rows, footer, dense = false }) {
|
|
21
|
+
const safeColumns = Array.isArray(columns) ? columns : [];
|
|
22
|
+
const safeRows = Array.isArray(rows) ? rows : [];
|
|
21
23
|
const tableClass = dense ? "wp-table wp-table--dense erp-sumtable" : "wp-table erp-sumtable";
|
|
22
24
|
return /* @__PURE__ */ jsxs("div", { className: "erp-sumtable__scroll", children: [
|
|
23
25
|
/* @__PURE__ */ jsx(SummaryTableStyles, {}),
|
|
24
26
|
/* @__PURE__ */ jsxs("table", { className: tableClass, children: [
|
|
25
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children:
|
|
27
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: safeColumns.map((column) => /* @__PURE__ */ jsx(
|
|
26
28
|
"th",
|
|
27
29
|
{
|
|
28
30
|
style: column.align === "right" ? { textAlign: "right" } : void 0,
|
|
@@ -30,8 +32,8 @@ function SummaryTableImpl({ columns, rows, footer, dense = false }) {
|
|
|
30
32
|
},
|
|
31
33
|
column.key
|
|
32
34
|
)) }) }),
|
|
33
|
-
/* @__PURE__ */ jsx("tbody", { children:
|
|
34
|
-
footer !== void 0 ? /* @__PURE__ */ jsx("tfoot", { children: /* @__PURE__ */ jsx("tr", { children:
|
|
35
|
+
/* @__PURE__ */ jsx("tbody", { children: safeRows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { className: "erp-sumtable__empty", colSpan: Math.max(safeColumns.length, 1), children: "\uD45C\uC2DC\uD560 \uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) }) : safeRows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", { children: safeColumns.map((column) => /* @__PURE__ */ jsx("td", { className: cellClass(column), children: row[column.key] }, column.key)) }, rowIndex)) }),
|
|
36
|
+
footer !== void 0 ? /* @__PURE__ */ jsx("tfoot", { children: /* @__PURE__ */ jsx("tr", { children: safeColumns.map((column) => /* @__PURE__ */ jsx("td", { className: cellClass(column), children: footer[column.key] }, column.key)) }) }) : null
|
|
35
37
|
] })
|
|
36
38
|
] });
|
|
37
39
|
}
|
|
@@ -1,22 +1,11 @@
|
|
|
1
|
-
import { mergeStyle, containerLayoutStyle, joinClass, columnsClass, typographyStyle } from './chunk-
|
|
1
|
+
import { mergeStyle, containerLayoutStyle, joinClass, columnsClass, typographyStyle, GAP_CSS } from './chunk-5WW4MBRO.js';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
function paddingStyle(padding) {
|
|
6
|
-
const value = padding === void 0 ? void 0 :
|
|
6
|
+
const value = padding === void 0 ? void 0 : GAP_CSS[padding];
|
|
7
7
|
return value === void 0 ? {} : { padding: value };
|
|
8
8
|
}
|
|
9
|
-
var PADDING_CSS = {
|
|
10
|
-
"0": "0px",
|
|
11
|
-
"2": "2px",
|
|
12
|
-
"4": "4px",
|
|
13
|
-
"8": "8px",
|
|
14
|
-
"12": "12px",
|
|
15
|
-
"16": "16px",
|
|
16
|
-
"20": "20px",
|
|
17
|
-
"24": "24px",
|
|
18
|
-
"32": "32px"
|
|
19
|
-
};
|
|
20
9
|
function Grid({
|
|
21
10
|
columns = 3,
|
|
22
11
|
template,
|
|
@@ -171,4 +171,4 @@ function boxed(Inner, displayName) {
|
|
|
171
171
|
return Wrapped;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
export { CHILD_LAYOUT_PROPS, LAYOUT_CSS, boxed, childLayoutFrom, columnsClass, containerLayoutStyle, joinClass, mergeStyle, typographyStyle };
|
|
174
|
+
export { CHILD_LAYOUT_PROPS, GAP_CSS, LAYOUT_CSS, boxed, childLayoutFrom, columnsClass, containerLayoutStyle, joinClass, mergeStyle, typographyStyle };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { TimePicker } from './chunk-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { boxed } from './chunk-YQOMSWW5.js';
|
|
1
|
+
import { DatePicker, TimePicker } from './chunk-WSLT32Q4.js';
|
|
2
|
+
import { Field } from './chunk-RNOUXUBO.js';
|
|
3
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
5
4
|
import { useState, useRef, useEffect, useMemo } from 'react';
|
|
6
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
6
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { resolveTreeNodes, TreeView } from './chunk-
|
|
1
|
+
import { resolveTreeNodes, TreeView } from './chunk-C37U3GCC.js';
|
|
2
2
|
import { OverlayLayer } from './chunk-XQPTSEJC.js';
|
|
3
|
-
import { Field, Dialog, Icon, Button, Input } from './chunk-
|
|
4
|
-
import { boxed } from './chunk-
|
|
5
|
-
import { useState, useMemo
|
|
3
|
+
import { Field, Dialog, Icon, Button, Input } from './chunk-RNOUXUBO.js';
|
|
4
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
5
|
+
import { useState, useMemo } from 'react';
|
|
6
6
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
8
|
var PICKER_CSS = `
|
|
@@ -55,14 +55,6 @@ function TreePickerImpl({
|
|
|
55
55
|
onChange?.(pendingId, node);
|
|
56
56
|
setOpen(false);
|
|
57
57
|
};
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (!open) return;
|
|
60
|
-
const onKeyDown = (event) => {
|
|
61
|
-
if (event.key === "Escape") setOpen(false);
|
|
62
|
-
};
|
|
63
|
-
document.addEventListener("keydown", onKeyDown);
|
|
64
|
-
return () => document.removeEventListener("keydown", onKeyDown);
|
|
65
|
-
}, [open]);
|
|
66
58
|
const commitDisabled = !allowEmpty && pendingId == null;
|
|
67
59
|
const noneSelected = pendingId == null;
|
|
68
60
|
const trigger = /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "var(--wp-space-2)", minWidth: 0 }, children: [
|
|
@@ -98,7 +90,7 @@ function TreePickerImpl({
|
|
|
98
90
|
)
|
|
99
91
|
] });
|
|
100
92
|
return /* @__PURE__ */ jsxs("div", { className: "erp-treepicker", style: { minWidth: 0 }, children: [
|
|
101
|
-
/* @__PURE__ */ jsx("style", { children: PICKER_CSS }),
|
|
93
|
+
/* @__PURE__ */ jsx("style", { href: "erp-treepicker", precedence: "medium", children: PICKER_CSS }),
|
|
102
94
|
label ? /* @__PURE__ */ jsx(Field, { label, children: trigger }) : trigger,
|
|
103
95
|
open ? /* @__PURE__ */ jsx(OverlayLayer, { onClose: closeDialog, children: /* @__PURE__ */ jsx(
|
|
104
96
|
Dialog,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Text } from './chunk-
|
|
2
|
-
import { Switch, Field, Select, Input } from './chunk-
|
|
3
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { Text } from './chunk-37SFFW37.js';
|
|
2
|
+
import { Switch, Field, Select, Input } from './chunk-RNOUXUBO.js';
|
|
3
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
4
4
|
import React, { useMemo } from 'react';
|
|
5
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -13,7 +13,8 @@ function OptionValueFieldsImpl({
|
|
|
13
13
|
value,
|
|
14
14
|
onChange,
|
|
15
15
|
disabled = false,
|
|
16
|
-
readOnly = false
|
|
16
|
+
readOnly = false,
|
|
17
|
+
emptySchemaText = "\uC774 \uC7A5\uBE44\uC5D0 \uC815\uD574 \uB454 \uC635\uC158\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC7A5\uBE44 \uC0C1\uC138\uC758 \uC218\uC815 \u2192 \uC635\uC158 \uD0ED\uC5D0\uC11C \uBA3C\uC800 \uC11C\uC2DD\uC744 \uC815\uD558\uC138\uC694."
|
|
17
18
|
}) {
|
|
18
19
|
const fields = useMemo(() => normalizeSchema(schema), [schema]);
|
|
19
20
|
const current = useMemo(
|
|
@@ -48,7 +49,7 @@ function OptionValueFieldsImpl({
|
|
|
48
49
|
}) });
|
|
49
50
|
}
|
|
50
51
|
if (fields.length === 0) {
|
|
51
|
-
return /* @__PURE__ */ jsx(Text, { preset: "body-sm", style: { color: "var(--wp-text-muted)" }, children:
|
|
52
|
+
return /* @__PURE__ */ jsx(Text, { preset: "body-sm", style: { color: "var(--wp-text-muted)" }, children: emptySchemaText });
|
|
52
53
|
}
|
|
53
54
|
return /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-3)" }, children: [
|
|
54
55
|
fields.map((field) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IconButton, Input } from './chunk-
|
|
2
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { IconButton, Input } from './chunk-RNOUXUBO.js';
|
|
2
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
3
3
|
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { fetchAllPages } from './chunk-Q4SWUINA.js';
|
|
2
|
+
import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
|
|
3
|
+
import { Alert, Badge, Spinner, Button, Input, Checkbox } from './chunk-RNOUXUBO.js';
|
|
4
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
5
|
+
import { useRef, useMemo, useState, useCallback, useEffect } from 'react';
|
|
5
6
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
7
|
|
|
7
8
|
var deptOf = (row) => row.department_name ?? row.department?.name ?? null;
|
|
@@ -24,10 +25,13 @@ function RoleMemberPickerImpl({
|
|
|
24
25
|
catalogEndpoint = "/employees",
|
|
25
26
|
employees,
|
|
26
27
|
sourceEndpoint,
|
|
27
|
-
disabled = false
|
|
28
|
+
disabled = false,
|
|
29
|
+
silentStatuses
|
|
28
30
|
}) {
|
|
29
31
|
const adapter = useSduiAdapter();
|
|
30
32
|
const api = hostFetchOf(adapter) ?? defaultAdapter.fetch;
|
|
33
|
+
const apiRef = useRef(api);
|
|
34
|
+
apiRef.current = api;
|
|
31
35
|
const base = useMemo(() => sourceEndpoint ? sourceEndpoint.split("?")[0] : null, [sourceEndpoint]);
|
|
32
36
|
const [members, setMembers] = useState(null);
|
|
33
37
|
const [membersLoading, setMembersLoading] = useState(false);
|
|
@@ -38,16 +42,20 @@ function RoleMemberPickerImpl({
|
|
|
38
42
|
const [saving, setSaving] = useState(false);
|
|
39
43
|
const [removingId, setRemovingId] = useState(null);
|
|
40
44
|
const requestSeq = useRef(0);
|
|
45
|
+
const silentStatusesRef = useRef(silentStatuses);
|
|
46
|
+
silentStatusesRef.current = silentStatuses;
|
|
41
47
|
const fetchMembers = useCallback((endpoint) => {
|
|
42
48
|
const seq = ++requestSeq.current;
|
|
43
49
|
setMembersLoading(true);
|
|
44
|
-
|
|
50
|
+
apiRef.current(endpoint, { method: "GET" }).then((response) => {
|
|
45
51
|
if (requestSeq.current !== seq) return;
|
|
46
52
|
setMembers(parseMembers(response));
|
|
47
53
|
}).catch((err) => {
|
|
48
54
|
if (requestSeq.current !== seq) return;
|
|
49
55
|
setMembers((prev) => prev ?? []);
|
|
50
|
-
|
|
56
|
+
const status = err?.status;
|
|
57
|
+
const silent = typeof status === "number" && (silentStatusesRef.current ?? []).includes(status);
|
|
58
|
+
if (!silent) {
|
|
51
59
|
setError(messageOf(err, "\uC5ED\uD560\uC5D0 \uBD80\uC5EC\uB41C \uC0AC\uC6A9\uC790\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."));
|
|
52
60
|
}
|
|
53
61
|
}).finally(() => {
|
|
@@ -72,25 +80,20 @@ function RoleMemberPickerImpl({
|
|
|
72
80
|
useEffect(() => {
|
|
73
81
|
if (givenCatalog.length > 0 || fetchedCatalog !== null) return;
|
|
74
82
|
let alive = true;
|
|
75
|
-
(
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const batch = Array.isArray(response?.data) ? response.data : [];
|
|
82
|
-
rows.push(...batch.filter((row) => row && typeof row.id === "string"));
|
|
83
|
-
const total = typeof response?.total === "number" ? response.total : rows.length;
|
|
84
|
-
if (batch.length === 0 || rows.length >= total) break;
|
|
85
|
-
}
|
|
83
|
+
fetchAllPages(apiRef.current, catalogEndpoint, (body) => {
|
|
84
|
+
const batch = Array.isArray(body.data) ? body.data : [];
|
|
85
|
+
return batch.filter(
|
|
86
|
+
(row) => typeof row === "object" && row !== null && typeof row.id === "string"
|
|
87
|
+
);
|
|
88
|
+
}).then((rows) => {
|
|
86
89
|
if (alive) setFetchedCatalog(rows);
|
|
87
|
-
})
|
|
90
|
+
}).catch(() => {
|
|
88
91
|
if (alive) setFetchedCatalog([]);
|
|
89
92
|
});
|
|
90
93
|
return () => {
|
|
91
94
|
alive = false;
|
|
92
95
|
};
|
|
93
|
-
}, [givenCatalog, fetchedCatalog,
|
|
96
|
+
}, [givenCatalog, fetchedCatalog, catalogEndpoint]);
|
|
94
97
|
const catalog = givenCatalog.length > 0 ? givenCatalog : fetchedCatalog ?? [];
|
|
95
98
|
const catalogLoading = givenCatalog.length === 0 && fetchedCatalog === null;
|
|
96
99
|
const memberIds = useMemo(() => new Set((members ?? []).map((row) => row.id)), [members]);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { usePanZoomCanvas, MIN_ZOOM, MAX_ZOOM } from './chunk-MMIGOPO5.js';
|
|
2
|
+
import { IconButton, Badge } from './chunk-RNOUXUBO.js';
|
|
3
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
4
|
+
import { useState, useMemo, useCallback, useEffect } from 'react';
|
|
4
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
var NODE_W = 176;
|
|
@@ -8,10 +9,7 @@ var NODE_H = 64;
|
|
|
8
9
|
var SIBLING_GAP = 24;
|
|
9
10
|
var LEVEL_GAP = 48;
|
|
10
11
|
var CANVAS_PADDING = 48;
|
|
11
|
-
var MIN_ZOOM = 0.35;
|
|
12
|
-
var MAX_ZOOM = 1.8;
|
|
13
12
|
var ZOOM_STEP = 1.2;
|
|
14
|
-
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
15
13
|
function buildBlock(node) {
|
|
16
14
|
const childBlocks = (node.children ?? []).map(buildBlock);
|
|
17
15
|
const childAreaWidth = childBlocks.reduce(
|
|
@@ -108,11 +106,20 @@ function OrgChartImpl({
|
|
|
108
106
|
selectedId,
|
|
109
107
|
height = 520
|
|
110
108
|
}) {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
109
|
+
const {
|
|
110
|
+
viewportRef,
|
|
111
|
+
view,
|
|
112
|
+
setView,
|
|
113
|
+
dragging,
|
|
114
|
+
isFullscreen,
|
|
115
|
+
viewportCenter,
|
|
116
|
+
zoomAt,
|
|
117
|
+
toggleFullscreen,
|
|
118
|
+
pointerHandlers
|
|
119
|
+
} = usePanZoomCanvas({
|
|
120
|
+
stopSelector: "[data-orgchart-stop]",
|
|
121
|
+
initialView: { scale: 1, x: 0, y: 0 }
|
|
122
|
+
});
|
|
116
123
|
const [internalSelected, setInternalSelected] = useState(
|
|
117
124
|
void 0
|
|
118
125
|
);
|
|
@@ -128,103 +135,11 @@ function OrgChartImpl({
|
|
|
128
135
|
y: 0
|
|
129
136
|
});
|
|
130
137
|
},
|
|
131
|
-
[layout.width]
|
|
138
|
+
[layout.width, setView, viewportRef]
|
|
132
139
|
);
|
|
133
140
|
useEffect(() => {
|
|
134
141
|
centerView(1);
|
|
135
142
|
}, [centerView]);
|
|
136
|
-
useEffect(() => {
|
|
137
|
-
const handleChange = () => {
|
|
138
|
-
setIsFullscreen(document.fullscreenElement === viewportRef.current);
|
|
139
|
-
};
|
|
140
|
-
document.addEventListener("fullscreenchange", handleChange);
|
|
141
|
-
return () => document.removeEventListener("fullscreenchange", handleChange);
|
|
142
|
-
}, []);
|
|
143
|
-
const zoomAt = useCallback(
|
|
144
|
-
(nextScale, focal) => {
|
|
145
|
-
setView((current) => {
|
|
146
|
-
const scale = clamp(nextScale, MIN_ZOOM, MAX_ZOOM);
|
|
147
|
-
return {
|
|
148
|
-
scale,
|
|
149
|
-
x: focal.x - (focal.x - current.x) / current.scale * scale,
|
|
150
|
-
y: focal.y - (focal.y - current.y) / current.scale * scale
|
|
151
|
-
};
|
|
152
|
-
});
|
|
153
|
-
},
|
|
154
|
-
[]
|
|
155
|
-
);
|
|
156
|
-
useEffect(() => {
|
|
157
|
-
const el = viewportRef.current;
|
|
158
|
-
if (!el) return;
|
|
159
|
-
const handleWheel = (event) => {
|
|
160
|
-
event.preventDefault();
|
|
161
|
-
const rect = el.getBoundingClientRect();
|
|
162
|
-
const focal = {
|
|
163
|
-
x: event.clientX - rect.left,
|
|
164
|
-
y: event.clientY - rect.top
|
|
165
|
-
};
|
|
166
|
-
setView((current) => {
|
|
167
|
-
const scale = clamp(
|
|
168
|
-
current.scale * (event.deltaY > 0 ? 0.9 : 1.1),
|
|
169
|
-
MIN_ZOOM,
|
|
170
|
-
MAX_ZOOM
|
|
171
|
-
);
|
|
172
|
-
return {
|
|
173
|
-
scale,
|
|
174
|
-
x: focal.x - (focal.x - current.x) / current.scale * scale,
|
|
175
|
-
y: focal.y - (focal.y - current.y) / current.scale * scale
|
|
176
|
-
};
|
|
177
|
-
});
|
|
178
|
-
};
|
|
179
|
-
el.addEventListener("wheel", handleWheel, { passive: false });
|
|
180
|
-
return () => el.removeEventListener("wheel", handleWheel);
|
|
181
|
-
}, []);
|
|
182
|
-
const viewportCenter = useCallback(() => {
|
|
183
|
-
const rect = viewportRef.current?.getBoundingClientRect();
|
|
184
|
-
if (!rect) return { x: 0, y: 0 };
|
|
185
|
-
return { x: rect.width / 2, y: rect.height / 2 };
|
|
186
|
-
}, []);
|
|
187
|
-
const handlePointerDown = (event) => {
|
|
188
|
-
if (event.target.closest("[data-orgchart-stop]")) return;
|
|
189
|
-
dragRef.current = {
|
|
190
|
-
pointerId: event.pointerId,
|
|
191
|
-
startX: event.clientX,
|
|
192
|
-
startY: event.clientY,
|
|
193
|
-
originX: view.x,
|
|
194
|
-
originY: view.y
|
|
195
|
-
};
|
|
196
|
-
setDragging(true);
|
|
197
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
198
|
-
};
|
|
199
|
-
const handlePointerMove = (event) => {
|
|
200
|
-
const drag = dragRef.current;
|
|
201
|
-
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
202
|
-
setView((current) => ({
|
|
203
|
-
...current,
|
|
204
|
-
x: drag.originX + event.clientX - drag.startX,
|
|
205
|
-
y: drag.originY + event.clientY - drag.startY
|
|
206
|
-
}));
|
|
207
|
-
};
|
|
208
|
-
const handlePointerUp = (event) => {
|
|
209
|
-
if (dragRef.current?.pointerId !== event.pointerId) return;
|
|
210
|
-
dragRef.current = null;
|
|
211
|
-
setDragging(false);
|
|
212
|
-
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
213
|
-
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
const toggleFullscreen = async () => {
|
|
217
|
-
const viewport = viewportRef.current;
|
|
218
|
-
if (!viewport) return;
|
|
219
|
-
try {
|
|
220
|
-
if (document.fullscreenElement === viewport) {
|
|
221
|
-
await document.exitFullscreen();
|
|
222
|
-
} else {
|
|
223
|
-
await viewport.requestFullscreen();
|
|
224
|
-
}
|
|
225
|
-
} catch {
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
143
|
const handleNodeClick = (node) => {
|
|
229
144
|
if (selectedId === void 0) setInternalSelected(node.id);
|
|
230
145
|
onNodeClick?.(node);
|
|
@@ -235,10 +150,7 @@ function OrgChartImpl({
|
|
|
235
150
|
ref: viewportRef,
|
|
236
151
|
role: "application",
|
|
237
152
|
"aria-label": "\uC870\uC9C1\uB3C4 \uCE94\uBC84\uC2A4",
|
|
238
|
-
|
|
239
|
-
onPointerMove: handlePointerMove,
|
|
240
|
-
onPointerUp: handlePointerUp,
|
|
241
|
-
onPointerCancel: handlePointerUp,
|
|
153
|
+
...pointerHandlers,
|
|
242
154
|
style: {
|
|
243
155
|
position: "relative",
|
|
244
156
|
height: isFullscreen ? "100vh" : height,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { includesLooseSearch } from './chunk-
|
|
1
|
+
import { includesLooseSearch } from './chunk-WOYMEEPH.js';
|
|
2
2
|
import { OverlayLayer } from './chunk-XQPTSEJC.js';
|
|
3
|
-
import { Button, Dialog, Input, Tag, Checkbox } from './chunk-
|
|
4
|
-
import { boxed } from './chunk-
|
|
5
|
-
import React, { useMemo, useState
|
|
3
|
+
import { Button, Dialog, Input, Tag, Checkbox } from './chunk-RNOUXUBO.js';
|
|
4
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
5
|
+
import React, { useMemo, useState } from 'react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
8
|
function SearchableMultiPickerImpl({
|
|
@@ -16,7 +16,7 @@ function SearchableMultiPickerImpl({
|
|
|
16
16
|
const safeOptions = useMemo(() => options ?? [], [options]);
|
|
17
17
|
const isControlled = values !== void 0 && typeof onChange === "function";
|
|
18
18
|
const [internalValues, setInternalValues] = useState(values ?? []);
|
|
19
|
-
const committed = isControlled ? values : internalValues;
|
|
19
|
+
const committed = (isControlled ? values : internalValues) ?? [];
|
|
20
20
|
const [open, setOpen] = useState(false);
|
|
21
21
|
const [query, setQuery] = useState("");
|
|
22
22
|
const [draft, setDraft] = useState([]);
|
|
@@ -33,9 +33,8 @@ function SearchableMultiPickerImpl({
|
|
|
33
33
|
};
|
|
34
34
|
const openDialog = () => {
|
|
35
35
|
if (disabled) return;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
setSelectedAtOpen(new Set(current));
|
|
36
|
+
setDraft(sortByOptionOrder(committed));
|
|
37
|
+
setSelectedAtOpen(new Set(committed));
|
|
39
38
|
setQuery("");
|
|
40
39
|
setOpen(true);
|
|
41
40
|
};
|
|
@@ -51,14 +50,6 @@ function SearchableMultiPickerImpl({
|
|
|
51
50
|
(current) => sortByOptionOrder(checked ? [...current, value] : current.filter((item) => item !== value))
|
|
52
51
|
);
|
|
53
52
|
};
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
if (!open) return;
|
|
56
|
-
const closeOnEscape = (event) => {
|
|
57
|
-
if (event.key === "Escape") setOpen(false);
|
|
58
|
-
};
|
|
59
|
-
document.addEventListener("keydown", closeOnEscape);
|
|
60
|
-
return () => document.removeEventListener("keydown", closeOnEscape);
|
|
61
|
-
}, [open]);
|
|
62
53
|
const visibleOptions = useMemo(() => {
|
|
63
54
|
const selectedFirst = [
|
|
64
55
|
...safeOptions.filter((option) => selectedAtOpen.has(option.value)),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Text } from './chunk-
|
|
2
|
-
import { Field, Input, Select, IconButton, Button } from './chunk-
|
|
3
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { Text } from './chunk-37SFFW37.js';
|
|
2
|
+
import { Field, Input, Select, IconButton, Button } from './chunk-RNOUXUBO.js';
|
|
3
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
4
4
|
import { useMemo } from 'react';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { buildCascadingTree } from './chunk-
|
|
2
|
-
import { Input, IconButton, EmptyState, Icon, Badge } from './chunk-
|
|
3
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { buildCascadingTree } from './chunk-WOYMEEPH.js';
|
|
2
|
+
import { Input, IconButton, EmptyState, Icon, Badge } from './chunk-RNOUXUBO.js';
|
|
3
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
4
4
|
import React, { useMemo, useState, useRef, useEffect } from 'react';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -239,7 +239,7 @@ function TreeViewImpl({
|
|
|
239
239
|
className: "erp-treeview",
|
|
240
240
|
style: { display: "flex", flexDirection: "column", gap: "var(--wp-space-2)", minWidth: 0 },
|
|
241
241
|
children: [
|
|
242
|
-
/* @__PURE__ */ jsx("style", { children: TREE_CSS }),
|
|
242
|
+
/* @__PURE__ */ jsx("style", { href: "erp-treeview", precedence: "medium", children: TREE_CSS }),
|
|
243
243
|
searchable ? /* @__PURE__ */ jsx(
|
|
244
244
|
Input,
|
|
245
245
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Button } from './chunk-
|
|
2
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { Button } from './chunk-RNOUXUBO.js';
|
|
2
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
3
3
|
import { useEffect } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { orderCircleStyle, ellipsisStyle, unwrapRows, uid } from './chunk-Q4SWUINA.js';
|
|
2
|
+
import { includesLooseSearch } from './chunk-WOYMEEPH.js';
|
|
3
|
+
import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
|
|
4
|
+
import { Icon, Badge, IconButton, Field, Select, Input, Tag, Spinner, Button, isPlainObject } from './chunk-RNOUXUBO.js';
|
|
5
|
+
import { boxed } from './chunk-5WW4MBRO.js';
|
|
5
6
|
import React, { useState, useId, useRef, useEffect } from 'react';
|
|
6
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
8
|
|
|
@@ -47,29 +48,13 @@ var stepLabel = (step) => {
|
|
|
47
48
|
}
|
|
48
49
|
};
|
|
49
50
|
var renumber = (steps) => steps.map((step, index) => ({ ...step, order: index + 1 }));
|
|
50
|
-
var uidCounter = 0;
|
|
51
|
-
var uid = (prefix) => `${prefix}-${Date.now()}-${++uidCounter}`;
|
|
52
|
-
function isRecord(value) {
|
|
53
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
54
|
-
}
|
|
55
51
|
function toSearchResults(payload) {
|
|
56
|
-
|
|
57
|
-
if (Array.isArray(payload)) rows = payload;
|
|
58
|
-
else if (isRecord(payload)) {
|
|
59
|
-
for (const key of ["items", "data", "results", "rows"]) {
|
|
60
|
-
const inner = payload[key];
|
|
61
|
-
if (Array.isArray(inner)) {
|
|
62
|
-
rows = inner;
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return rows.filter(isRecord).flatMap((row) => {
|
|
52
|
+
return unwrapRows(payload).flatMap((row) => {
|
|
68
53
|
const id = row.id;
|
|
69
54
|
const name = row.name ?? row.label;
|
|
70
55
|
if (id === null || id === void 0 || name === null || name === void 0) return [];
|
|
71
56
|
const subRaw = row.sub ?? row.email ?? row.workEmail ?? row.department;
|
|
72
|
-
const sub =
|
|
57
|
+
const sub = isPlainObject(subRaw) ? subRaw.name : subRaw;
|
|
73
58
|
return [
|
|
74
59
|
{
|
|
75
60
|
id: String(id),
|
|
@@ -80,23 +65,6 @@ function toSearchResults(payload) {
|
|
|
80
65
|
];
|
|
81
66
|
});
|
|
82
67
|
}
|
|
83
|
-
var ellipsisStyle = {
|
|
84
|
-
display: "block",
|
|
85
|
-
overflow: "hidden",
|
|
86
|
-
textOverflow: "ellipsis",
|
|
87
|
-
whiteSpace: "nowrap"
|
|
88
|
-
};
|
|
89
|
-
var orderCircleStyle = {
|
|
90
|
-
display: "inline-flex",
|
|
91
|
-
alignItems: "center",
|
|
92
|
-
justifyContent: "center",
|
|
93
|
-
width: 28,
|
|
94
|
-
height: 28,
|
|
95
|
-
flex: "none",
|
|
96
|
-
borderRadius: "var(--wp-radius-pill)",
|
|
97
|
-
background: "var(--wp-surface-brand-tint)",
|
|
98
|
-
color: "var(--wp-text-brand)"
|
|
99
|
-
};
|
|
100
68
|
var dashedEmptyStyle = {
|
|
101
69
|
border: "var(--wp-border-w) dashed var(--wp-border-default)",
|
|
102
70
|
borderRadius: "var(--wp-radius-lg)",
|