@wipco/sdui 1.1.0 → 1.3.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.
@@ -1,4 +1,4 @@
1
- import { fetchAllJobPositions } from './chunk-Z4PYMTTS.js';
1
+ import { fetchAllJobPositions } from './chunk-XRHR452N.js';
2
2
  import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
3
3
  import { Select, Button } from './chunk-RNOUXUBO.js';
4
4
  import { boxed } from './chunk-5WW4MBRO.js';
@@ -1,4 +1,4 @@
1
- import { parseJobPositionRow } from './chunk-Z4PYMTTS.js';
1
+ import { parseJobPositionRow } from './chunk-XRHR452N.js';
2
2
  import { usePanZoomCanvas } from './chunk-MMIGOPO5.js';
3
3
  import { ImageLightbox } from './chunk-VY7MVBSE.js';
4
4
  import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
@@ -1,4 +1,4 @@
1
- import { fetchAllJobPositions } from './chunk-Z4PYMTTS.js';
1
+ import { fetchAllJobPositions } from './chunk-XRHR452N.js';
2
2
  import { useSduiDispatch, useSduiCan, SduiDialog } from './chunk-TFGNKFL2.js';
3
3
  import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
4
4
  import { Card, Input, Button, Icon, Badge, IconButton } from './chunk-RNOUXUBO.js';
@@ -351,6 +351,22 @@ function RankBoardImpl({
351
351
  "\uC0AC\uC6A9 \uC5EC\uBD80 \uBCC0\uACBD \uC2E4\uD328"
352
352
  );
353
353
  };
