@j-solution/components 1.7.0 → 1.8.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.
Files changed (176) hide show
  1. package/README.md +8 -8
  2. package/assets/jwms-portal-frontend-BtHTA-UF.css +1 -0
  3. package/assets/styles/global-utilities.css +34 -0
  4. package/assets/styles/j-components.css +1 -1
  5. package/assets/styles/themes.css +21 -21
  6. package/components/atoms/JButton.vue.cjs +6 -1
  7. package/components/atoms/JButton.vue.cjs.map +1 -1
  8. package/components/atoms/JButton.vue.js +10 -85
  9. package/components/atoms/JButton.vue.js.map +1 -1
  10. package/components/atoms/JButton.vue2.cjs +1 -1
  11. package/components/atoms/JButton.vue2.cjs.map +1 -1
  12. package/components/atoms/JButton.vue2.js +85 -2
  13. package/components/atoms/JButton.vue2.js.map +1 -1
  14. package/components/atoms/JGrid.vue.cjs +1 -1
  15. package/components/atoms/JGrid.vue.js +1 -1
  16. package/components/atoms/JGrid.vue2.cjs +1 -1
  17. package/components/atoms/JGrid.vue2.cjs.map +1 -1
  18. package/components/atoms/JGrid.vue2.js +39 -35
  19. package/components/atoms/JGrid.vue2.js.map +1 -1
  20. package/components/atoms/JLabel.vue.cjs +1 -1
  21. package/components/atoms/JLabel.vue.cjs.map +1 -1
  22. package/components/atoms/JLabel.vue.js +26 -22
  23. package/components/atoms/JLabel.vue.js.map +1 -1
  24. package/components/atoms/JSectionTitle.vue.cjs +7 -0
  25. package/components/atoms/JSectionTitle.vue.cjs.map +1 -0
  26. package/components/atoms/JSectionTitle.vue.js +13 -0
  27. package/components/atoms/JSectionTitle.vue.js.map +1 -0
  28. package/components/atoms/JSectionTitle.vue2.cjs +2 -0
  29. package/components/atoms/JSectionTitle.vue2.cjs.map +1 -0
  30. package/components/atoms/JSectionTitle.vue2.js +67 -0
  31. package/components/atoms/JSectionTitle.vue2.js.map +1 -0
  32. package/components/atoms/JSplitter.vue.cjs +6 -1
  33. package/components/atoms/JSplitter.vue.cjs.map +1 -1
  34. package/components/atoms/JSplitter.vue.js +10 -59
  35. package/components/atoms/JSplitter.vue.js.map +1 -1
  36. package/components/atoms/JSplitter.vue2.cjs +1 -1
  37. package/components/atoms/JSplitter.vue2.cjs.map +1 -1
  38. package/components/atoms/JSplitter.vue2.js +59 -2
  39. package/components/atoms/JSplitter.vue2.js.map +1 -1
  40. package/components/examples/ExampleCrudPage.vue.cjs +1 -1
  41. package/components/examples/ExampleCrudPage.vue.cjs.map +1 -1
  42. package/components/examples/ExampleCrudPage.vue.js +228 -208
  43. package/components/examples/ExampleCrudPage.vue.js.map +1 -1
  44. package/components/examples/ExampleTabMappingPage.vue.cjs +1 -1
  45. package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -1
  46. package/components/examples/ExampleTabMappingPage.vue.js +341 -368
  47. package/components/examples/ExampleTabMappingPage.vue.js.map +1 -1
  48. package/components/molecules/JAlert.vue.cjs +1 -1
  49. package/components/molecules/JAlert.vue.cjs.map +1 -1
  50. package/components/molecules/JAlert.vue.js +18 -16
  51. package/components/molecules/JAlert.vue.js.map +1 -1
  52. package/components/molecules/JCard.vue.cjs +1 -1
  53. package/components/molecules/JCard.vue.cjs.map +1 -1
  54. package/components/molecules/JCard.vue.js +55 -39
  55. package/components/molecules/JCard.vue.js.map +1 -1
  56. package/components/molecules/JEmptyState.vue.cjs +7 -0
  57. package/components/molecules/JEmptyState.vue.cjs.map +1 -0
  58. package/components/molecules/JEmptyState.vue.js +13 -0
  59. package/components/molecules/JEmptyState.vue.js.map +1 -0
  60. package/components/molecules/JEmptyState.vue2.cjs +2 -0
  61. package/components/molecules/JEmptyState.vue2.cjs.map +1 -0
  62. package/components/molecules/JEmptyState.vue2.js +127 -0
  63. package/components/molecules/JEmptyState.vue2.js.map +1 -0
  64. package/components/molecules/JFormField.vue.cjs +6 -1
  65. package/components/molecules/JFormField.vue.cjs.map +1 -1
  66. package/components/molecules/JFormField.vue.js +10 -264
  67. package/components/molecules/JFormField.vue.js.map +1 -1
  68. package/components/molecules/JFormField.vue2.cjs +2 -0
  69. package/components/molecules/JFormField.vue2.cjs.map +1 -0
  70. package/components/molecules/JFormField.vue2.js +271 -0
  71. package/components/molecules/JFormField.vue2.js.map +1 -0
  72. package/components/molecules/JTabs.vue.cjs +1 -1
  73. package/components/molecules/JTabs.vue.js +1 -1
  74. package/components/molecules/JTabs.vue2.cjs +1 -1
  75. package/components/molecules/JTabs.vue2.cjs.map +1 -1
  76. package/components/molecules/JTabs.vue2.js +44 -50
  77. package/components/molecules/JTabs.vue2.js.map +1 -1
  78. package/components/molecules/JTitlebar.vue.cjs +1 -1
  79. package/components/molecules/JTitlebar.vue.cjs.map +1 -1
  80. package/components/molecules/JTitlebar.vue.js +23 -20
  81. package/components/molecules/JTitlebar.vue.js.map +1 -1
  82. package/components/organisms/JDynamicForm.vue2.cjs +1 -1
  83. package/components/organisms/JDynamicForm.vue2.cjs.map +1 -1
  84. package/components/organisms/JDynamicForm.vue2.js +35 -32
  85. package/components/organisms/JDynamicForm.vue2.js.map +1 -1
  86. package/components/organisms/JDynamicTabs.vue.cjs +1 -1
  87. package/components/organisms/JDynamicTabs.vue.cjs.map +1 -1
  88. package/components/organisms/JDynamicTabs.vue.js +47 -52
  89. package/components/organisms/JDynamicTabs.vue.js.map +1 -1
  90. package/components/organisms/JFilterBar.vue.cjs +6 -1
  91. package/components/organisms/JFilterBar.vue.cjs.map +1 -1
  92. package/components/organisms/JFilterBar.vue.js +10 -137
  93. package/components/organisms/JFilterBar.vue.js.map +1 -1
  94. package/components/organisms/JFilterBar.vue2.cjs +1 -1
  95. package/components/organisms/JFilterBar.vue2.cjs.map +1 -1
  96. package/components/organisms/JFilterBar.vue2.js +141 -2
  97. package/components/organisms/JFilterBar.vue2.js.map +1 -1
  98. package/components/organisms/JFormModal.vue.cjs +1 -1
  99. package/components/organisms/JFormModal.vue.cjs.map +1 -1
  100. package/components/organisms/JFormModal.vue.js +54 -49
  101. package/components/organisms/JFormModal.vue.js.map +1 -1
  102. package/components/organisms/JHeader.vue.cjs +1 -1
  103. package/components/organisms/JHeader.vue.cjs.map +1 -1
  104. package/components/organisms/JHeader.vue.js +191 -190
  105. package/components/organisms/JHeader.vue.js.map +1 -1
  106. package/components/organisms/JModal.vue.cjs +1 -1
  107. package/components/organisms/JModal.vue.cjs.map +1 -1
  108. package/components/organisms/JModal.vue.js +47 -45
  109. package/components/organisms/JModal.vue.js.map +1 -1
  110. package/components/organisms/JPageContainer.vue.cjs +1 -1
  111. package/components/organisms/JPageContainer.vue.cjs.map +1 -1
  112. package/components/organisms/JPageContainer.vue.js +22 -22
  113. package/components/organisms/JPageContainer.vue.js.map +1 -1
  114. package/components/organisms/JSearchPanel.vue2.cjs +1 -1
  115. package/components/organisms/JSearchPanel.vue2.cjs.map +1 -1
  116. package/components/organisms/JSearchPanel.vue2.js +34 -32
  117. package/components/organisms/JSearchPanel.vue2.js.map +1 -1
  118. package/components/organisms/JShuttle.vue.cjs +7 -0
  119. package/components/organisms/JShuttle.vue.cjs.map +1 -0
  120. package/components/organisms/JShuttle.vue.js +13 -0
  121. package/components/organisms/JShuttle.vue.js.map +1 -0
  122. package/components/organisms/JShuttle.vue2.cjs +2 -0
  123. package/components/organisms/JShuttle.vue2.cjs.map +1 -0
  124. package/components/organisms/JShuttle.vue2.js +216 -0
  125. package/components/organisms/JShuttle.vue2.js.map +1 -0
  126. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
  127. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
  128. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +52 -52
  129. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js.map +1 -1
  130. package/components/shadcn/Card.vue.cjs +1 -1
  131. package/components/shadcn/Card.vue.cjs.map +1 -1
  132. package/components/shadcn/Card.vue.js +1 -1
  133. package/components/shadcn/Card.vue.js.map +1 -1
  134. package/components/shadcn/CardContent.vue.cjs +1 -1
  135. package/components/shadcn/CardContent.vue.cjs.map +1 -1
  136. package/components/shadcn/CardContent.vue.js +4 -4
  137. package/components/shadcn/CardContent.vue.js.map +1 -1
  138. package/components/shadcn/CardHeader.vue.cjs +1 -1
  139. package/components/shadcn/CardHeader.vue.cjs.map +1 -1
  140. package/components/shadcn/CardHeader.vue.js +5 -5
  141. package/components/shadcn/CardHeader.vue.js.map +1 -1
  142. package/components/shadcn/Input.vue.cjs +1 -1
  143. package/components/shadcn/Input.vue.cjs.map +1 -1
  144. package/components/shadcn/Input.vue.js +3 -3
  145. package/components/shadcn/Input.vue.js.map +1 -1
  146. package/components/shadcn/SelectTrigger.vue.cjs +1 -1
  147. package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
  148. package/components/shadcn/SelectTrigger.vue.js +1 -1
  149. package/components/shadcn/SelectTrigger.vue.js.map +1 -1
  150. package/components/shadcn/TabsContent.vue.cjs +1 -1
  151. package/components/shadcn/TabsContent.vue.cjs.map +1 -1
  152. package/components/shadcn/TabsContent.vue.js +1 -1
  153. package/components/shadcn/TabsContent.vue.js.map +1 -1
  154. package/components/shadcn/TabsList.vue.cjs +1 -1
  155. package/components/shadcn/TabsList.vue.cjs.map +1 -1
  156. package/components/shadcn/TabsList.vue.js +10 -10
  157. package/components/shadcn/TabsList.vue.js.map +1 -1
  158. package/components/shadcn/Textarea.vue.cjs +1 -1
  159. package/components/shadcn/Textarea.vue.cjs.map +1 -1
  160. package/components/shadcn/Textarea.vue.js +1 -1
  161. package/components/shadcn/Textarea.vue.js.map +1 -1
  162. package/components/shadcn/index.cjs +1 -1
  163. package/components/shadcn/index.cjs.map +1 -1
  164. package/components/shadcn/index.js +4 -4
  165. package/components/shadcn/index.js.map +1 -1
  166. package/components/templates/JLayout.vue.cjs.map +1 -1
  167. package/components/templates/JLayout.vue.js.map +1 -1
  168. package/index.cjs +1 -1
  169. package/index.js +73 -67
  170. package/package.json +1 -1
  171. package/types/index.d.ts +920 -777
  172. package/assets/jwms-portal-frontend-CwxPfHfa.css +0 -1
  173. package/components/molecules/JFormField.vue3.cjs +0 -2
  174. package/components/molecules/JFormField.vue3.cjs.map +0 -1
  175. package/components/molecules/JFormField.vue3.js +0 -6
  176. package/components/molecules/JFormField.vue3.js.map +0 -1
