@wipco/sdui 0.33.0 → 0.34.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/chunk-D4AILKSJ.js +159 -0
- package/dist/{chunk-LDJ2CFFH.js → chunk-XAYXHY7R.js} +9 -2
- package/dist/meta.d.ts +3 -1
- package/dist/meta.js +50 -2
- package/dist/widgets/DiffView.d.ts +11 -0
- package/dist/widgets/DiffView.js +1 -1
- package/dist/widgets/PositionSelect.d.ts +44 -0
- package/dist/widgets/PositionSelect.js +4 -0
- package/dist/widgets/index.d.ts +4 -1
- package/dist/widgets/index.js +7 -4
- package/package.json +5 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-DKPNFEVU.js';
|
|
2
|
+
import { Select, Button } from './chunk-WIDDHR7L.js';
|
|
3
|
+
import { boxed } from './chunk-SAN4IX6N.js';
|
|
4
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var EMPTY_VALUE = "__wipco_position_none__";
|
|
8
|
+
var LOADING_VALUE = "__wipco_position_loading__";
|
|
9
|
+
var toNumber = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
10
|
+
function parseRow(raw) {
|
|
11
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
12
|
+
const row = raw;
|
|
13
|
+
if (typeof row.name !== "string") return null;
|
|
14
|
+
return {
|
|
15
|
+
name: row.name,
|
|
16
|
+
rankOrder: toNumber(row.rank_order),
|
|
17
|
+
sortOrder: toNumber(row.sort_order),
|
|
18
|
+
// is_active 결측은 true 폴백 — 파서 사정으로 목록이 전부 사라지는 사고 방지(v2와 동일).
|
|
19
|
+
isActive: row.is_active === void 0 || row.is_active === null ? true : row.is_active === true
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
async function fetchAllPositions(api, endpoint) {
|
|
23
|
+
const LIMIT = 500;
|
|
24
|
+
const MAX_PAGES = 10;
|
|
25
|
+
const rows = [];
|
|
26
|
+
let offset = 0;
|
|
27
|
+
for (let page = 0; page < MAX_PAGES; page += 1) {
|
|
28
|
+
const sep = endpoint.includes("?") ? "&" : "?";
|
|
29
|
+
const res = await api(`${endpoint}${sep}limit=${LIMIT}&offset=${offset}`, {
|
|
30
|
+
method: "GET"
|
|
31
|
+
});
|
|
32
|
+
const data = Array.isArray(res?.data) ? res.data : [];
|
|
33
|
+
for (const raw of data) {
|
|
34
|
+
const parsed = parseRow(raw);
|
|
35
|
+
if (parsed) rows.push(parsed);
|
|
36
|
+
}
|
|
37
|
+
const total = typeof res?.total === "number" ? res.total : rows.length;
|
|
38
|
+
offset += LIMIT;
|
|
39
|
+
if (data.length === 0 || rows.length >= total) break;
|
|
40
|
+
}
|
|
41
|
+
return rows;
|
|
42
|
+
}
|
|
43
|
+
var inflight = /* @__PURE__ */ new Map();
|
|
44
|
+
function loadPositions(api, endpoint) {
|
|
45
|
+
const pending = inflight.get(endpoint);
|
|
46
|
+
if (pending) return pending;
|
|
47
|
+
const next = fetchAllPositions(api, endpoint).finally(() => {
|
|
48
|
+
inflight.delete(endpoint);
|
|
49
|
+
});
|
|
50
|
+
inflight.set(endpoint, next);
|
|
51
|
+
return next;
|
|
52
|
+
}
|
|
53
|
+
function PositionSelectImpl({
|
|
54
|
+
endpoint = "/job-positions",
|
|
55
|
+
value,
|
|
56
|
+
onChange,
|
|
57
|
+
allowEmpty = false,
|
|
58
|
+
disabled = false,
|
|
59
|
+
size,
|
|
60
|
+
invalid,
|
|
61
|
+
placeholder = "\uC9C1\uC704\uB97C \uC120\uD0DD\uD558\uC138\uC694",
|
|
62
|
+
id
|
|
63
|
+
}) {
|
|
64
|
+
const adapter = useSduiAdapter();
|
|
65
|
+
const api = hostFetchOf(adapter) ?? defaultAdapter.fetch;
|
|
66
|
+
const [positions, setPositions] = useState(null);
|
|
67
|
+
const [failed, setFailed] = useState(false);
|
|
68
|
+
const [attempt, setAttempt] = useState(0);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
let alive = true;
|
|
71
|
+
loadPositions(api, endpoint).then((rows2) => {
|
|
72
|
+
if (!alive) return;
|
|
73
|
+
setPositions(rows2);
|
|
74
|
+
setFailed(false);
|
|
75
|
+
}).catch(() => {
|
|
76
|
+
if (!alive) return;
|
|
77
|
+
setPositions([]);
|
|
78
|
+
setFailed(true);
|
|
79
|
+
});
|
|
80
|
+
return () => {
|
|
81
|
+
alive = false;
|
|
82
|
+
};
|
|
83
|
+
}, [attempt]);
|
|
84
|
+
const isLoading = positions === null && !failed;
|
|
85
|
+
const rows = useMemo(() => positions ?? [], [positions]);
|
|
86
|
+
const activeByName = useMemo(() => {
|
|
87
|
+
const map = /* @__PURE__ */ new Map();
|
|
88
|
+
for (const position of rows) {
|
|
89
|
+
if (position.name.trim() === "") continue;
|
|
90
|
+
map.set(position.name, (map.get(position.name) ?? false) || position.isActive);
|
|
91
|
+
}
|
|
92
|
+
return map;
|
|
93
|
+
}, [rows]);
|
|
94
|
+
const activeNames = useMemo(() => {
|
|
95
|
+
const sorted = [...rows].sort(
|
|
96
|
+
(a, b) => a.rankOrder - b.rankOrder || a.sortOrder - b.sortOrder || a.name.localeCompare(b.name, "ko")
|
|
97
|
+
);
|
|
98
|
+
const seen = /* @__PURE__ */ new Set();
|
|
99
|
+
const names = [];
|
|
100
|
+
for (const position of sorted) {
|
|
101
|
+
if (!position.isActive) continue;
|
|
102
|
+
if (position.name.trim() === "" || seen.has(position.name)) continue;
|
|
103
|
+
seen.add(position.name);
|
|
104
|
+
names.push(position.name);
|
|
105
|
+
}
|
|
106
|
+
return names;
|
|
107
|
+
}, [rows]);
|
|
108
|
+
const current = typeof value === "string" ? value : "";
|
|
109
|
+
const isOffList = current !== "" && !activeNames.includes(current);
|
|
110
|
+
const suffix = isLoading || failed ? "" : activeByName.has(current) ? " (\uBBF8\uC0AC\uC6A9)" : " (\uBBF8\uB4F1\uB85D \uC9C1\uC704)";
|
|
111
|
+
const options = useMemo(() => {
|
|
112
|
+
const list = [];
|
|
113
|
+
if (allowEmpty) list.push({ value: EMPTY_VALUE, label: "\uC120\uD0DD \uC548 \uD568" });
|
|
114
|
+
if (isOffList) list.push({ value: current, label: `${current}${suffix}` });
|
|
115
|
+
if (isLoading) list.push({ value: LOADING_VALUE, label: "\uBD88\uB7EC\uC624\uB294 \uC911\u2026", disabled: true });
|
|
116
|
+
for (const name of activeNames) list.push({ value: name, label: name });
|
|
117
|
+
return list;
|
|
118
|
+
}, [allowEmpty, isOffList, current, suffix, isLoading, activeNames]);
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-1)" }, children: [
|
|
120
|
+
/* @__PURE__ */ jsx(
|
|
121
|
+
Select,
|
|
122
|
+
{
|
|
123
|
+
id,
|
|
124
|
+
size,
|
|
125
|
+
invalid,
|
|
126
|
+
disabled,
|
|
127
|
+
value: current,
|
|
128
|
+
options,
|
|
129
|
+
placeholder,
|
|
130
|
+
onChange: (event) => {
|
|
131
|
+
const next = event.target.value;
|
|
132
|
+
if (next === LOADING_VALUE) return;
|
|
133
|
+
onChange?.(next === EMPTY_VALUE ? "" : next);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
!isLoading && failed && /* @__PURE__ */ jsxs("div", { className: "wp-row", style: { alignItems: "center", gap: "var(--wp-space-2)" }, children: [
|
|
138
|
+
/* @__PURE__ */ jsx("span", { className: "wp-caption", style: { color: "var(--wp-text-muted)" }, children: "\uC9C1\uC704 \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4" }),
|
|
139
|
+
/* @__PURE__ */ jsx(
|
|
140
|
+
Button,
|
|
141
|
+
{
|
|
142
|
+
type: "button",
|
|
143
|
+
size: "sm",
|
|
144
|
+
variant: "secondary",
|
|
145
|
+
onClick: () => {
|
|
146
|
+
setPositions(null);
|
|
147
|
+
setFailed(false);
|
|
148
|
+
setAttempt((n) => n + 1);
|
|
149
|
+
},
|
|
150
|
+
children: "\uB2E4\uC2DC \uC2DC\uB3C4"
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
] }),
|
|
154
|
+
!isLoading && !failed && activeNames.length === 0 && !isOffList && /* @__PURE__ */ jsx("span", { className: "wp-caption", style: { color: "var(--wp-text-muted)" }, children: "\uB4F1\uB85D\uB41C \uC9C1\uC704\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uC778\uC0AC > \uC9C1\uC704 \uAD00\uB9AC\uC5D0\uC11C \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4." })
|
|
155
|
+
] });
|
|
156
|
+
}
|
|
157
|
+
var PositionSelect = boxed(PositionSelectImpl, "PositionSelect");
|
|
158
|
+
|
|
159
|
+
export { PositionSelect };
|
|
@@ -51,10 +51,17 @@ function DiffViewImpl({ fields, lists }) {
|
|
|
51
51
|
const added = list.added ?? [];
|
|
52
52
|
const removed = list.removed ?? [];
|
|
53
53
|
const kept = list.kept ?? [];
|
|
54
|
-
const
|
|
54
|
+
const isReplace = list.before !== void 0 || list.after !== void 0;
|
|
55
|
+
const before = list.before ?? [];
|
|
56
|
+
const after = list.after ?? [];
|
|
57
|
+
const isEmpty = isReplace ? before.length === 0 && after.length === 0 : added.length === 0 && removed.length === 0 && kept.length === 0;
|
|
55
58
|
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
56
59
|
/* @__PURE__ */ jsx("span", { className: "erp-diff__label", children: list.label }),
|
|
57
|
-
/* @__PURE__ */ jsx("span", { className: "erp-diff__badges", children: isEmpty ? /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uBCC0\uACBD \uC5C6\uC74C" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "erp-diff__badges", children: isEmpty ? /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uBCC0\uACBD \uC5C6\uC74C" }) : isReplace ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
61
|
+
before.map((value, i) => /* @__PURE__ */ jsx(Badge, { tone: "neutral", children: value }, `b-${value}-${i}`)),
|
|
62
|
+
/* @__PURE__ */ jsx("span", { className: "erp-diff__arrow", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Icon, { name: "arrow-right", size: 14 }) }),
|
|
63
|
+
after.length === 0 ? /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uBE44\uC6C0" }) : after.map((value, i) => /* @__PURE__ */ jsx(Badge, { tone: "success", children: value }, `f-${value}-${i}`))
|
|
64
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
58
65
|
added.map((value, i) => /* @__PURE__ */ jsxs(Badge, { tone: "success", children: [
|
|
59
66
|
"+ ",
|
|
60
67
|
value
|
package/dist/meta.d.ts
CHANGED
|
@@ -436,6 +436,7 @@ declare const OptionSchemaEditorMeta: SduiComponentMeta;
|
|
|
436
436
|
declare const OptionValueFieldsMeta: SduiComponentMeta;
|
|
437
437
|
declare const StagePeriodEditorMeta: SduiComponentMeta;
|
|
438
438
|
declare const QRDisplayMeta: SduiComponentMeta;
|
|
439
|
+
declare const PositionSelectMeta: SduiComponentMeta;
|
|
439
440
|
declare const AutocompleteFieldMeta: SduiComponentMeta;
|
|
440
441
|
declare const InlineEditMeta: SduiComponentMeta;
|
|
441
442
|
declare const JsonFieldMeta: SduiComponentMeta;
|
|
@@ -472,6 +473,7 @@ declare const widgetComponentMeta: {
|
|
|
472
473
|
ApprovalLineEditor: SduiComponentMeta;
|
|
473
474
|
ApprovalOverridesEditor: SduiComponentMeta;
|
|
474
475
|
ApprovalStepper: SduiComponentMeta;
|
|
476
|
+
PositionSelect: SduiComponentMeta;
|
|
475
477
|
QRDisplay: SduiComponentMeta;
|
|
476
478
|
OptionSchemaEditor: SduiComponentMeta;
|
|
477
479
|
OptionValueFields: SduiComponentMeta;
|
|
@@ -614,4 +616,4 @@ declare function paletteGroups(catalog?: Record<string, SduiComponentMeta>): Arr
|
|
|
614
616
|
items: SduiComponentMeta[];
|
|
615
617
|
}>;
|
|
616
618
|
|
|
617
|
-
export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PrintSheetMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, type SduiCategory, type SduiChildrenMeta, type SduiComponentMeta, type SduiDomMeta, type SduiEnumOption, type SduiPropGroup, type SduiPropKind, type SduiPropMeta, type SduiResizeMeta, type SduiSlotMeta, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
|
|
619
|
+
export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PositionSelectMeta, PrintSheetMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, type SduiCategory, type SduiChildrenMeta, type SduiComponentMeta, type SduiDomMeta, type SduiEnumOption, type SduiPropGroup, type SduiPropKind, type SduiPropMeta, type SduiResizeMeta, type SduiSlotMeta, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
|
package/dist/meta.js
CHANGED
|
@@ -4229,6 +4229,44 @@ var QRDisplayMeta = {
|
|
|
4229
4229
|
// 죽어 있었다. resize.ts의 "같은 프롭이면 축을 합친다" 분기를 그때 넣어 참으로 만들었다.
|
|
4230
4230
|
resize: { kind: "numeric", widthProp: "size", heightProp: "size", unit: "px", axis: "both" }
|
|
4231
4231
|
};
|
|
4232
|
+
var PositionSelectMeta = {
|
|
4233
|
+
name: "PositionSelect",
|
|
4234
|
+
label: "\uC9C1\uC704 \uC120\uD0DD",
|
|
4235
|
+
category: "input",
|
|
4236
|
+
icon: "circle-user",
|
|
4237
|
+
description: '\uC9C1\uC704 \uB9C8\uC2A4\uD130(/job-positions) \uC140\uB809\uD2B8. \uD65C\uC131 \uC9C1\uC704\uB97C \uC11C\uC5F4(rank_order\u2192sort_order) \uC21C\uC73C\uB85C \uBCF4\uC5EC\uC8FC\uACE0, \uBAA9\uB85D \uBC16 \uD604\uC7AC \uAC12\uC740 " (\uBBF8\uC0AC\uC6A9)"/" (\uBBF8\uB4F1\uB85D \uC9C1\uC704)" \uC811\uBBF8\uC0AC\uB85C \uC5B9\uC5B4 \uBCF4\uC874\uD55C\uB2E4. \uAC12\uC740 employees.grade \uBB38\uC790\uC5F4 \uC0AC\uBCF8 \uADF8\uB300\uB85C\uB2E4.',
|
|
4238
|
+
props: [
|
|
4239
|
+
{ name: "value", kind: "string", label: "\uD604\uC7AC \uC9C1\uC704", required: true, bindable: true, description: "\uC9C1\uC704 \uC774\uB984 \uBB38\uC790\uC5F4(employees.grade).", group: "data" },
|
|
4240
|
+
{ name: "onChange", kind: "action", label: "\uC9C1\uC704 \uBCC0\uACBD", required: true, eventArg: '\uBC14\uB010 \uC9C1\uC704 \uC774\uB984 \uBB38\uC790\uC5F4 \u2014 "\uC120\uD0DD \uC548 \uD568"\uC740 \uBE48 \uBB38\uC790\uC5F4', group: "behavior" },
|
|
4241
|
+
{ name: "allowEmpty", kind: "boolean", label: "\uC120\uD0DD \uC548 \uD568 \uB178\uCD9C", default: false, description: '\uB9E8 \uC704\uC5D0 "\uC120\uD0DD \uC548 \uD568" \uD56D\uBAA9\uC744 \uB178\uCD9C\uD55C\uB2E4. \uC120\uD0DD \uC2DC \uBE48 \uBB38\uC790\uC5F4\uC744 \uD758\uB9B0\uB2E4.', group: "behavior" },
|
|
4242
|
+
{ name: "placeholder", kind: "string", label: "\uD50C\uB808\uC774\uC2A4\uD640\uB354", default: "\uC9C1\uC704\uB97C \uC120\uD0DD\uD558\uC138\uC694", group: "content" },
|
|
4243
|
+
{ name: "disabled", kind: "boolean", label: "\uBE44\uD65C\uC131", default: false, bindable: true, group: "behavior" },
|
|
4244
|
+
{ name: "invalid", kind: "boolean", label: "\uC624\uB958 \uD45C\uC2DC", bindable: true, group: "appearance", advanced: true },
|
|
4245
|
+
{ name: "size", kind: "enum", label: "\uD06C\uAE30", options: [{ value: "sm", label: "\uC791\uAC8C" }, { value: "md", label: "\uBCF4\uD1B5" }, { value: "lg", label: "\uD06C\uAC8C" }], group: "appearance", advanced: true },
|
|
4246
|
+
{ name: "id", kind: "string", label: "\uC694\uC18C id", group: "behavior", advanced: true },
|
|
4247
|
+
{
|
|
4248
|
+
name: "endpoint",
|
|
4249
|
+
kind: "string",
|
|
4250
|
+
label: "\uC9C1\uC704 \uBAA9\uB85D \uACBD\uB85C",
|
|
4251
|
+
description: "\uC751\uB2F5 {data:[\u2026], total} \uC744 500\uAC74\uC529 \uC218\uC9D1\uD55C\uB2E4. \uAE30\uBCF8 '/job-positions'.",
|
|
4252
|
+
group: "data",
|
|
4253
|
+
advanced: true
|
|
4254
|
+
}
|
|
4255
|
+
],
|
|
4256
|
+
children: { accepts: false },
|
|
4257
|
+
dom: { element: "div" },
|
|
4258
|
+
// 루트 <div class="wp-col"> (Select + 안내문)
|
|
4259
|
+
// 마운트 즉시 GET /job-positions 1회가 나간다 — RoleTagPicker.sourceEndpoint와 같은 결(캔버스에서는 조용히 실패).
|
|
4260
|
+
preset: {
|
|
4261
|
+
component: "PositionSelect",
|
|
4262
|
+
props: {
|
|
4263
|
+
value: { $state: "empForm.grade", default: "" },
|
|
4264
|
+
onChange: { action: "setState", key: "empForm.grade", fromEvent: true },
|
|
4265
|
+
allowEmpty: true
|
|
4266
|
+
}
|
|
4267
|
+
},
|
|
4268
|
+
resize: { kind: "none" }
|
|
4269
|
+
};
|
|
4232
4270
|
var AutocompleteFieldMeta = {
|
|
4233
4271
|
name: "AutocompleteField",
|
|
4234
4272
|
label: "\uC790\uB3D9\uC644\uC131",
|
|
@@ -5041,7 +5079,16 @@ var DiffViewMeta = {
|
|
|
5041
5079
|
{ name: "label", kind: "string", label: "\uD56D\uBAA9\uBA85", required: true },
|
|
5042
5080
|
{ name: "added", kind: "array", label: "\uCD94\uAC00\uB428", item: [], itemKind: "string" },
|
|
5043
5081
|
{ name: "removed", kind: "array", label: "\uC0AD\uC81C\uB428", item: [], itemKind: "string" },
|
|
5044
|
-
{ name: "kept", kind: "array", label: "\uC720\uC9C0\uB428", item: [], itemKind: "string" }
|
|
5082
|
+
{ name: "kept", kind: "array", label: "\uC720\uC9C0\uB428", item: [], itemKind: "string" },
|
|
5083
|
+
{
|
|
5084
|
+
name: "before",
|
|
5085
|
+
kind: "array",
|
|
5086
|
+
label: "\uBCC0\uACBD \uC804(\uC804\uCCB4 \uAD50\uCCB4)",
|
|
5087
|
+
item: [],
|
|
5088
|
+
itemKind: "string",
|
|
5089
|
+
description: '\uC774 \uCD95\uC744 \uC8FC\uBA74 added/removed/kept \uB300\uC2E0 "before \u2192 after" \uB85C \uADF8\uB9B0\uB2E4 \u2014 \uC885\uB958 \uB2E8\uC704 \uC804\uCCB4 \uAD50\uCCB4.'
|
|
5090
|
+
},
|
|
5091
|
+
{ name: "after", kind: "array", label: "\uBCC0\uACBD \uD6C4(\uC804\uCCB4 \uAD50\uCCB4)", item: [], itemKind: "string" }
|
|
5045
5092
|
]
|
|
5046
5093
|
}
|
|
5047
5094
|
],
|
|
@@ -5649,6 +5696,7 @@ var widgetComponentMeta = {
|
|
|
5649
5696
|
ApprovalLineEditor: ApprovalLineEditorMeta,
|
|
5650
5697
|
ApprovalOverridesEditor: ApprovalOverridesEditorMeta,
|
|
5651
5698
|
ApprovalStepper: ApprovalStepperMeta,
|
|
5699
|
+
PositionSelect: PositionSelectMeta,
|
|
5652
5700
|
QRDisplay: QRDisplayMeta,
|
|
5653
5701
|
OptionSchemaEditor: OptionSchemaEditorMeta,
|
|
5654
5702
|
OptionValueFields: OptionValueFieldsMeta,
|
|
@@ -5716,4 +5764,4 @@ function paletteGroups(catalog = allComponentMeta) {
|
|
|
5716
5764
|
})).filter((group) => group.items.length > 0);
|
|
5717
5765
|
}
|
|
5718
5766
|
|
|
5719
|
-
export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PrintSheetMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
|
|
5767
|
+
export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PositionSelectMeta, PrintSheetMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
|
|
@@ -11,6 +11,17 @@ interface DiffList {
|
|
|
11
11
|
added?: string[];
|
|
12
12
|
removed?: string[];
|
|
13
13
|
kept?: string[];
|
|
14
|
+
/**
|
|
15
|
+
* **종류 단위 전체 교체**를 그린다 — `before`/`after` 중 하나라도 있으면
|
|
16
|
+
* added/removed/kept 대신 이쪽으로 그린다.
|
|
17
|
+
*
|
|
18
|
+
* 항목별 추가·삭제가 아니라 "이 종류가 통째로 이 목록으로 바뀐다"가 참인 자리가
|
|
19
|
+
* 있다(학력·자격처럼 서버가 종류째 갈아 끼우는 관계). 그걸 added/removed 로 그리면
|
|
20
|
+
* **의미가 달라진다** — 같은 값이 양쪽에 있어도 "유지"가 아니라 "지웠다 다시 넣음"이
|
|
21
|
+
* 서버에서 실제로 일어나기 때문이다.
|
|
22
|
+
*/
|
|
23
|
+
before?: string[];
|
|
24
|
+
after?: string[];
|
|
14
25
|
}
|
|
15
26
|
interface DiffViewProps {
|
|
16
27
|
fields?: DiffField[];
|
package/dist/widgets/DiffView.js
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { S as SduiBoxProps } from '../layout-B1QrIBm6.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* PositionSelect — 직위 마스터(/job-positions) 셀렉트. v2 position-select.tsx 이식.
|
|
6
|
+
*
|
|
7
|
+
* 옵션은 **활성 직위만**, 마스터 서열(rank_order → sort_order → 이름 ko) 순서 그대로다 —
|
|
8
|
+
* 서열이 곧 표시 순서라 가나다 재정렬로 덮으면 안 된다. 같은 이름이 중복되면
|
|
9
|
+
* 첫 등장(서열 높은 쪽)만 남긴다(같은 value 옵션이 둘 생기는 사고 방지).
|
|
10
|
+
*
|
|
11
|
+
* **off-list 값 처리**: 현재 값이 활성 목록에 없으면(미사용 전환·예전 자유 입력) 그 값을
|
|
12
|
+
* 항목으로 얹어 표시를 유지한다 — 안 얹으면 셀렉트가 비어 보이고 저장 시 기존 값이
|
|
13
|
+
* 날아간 것처럼 오해된다(v2가 고친 문제). 접미사: 마스터에 있으나 미사용이면 " (미사용)",
|
|
14
|
+
* 마스터에 아예 없으면 " (미등록 직위)". 로딩/에러 중에는 접미사를 생략한다 —
|
|
15
|
+
* 조회 한 번 실패했다고 멀쩡한 값이 "미등록"으로 낙인찍히면 안 된다.
|
|
16
|
+
*
|
|
17
|
+
* **조회는 매 마운트 1회**(limit 500씩 total까지 페이지 수집) — v2의 60초 모듈 캐시 +
|
|
18
|
+
* 세대 카운터 대신 단순화했다. 직위 관리 화면 변경 뒤 폼 다이얼로그가 다시 열리면
|
|
19
|
+
* (Show 언마운트→재마운트) 새로 읽으므로 invalidate 별도 배선이 필요 없다.
|
|
20
|
+
* 한 화면 다중 인스턴스(등록 폼+필터)의 중복 조회만 모듈 인플라이트 공유로 억제한다.
|
|
21
|
+
*
|
|
22
|
+
* **onChange는 문자열**을 흘린다 — "선택 안 함"은 ''(빈 문자열). v2 계약은 null이었지만
|
|
23
|
+
* 호출부가 전부 null→''로 접어 저장했고, SDUI setState(fromEvent)에는 값 변환 어휘가
|
|
24
|
+
* 없어 그 접기를 위젯이 대신한다. employees.grade는 문자열 사본 컬럼이라 ''가 "미지정"이다.
|
|
25
|
+
*/
|
|
26
|
+
interface PositionSelectProps {
|
|
27
|
+
/** 직위 목록 경로. 응답 `{data:[…], total}` 을 500건씩 수집한다. 기본 '/job-positions'. */
|
|
28
|
+
endpoint?: string;
|
|
29
|
+
/** 현재 직위 이름(employees.grade 문자열 사본). */
|
|
30
|
+
value?: string | null;
|
|
31
|
+
/** 바뀐 직위 이름. "선택 안 함"은 ''(빈 문자열). */
|
|
32
|
+
onChange?: (value: string) => void;
|
|
33
|
+
/** "선택 안 함" 항목을 맨 위에 노출한다. 선택 시 onChange(''). */
|
|
34
|
+
allowEmpty?: boolean;
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
size?: 'sm' | 'md' | 'lg';
|
|
37
|
+
invalid?: boolean;
|
|
38
|
+
placeholder?: string;
|
|
39
|
+
id?: string;
|
|
40
|
+
}
|
|
41
|
+
/** 바깥 style·className을 뿌리에 얹는다 — 자기 축(폭·여백) 통로. */
|
|
42
|
+
declare const PositionSelect: React.FC<PositionSelectProps & SduiBoxProps>;
|
|
43
|
+
|
|
44
|
+
export { PositionSelect, type PositionSelectProps };
|
package/dist/widgets/index.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ import { QRDisplayProps } from './QRDisplay.js';
|
|
|
28
28
|
export { QRDisplay } from './QRDisplay.js';
|
|
29
29
|
import { PrintSheetProps } from './PrintSheet.js';
|
|
30
30
|
export { PrintSheet } from './PrintSheet.js';
|
|
31
|
+
import { PositionSelectProps } from './PositionSelect.js';
|
|
32
|
+
export { PositionSelect } from './PositionSelect.js';
|
|
31
33
|
import { PeriodFilterProps } from './PeriodFilter.js';
|
|
32
34
|
export { Period, PeriodFilter, PeriodMode, PeriodModeItem } from './PeriodFilter.js';
|
|
33
35
|
import { PermissionMatrixEditorProps } from './PermissionMatrixEditor.js';
|
|
@@ -92,6 +94,7 @@ declare const widgetComponents: {
|
|
|
92
94
|
OrgChartBoard: React.FC<OrgChartBoardProps & SduiBoxProps>;
|
|
93
95
|
PermissionMatrixEditor: React.FC<PermissionMatrixEditorProps & SduiBoxProps>;
|
|
94
96
|
PeriodFilter: React.FC<PeriodFilterProps & SduiBoxProps>;
|
|
97
|
+
PositionSelect: React.FC<PositionSelectProps & SduiBoxProps>;
|
|
95
98
|
PrintSheet: React.FC<PrintSheetProps & SduiBoxProps>;
|
|
96
99
|
QRDisplay: React.FC<QRDisplayProps & SduiBoxProps>;
|
|
97
100
|
RankBoard: React.FC<RankBoardProps & SduiBoxProps>;
|
|
@@ -111,4 +114,4 @@ declare const widgetComponents: {
|
|
|
111
114
|
/** 위젯 어휘의 컴포넌트 이름 union — 메타데이터 대조에 쓴다(`@wipco/sdui/meta`). */
|
|
112
115
|
type SduiWidgetComponentName = keyof typeof widgetComponents;
|
|
113
116
|
|
|
114
|
-
export { ApprovalLineEditorProps, ApprovalOverridesEditorProps, ApprovalStepperProps, ColumnBoardProps, DiffViewProps, DisclosureProps, EventCalendarProps, ImageLightboxProps, InlineEditProps, JsonFieldProps, LiveClockProps, OptionSchemaEditorProps, OptionValueFieldsProps, OrgChartBoardProps, OrgChartProps, PeriodFilterProps, PermissionMatrixEditorProps, PrintSheetProps, QRDisplayProps, RankBoardProps, RecordSheetProps, RoleMemberPickerProps, type SduiWidgetComponentName, SearchableMultiPickerProps, SecureScreenProps, StackedMeterProps, StagePeriodEditorProps, StripProps, SummaryTableProps, TagMultiSelectProps, TimelineProps, TreePickerProps, TreeViewProps, widgetComponents };
|
|
117
|
+
export { ApprovalLineEditorProps, ApprovalOverridesEditorProps, ApprovalStepperProps, ColumnBoardProps, DiffViewProps, DisclosureProps, EventCalendarProps, ImageLightboxProps, InlineEditProps, JsonFieldProps, LiveClockProps, OptionSchemaEditorProps, OptionValueFieldsProps, OrgChartBoardProps, OrgChartProps, PeriodFilterProps, PermissionMatrixEditorProps, PositionSelectProps, PrintSheetProps, QRDisplayProps, RankBoardProps, RecordSheetProps, RoleMemberPickerProps, type SduiWidgetComponentName, SearchableMultiPickerProps, SecureScreenProps, StackedMeterProps, StagePeriodEditorProps, StripProps, SummaryTableProps, TagMultiSelectProps, TimelineProps, TreePickerProps, TreeViewProps, widgetComponents };
|
package/dist/widgets/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { StackedMeter } from '../chunk-BMZKZGJF.js';
|
|
2
|
+
export { StackedMeter } from '../chunk-BMZKZGJF.js';
|
|
1
3
|
import { StagePeriodEditor } from '../chunk-KVFHPBAY.js';
|
|
2
4
|
export { StagePeriodEditor } from '../chunk-KVFHPBAY.js';
|
|
3
5
|
import { Strip } from '../chunk-ZH5MLOZS.js';
|
|
@@ -10,6 +12,8 @@ import { TreePicker } from '../chunk-U3HYQCFA.js';
|
|
|
10
12
|
export { TreePicker } from '../chunk-U3HYQCFA.js';
|
|
11
13
|
import { TreeView } from '../chunk-X5R2HHEN.js';
|
|
12
14
|
export { TreeView, buildTreeNodes } from '../chunk-X5R2HHEN.js';
|
|
15
|
+
import { PositionSelect } from '../chunk-D4AILKSJ.js';
|
|
16
|
+
export { PositionSelect } from '../chunk-D4AILKSJ.js';
|
|
13
17
|
import { PrintSheet } from '../chunk-MYJ2KEIP.js';
|
|
14
18
|
export { PrintSheet } from '../chunk-MYJ2KEIP.js';
|
|
15
19
|
import { QRDisplay } from '../chunk-PCMJE2GO.js';
|
|
@@ -24,8 +28,6 @@ import { SearchableMultiPicker } from '../chunk-C53NGSA3.js';
|
|
|
24
28
|
export { SearchableMultiPicker } from '../chunk-C53NGSA3.js';
|
|
25
29
|
import { SecureScreen } from '../chunk-IIRENCDS.js';
|
|
26
30
|
export { SecureScreen } from '../chunk-IIRENCDS.js';
|
|
27
|
-
import { StackedMeter } from '../chunk-BMZKZGJF.js';
|
|
28
|
-
export { StackedMeter } from '../chunk-BMZKZGJF.js';
|
|
29
31
|
import { JsonField } from '../chunk-JVBZRDC2.js';
|
|
30
32
|
export { JsonField } from '../chunk-JVBZRDC2.js';
|
|
31
33
|
import { LiveClock } from '../chunk-Z3WGIFJP.js';
|
|
@@ -45,8 +47,8 @@ export { PeriodFilter } from '../chunk-INWASR2G.js';
|
|
|
45
47
|
export { AutocompleteField, toAutocompleteOptions } from '../chunk-CVCP52OD.js';
|
|
46
48
|
import { ColumnBoard } from '../chunk-C4JRSZGS.js';
|
|
47
49
|
export { ColumnBoard } from '../chunk-C4JRSZGS.js';
|
|
48
|
-
import { DiffView } from '../chunk-
|
|
49
|
-
export { DiffView } from '../chunk-
|
|
50
|
+
import { DiffView } from '../chunk-XAYXHY7R.js';
|
|
51
|
+
export { DiffView } from '../chunk-XAYXHY7R.js';
|
|
50
52
|
import { Disclosure } from '../chunk-HIZ2OVJA.js';
|
|
51
53
|
export { Disclosure } from '../chunk-HIZ2OVJA.js';
|
|
52
54
|
import { EventCalendar } from '../chunk-C3JY6GA3.js';
|
|
@@ -94,6 +96,7 @@ var widgetComponents = {
|
|
|
94
96
|
OrgChartBoard,
|
|
95
97
|
PermissionMatrixEditor,
|
|
96
98
|
PeriodFilter,
|
|
99
|
+
PositionSelect,
|
|
97
100
|
PrintSheet,
|
|
98
101
|
QRDisplay,
|
|
99
102
|
RankBoard,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wipco/sdui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"description": "WIPCO 서버 주도 UI(SDUI) 렌더러 — JSON 페이지 스펙을 React 컴포넌트로 렌더링",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sdui",
|
|
@@ -116,6 +116,10 @@
|
|
|
116
116
|
"types": "./dist/widgets/PeriodFilter.d.ts",
|
|
117
117
|
"default": "./dist/widgets/PeriodFilter.js"
|
|
118
118
|
},
|
|
119
|
+
"./widgets/PositionSelect": {
|
|
120
|
+
"types": "./dist/widgets/PositionSelect.d.ts",
|
|
121
|
+
"default": "./dist/widgets/PositionSelect.js"
|
|
122
|
+
},
|
|
119
123
|
"./widgets/PrintSheet": {
|
|
120
124
|
"types": "./dist/widgets/PrintSheet.d.ts",
|
|
121
125
|
"default": "./dist/widgets/PrintSheet.js"
|