354
+ const toggleAutoEvalExclusion = async (position) => {
355
+ const next = !position.excludeFromAutoEvaluation;
356
+ const ok = await runMutation(
357
+ () => api(`${endpoint}/${encodeURIComponent(position.id)}`, {
358
+ method: "PATCH",
359
+ body: { excludeFromAutoEvaluation: next }
360
+ }).then(() => void 0),
361
+ "\uC790\uB3D9\uD3C9\uAC00 \uC81C\uC678 \uBCC0\uACBD \uC2E4\uD328"
362
+ );
363
+ if (ok) {
364
+ toast(
365
+ "success",
366
+ next ? `'${position.name}' \uC9C1\uC704\uB294 \uC774\uC81C \uD3C9\uAC00 \uD68C\uCC28\uC758 \uC790\uB3D9 \uBC30\uC815\uC5D0\uC11C \uBE60\uC9D1\uB2C8\uB2E4.` : `'${position.name}' \uC9C1\uC704\uAC00 \uB2E4\uC2DC \uC790\uB3D9 \uBC30\uC815\uC5D0 \uD3EC\uD568\uB429\uB2C8\uB2E4.`
367
+ );
368
+ }
369
+ };
354
370
  const handleDelete = (position) => {
355
371
  const message = (deleteConfirmMessage || DELETE_CONFIRM_DEFAULT).replaceAll(
356
372
  "{name}",
@@ -568,6 +584,7 @@ function RankBoardImpl({
568
584
  children: [
569
585
  /* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: position.name }),
570
586
  !position.isActive ? /* @__PURE__ */ jsx(Badge, { tone: "neutral", children: "\uBBF8\uC0AC\uC6A9" }) : null,
587
+ position.excludeFromAutoEvaluation ? /* @__PURE__ */ jsx(Badge, { tone: "warning", children: "\uC790\uB3D9\uD3C9\uAC00 \uC81C\uC678" }) : null,
571
588
  canUpdate || canDelete ? /* @__PURE__ */ jsxs("span", { "data-rb-menu": true, style: { position: "relative", display: "inline-flex" }, children: [
572
589
  /* @__PURE__ */ jsx(
573
590
  IconButton,
@@ -666,6 +683,17 @@ function RankBoardImpl({
666
683
  toggleActive(position);
667
684
  }
668
685
  }
686
+ ),
687
+ /* @__PURE__ */ jsx(
688
+ MenuItem,
689
+ {
690
+ icon: position.excludeFromAutoEvaluation ? "circle-check" : "circle-x",
691
+ label: position.excludeFromAutoEvaluation ? "\uC790\uB3D9\uD3C9\uAC00 \uC81C\uC678 \uD574\uC81C" : "\uC790\uB3D9\uD3C9\uAC00 \uC81C\uC678",
692
+ onSelect: () => {
693
+ setMenuFor(null);
694
+ void toggleAutoEvalExclusion(position);
695
+ }
696
+ }
669
697
  )
670
698
  ] }) : null,
671
699
  canDelete ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -11,13 +11,16 @@ function parseJobPositionRow(raw) {
11
11
  const row = raw;
12
12
  if (typeof row.name !== "string") return null;
13
13
  const active = row.is_active ?? row.isActive;
14
+ const excluded = row.exclude_from_auto_evaluation ?? row.excludeFromAutoEvaluation;
14
15
  return {
15
16
  ...typeof row.id === "string" ? { id: row.id } : null,
16
17
  name: row.name,
17
18
  rankOrder: num(row.rank_order, row.rankOrder),
18
19
  sortOrder: num(row.sort_order, row.sortOrder),
19
20
  // is_active 결측을 false로 단정하면 목록이 전부 사라져 보인다 — true 폴백(v2와 동일).
20
- isActive: typeof active === "boolean" ? active : true
21
+ isActive: typeof active === "boolean" ? active : true,
22
+ // 반대로 제외 결측은 false — 옵션이 없는 백엔드에서 전원이 제외로 보이면 안 된다.
23
+ excludeFromAutoEvaluation: excluded === true
21
24
  };
22
25
  }
23
26
  async function fetchAllJobPositions(api, endpoint) {
package/dist/meta.js CHANGED
@@ -3517,7 +3517,7 @@ var RankBoardMeta = {
3517
3517
  label: "\uC9C1\uC704 \uC11C\uC5F4 \uBCF4\uB4DC",
3518
3518
  category: "input",
3519
3519
  icon: "list",
3520
- description: "\uC9C1\uC704 \uB9C8\uC2A4\uD130\uB97C \uAE09(rank_order) \uD589 \xD7 \uC9C1\uC704 \uCE69\uC758 2\uCC28\uC6D0 \uB4DC\uB798\uADF8 \uBCF4\uB4DC\uB85C \uD3B8\uC9D1\uD55C\uB2E4. \uBAA9\uB85D\xB7\uB4F1\uB85D\xB7\uC218\uC815\xB7\uC0AD\uC81C\xB7\uC21C\uC11C \uC800\uC7A5(PUT {endpoint}/order {ranks})\uC744 \uC704\uC82F\uC774 \uC18C\uC720\uD558\uACE0, \uBCC0\uACBD \uD6C4 invalidate \uC561\uC158\uC73C\uB85C \uB2E4\uB978 \uD654\uBA74\uC758 \uC9C1\uC704 \uC870\uD68C\uB97C \uB3D9\uAE30\uD654\uD55C\uB2E4.",
3520
+ description: "\uC9C1\uC704 \uB9C8\uC2A4\uD130\uB97C \uAE09(rank_order) \uD589 \xD7 \uC9C1\uC704 \uCE69\uC758 2\uCC28\uC6D0 \uB4DC\uB798\uADF8 \uBCF4\uB4DC\uB85C \uD3B8\uC9D1\uD55C\uB2E4. \uBAA9\uB85D\xB7\uB4F1\uB85D\xB7\uC218\uC815\xB7\uC0AD\uC81C\xB7\uC21C\uC11C \uC800\uC7A5(PUT {endpoint}/order {ranks})\xB7\uC0AC\uC6A9 \uC5EC\uBD80\xB7\uC790\uB3D9\uD3C9\uAC00 \uC81C\uC678 \uD1A0\uAE00\uC744 \uC704\uC82F\uC774 \uC18C\uC720\uD558\uACE0, \uBCC0\uACBD \uD6C4 invalidate \uC561\uC158\uC73C\uB85C \uB2E4\uB978 \uD654\uBA74\uC758 \uC9C1\uC704 \uC870\uD68C\uB97C \uB3D9\uAE30\uD654\uD55C\uB2E4.",
3521
3521
  props: [
3522
3522
  { name: "endpoint", kind: "string", label: "API \uACBD\uB85C", default: "/job-positions", description: "\uC9C1\uC704 \uB9C8\uC2A4\uD130 \uB9AC\uC18C\uC2A4 \uACBD\uB85C \u2014 GET/POST/PATCH/DELETE\uC640 PUT {endpoint}/order \uC804\uBD80 \uC774 \uACBD\uB85C\uB97C \uC4F4\uB2E4.", group: "data", advanced: true },
3523
3523
  { name: "entity", kind: "string", label: "\uAD8C\uD55C \uC5D4\uD2F0\uD2F0", default: "job_position", description: "\uD504\uB86D \uC0DD\uB7B5 \uC2DC \uB80C\uB354\uB7EC \uAD8C\uD55C \uD310\uC815\uC5D0 \uC4F8 \uC5D4\uD2F0\uD2F0.", group: "behavior", advanced: true },
@@ -4119,6 +4119,20 @@ var ExcelUploadCardMeta = {
4119
4119
  icon: "cloud-upload",
4120
4120
  description: "\uC5D1\uC140 \uC77C\uAD04 \uC5C5\uB85C\uB4DC \uCE74\uB4DC. server\uB294 \uD30C\uC77C\uC744 \uADF8\uB300\uB85C \uC62C\uB824 \uCC98\uB9AC \uC694\uC57D\uC744 \uBC1B\uACE0, preview\uB294 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uD30C\uC2F1\xB7\uAC80\uC99D\uD558\uACE0 \uC624\uB958 \uC140\uC744 \uACE0\uCE5C \uB4A4 \uC720\uD6A8 \uD589\uB9CC \uBCF4\uB0B8\uB2E4.",
4121
4121
  props: [
4122
+ {
4123
+ name: "title",
4124
+ kind: "string",
4125
+ label: "\uC81C\uBAA9",
4126
+ description: "\uC0DD\uB7B5 \uC2DC '\uC5D1\uC140 \uC77C\uAD04 \uC5C5\uB85C\uB4DC'. \uC5EC\uB7EC \uC5C5\uB85C\uB4DC\uAC00 \uD55C \uD654\uBA74\uC5D0 \uC124 \uB54C \uAC01\uC790\uC758 \uC774\uB984\uC744 \uB2E8\uB2E4.",
4127
+ group: "content"
4128
+ },
4129
+ {
4130
+ name: "subtitle",
4131
+ kind: "string",
4132
+ label: "\uBD80\uC81C",
4133
+ description: "\uC0DD\uB7B5 \uC2DC \uBAA8\uB4DC\uBCC4 \uAE30\uBCF8 \uC548\uB0B4 \uBB38\uAD6C.",
4134
+ group: "content"
4135
+ },
4122
4136
  {
4123
4137
  name: "mode",
4124
4138
  kind: "enum",
@@ -4202,7 +4216,7 @@ var ExcelUploadCardMeta = {
4202
4216
  }
4203
4217
  // 실측 5/8 — 단일 toast×3, 액션 배열×2(close→toast)
4204
4218
  ],
4205
- children: { accepts: false },
4219
+ children: { accepts: true, label: "\uC124\uBA85 \uC601\uC5ED \u2014 \uBA38\uB9AC\uAE00\uACFC \uD30C\uC77C \uC120\uD0DD \uD589 \uC0AC\uC774\uC5D0 \uC120\uB2E4(\uCC98\uB9AC \uADDC\uCE59 \uC548\uB0B4, \uD15C\uD50C\uB9BF \uD5E4\uB354 \uBAA9\uB85D \uB4F1)" },
4206
4220
  dom: { element: "div" },
4207
4221
  // 실측: 루트가 라이브러리 Card → <div class="wp-card">
4208
4222
  // 프리셋에 endpoint·templateEndpoint를 넣지 않는다. 이 조합이면 템플릿은 브라우저에서
@@ -16,6 +16,13 @@ interface ExcelPreviewColumn {
16
16
  options?: string[];
17
17
  }
18
18
  interface ExcelUploadCardProps {
19
+ /**
20
+ * 카드 제목 — 생략 시 '엑셀 일괄 업로드'. 여러 업로드가 한 화면에 설 때 각자의
21
+ * 이름을 달 수 있게 연다(바깥 Card로 한 번 더 감싸면 카드 속 카드가 된다).
22
+ */
23
+ title?: string;
24
+ /** 카드 부제 — 생략 시 모드별 기본 안내 문구 */
25
+ subtitle?: string;
19
26
  /** server = 파일을 서버로 바로 업로드, preview = 클라이언트 파싱·검증 후 가져오기 */
20
27
  mode?: 'server' | 'preview';
21
28
  /** server: multipart POST 대상 / preview: 검증된 rows JSON POST 대상 */
@@ -37,6 +44,8 @@ interface ExcelUploadCardProps {
37
44
  * 업로드 버튼이 잠기면 안 된다.
38
45
  */
39
46
  demoModeOn503?: boolean;
47
+ /** 머리글과 파일 선택 행 사이의 설명 영역 — 처리 규칙 안내, 템플릿 헤더 목록 등 */
48
+ children?: React__default.ReactNode;
40
49
  }
41
50
  /** 바깥에서 온 `style`·`className`을 뿌리에 얹어 내보낸다 — 자기 축(폭·여백)이 닿게 하는 통로. */
42
51
  declare const ExcelUploadCard: React__default.FC<ExcelUploadCardProps & SduiBoxProps>;
@@ -43,6 +43,8 @@ function errorMessage(error, fallback) {
43
43
  return error instanceof Error && error.message ? error.message : fallback;
44
44
  }
45
45
  function ExcelUploadCardImpl({
46
+ title,
47
+ subtitle,
46
48
  mode = "server",
47
49
  endpoint,
48
50
  templateEndpoint,
@@ -50,7 +52,8 @@ function ExcelUploadCardImpl({
50
52
  columns,
51
53
  summaryLabels,
52
54
  onComplete,
53
- demoModeOn503 = false
55
+ demoModeOn503 = false,
56
+ children
54
57
  }) {
55
58
  const adapter = useSduiAdapter();
56
59
  const sandbox = useSduiSandbox();
@@ -363,8 +366,8 @@ function ExcelUploadCardImpl({
363
366
  return /* @__PURE__ */ jsx(
364
367
  Card,
365
368
  {
366
- title: "\uC5D1\uC140 \uC77C\uAD04 \uC5C5\uB85C\uB4DC",
367
- subtitle: mode === "preview" ? "\uC5D1\uC140 \uD30C\uC77C\uC744 \uBD88\uB7EC\uC640 \uAC80\uC99D\uD55C \uB4A4 \uC815\uC0C1 \uD589\uB9CC \uAC00\uC838\uC635\uB2C8\uB2E4" : "\uC5D1\uC140 \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD558\uBA74 \uC11C\uBC84\uC5D0\uC11C \uC77C\uAD04 \uCC98\uB9AC\uD569\uB2C8\uB2E4",
369
+ title: title ?? "\uC5D1\uC140 \uC77C\uAD04 \uC5C5\uB85C\uB4DC",
370
+ subtitle: subtitle ?? (mode === "preview" ? "\uC5D1\uC140 \uD30C\uC77C\uC744 \uBD88\uB7EC\uC640 \uAC80\uC99D\uD55C \uB4A4 \uC815\uC0C1 \uD589\uB9CC \uAC00\uC838\uC635\uB2C8\uB2E4" : "\uC5D1\uC140 \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD558\uBA74 \uC11C\uBC84\uC5D0\uC11C \uC77C\uAD04 \uCC98\uB9AC\uD569\uB2C8\uB2E4"),
368
371
  actions: hasTemplate ? /* @__PURE__ */ jsx(
369
372
  Button,
370
373
  {
@@ -388,6 +391,7 @@ function ExcelUploadCardImpl({
388
391
  },
389
392
  inputKey
390
393
  ),
394
+ children,
391
395
  /* @__PURE__ */ jsxs(
392
396
  "div",
393
397
  {
@@ -1,5 +1,5 @@
1
- export { OrgChartBoard, buildModel, compareMembers, isUnassignedGroup, leadershipEmployees, orgVocabOf, pickEmployees, pickGroups, pickPositions } from '../chunk-SJ3737RA.js';
2
- import '../chunk-Z4PYMTTS.js';
1
+ export { OrgChartBoard, buildModel, compareMembers, isUnassignedGroup, leadershipEmployees, orgVocabOf, pickEmployees, pickGroups, pickPositions } from '../chunk-JZXU22PE.js';
2
+ import '../chunk-XRHR452N.js';
3
3
  import '../chunk-MMIGOPO5.js';
4
4
  import '../chunk-VY7MVBSE.js';
5
5
  import '../chunk-SAPBDJJQ.js';
@@ -1,5 +1,5 @@
1
- export { PositionSelect } from '../chunk-IFKYGJXP.js';
2
- import '../chunk-Z4PYMTTS.js';
1
+ export { PositionSelect } from '../chunk-DOL57OOP.js';
2
+ import '../chunk-XRHR452N.js';
3
3
  import '../chunk-KO6OEY3G.js';
4
4
  import '../chunk-RNOUXUBO.js';
5
5
  import '../chunk-5WW4MBRO.js';
@@ -8,6 +8,7 @@ interface JobPosition {
8
8
  rankOrder: number;
9
9
  sortOrder: number;
10
10
  isActive: boolean;
11
+ excludeFromAutoEvaluation: boolean;
11
12
  }
12
13
  interface RankBoardProps {
13
14
  /** 직위 마스터 API 경로(기본 /job-positions). 목록·등록·수정·삭제·순서 저장 전부 이 경로다. */
@@ -1,5 +1,5 @@
1
- export { RankBoard } from '../chunk-RYHEV5E3.js';
2
- import '../chunk-Z4PYMTTS.js';
1
+ export { RankBoard } from '../chunk-RYBBPFI7.js';
2
+ import '../chunk-XRHR452N.js';
3
3
  import '../chunk-TFGNKFL2.js';
4
4
  import '../chunk-XQPTSEJC.js';
5
5
  import '../chunk-KO6OEY3G.js';
@@ -14,16 +14,16 @@ import { TreePicker } from '../chunk-7BGDSSAN.js';
14
14
  export { TreePicker } from '../chunk-7BGDSSAN.js';
15
15
  import { TreeView } from '../chunk-C37U3GCC.js';
16
16
  export { TreeView, buildTreeNodes } from '../chunk-C37U3GCC.js';
17
- import { PositionSelect } from '../chunk-IFKYGJXP.js';
18
- export { PositionSelect } from '../chunk-IFKYGJXP.js';
17
+ import { PositionSelect } from '../chunk-DOL57OOP.js';
18
+ export { PositionSelect } from '../chunk-DOL57OOP.js';
19
19
  import { PrintSheet } from '../chunk-E6ISNQK3.js';
20
20
  export { PrintSheet } from '../chunk-E6ISNQK3.js';
21
21
  import { QRDisplay } from '../chunk-IZ3JA2BR.js';
22
22
  export { QRDisplay } from '../chunk-IZ3JA2BR.js';
23
23
  import { ProfileEditDiffCard } from '../chunk-YOZN35HD.js';
24
24
  export { ProfileEditDiffCard } from '../chunk-YOZN35HD.js';
25
- import { RankBoard } from '../chunk-RYHEV5E3.js';
26
- export { RankBoard } from '../chunk-RYHEV5E3.js';
25
+ import { RankBoard } from '../chunk-RYBBPFI7.js';
26
+ export { RankBoard } from '../chunk-RYBBPFI7.js';
27
27
  import { RecordSheet } from '../chunk-O4IISNE7.js';
28
28
  export { RecordSheet } from '../chunk-O4IISNE7.js';
29
29
  import { RoleMemberPicker } from '../chunk-A5XQOEVH.js';
@@ -40,9 +40,9 @@ import { OptionValueFields } from '../chunk-7FZTUI6U.js';
40
40
  export { OptionValueFields } from '../chunk-7FZTUI6U.js';
41
41
  import { OrgChart } from '../chunk-A6LAIGUS.js';
42
42
  export { OrgChart } from '../chunk-A6LAIGUS.js';
43
- import { OrgChartBoard } from '../chunk-SJ3737RA.js';
44
- export { OrgChartBoard } from '../chunk-SJ3737RA.js';
45
- import '../chunk-Z4PYMTTS.js';
43
+ import { OrgChartBoard } from '../chunk-JZXU22PE.js';
44
+ export { OrgChartBoard } from '../chunk-JZXU22PE.js';
45
+ import '../chunk-XRHR452N.js';
46
46
  import '../chunk-MMIGOPO5.js';
47
47
  import { PermissionMatrixEditor } from '../chunk-LFEJLOFN.js';
48
48
  export { PermissionMatrixEditor } from '../chunk-LFEJLOFN.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipco/sdui",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "WIPCO 서버 주도 UI(SDUI) 렌더러 — JSON 페이지 스펙을 React 컴포넌트로 렌더링",
5
5
  "keywords": [
6
6
  "sdui",