@@ -1,62 +1,13 @@
1
- import { defineComponent as z, computed as f, createBlock as r, openBlock as u, unref as i, normalizeClass as l, withCtx as n, createVNode as s, normalizeStyle as o, renderSlot as t } from "vue";
2
- import S from "../shadcn/resizable/ResizableHandle.vue.js";
3
- import g from "../shadcn/resizable/ResizablePanelGroup.vue.js";
4
- import { SplitterPanel as c } from "reka-ui";
5
- const w = /* @__PURE__ */ z({
6
- __name: "JSplitter",
7
- props: {
8
- direction: { default: "horizontal" },
9
- defaultSize: { default: 40 },
10
- minSize: { default: 20 },
11
- maxSize: {},
12
- secondMinSize: {},
13
- secondMaxSize: {},
14
- withHandle: { type: Boolean, default: !0 },
15
- gap: { default: 2 },
16
- class: {}
17
- },
18
- setup(e) {
19
- const d = e, m = f(() => 100 - d.defaultSize);
20
- return (a, h) => (u(), r(i(g), {
21
- direction: e.direction,
22
- class: l(e.class)
23
- }, {
24
- default: n(() => [
25
- s(i(c), {
26
- "default-size": e.defaultSize,
27
- "min-size": e.minSize,
28
- "max-size": e.maxSize,
29
- class: l(e.gap > 0 ? e.direction === "horizontal" ? "pr-[calc(var(--gap)/2)]" : "pb-[calc(var(--gap)/2)]" : ""),
30
- style: o(e.gap > 0 ? { "--gap": `${e.gap}px` } : {})
31
- }, {
32
- default: n(() => [
33
- t(a.$slots, "first"),
34
- t(a.$slots, "left"),
35
- t(a.$slots, "top")
36
- ]),
37
- _: 3
38
- }, 8, ["default-size", "min-size", "max-size", "class", "style"]),
39
- s(i(S), { "with-handle": e.withHandle }, null, 8, ["with-handle"]),
40
- s(i(c), {
41
- "default-size": m.value,
42
- "min-size": e.secondMinSize,
43
- "max-size": e.secondMaxSize,
44
- class: l(e.gap > 0 ? e.direction === "horizontal" ? "pl-[calc(var(--gap)/2)]" : "pt-[calc(var(--gap)/2)]" : ""),
45
- style: o(e.gap > 0 ? { "--gap": `${e.gap}px` } : {})
46
- }, {
47
- default: n(() => [
48
- t(a.$slots, "second"),
49
- t(a.$slots, "right"),
50
- t(a.$slots, "bottom")
51
- ]),
52
- _: 3
53
- }, 8, ["default-size", "min-size", "max-size", "class", "style"])
54
- ]),
55
- _: 3
56
- }, 8, ["direction", "class"]));
57
- }
58
- });
1
+ import t from "./JSplitter.vue2.js";
2
+ /* empty css */
3
+ const o = (o_comp, o_opts) => {
4
+ const o_merged = o_comp.__vccOpts || o_comp;
5
+ for (const [o_key, o_val] of o_opts)
6
+ o_merged[o_key] = o_val;
7
+ return o_merged;
8
+ };
9
+ const m = /* @__PURE__ */ o(t, [["__scopeId", "data-v-4ac249d6"]]);
59
10
  export {
60
- w as default
11
+ m as default
61
12
  };
62
13
  //# sourceMappingURL=JSplitter.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JSplitter.vue.js","sources":["../../../../src/components/atoms/JSplitter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport {\n ResizablePanelGroup,\n ResizablePanel,\n ResizableHandle,\n} from '@/components/shadcn/resizable'\n\ntype Orientation = 'horizontal' | 'vertical'\n\nconst props = withDefaults(\n defineProps<{\n /** 분할 방향 (horizontal: 좌우, vertical: 상하) */\n direction?: Orientation\n /** 첫 번째 패널의 기본 크기 (%) */\n defaultSize?: number\n /** 첫 번째 패널의 최소 크기 (%) */\n minSize?: number\n /** 첫 번째 패널의 최대 크기 (%) */\n maxSize?: number\n /** 두 번째 패널의 최소 크기 (%) */\n secondMinSize?: number\n /** 두 번째 패널의 최대 크기 (%) */\n secondMaxSize?: number\n /** ResizableHandle에 grip 아이콘 표시 여부 */\n withHandle?: boolean\n /** 패널 간 여백 (px) */\n gap?: number\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n direction: 'horizontal',\n defaultSize: 40,\n minSize: 20,\n withHandle: true,\n gap: 2,\n },\n)\n\n// 두 번째 패널의 기본 크기 계산\nconst secondDefaultSize = computed(() => 100 - props.defaultSize)\n</script>\n\n<template>\n <ResizablePanelGroup :direction=\"direction\" :class=\"class\">\n <!-- 첫 번째 패널 (좌측/상단) -->\n <ResizablePanel \n :default-size=\"defaultSize\" \n :min-size=\"minSize\" \n :max-size=\"maxSize\"\n :class=\"gap > 0 ? (direction === 'horizontal' ? 'pr-[calc(var(--gap)/2)]' : 'pb-[calc(var(--gap)/2)]') : ''\"\n :style=\"gap > 0 ? { '--gap': `${gap}px` } : {}\"\n >\n <slot name=\"first\" />\n <!-- direction=\"horizontal\"일 때 left, vertical일 때 top으로도 사용 가능 -->\n <slot name=\"left\" />\n <slot name=\"top\" />\n </ResizablePanel>\n\n <!-- 크기 조정 핸들 -->\n <ResizableHandle :with-handle=\"withHandle\" />\n\n <!-- 두 번째 패널 (우측/하단) -->\n <ResizablePanel\n :default-size=\"secondDefaultSize\"\n :min-size=\"secondMinSize\"\n :max-size=\"secondMaxSize\"\n :class=\"gap > 0 ? (direction === 'horizontal' ? 'pl-[calc(var(--gap)/2)]' : 'pt-[calc(var(--gap)/2)]') : ''\"\n :style=\"gap > 0 ? { '--gap': `${gap}px` } : {}\"\n >\n <slot name=\"second\" />\n <!-- direction=\"horizontal\"일 때 right, vertical일 때 bottom으로도 사용 가능 -->\n <slot name=\"right\" />\n <slot name=\"bottom\" />\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n"],"names":["props","__props","secondDefaultSize","computed","_createBlock","_unref","ResizablePanelGroup","_createVNode","ResizablePanel","_normalizeClass","_normalizeStyle","_renderSlot","_ctx","ResizableHandle"],"mappings":";;;;;;;;;;;;;;;;;;AAUA,UAAMA,IAAQC,GA+BRC,IAAoBC,EAAS,MAAM,MAAMH,EAAM,WAAW;2BAI9DI,EA+BsBC,EAAAC,CAAA,GAAA;AAAA,MA/BA,WAAWL,EAAA;AAAA,MAAY,SAAOA,EAAA,KAAK;AAAA,IAAA;iBAEvD,MAWiB;AAAA,QAXjBM,EAWiBF,EAAAG,CAAA,GAAA;AAAA,UAVd,gBAAcP,EAAA;AAAA,UACd,YAAUA,EAAA;AAAA,UACV,YAAUA,EAAA;AAAA,UACV,OAAKQ,EAAER,EAAA,MAAG,IAAQA,EAAA,cAAS,eAAA,4BAAA,4BAAA,EAAA;AAAA,UAC3B,OAAKS,EAAET,EAAA,MAAG,IAAA,EAAA,SAAA,GAAqBA,EAAA,GAAG,KAAA,IAAA,CAAA,CAAA;AAAA,QAAA;qBAEnC,MAAqB;AAAA,YAArBU,EAAqBC,EAAA,QAAA,OAAA;AAAA,YAErBD,EAAoBC,EAAA,QAAA,MAAA;AAAA,YACpBD,EAAmBC,EAAA,QAAA,KAAA;AAAA,UAAA;;;QAIrBL,EAA6CF,EAAAQ,CAAA,GAAA,EAA3B,eAAaZ,EAAA,WAAA,GAAU,MAAA,GAAA,CAAA,aAAA,CAAA;AAAA,QAGzCM,EAWiBF,EAAAG,CAAA,GAAA;AAAA,UAVd,gBAAcN,EAAA;AAAA,UACd,YAAUD,EAAA;AAAA,UACV,YAAUA,EAAA;AAAA,UACV,OAAKQ,EAAER,EAAA,MAAG,IAAQA,EAAA,cAAS,eAAA,4BAAA,4BAAA,EAAA;AAAA,UAC3B,OAAKS,EAAET,EAAA,MAAG,IAAA,EAAA,SAAA,GAAqBA,EAAA,GAAG,KAAA,IAAA,CAAA,CAAA;AAAA,QAAA;qBAEnC,MAAsB;AAAA,YAAtBU,EAAsBC,EAAA,QAAA,QAAA;AAAA,YAEtBD,EAAqBC,EAAA,QAAA,OAAA;AAAA,YACrBD,EAAsBC,EAAA,QAAA,QAAA;AAAA,UAAA;;;;;;;;"}
1
+ {"version":3,"file":"JSplitter.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./JSplitter.vue.cjs");exports.default=e.default;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),s=require("../shadcn/resizable/ResizableHandle.vue.cjs"),r=require("../shadcn/resizable/ResizablePanelGroup.vue.cjs"),l=require("reka-ui"),u=e.defineComponent({__name:"JSplitter",props:{direction:{default:"horizontal"},defaultSize:{default:40},minSize:{default:20},maxSize:{},secondMinSize:{},secondMaxSize:{},withHandle:{type:Boolean,default:!0},gap:{default:10},class:{}},setup(t){const i=t,n=e.computed(()=>100-i.defaultSize);return(a,d)=>(e.openBlock(),e.createBlock(e.unref(r.default),{direction:t.direction,class:e.normalizeClass(t.class)},{default:e.withCtx(()=>[e.createVNode(e.unref(l.SplitterPanel),{"default-size":t.defaultSize,"min-size":t.minSize,"max-size":t.maxSize,class:e.normalizeClass(t.gap>0?t.direction==="horizontal"?"pr-[calc(var(--gap)/2)]":"pb-[calc(var(--gap)/2)]":""),style:e.normalizeStyle(t.gap>0?{"--gap":`${t.gap}px`}:{})},{default:e.withCtx(()=>[e.renderSlot(a.$slots,"first",{},void 0,!0),e.renderSlot(a.$slots,"left",{},void 0,!0),e.renderSlot(a.$slots,"top",{},void 0,!0)]),_:3},8,["default-size","min-size","max-size","class","style"]),e.createVNode(e.unref(s.default),{"with-handle":t.withHandle},null,8,["with-handle"]),e.createVNode(e.unref(l.SplitterPanel),{"default-size":n.value,"min-size":t.secondMinSize,"max-size":t.secondMaxSize,class:e.normalizeClass(t.gap>0?t.direction==="horizontal"?"pl-[calc(var(--gap)/2)]":"pt-[calc(var(--gap)/2)]":""),style:e.normalizeStyle(t.gap>0?{"--gap":`${t.gap}px`}:{})},{default:e.withCtx(()=>[e.renderSlot(a.$slots,"second",{},void 0,!0),e.renderSlot(a.$slots,"right",{},void 0,!0),e.renderSlot(a.$slots,"bottom",{},void 0,!0)]),_:3},8,["default-size","min-size","max-size","class","style"])]),_:3},8,["direction","class"]))}});exports.default=u;
2
2
  //# sourceMappingURL=JSplitter.vue2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JSplitter.vue2.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"JSplitter.vue2.cjs","sources":["../../../../src/components/atoms/JSplitter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport {\n ResizablePanelGroup,\n ResizablePanel,\n ResizableHandle,\n} from '@/components/shadcn/resizable'\n\ntype Orientation = 'horizontal' | 'vertical'\n\nconst props = withDefaults(\n defineProps<{\n /** 분할 방향 (horizontal: 좌우, vertical: 상하) */\n direction?: Orientation\n /** 첫 번째 패널의 기본 크기 (%) */\n defaultSize?: number\n /** 첫 번째 패널의 최소 크기 (%) */\n minSize?: number\n /** 첫 번째 패널의 최대 크기 (%) */\n maxSize?: number\n /** 두 번째 패널의 최소 크기 (%) */\n secondMinSize?: number\n /** 두 번째 패널의 최대 크기 (%) */\n secondMaxSize?: number\n /** ResizableHandle에 grip 아이콘 표시 여부 */\n withHandle?: boolean\n /** 패널 간 여백 (px) */\n gap?: number\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n direction: 'horizontal',\n defaultSize: 40,\n minSize: 20,\n withHandle: true,\n gap: 10,\n },\n)\n\n// 두 번째 패널의 기본 크기 계산\nconst secondDefaultSize = computed(() => 100 - props.defaultSize)\n</script>\n\n<template>\n <ResizablePanelGroup :direction=\"direction\" :class=\"class\">\n <!-- 첫 번째 패널 (좌측/상단) -->\n <ResizablePanel \n :default-size=\"defaultSize\" \n :min-size=\"minSize\" \n :max-size=\"maxSize\"\n :class=\"gap > 0 ? (direction === 'horizontal' ? 'pr-[calc(var(--gap)/2)]' : 'pb-[calc(var(--gap)/2)]') : ''\"\n :style=\"gap > 0 ? { '--gap': `${gap}px` } : {}\"\n >\n <slot name=\"first\" />\n <!-- direction=\"horizontal\"일 때 left, vertical일 때 top으로도 사용 가능 -->\n <slot name=\"left\" />\n <slot name=\"top\" />\n </ResizablePanel>\n\n <!-- 크기 조정 핸들 -->\n <ResizableHandle :with-handle=\"withHandle\" />\n\n <!-- 두 번째 패널 (우측/하단) -->\n <ResizablePanel\n :default-size=\"secondDefaultSize\"\n :min-size=\"secondMinSize\"\n :max-size=\"secondMaxSize\"\n :class=\"gap > 0 ? (direction === 'horizontal' ? 'pl-[calc(var(--gap)/2)]' : 'pt-[calc(var(--gap)/2)]') : ''\"\n :style=\"gap > 0 ? { '--gap': `${gap}px` } : {}\"\n >\n <slot name=\"second\" />\n <!-- direction=\"horizontal\"일 때 right, vertical일 때 bottom으로도 사용 가능 -->\n <slot name=\"right\" />\n <slot name=\"bottom\" />\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n\n<style scoped>\n/* ========================================\n 패턴 5: Splitter Handle 스타일\n ======================================== */\n\n:deep([data-panel-resize-handle-id]) {\n background: hsl(var(--border) / 0.8);\n transition: all 0.2s ease;\n position: relative;\n}\n\n:deep([data-panel-resize-handle-id]::before) {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: hsl(var(--muted-foreground) / 0.2);\n}\n\n:deep([data-panel-resize-handle-id]:hover) {\n background: hsl(var(--primary) / 0.6);\n}\n\n:deep([data-panel-resize-handle-id]:hover::before) {\n background: hsl(var(--primary) / 0.3);\n}\n\n:deep([data-panel-resize-handle-id]:active) {\n background: hsl(var(--primary));\n}\n\n:deep([data-panel-resize-handle-id]:active::before) {\n background: hsl(var(--primary) / 0.5);\n}\n\n:deep([data-panel-resize-handle-id][data-resize-handle-orientation=\"horizontal\"]) {\n cursor: col-resize;\n width: 6px;\n}\n\n:deep([data-panel-resize-handle-id][data-resize-handle-orientation=\"vertical\"]) {\n cursor: row-resize;\n height: 6px;\n}\n</style>\n"],"names":["props","__props","secondDefaultSize","computed","_createBlock","_unref","ResizablePanelGroup","_createVNode","ResizablePanel","_normalizeClass","_normalizeStyle","_renderSlot","_ctx","ResizableHandle"],"mappings":"kgBAUA,MAAMA,EAAQC,EA+BRC,EAAoBC,EAAAA,SAAS,IAAM,IAAMH,EAAM,WAAW,8BAI9DI,EAAAA,YA+BsBC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CA/BA,UAAWL,EAAA,UAAY,uBAAOA,EAAA,KAAK,CAAA,qBAEvD,IAWiB,CAXjBM,cAWiBF,EAAAA,MAAAG,EAAAA,aAAA,EAAA,CAVd,eAAcP,EAAA,YACd,WAAUA,EAAA,QACV,WAAUA,EAAA,QACV,MAAKQ,EAAAA,eAAER,EAAA,IAAG,EAAQA,EAAA,YAAS,aAAA,0BAAA,0BAAA,EAAA,EAC3B,MAAKS,EAAAA,eAAET,EAAA,IAAG,EAAA,CAAA,QAAA,GAAqBA,EAAA,GAAG,IAAA,EAAA,CAAA,CAAA,CAAA,qBAEnC,IAAqB,CAArBU,EAAAA,WAAqBC,EAAA,OAAA,QAAA,CAAA,EAAA,OAAA,EAAA,EAErBD,EAAAA,WAAoBC,EAAA,OAAA,OAAA,CAAA,EAAA,OAAA,EAAA,EACpBD,EAAAA,WAAmBC,EAAA,OAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,kEAIrBL,EAAAA,YAA6CF,EAAAA,MAAAQ,SAAA,EAAA,CAA3B,cAAaZ,EAAA,UAAA,EAAU,KAAA,EAAA,CAAA,aAAA,CAAA,EAGzCM,cAWiBF,EAAAA,MAAAG,EAAAA,aAAA,EAAA,CAVd,eAAcN,EAAA,MACd,WAAUD,EAAA,cACV,WAAUA,EAAA,cACV,MAAKQ,EAAAA,eAAER,EAAA,IAAG,EAAQA,EAAA,YAAS,aAAA,0BAAA,0BAAA,EAAA,EAC3B,MAAKS,EAAAA,eAAET,EAAA,IAAG,EAAA,CAAA,QAAA,GAAqBA,EAAA,GAAG,IAAA,EAAA,CAAA,CAAA,CAAA,qBAEnC,IAAsB,CAAtBU,EAAAA,WAAsBC,EAAA,OAAA,SAAA,CAAA,EAAA,OAAA,EAAA,EAEtBD,EAAAA,WAAqBC,EAAA,OAAA,QAAA,CAAA,EAAA,OAAA,EAAA,EACrBD,EAAAA,WAAsBC,EAAA,OAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA"}
@@ -1,5 +1,62 @@
1
- import f from "./JSplitter.vue.js";
1
+ import { defineComponent as u, computed as m, createBlock as z, openBlock as f, unref as i, normalizeClass as l, withCtx as n, createVNode as s, normalizeStyle as o, renderSlot as t } from "vue";
2
+ import S from "../shadcn/resizable/ResizableHandle.vue.js";
3
+ import g from "../shadcn/resizable/ResizablePanelGroup.vue.js";
4
+ import { SplitterPanel as d } from "reka-ui";
5
+ const w = /* @__PURE__ */ u({
6
+ __name: "JSplitter",
7
+ props: {
8
+ direction: { default: "horizontal" },
9
+ defaultSize: { default: 40 },
10
+ minSize: { default: 20 },
11
+ maxSize: {},
12
+ secondMinSize: {},
13
+ secondMaxSize: {},
14
+ withHandle: { type: Boolean, default: !0 },
15
+ gap: { default: 10 },
16
+ class: {}
17
+ },
18
+ setup(e) {
19
+ const c = e, r = m(() => 100 - c.defaultSize);
20
+ return (a, h) => (f(), z(i(g), {
21
+ direction: e.direction,
22
+ class: l(e.class)
23
+ }, {
24
+ default: n(() => [
25
+ s(i(d), {
26
+ "default-size": e.defaultSize,
27
+ "min-size": e.minSize,
28
+ "max-size": e.maxSize,
29
+ class: l(e.gap > 0 ? e.direction === "horizontal" ? "pr-[calc(var(--gap)/2)]" : "pb-[calc(var(--gap)/2)]" : ""),
30
+ style: o(e.gap > 0 ? { "--gap": `${e.gap}px` } : {})
31
+ }, {
32
+ default: n(() => [
33
+ t(a.$slots, "first", {}, void 0, !0),
34
+ t(a.$slots, "left", {}, void 0, !0),
35
+ t(a.$slots, "top", {}, void 0, !0)
36
+ ]),
37
+ _: 3
38
+ }, 8, ["default-size", "min-size", "max-size", "class", "style"]),
39
+ s(i(S), { "with-handle": e.withHandle }, null, 8, ["with-handle"]),
40
+ s(i(d), {
41
+ "default-size": r.value,
42
+ "min-size": e.secondMinSize,
43
+ "max-size": e.secondMaxSize,
44
+ class: l(e.gap > 0 ? e.direction === "horizontal" ? "pl-[calc(var(--gap)/2)]" : "pt-[calc(var(--gap)/2)]" : ""),
45
+ style: o(e.gap > 0 ? { "--gap": `${e.gap}px` } : {})
46
+ }, {
47
+ default: n(() => [
48
+ t(a.$slots, "second", {}, void 0, !0),
49
+ t(a.$slots, "right", {}, void 0, !0),
50
+ t(a.$slots, "bottom", {}, void 0, !0)
51
+ ]),
52
+ _: 3
53
+ }, 8, ["default-size", "min-size", "max-size", "class", "style"])
54
+ ]),
55
+ _: 3
56
+ }, 8, ["direction", "class"]));
57
+ }
58
+ });
2
59
  export {
3
- f as default
60
+ w as default
4
61
  };
5
62
  //# sourceMappingURL=JSplitter.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JSplitter.vue2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"JSplitter.vue2.js","sources":["../../../../src/components/atoms/JSplitter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport {\n ResizablePanelGroup,\n ResizablePanel,\n ResizableHandle,\n} from '@/components/shadcn/resizable'\n\ntype Orientation = 'horizontal' | 'vertical'\n\nconst props = withDefaults(\n defineProps<{\n /** 분할 방향 (horizontal: 좌우, vertical: 상하) */\n direction?: Orientation\n /** 첫 번째 패널의 기본 크기 (%) */\n defaultSize?: number\n /** 첫 번째 패널의 최소 크기 (%) */\n minSize?: number\n /** 첫 번째 패널의 최대 크기 (%) */\n maxSize?: number\n /** 두 번째 패널의 최소 크기 (%) */\n secondMinSize?: number\n /** 두 번째 패널의 최대 크기 (%) */\n secondMaxSize?: number\n /** ResizableHandle에 grip 아이콘 표시 여부 */\n withHandle?: boolean\n /** 패널 간 여백 (px) */\n gap?: number\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n direction: 'horizontal',\n defaultSize: 40,\n minSize: 20,\n withHandle: true,\n gap: 10,\n },\n)\n\n// 두 번째 패널의 기본 크기 계산\nconst secondDefaultSize = computed(() => 100 - props.defaultSize)\n</script>\n\n<template>\n <ResizablePanelGroup :direction=\"direction\" :class=\"class\">\n <!-- 첫 번째 패널 (좌측/상단) -->\n <ResizablePanel \n :default-size=\"defaultSize\" \n :min-size=\"minSize\" \n :max-size=\"maxSize\"\n :class=\"gap > 0 ? (direction === 'horizontal' ? 'pr-[calc(var(--gap)/2)]' : 'pb-[calc(var(--gap)/2)]') : ''\"\n :style=\"gap > 0 ? { '--gap': `${gap}px` } : {}\"\n >\n <slot name=\"first\" />\n <!-- direction=\"horizontal\"일 때 left, vertical일 때 top으로도 사용 가능 -->\n <slot name=\"left\" />\n <slot name=\"top\" />\n </ResizablePanel>\n\n <!-- 크기 조정 핸들 -->\n <ResizableHandle :with-handle=\"withHandle\" />\n\n <!-- 두 번째 패널 (우측/하단) -->\n <ResizablePanel\n :default-size=\"secondDefaultSize\"\n :min-size=\"secondMinSize\"\n :max-size=\"secondMaxSize\"\n :class=\"gap > 0 ? (direction === 'horizontal' ? 'pl-[calc(var(--gap)/2)]' : 'pt-[calc(var(--gap)/2)]') : ''\"\n :style=\"gap > 0 ? { '--gap': `${gap}px` } : {}\"\n >\n <slot name=\"second\" />\n <!-- direction=\"horizontal\"일 때 right, vertical일 때 bottom으로도 사용 가능 -->\n <slot name=\"right\" />\n <slot name=\"bottom\" />\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n\n<style scoped>\n/* ========================================\n 패턴 5: Splitter Handle 스타일\n ======================================== */\n\n:deep([data-panel-resize-handle-id]) {\n background: hsl(var(--border) / 0.8);\n transition: all 0.2s ease;\n position: relative;\n}\n\n:deep([data-panel-resize-handle-id]::before) {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: hsl(var(--muted-foreground) / 0.2);\n}\n\n:deep([data-panel-resize-handle-id]:hover) {\n background: hsl(var(--primary) / 0.6);\n}\n\n:deep([data-panel-resize-handle-id]:hover::before) {\n background: hsl(var(--primary) / 0.3);\n}\n\n:deep([data-panel-resize-handle-id]:active) {\n background: hsl(var(--primary));\n}\n\n:deep([data-panel-resize-handle-id]:active::before) {\n background: hsl(var(--primary) / 0.5);\n}\n\n:deep([data-panel-resize-handle-id][data-resize-handle-orientation=\"horizontal\"]) {\n cursor: col-resize;\n width: 6px;\n}\n\n:deep([data-panel-resize-handle-id][data-resize-handle-orientation=\"vertical\"]) {\n cursor: row-resize;\n height: 6px;\n}\n</style>\n"],"names":["props","__props","secondDefaultSize","computed","_createBlock","_unref","ResizablePanelGroup","_createVNode","ResizablePanel","_normalizeClass","_normalizeStyle","_renderSlot","_ctx","ResizableHandle"],"mappings":";;;;;;;;;;;;;;;;;;AAUA,UAAMA,IAAQC,GA+BRC,IAAoBC,EAAS,MAAM,MAAMH,EAAM,WAAW;2BAI9DI,EA+BsBC,EAAAC,CAAA,GAAA;AAAA,MA/BA,WAAWL,EAAA;AAAA,MAAY,SAAOA,EAAA,KAAK;AAAA,IAAA;iBAEvD,MAWiB;AAAA,QAXjBM,EAWiBF,EAAAG,CAAA,GAAA;AAAA,UAVd,gBAAcP,EAAA;AAAA,UACd,YAAUA,EAAA;AAAA,UACV,YAAUA,EAAA;AAAA,UACV,OAAKQ,EAAER,EAAA,MAAG,IAAQA,EAAA,cAAS,eAAA,4BAAA,4BAAA,EAAA;AAAA,UAC3B,OAAKS,EAAET,EAAA,MAAG,IAAA,EAAA,SAAA,GAAqBA,EAAA,GAAG,KAAA,IAAA,CAAA,CAAA;AAAA,QAAA;qBAEnC,MAAqB;AAAA,YAArBU,EAAqBC,EAAA,QAAA,SAAA,CAAA,GAAA,QAAA,EAAA;AAAA,YAErBD,EAAoBC,EAAA,QAAA,QAAA,CAAA,GAAA,QAAA,EAAA;AAAA,YACpBD,EAAmBC,EAAA,QAAA,OAAA,CAAA,GAAA,QAAA,EAAA;AAAA,UAAA;;;QAIrBL,EAA6CF,EAAAQ,CAAA,GAAA,EAA3B,eAAaZ,EAAA,WAAA,GAAU,MAAA,GAAA,CAAA,aAAA,CAAA;AAAA,QAGzCM,EAWiBF,EAAAG,CAAA,GAAA;AAAA,UAVd,gBAAcN,EAAA;AAAA,UACd,YAAUD,EAAA;AAAA,UACV,YAAUA,EAAA;AAAA,UACV,OAAKQ,EAAER,EAAA,MAAG,IAAQA,EAAA,cAAS,eAAA,4BAAA,4BAAA,EAAA;AAAA,UAC3B,OAAKS,EAAET,EAAA,MAAG,IAAA,EAAA,SAAA,GAAqBA,EAAA,GAAG,KAAA,IAAA,CAAA,CAAA;AAAA,QAAA;qBAEnC,MAAsB;AAAA,YAAtBU,EAAsBC,EAAA,QAAA,UAAA,CAAA,GAAA,QAAA,EAAA;AAAA,YAEtBD,EAAqBC,EAAA,QAAA,SAAA,CAAA,GAAA,QAAA,EAAA;AAAA,YACrBD,EAAsBC,EAAA,QAAA,UAAA,CAAA,GAAA,QAAA,EAAA;AAAA,UAAA;;;;;;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),u=require("../molecules/JFormField.vue.cjs");;/* empty css */require("../shadcn/index.cjs");require("@vueuse/core");require("reka-ui");require("clsx");require("tailwind-merge");require("lucide-vue-next");;/* empty css */;/* empty css */;/* empty css */const w=require("../molecules/JCard.vue.cjs"),n=require("../atoms/JButton.vue.cjs");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */const x=require("../atoms/JGrid.vue.cjs"),A=require("../atoms/JSplitter.vue.cjs");require("vue-sonner");const h=require("../molecules/JTitlebar.vue.cjs");;/* empty css */;/* empty css */const z=require("../organisms/JFilterBar.vue.cjs");require("vue-router");;/* empty css */;/* empty css */const B={class:"flex flex-col h-full gap-2 bg-background text-foreground"},Y={class:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2"},E={class:"h-full overflow-auto bg-background"},U={class:"h-full overflow-y-auto border-l bg-muted/30"},P={class:"grid grid-cols-1 md:grid-cols-2 gap-2 mt-2"},T={class:"grid grid-cols-1 md:grid-cols-2 gap-2 mt-2"},J={class:"grid grid-cols-1 gap-2 mt-2"},R={class:"flex justify-end gap-2"},S=e.defineComponent({__name:"ExampleCrudPage",setup(G,{expose:c}){const d=e.ref(!1),o=e.ref({isActive:"",keyword:""}),f={isActive:{label:"활성여부",displayValue:r=>r==="Y"?"Y:활성":r==="N"?"N:비활성":""},keyword:{label:"검색어"}},m=[{value:"Y",label:"Y:활성"},{value:"N",label:"N:비활성"}],v=[{value:"A",label:"A등급"},{value:"B",label:"B등급"},{value:"C",label:"C등급"}],s=e.ref(),p=e.ref([{code:"C001",name:"제이솔루션",category:"A",isActive:"Y",remark:"주력 고객사"},{code:"C002",name:"ABC물류",category:"B",isActive:"Y",remark:""},{code:"C003",name:"XYZ유통",category:"A",isActive:"N",remark:"비활성"},{code:"C004",name:"대한물류",category:"B",isActive:"Y",remark:""},{code:"C005",name:"글로벌이커머스",category:"A",isActive:"Y",remark:"신규 고객사"}]),g=e.ref([{field:"code",headerName:"코드",width:120,enableValue:!0},{field:"name",headerName:"이름",width:200,enableValue:!0},{field:"category",headerName:"분류",width:100,enableRowGroup:!0,enablePivot:!0},{field:"isActive",headerName:"활성",width:100,cellRenderer:r=>r.value==="Y"?"✓":"",enableRowGroup:!0,enablePivot:!0},{field:"remark",headerName:"비고",flex:1,enableValue:!0}]),V=[{icon:"pencil",label:"수정",tooltip:"편집",onClick:r=>{i.value=!1,t.value={code:r.code,name:r.name,category:r.category,isActive:r.isActive,remark:r.remark}}},{icon:"trash2",label:"삭제",tooltip:"삭제",styletype:"danger",onClick:r=>{confirm(`${r.name}을(를) 삭제하시겠습니까?`)&&(console.log("삭제:",r.code),alert(`삭제되었습니다: ${r.name}`))}}],i=e.ref(!1),t=e.ref({code:"",name:"",category:"",isActive:"Y",remark:""});function y(r){i.value=!1;const l=r.data;t.value={code:l.code,name:l.name,category:l.category,isActive:l.isActive,remark:l.remark}}function _(){i.value=!0,t.value={code:"",name:"",category:"",isActive:"Y",remark:""}}function b(){console.log("저장:",t.value),alert(`저장되었습니다: ${t.value.name}`)}function N(){confirm(`${t.value.name}을(를) 삭제하시겠습니까?`)&&(console.log("삭제:",t.value.code),alert(`삭제되었습니다: ${t.value.name}`))}function k(){o.value={isActive:"",keyword:""},console.log("필터 초기화")}function q(){console.log("조회 조건:",o.value)}function C(){alert("고객사 관리 페이지 도움말")}return c({gridRef:s}),(r,l)=>(e.openBlock(),e.createElementBlock("div",B,[e.createVNode(e.unref(h.default),{icon:"building",title:"고객사 관리",description:"고객사 정보를 조회하고 관리합니다",showHelp:!0,onHelp:C}),e.createVNode(e.unref(z.default),{collapsed:d.value,"onUpdate:collapsed":l[2]||(l[2]=a=>d.value=a),filterValues:o.value,"onUpdate:filterValues":l[3]||(l[3]=a=>o.value=a),filterDisplay:f,collapsible:!0,title:"고객사 목록"},{actions:e.withCtx(()=>[e.createVNode(e.unref(n.default),{size:"sm",variant:"outline",onClick:k},{default:e.withCtx(()=>[...l[9]||(l[9]=[e.createTextVNode("초기화",-1)])]),_:1}),e.createVNode(e.unref(n.default),{size:"sm",styletype:"primary",onClick:q},{default:e.withCtx(()=>[...l[10]||(l[10]=[e.createTextVNode("조회",-1)])]),_:1}),e.createVNode(e.unref(n.default),{size:"sm",styletype:"primary",onClick:_},{default:e.withCtx(()=>[...l[11]||(l[11]=[e.createTextVNode("신규",-1)])]),_:1})]),filters:e.withCtx(()=>[e.createElementVNode("div",Y,[e.createVNode(e.unref(u.default),{type:"combo",label:"활성여부",modelValue:o.value.isActive,"onUpdate:modelValue":l[0]||(l[0]=a=>o.value.isActive=a),options:m,orientation:"horizontal",labelWidth:"30%"},null,8,["modelValue"]),e.createVNode(e.unref(u.default),{type:"input",label:"검색어",modelValue:o.value.keyword,"onUpdate:modelValue":l[1]||(l[1]=a=>o.value.keyword=a),orientation:"horizontal",labelWidth:"30%"},null,8,["modelValue"])])]),_:1},8,["collapsed","filterValues"]),e.createVNode(e.unref(A.default),{direction:"horizontal","default-size":60,"min-size":30,"second-min-size":20,"second-max-size":60,gap:2,class:"flex-1"},{left:e.withCtx(()=>[e.createElementVNode("div",E,[e.createVNode(e.unref(x.default),{ref_key:"gridRef",ref:s,columnDefs:g.value,rowData:p.value,"action-buttons":V,enableGrouping:!0,enablePivot:!0,enableColumnsToolPanel:!0,rowGroupPanelShow:"always",pivotPanelShow:"always",groupDefaultExpanded:1,compactFooter:!0,onRowClicked:y},null,8,["columnDefs","rowData"])])]),right:e.withCtx(()=>[e.createElementVNode("div",U,[e.createVNode(e.unref(w.default),{class:"h-full",title:i.value?"신규 등록":"상세 정보"},{footer:e.withCtx(()=>[e.createElementVNode("div",R,[e.createVNode(e.unref(n.default),{styletype:"primary",size:"sm",onClick:b},{default:e.withCtx(()=>[...l[12]||(l[12]=[e.createTextVNode("저장",-1)])]),_:1}),i.value?e.createCommentVNode("",!0):(e.openBlock(),e.createBlock(e.unref(n.default),{key:0,variant:"outline",size:"sm",onClick:N},{default:e.withCtx(()=>[...l[13]||(l[13]=[e.createTextVNode("삭제",-1)])]),_:1}))])]),default:e.withCtx(()=>[e.createElementVNode("div",P,[e.createVNode(e.unref(u.default),{type:"input",label:"코드",modelValue:t.value.code,"onUpdate:modelValue":l[4]||(l[4]=a=>t.value.code=a),readonly:!i.value,placeholder:"고객사 코드"},null,8,["modelValue","readonly"]),e.createVNode(e.unref(u.default),{type:"input",label:"이름",modelValue:t.value.name,"onUpdate:modelValue":l[5]||(l[5]=a=>t.value.name=a),placeholder:"고객사 이름"},null,8,["modelValue"])]),e.createElementVNode("div",T,[e.createVNode(e.unref(u.default),{type:"combo",label:"분류",modelValue:t.value.category,"onUpdate:modelValue":l[6]||(l[6]=a=>t.value.category=a),options:v},null,8,["modelValue"]),e.createVNode(e.unref(u.default),{type:"checkbox",label:"활성여부",modelValue:t.value.isActive,"onUpdate:modelValue":l[7]||(l[7]=a=>t.value.isActive=a),inlineLabel:"활성"},null,8,["modelValue"])]),e.createElementVNode("div",J,[e.createVNode(e.unref(u.default),{type:"textarea",label:"비고",modelValue:t.value.remark,"onUpdate:modelValue":l[8]||(l[8]=a=>t.value.remark=a),placeholder:"비고"},null,8,["modelValue"])])]),_:1},8,["title"])])]),_:1})]))}});exports.default=S;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),u=require("../molecules/JFormField.vue.cjs");require("../shadcn/index.cjs");require("@vueuse/core");require("reka-ui");require("clsx");require("tailwind-merge");require("lucide-vue-next");;/* empty css */;/* empty css */;/* empty css */const w=require("../molecules/JCard.vue.cjs"),n=require("../atoms/JButton.vue.cjs");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */const A=require("../atoms/JGrid.vue.cjs"),h=require("../atoms/JSplitter.vue.cjs");;/* empty css */require("vue-sonner");const _=require("../molecules/JEmptyState.vue.cjs");;/* empty css */;/* empty css */const B=require("../organisms/JFilterBar.vue.cjs");require("vue-router");;/* empty css */;/* empty css */const z=require("../organisms/JPageContainer.vue.cjs");;/* empty css */const Y={class:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2"},P={class:"h-full overflow-auto bg-background"},E={class:"h-full overflow-y-auto bg-muted/30"},U={class:"grid grid-cols-1 md:grid-cols-2 gap-2"},J={class:"grid grid-cols-1 md:grid-cols-2 gap-2 mt-2"},S={class:"grid grid-cols-1 gap-2 mt-2"},T=e.defineComponent({__name:"ExampleCrudPage",setup(R,{expose:f}){const d=e.ref(!1),o=e.ref({isActive:"",keyword:""}),m={isActive:{label:"활성여부",displayValue:r=>r==="Y"?"Y:활성":r==="N"?"N:비활성":""},keyword:{label:"검색어"}},v=[{value:"Y",label:"Y:활성"},{value:"N",label:"N:비활성"}],p=[{value:"A",label:"A등급"},{value:"B",label:"B등급"},{value:"C",label:"C등급"}],s=e.ref(),V=e.ref([{code:"C001",name:"제이솔루션",category:"A",isActive:"Y",remark:"주력 고객사"},{code:"C002",name:"ABC물류",category:"B",isActive:"Y",remark:""},{code:"C003",name:"XYZ유통",category:"A",isActive:"N",remark:"비활성"},{code:"C004",name:"대한물류",category:"B",isActive:"Y",remark:""},{code:"C005",name:"글로벌이커머스",category:"A",isActive:"Y",remark:"신규 고객사"}]),g=e.ref([{field:"code",headerName:"코드",width:120,enableValue:!0},{field:"name",headerName:"이름",width:200,enableValue:!0},{field:"category",headerName:"분류",width:100,enableRowGroup:!0,enablePivot:!0},{field:"isActive",headerName:"활성",width:100,cellRenderer:r=>r.value==="Y"?"✓":"",enableRowGroup:!0,enablePivot:!0},{field:"remark",headerName:"비고",flex:1,enableValue:!0}]),y=[{icon:"pencil",label:"수정",tooltip:"편집",onClick:r=>{i.value=!1,t.value={code:r.code,name:r.name,category:r.category,isActive:r.isActive,remark:r.remark}}},{icon:"trash2",label:"삭제",tooltip:"삭제",styletype:"danger",onClick:r=>{confirm(`${r.name}을(를) 삭제하시겠습니까?`)&&(console.log("삭제:",r.code),alert(`삭제되었습니다: ${r.name}`))}}],i=e.ref(!1),t=e.ref({code:"",name:"",category:"",isActive:"Y",remark:""});function k(r){i.value=!1;const l=r.data;t.value={code:l.code,name:l.name,category:l.category,isActive:l.isActive,remark:l.remark}}function b(){i.value=!0,t.value={code:"",name:"",category:"",isActive:"Y",remark:""}}function N(){console.log("저장:",t.value),alert(`저장되었습니다: ${t.value.name}`)}function C(){confirm(`${t.value.name}을(를) 삭제하시겠습니까?`)&&(console.log("삭제:",t.value.code),alert(`삭제되었습니다: ${t.value.name}`))}function c(){o.value={isActive:"",keyword:""},console.log("필터 초기화")}function q(){console.log("조회 조건:",o.value)}function x(){alert("고객사 관리 페이지 도움말")}return f({gridRef:s}),(r,l)=>(e.openBlock(),e.createBlock(z.default,{title:"고객사 관리",icon:"building",description:"고객사 정보를 조회하고 관리합니다",showHelp:!0,onHelp:x,"content-scroll":!1},{default:e.withCtx(()=>[e.createVNode(e.unref(B.default),{collapsed:d.value,"onUpdate:collapsed":l[2]||(l[2]=a=>d.value=a),filterValues:o.value,"onUpdate:filterValues":l[3]||(l[3]=a=>o.value=a),filterDisplay:m,collapsible:!0,title:"고객사 목록"},{actions:e.withCtx(()=>[e.createVNode(e.unref(n.default),{size:"xs",variant:"outline",onClick:c},{default:e.withCtx(()=>[...l[9]||(l[9]=[e.createTextVNode("초기화",-1)])]),_:1}),e.createVNode(e.unref(n.default),{size:"xs",styletype:"primary",onClick:q},{default:e.withCtx(()=>[...l[10]||(l[10]=[e.createTextVNode("조회",-1)])]),_:1}),e.createVNode(e.unref(n.default),{size:"xs",styletype:"primary",onClick:b},{default:e.withCtx(()=>[...l[11]||(l[11]=[e.createTextVNode("신규",-1)])]),_:1})]),filters:e.withCtx(()=>[e.createElementVNode("div",Y,[e.createVNode(e.unref(u.default),{type:"combo",label:"활성여부",modelValue:o.value.isActive,"onUpdate:modelValue":l[0]||(l[0]=a=>o.value.isActive=a),options:v,orientation:"horizontal",labelWidth:"30%"},null,8,["modelValue"]),e.createVNode(e.unref(u.default),{type:"input",label:"검색어",modelValue:o.value.keyword,"onUpdate:modelValue":l[1]||(l[1]=a=>o.value.keyword=a),orientation:"horizontal",labelWidth:"30%"},null,8,["modelValue"])])]),_:1},8,["collapsed","filterValues"]),e.createVNode(e.unref(h.default),{direction:"horizontal","default-size":60,"min-size":30,"second-min-size":20,"second-max-size":60,class:"flex-1"},{left:e.withCtx(()=>[e.createElementVNode("div",P,[e.createVNode(e.unref(A.default),{ref_key:"gridRef",ref:s,columnDefs:g.value,rowData:V.value,"action-buttons":y,enableGrouping:!0,enablePivot:!0,enableColumnsToolPanel:!0,rowGroupPanelShow:"always",pivotPanelShow:"always",groupDefaultExpanded:1,compactFooter:!0,onRowClicked:k},null,8,["columnDefs","rowData"])])]),right:e.withCtx(()=>[e.createElementVNode("div",E,[!t.value.code&&!i.value?(e.openBlock(),e.createBlock(e.unref(_.default),{key:0,variant:"simple",icon:"mousePointerClick",title:"항목을 선택하거나 신규 버튼을 클릭하세요",class:"h-full"})):(e.openBlock(),e.createBlock(e.unref(w.default),{key:1,class:"h-full",title:i.value?"신규 등록":"상세 정보",variant:"elevated"},{actions:e.withCtx(()=>[e.createVNode(e.unref(n.default),{size:"xs",styletype:"primary",onClick:N},{default:e.withCtx(()=>[...l[12]||(l[12]=[e.createTextVNode("저장",-1)])]),_:1}),i.value?e.createCommentVNode("",!0):(e.openBlock(),e.createBlock(e.unref(n.default),{key:0,size:"xs",variant:"destructive",onClick:C},{default:e.withCtx(()=>[...l[13]||(l[13]=[e.createTextVNode("삭제",-1)])]),_:1})),e.createVNode(e.unref(n.default),{size:"xs",variant:"outline",onClick:c},{default:e.withCtx(()=>[...l[14]||(l[14]=[e.createTextVNode("취소",-1)])]),_:1})]),default:e.withCtx(()=>[e.createElementVNode("div",U,[e.createVNode(e.unref(u.default),{type:"input",label:"코드",modelValue:t.value.code,"onUpdate:modelValue":l[4]||(l[4]=a=>t.value.code=a),readonly:!i.value,placeholder:"고객사 코드"},null,8,["modelValue","readonly"]),e.createVNode(e.unref(u.default),{type:"input",label:"이름",modelValue:t.value.name,"onUpdate:modelValue":l[5]||(l[5]=a=>t.value.name=a),placeholder:"고객사 이름"},null,8,["modelValue"])]),e.createElementVNode("div",J,[e.createVNode(e.unref(u.default),{type:"combo",label:"분류",modelValue:t.value.category,"onUpdate:modelValue":l[6]||(l[6]=a=>t.value.category=a),options:p},null,8,["modelValue"]),e.createVNode(e.unref(u.default),{type:"checkbox",label:"활성여부",modelValue:t.value.isActive,"onUpdate:modelValue":l[7]||(l[7]=a=>t.value.isActive=a),inlineLabel:"활성"},null,8,["modelValue"])]),e.createElementVNode("div",S,[e.createVNode(e.unref(u.default),{type:"textarea",label:"비고",modelValue:t.value.remark,"onUpdate:modelValue":l[8]||(l[8]=a=>t.value.remark=a),placeholder:"비고"},null,8,["modelValue"])])]),_:1},8,["title"]))])]),_:1})]),_:1}))}});exports.default=T;
2
2
  //# sourceMappingURL=ExampleCrudPage.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExampleCrudPage.vue.cjs","sources":["../../../../src/components/examples/ExampleCrudPage.vue"],"sourcesContent":["<template>\n <div class=\"flex flex-col h-full gap-2 bg-background text-foreground\">\n <!-- ==================== 타이틀바 ==================== -->\n <JTitlebar \n icon=\"building\" \n title=\"고객사 관리\" \n description=\"고객사 정보를 조회하고 관리합니다\"\n :showHelp=\"true\" \n @help=\"onHelp\" \n />\n\n <!-- ==================== 필터바 ==================== -->\n <JFilterBar\n v-model:collapsed=\"filterCollapsed\"\n v-model:filterValues=\"filterValues\"\n :filterDisplay=\"filterDisplay\"\n :collapsible=\"true\"\n title=\"고객사 목록\"\n >\n <!-- 액션 버튼 -->\n <template #actions>\n <JButton size=\"sm\" variant=\"outline\" @click=\"onReset\">초기화</JButton>\n <JButton size=\"sm\" styletype=\"primary\" @click=\"onSearch\">조회</JButton>\n <JButton size=\"sm\" styletype=\"primary\" @click=\"onNew\">신규</JButton>\n </template>\n\n <!-- 필터 필드 - 다중 열 배치 -->\n <template #filters>\n <div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2\">\n <JFormField\n type=\"combo\"\n label=\"활성여부\"\n v-model=\"filterValues.isActive\"\n :options=\"activeOptions\"\n orientation=\"horizontal\"\n labelWidth=\"30%\"\n />\n <JFormField type=\"input\" label=\"검색어\" v-model=\"filterValues.keyword\"\n orientation=\"horizontal\"\n labelWidth=\"30%\" />\n </div>\n </template>\n </JFilterBar>\n\n <!-- ==================== 그리드 + 상세 영역 (Resizable) ==================== -->\n <JSplitter\n direction=\"horizontal\"\n :default-size=\"60\"\n :min-size=\"30\"\n :second-min-size=\"20\"\n :second-max-size=\"60\"\n :gap=\"2\"\n class=\"flex-1\"\n >\n <!-- 좌측: 그리드 -->\n <template #left>\n <div class=\"h-full overflow-auto bg-background\">\n <JGrid\n ref=\"gridRef\"\n :columnDefs=\"columnDefs\"\n :rowData=\"rowData\"\n :action-buttons=\"actionButtons\"\n :enableGrouping=\"true\"\n :enablePivot=\"true\"\n :enableColumnsToolPanel=\"true\"\n rowGroupPanelShow=\"always\"\n pivotPanelShow=\"always\"\n :groupDefaultExpanded=\"1\"\n :compactFooter=\"true\"\n @row-clicked=\"onRowClicked\"\n />\n </div>\n </template>\n\n <!-- 우측: 상세 영역 -->\n <template #right>\n <div class=\"h-full overflow-y-auto border-l bg-muted/30\">\n <JCard class=\"h-full\" :title=\"isNew ? '신규 등록' : '상세 정보'\">\n\n <!-- 2열 그리드: 코드, 이름 -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-2 mt-2\">\n <JFormField\n type=\"input\"\n label=\"코드\"\n v-model=\"detail.code\"\n :readonly=\"!isNew\"\n placeholder=\"고객사 코드\"\n />\n <JFormField\n type=\"input\"\n label=\"이름\"\n v-model=\"detail.name\"\n placeholder=\"고객사 이름\"\n />\n </div>\n\n <!-- 2열 그리드: 분류, 활성여부 -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-2 mt-2\">\n <JFormField\n type=\"combo\"\n label=\"분류\"\n v-model=\"detail.category\"\n :options=\"categoryOptions\"\n />\n <JFormField\n type=\"checkbox\"\n label=\"활성여부\"\n v-model=\"detail.isActive\"\n inlineLabel=\"활성\"\n />\n </div>\n <div class=\"grid grid-cols-1 gap-2 mt-2\">\n <!-- 전체 너비: 비고 -->\n <JFormField type=\"textarea\" label=\"비고\" v-model=\"detail.remark\" placeholder=\"비고\" />\n\n </div>\n\n \n <!-- 액션 버튼 -->\n <template #footer>\n <div class=\"flex justify-end gap-2\">\n <JButton styletype=\"primary\" size=\"sm\" @click=\"onSave\">저장</JButton>\n <JButton variant=\"outline\" size=\"sm\" @click=\"onDelete\" v-if=\"!isNew\">삭제</JButton>\n </div>\n </template>\n </JCard>\n </div>\n </template>\n </JSplitter>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { JTitlebar, JCard } from '@/components/molecules'\nimport { JFilterBar } from '@/components/organisms'\nimport { JGrid, JButton, JSplitter, type ActionButton } from '@/components/atoms'\nimport { JFormField } from '@/components/molecules'\n\n// ==================== 필터 상태 ====================\nconst filterCollapsed = ref(false)\n\n// 필터 값 (v-model:filterValues)\nconst filterValues = ref({\n isActive: '',\n keyword: '',\n})\n\n// 필터 표시 설정 (배지에 표시될 라벨 및 값 변환 함수)\nconst filterDisplay = {\n isActive: {\n label: '활성여부',\n displayValue: (val: unknown) => {\n if (val === 'Y') return 'Y:활성'\n if (val === 'N') return 'N:비활성'\n return ''\n },\n },\n keyword: {\n label: '검색어',\n },\n}\n\n// ==================== 옵션 데이터 ====================\nconst activeOptions = [\n { value: 'Y', label: 'Y:활성' },\n { value: 'N', label: 'N:비활성' },\n]\n\nconst categoryOptions = [\n { value: 'A', label: 'A등급' },\n { value: 'B', label: 'B등급' },\n { value: 'C', label: 'C등급' },\n]\n\n// ==================== 그리드 설정 ====================\nconst gridRef = ref()\n\n// Mock 데이터 - 실제 백엔드 응답 구조\nconst rowData = ref([\n { code: 'C001', name: '제이솔루션', category: 'A', isActive: 'Y', remark: '주력 고객사' },\n { code: 'C002', name: 'ABC물류', category: 'B', isActive: 'Y', remark: '' },\n { code: 'C003', name: 'XYZ유통', category: 'A', isActive: 'N', remark: '비활성' },\n { code: 'C004', name: '대한물류', category: 'B', isActive: 'Y', remark: '' },\n { code: 'C005', name: '글로벌이커머스', category: 'A', isActive: 'Y', remark: '신규 고객사' },\n])\n\nconst columnDefs = ref([\n { \n field: 'code', \n headerName: '코드', \n width: 120,\n enableValue: true, // 집계 가능 (count)\n },\n { \n field: 'name', \n headerName: '이름', \n width: 200,\n enableValue: true, // 집계 가능 (count)\n },\n { \n field: 'category', \n headerName: '분류', \n width: 100,\n enableRowGroup: true, // Row Group으로 사용 가능\n enablePivot: true, // Pivot Column으로 사용 가능\n },\n {\n field: 'isActive',\n headerName: '활성',\n width: 100,\n cellRenderer: (params: any) => (params.value === 'Y' ? '✓' : ''),\n enableRowGroup: true, // Row Group으로 사용 가능\n enablePivot: true, // Pivot Column으로 사용 가능\n },\n { \n field: 'remark', \n headerName: '비고', \n flex: 1,\n enableValue: true, // 집계 가능 (count)\n },\n])\n\n// 행별 액션 버튼\nconst actionButtons: ActionButton[] = [\n {\n icon: 'pencil',\n label: '수정',\n tooltip: '편집',\n onClick: (rowData: any) => {\n isNew.value = false\n detail.value = {\n code: rowData.code,\n name: rowData.name,\n category: rowData.category,\n isActive: rowData.isActive,\n remark: rowData.remark,\n }\n },\n },\n {\n icon: 'trash2',\n label: '삭제',\n tooltip: '삭제',\n styletype: 'danger',\n onClick: (rowData: any) => {\n if (confirm(`${rowData.name}을(를) 삭제하시겠습니까?`)) {\n console.log('삭제:', rowData.code)\n alert(`삭제되었습니다: ${rowData.name}`)\n }\n },\n },\n]\n\n// ==================== 상세 영역 상태 ====================\nconst isNew = ref(false)\nconst detail = ref({\n code: '',\n name: '',\n category: '',\n isActive: 'Y',\n remark: '',\n})\n\n// ==================== 이벤트 핸들러 ====================\n\n/**\n * 그리드 행 클릭 핸들러\n */\nfunction onRowClicked(event: any) {\n isNew.value = false\n const rowData = event.data\n\n // 선택된 행 데이터를 상세 영역에 바인딩\n detail.value = {\n code: rowData.code,\n name: rowData.name,\n category: rowData.category,\n isActive: rowData.isActive,\n remark: rowData.remark,\n }\n}\n\n/**\n * 신규 버튼 클릭\n */\nfunction onNew() {\n isNew.value = true\n // 상세 영역 초기화\n detail.value = {\n code: '',\n name: '',\n category: '',\n isActive: 'Y',\n remark: '',\n }\n}\n\n/**\n * 저장 버튼 클릭\n */\nfunction onSave() {\n console.log('저장:', detail.value)\n // TODO: 실제 구현 시 API 호출로 대체\n // if (isNew.value) {\n // await api.createCustomer(detail.value)\n // } else {\n // await api.updateCustomer(detail.value.code, detail.value)\n // }\n // 성공 시 그리드 데이터 갱신\n alert(`저장되었습니다: ${detail.value.name}`)\n}\n\n/**\n * 삭제 버튼 클릭\n */\nfunction onDelete() {\n if (confirm(`${detail.value.name}을(를) 삭제하시겠습니까?`)) {\n console.log('삭제:', detail.value.code)\n // TODO: 실제 구현 시 API 호출로 대체\n // await api.deleteCustomer(detail.value.code)\n // 성공 시 그리드에서 해당 행 제거\n alert(`삭제되었습니다: ${detail.value.name}`)\n }\n}\n\n/**\n * 초기화 버튼 클릭\n */\nfunction onReset() {\n filterValues.value = {\n isActive: '',\n keyword: '',\n }\n console.log('필터 초기화')\n}\n\n/**\n * 조회 버튼 클릭\n */\nfunction onSearch() {\n console.log('조회 조건:', filterValues.value)\n // TODO: 실제 구현 시 API 호출로 대체\n // const result = await api.searchCustomers(filterValues.value)\n // rowData.value = result.data\n}\n\n/**\n * 도움말 아이콘 클릭\n */\nfunction onHelp() {\n alert('고객사 관리 페이지 도움말')\n}\n\ndefineExpose({ gridRef })\n</script>\n"],"names":["filterCollapsed","ref","filterValues","filterDisplay","val","activeOptions","categoryOptions","gridRef","rowData","columnDefs","params","actionButtons","isNew","detail","onRowClicked","event","onNew","onSave","onDelete","onReset","onSearch","onHelp","__expose","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_unref","JTitlebar","JFilterBar","$event","JButton","_cache","_createElementVNode","_hoisted_2","JFormField","JSplitter","_hoisted_3","JGrid","_hoisted_4","JCard","_hoisted_8","_createBlock","_hoisted_5","_hoisted_6","_hoisted_7"],"mappings":"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"}
1
+ {"version":3,"file":"ExampleCrudPage.vue.cjs","sources":["../../../../src/components/examples/ExampleCrudPage.vue"],"sourcesContent":["<template>\n <JPageContainer title=\"고객사 관리\" icon=\"building\" description=\"고객사 정보를 조회하고 관리합니다\" :showHelp=\"true\" @help=\"onHelp\" :content-scroll=\"false\">\n\n <!-- ==================== 필터바 ==================== -->\n <JFilterBar\n v-model:collapsed=\"filterCollapsed\"\n v-model:filterValues=\"filterValues\"\n :filterDisplay=\"filterDisplay\"\n :collapsible=\"true\"\n title=\"고객사 목록\"\n >\n <!-- 액션 버튼 -->\n <template #actions>\n <JButton size=\"xs\" variant=\"outline\" @click=\"onReset\">초기화</JButton>\n <JButton size=\"xs\" styletype=\"primary\" @click=\"onSearch\">조회</JButton>\n <JButton size=\"xs\" styletype=\"primary\" @click=\"onNew\">신규</JButton>\n </template>\n\n <!-- 필터 필드 - 다중 열 배치 -->\n <template #filters>\n <div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2\">\n <JFormField\n type=\"combo\"\n label=\"활성여부\"\n v-model=\"filterValues.isActive\"\n :options=\"activeOptions\"\n orientation=\"horizontal\"\n labelWidth=\"30%\"\n />\n <JFormField type=\"input\" label=\"검색어\" v-model=\"filterValues.keyword\"\n orientation=\"horizontal\"\n labelWidth=\"30%\" />\n </div>\n </template>\n </JFilterBar>\n\n <!-- ==================== 그리드 + 상세 영역 (Resizable) ==================== -->\n <JSplitter\n direction=\"horizontal\"\n :default-size=\"60\"\n :min-size=\"30\"\n :second-min-size=\"20\"\n :second-max-size=\"60\"\n class=\"flex-1\"\n >\n <!-- 좌측: 그리드 -->\n <template #left>\n <div class=\"h-full overflow-auto bg-background\">\n <JGrid\n ref=\"gridRef\"\n :columnDefs=\"columnDefs\"\n :rowData=\"rowData\"\n :action-buttons=\"actionButtons\"\n :enableGrouping=\"true\"\n :enablePivot=\"true\"\n :enableColumnsToolPanel=\"true\"\n rowGroupPanelShow=\"always\"\n pivotPanelShow=\"always\"\n :groupDefaultExpanded=\"1\"\n :compactFooter=\"true\"\n @row-clicked=\"onRowClicked\"\n />\n </div>\n </template>\n\n <!-- 우측: 상세 영역 -->\n <template #right>\n <div class=\"h-full overflow-y-auto bg-muted/30\">\n <!-- 선택된 항목이 없을 때: EmptyState -->\n <JEmptyState\n v-if=\"!detail.code && !isNew\"\n variant=\"simple\"\n icon=\"mousePointerClick\"\n title=\"항목을 선택하거나 신규 버튼을 클릭하세요\"\n class=\"h-full\"\n />\n \n <!-- 선택된 항목이 있거나 신규일 때: 상세 폼 -->\n <JCard \n v-else\n class=\"h-full\" \n :title=\"isNew ? '신규 등록' : '상세 정보'\"\n variant=\"elevated\"\n >\n <!-- actions 슬롯 (header 우측 버튼) -->\n <template #actions>\n <JButton size=\"xs\" styletype=\"primary\" @click=\"onSave\">저장</JButton>\n <JButton size=\"xs\" variant=\"destructive\" v-if=\"!isNew\" @click=\"onDelete\">삭제</JButton>\n <JButton size=\"xs\" variant=\"outline\" @click=\"onReset\">취소</JButton>\n </template>\n\n <!-- 2열 그리드: 코드, 이름 -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-2\">\n <JFormField\n type=\"input\"\n label=\"코드\"\n v-model=\"detail.code\"\n :readonly=\"!isNew\"\n placeholder=\"고객사 코드\"\n />\n <JFormField\n type=\"input\"\n label=\"이름\"\n v-model=\"detail.name\"\n placeholder=\"고객사 이름\"\n />\n </div>\n\n <!-- 2열 그리드: 분류, 활성여부 -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-2 mt-2\">\n <JFormField\n type=\"combo\"\n label=\"분류\"\n v-model=\"detail.category\"\n :options=\"categoryOptions\"\n />\n <JFormField\n type=\"checkbox\"\n label=\"활성여부\"\n v-model=\"detail.isActive\"\n inlineLabel=\"활성\"\n />\n </div>\n <div class=\"grid grid-cols-1 gap-2 mt-2\">\n <!-- 전체 너비: 비고 -->\n <JFormField type=\"textarea\" label=\"비고\" v-model=\"detail.remark\" placeholder=\"비고\" />\n\n </div>\n\n </JCard>\n </div>\n </template>\n </JSplitter>\n </JPageContainer> \n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { JTitlebar, JCard, JEmptyState } from '@/components/molecules'\nimport { JFilterBar } from '@/components/organisms'\nimport { JGrid, JButton, JSplitter, type ActionButton } from '@/components/atoms'\nimport { JFormField } from '@/components/molecules'\nimport JPageContainer from '../organisms/JPageContainer.vue'\n\n// ==================== 필터 상태 ====================\nconst filterCollapsed = ref(false)\n\n// 필터 값 (v-model:filterValues)\nconst filterValues = ref({\n isActive: '',\n keyword: '',\n})\n\n// 필터 표시 설정 (배지에 표시될 라벨 및 값 변환 함수)\nconst filterDisplay = {\n isActive: {\n label: '활성여부',\n displayValue: (val: unknown) => {\n if (val === 'Y') return 'Y:활성'\n if (val === 'N') return 'N:비활성'\n return ''\n },\n },\n keyword: {\n label: '검색어',\n },\n}\n\n// ==================== 옵션 데이터 ====================\nconst activeOptions = [\n { value: 'Y', label: 'Y:활성' },\n { value: 'N', label: 'N:비활성' },\n]\n\nconst categoryOptions = [\n { value: 'A', label: 'A등급' },\n { value: 'B', label: 'B등급' },\n { value: 'C', label: 'C등급' },\n]\n\n// ==================== 그리드 설정 ====================\nconst gridRef = ref()\n\n// Mock 데이터 - 실제 백엔드 응답 구조\nconst rowData = ref([\n { code: 'C001', name: '제이솔루션', category: 'A', isActive: 'Y', remark: '주력 고객사' },\n { code: 'C002', name: 'ABC물류', category: 'B', isActive: 'Y', remark: '' },\n { code: 'C003', name: 'XYZ유통', category: 'A', isActive: 'N', remark: '비활성' },\n { code: 'C004', name: '대한물류', category: 'B', isActive: 'Y', remark: '' },\n { code: 'C005', name: '글로벌이커머스', category: 'A', isActive: 'Y', remark: '신규 고객사' },\n])\n\nconst columnDefs = ref([\n { \n field: 'code', \n headerName: '코드', \n width: 120,\n enableValue: true, // 집계 가능 (count)\n },\n { \n field: 'name', \n headerName: '이름', \n width: 200,\n enableValue: true, // 집계 가능 (count)\n },\n { \n field: 'category', \n headerName: '분류', \n width: 100,\n enableRowGroup: true, // Row Group으로 사용 가능\n enablePivot: true, // Pivot Column으로 사용 가능\n },\n {\n field: 'isActive',\n headerName: '활성',\n width: 100,\n cellRenderer: (params: any) => (params.value === 'Y' ? '✓' : ''),\n enableRowGroup: true, // Row Group으로 사용 가능\n enablePivot: true, // Pivot Column으로 사용 가능\n },\n { \n field: 'remark', \n headerName: '비고', \n flex: 1,\n enableValue: true, // 집계 가능 (count)\n },\n])\n\n// 행별 액션 버튼\nconst actionButtons: ActionButton[] = [\n {\n icon: 'pencil',\n label: '수정',\n tooltip: '편집',\n onClick: (rowData: any) => {\n isNew.value = false\n detail.value = {\n code: rowData.code,\n name: rowData.name,\n category: rowData.category,\n isActive: rowData.isActive,\n remark: rowData.remark,\n }\n },\n },\n {\n icon: 'trash2',\n label: '삭제',\n tooltip: '삭제',\n styletype: 'danger',\n onClick: (rowData: any) => {\n if (confirm(`${rowData.name}을(를) 삭제하시겠습니까?`)) {\n console.log('삭제:', rowData.code)\n alert(`삭제되었습니다: ${rowData.name}`)\n }\n },\n },\n]\n\n// ==================== 상세 영역 상태 ====================\nconst isNew = ref(false)\nconst detail = ref({\n code: '',\n name: '',\n category: '',\n isActive: 'Y',\n remark: '',\n})\n\n// ==================== 이벤트 핸들러 ====================\n\n/**\n * 그리드 행 클릭 핸들러\n */\nfunction onRowClicked(event: any) {\n isNew.value = false\n const rowData = event.data\n\n // 선택된 행 데이터를 상세 영역에 바인딩\n detail.value = {\n code: rowData.code,\n name: rowData.name,\n category: rowData.category,\n isActive: rowData.isActive,\n remark: rowData.remark,\n }\n}\n\n/**\n * 신규 버튼 클릭\n */\nfunction onNew() {\n isNew.value = true\n // 상세 영역 초기화\n detail.value = {\n code: '',\n name: '',\n category: '',\n isActive: 'Y',\n remark: '',\n }\n}\n\n/**\n * 저장 버튼 클릭\n */\nfunction onSave() {\n console.log('저장:', detail.value)\n // TODO: 실제 구현 시 API 호출로 대체\n // if (isNew.value) {\n // await api.createCustomer(detail.value)\n // } else {\n // await api.updateCustomer(detail.value.code, detail.value)\n // }\n // 성공 시 그리드 데이터 갱신\n alert(`저장되었습니다: ${detail.value.name}`)\n}\n\n/**\n * 삭제 버튼 클릭\n */\nfunction onDelete() {\n if (confirm(`${detail.value.name}을(를) 삭제하시겠습니까?`)) {\n console.log('삭제:', detail.value.code)\n // TODO: 실제 구현 시 API 호출로 대체\n // await api.deleteCustomer(detail.value.code)\n // 성공 시 그리드에서 해당 행 제거\n alert(`삭제되었습니다: ${detail.value.name}`)\n }\n}\n\n/**\n * 초기화 버튼 클릭\n */\nfunction onReset() {\n filterValues.value = {\n isActive: '',\n keyword: '',\n }\n console.log('필터 초기화')\n}\n\n/**\n * 조회 버튼 클릭\n */\nfunction onSearch() {\n console.log('조회 조건:', filterValues.value)\n // TODO: 실제 구현 시 API 호출로 대체\n // const result = await api.searchCustomers(filterValues.value)\n // rowData.value = result.data\n}\n\n/**\n * 도움말 아이콘 클릭\n */\nfunction onHelp() {\n alert('고객사 관리 페이지 도움말')\n}\n\ndefineExpose({ gridRef })\n</script>\n"],"names":["filterCollapsed","ref","filterValues","filterDisplay","val","activeOptions","categoryOptions","gridRef","rowData","columnDefs","params","actionButtons","isNew","detail","onRowClicked","event","onNew","onSave","onDelete","onReset","onSearch","onHelp","__expose","_createBlock","JPageContainer","_createVNode","_unref","JFilterBar","$event","JButton","_cache","_createElementVNode","_hoisted_1","JFormField","JSplitter","_hoisted_2","JGrid","_hoisted_3","JEmptyState","JCard","_hoisted_4","_hoisted_5","_hoisted_6"],"mappings":"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"}