@j-solution/components 1.8.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +415 -416
- package/assets/jwms-portal-frontend-Di6lStzZ.css +1 -0
- package/assets/styles/j-components.css +1 -1
- package/assets/styles/main.css +29 -29
- package/assets/styles/themes.css +422 -422
- package/components/atoms/JAvatar.vue.cjs.map +1 -1
- package/components/atoms/JAvatar.vue.js.map +1 -1
- package/components/atoms/JBadge.vue.cjs.map +1 -1
- package/components/atoms/JBadge.vue.js.map +1 -1
- package/components/atoms/JButton.vue.cjs +1 -1
- package/components/atoms/JButton.vue.js +1 -1
- package/components/atoms/JButton.vue2.cjs.map +1 -1
- package/components/atoms/JButton.vue2.js.map +1 -1
- package/components/atoms/JCombo.vue.cjs.map +1 -1
- package/components/atoms/JCombo.vue.js.map +1 -1
- package/components/atoms/JDatepicker.vue.cjs.map +1 -1
- package/components/atoms/JDatepicker.vue.js.map +1 -1
- package/components/atoms/JDivider.vue.cjs.map +1 -1
- package/components/atoms/JDivider.vue.js.map +1 -1
- package/components/atoms/JEditor.vue.cjs +1 -1
- package/components/atoms/JEditor.vue.js +2 -2
- package/components/atoms/JEditor.vue2.cjs.map +1 -1
- package/components/atoms/JEditor.vue2.js.map +1 -1
- package/components/atoms/JGrid.vue.cjs +1 -1
- package/components/atoms/JGrid.vue.js +2 -2
- package/components/atoms/JGrid.vue2.cjs +1 -1
- package/components/atoms/JGrid.vue2.cjs.map +1 -1
- package/components/atoms/JGrid.vue2.js +72 -85
- package/components/atoms/JGrid.vue2.js.map +1 -1
- package/components/atoms/JIcon.vue.cjs.map +1 -1
- package/components/atoms/JIcon.vue.js.map +1 -1
- package/components/atoms/JImage.vue.cjs.map +1 -1
- package/components/atoms/JImage.vue.js.map +1 -1
- package/components/atoms/JKbd.vue.cjs.map +1 -1
- package/components/atoms/JKbd.vue.js.map +1 -1
- package/components/atoms/JLabel.vue.cjs.map +1 -1
- package/components/atoms/JLabel.vue.js.map +1 -1
- package/components/atoms/JPreview.vue.cjs +1 -1
- package/components/atoms/JPreview.vue.js +7 -7
- package/components/atoms/JPreview.vue2.cjs.map +1 -1
- package/components/atoms/JPreview.vue2.js.map +1 -1
- package/components/atoms/JProgress.vue.cjs.map +1 -1
- package/components/atoms/JProgress.vue.js.map +1 -1
- package/components/atoms/JRadio.vue.cjs.map +1 -1
- package/components/atoms/JRadio.vue.js.map +1 -1
- package/components/atoms/JSearchCombo.vue.cjs.map +1 -1
- package/components/atoms/JSearchCombo.vue.js.map +1 -1
- package/components/atoms/JSectionTitle.vue2.cjs +1 -1
- package/components/atoms/JSectionTitle.vue2.cjs.map +1 -1
- package/components/atoms/JSectionTitle.vue2.js +5 -8
- package/components/atoms/JSectionTitle.vue2.js.map +1 -1
- package/components/atoms/JSpinner.vue.cjs.map +1 -1
- package/components/atoms/JSpinner.vue.js.map +1 -1
- package/components/atoms/JToast.vue.cjs.map +1 -1
- package/components/atoms/JToast.vue.js.map +1 -1
- package/components/atoms/JTooltip.vue.cjs.map +1 -1
- package/components/atoms/JTooltip.vue.js.map +1 -1
- package/components/molecules/JAlert.vue.cjs +1 -1
- package/components/molecules/JAlert.vue.cjs.map +1 -1
- package/components/molecules/JAlert.vue.js +2 -5
- package/components/molecules/JAlert.vue.js.map +1 -1
- package/components/molecules/JBreadcrumb.vue.cjs.map +1 -1
- package/components/molecules/JBreadcrumb.vue.js.map +1 -1
- package/components/molecules/JEmptyState.vue2.cjs +1 -1
- package/components/molecules/JEmptyState.vue2.cjs.map +1 -1
- package/components/molecules/JEmptyState.vue2.js +15 -18
- package/components/molecules/JEmptyState.vue2.js.map +1 -1
- package/components/molecules/JFormField.vue2.cjs +1 -1
- package/components/molecules/JFormField.vue2.cjs.map +1 -1
- package/components/molecules/JFormField.vue2.js +2 -5
- package/components/molecules/JFormField.vue2.js.map +1 -1
- package/components/molecules/JTabs.vue.cjs +1 -1
- package/components/molecules/JTabs.vue.js +1 -1
- package/components/molecules/JTabs.vue2.cjs.map +1 -1
- package/components/molecules/JTabs.vue2.js.map +1 -1
- package/components/molecules/JTitlebar.vue.cjs +1 -1
- package/components/molecules/JTitlebar.vue.cjs.map +1 -1
- package/components/molecules/JTitlebar.vue.js +16 -19
- package/components/molecules/JTitlebar.vue.js.map +1 -1
- package/components/organisms/JDynamicForm.vue2.cjs +1 -1
- package/components/organisms/JDynamicForm.vue2.cjs.map +1 -1
- package/components/organisms/JDynamicForm.vue2.js +2 -5
- package/components/organisms/JDynamicForm.vue2.js.map +1 -1
- package/components/organisms/JDynamicTabs.vue.cjs.map +1 -1
- package/components/organisms/JDynamicTabs.vue.js.map +1 -1
- package/components/organisms/JFilterBar.vue.cjs +1 -1
- package/components/organisms/JFilterBar.vue.js +2 -2
- package/components/organisms/JFilterBar.vue2.cjs +1 -1
- package/components/organisms/JFilterBar.vue2.cjs.map +1 -1
- package/components/organisms/JFilterBar.vue2.js +14 -12
- package/components/organisms/JFilterBar.vue2.js.map +1 -1
- package/components/organisms/JFormModal.vue.cjs +1 -1
- package/components/organisms/JFormModal.vue.cjs.map +1 -1
- package/components/organisms/JFormModal.vue.js +14 -17
- package/components/organisms/JFormModal.vue.js.map +1 -1
- package/components/organisms/JModal.vue.cjs +1 -1
- package/components/organisms/JModal.vue.cjs.map +1 -1
- package/components/organisms/JModal.vue.js +2 -5
- package/components/organisms/JModal.vue.js.map +1 -1
- package/components/organisms/JPageContainer.vue.cjs.map +1 -1
- package/components/organisms/JPageContainer.vue.js.map +1 -1
- package/components/organisms/JSearchPanel.vue2.cjs +1 -1
- package/components/organisms/JSearchPanel.vue2.cjs.map +1 -1
- package/components/organisms/JSearchPanel.vue2.js +20 -23
- package/components/organisms/JSearchPanel.vue2.js.map +1 -1
- package/components/organisms/JSidebar/JSidebar.vue.cjs +2 -0
- package/components/organisms/JSidebar/JSidebar.vue.cjs.map +1 -0
- package/components/organisms/JSidebar/JSidebar.vue.js +189 -0
- package/components/organisms/JSidebar/JSidebar.vue.js.map +1 -0
- package/components/organisms/JSidebar/JSidebar.vue2.cjs +2 -0
- package/components/organisms/JSidebar/JSidebar.vue2.cjs.map +1 -0
- package/components/organisms/JSidebar/JSidebar.vue2.js +5 -0
- package/components/organisms/JSidebar/JSidebar.vue2.js.map +1 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue.cjs +2 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue.cjs.map +1 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue.js +89 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue.js.map +1 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue2.cjs +2 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue2.cjs.map +1 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue2.js +5 -0
- package/components/organisms/JSidebar/JSidebarGroup.vue2.js.map +1 -0
- package/components/organisms/JSidebar/JSidebarItem.vue.cjs +2 -0
- package/components/organisms/JSidebar/JSidebarItem.vue.cjs.map +1 -0
- package/components/organisms/JSidebar/JSidebarItem.vue.js +79 -0
- package/components/organisms/JSidebar/JSidebarItem.vue.js.map +1 -0
- package/components/organisms/JSidebar/JSidebarItem.vue2.cjs +2 -0
- package/components/organisms/JSidebar/JSidebarItem.vue2.cjs.map +1 -0
- package/components/organisms/JSidebar/JSidebarItem.vue2.js +5 -0
- package/components/organisms/JSidebar/JSidebarItem.vue2.js.map +1 -0
- package/components/organisms/JSidebarAdvanced.vue.cjs +1 -1
- package/components/organisms/JSidebarAdvanced.vue.js +7 -7
- package/components/organisms/JSidebarAdvanced.vue2.cjs.map +1 -1
- package/components/organisms/JSidebarAdvanced.vue2.js.map +1 -1
- package/components/organisms/JSidebarSimple.vue.cjs +1 -1
- package/components/organisms/JSidebarSimple.vue.js +2 -2
- package/components/organisms/JSidebarSimple.vue2.cjs.map +1 -1
- package/components/organisms/JSidebarSimple.vue2.js.map +1 -1
- package/components/shadcn/AccordionTrigger.vue.cjs.map +1 -1
- package/components/shadcn/AccordionTrigger.vue.js.map +1 -1
- package/components/shadcn/Card.vue.cjs.map +1 -1
- package/components/shadcn/Card.vue.js.map +1 -1
- package/components/shadcn/CardContent.vue.cjs.map +1 -1
- package/components/shadcn/CardContent.vue.js.map +1 -1
- package/components/shadcn/CardDescription.vue.cjs.map +1 -1
- package/components/shadcn/CardDescription.vue.js.map +1 -1
- package/components/shadcn/CardFooter.vue.cjs.map +1 -1
- package/components/shadcn/CardFooter.vue.js.map +1 -1
- package/components/shadcn/CardHeader.vue.cjs.map +1 -1
- package/components/shadcn/CardHeader.vue.js.map +1 -1
- package/components/shadcn/CardTitle.vue.cjs.map +1 -1
- package/components/shadcn/CardTitle.vue.js.map +1 -1
- package/components/shadcn/Checkbox.vue.cjs.map +1 -1
- package/components/shadcn/Checkbox.vue.js.map +1 -1
- package/components/shadcn/Combobox.vue.cjs.map +1 -1
- package/components/shadcn/Combobox.vue.js.map +1 -1
- package/components/shadcn/ComboboxAnchor.vue.cjs.map +1 -1
- package/components/shadcn/ComboboxAnchor.vue.js.map +1 -1
- package/components/shadcn/ComboboxEmpty.vue.cjs.map +1 -1
- package/components/shadcn/ComboboxEmpty.vue.js.map +1 -1
- package/components/shadcn/ComboboxGroup.vue.cjs.map +1 -1
- package/components/shadcn/ComboboxGroup.vue.js.map +1 -1
- package/components/shadcn/ComboboxInput.vue.cjs.map +1 -1
- package/components/shadcn/ComboboxInput.vue.js.map +1 -1
- package/components/shadcn/ComboboxItem.vue.cjs.map +1 -1
- package/components/shadcn/ComboboxItem.vue.js.map +1 -1
- package/components/shadcn/ComboboxList.vue.cjs.map +1 -1
- package/components/shadcn/ComboboxList.vue.js.map +1 -1
- package/components/shadcn/ComboboxTrigger.vue.cjs.map +1 -1
- package/components/shadcn/ComboboxTrigger.vue.js.map +1 -1
- package/components/shadcn/ContextMenu.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenu.vue.js.map +1 -1
- package/components/shadcn/ContextMenuContent.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuContent.vue.js.map +1 -1
- package/components/shadcn/ContextMenuGroup.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuGroup.vue.js.map +1 -1
- package/components/shadcn/ContextMenuItem.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuItem.vue.js.map +1 -1
- package/components/shadcn/ContextMenuLabel.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuLabel.vue.js.map +1 -1
- package/components/shadcn/ContextMenuSeparator.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuSeparator.vue.js.map +1 -1
- package/components/shadcn/ContextMenuSub.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuSub.vue.js.map +1 -1
- package/components/shadcn/ContextMenuSubContent.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuSubContent.vue.js.map +1 -1
- package/components/shadcn/ContextMenuSubTrigger.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuSubTrigger.vue.js.map +1 -1
- package/components/shadcn/ContextMenuTrigger.vue.cjs.map +1 -1
- package/components/shadcn/ContextMenuTrigger.vue.js.map +1 -1
- package/components/shadcn/Field.vue.cjs.map +1 -1
- package/components/shadcn/Field.vue.js.map +1 -1
- package/components/shadcn/FieldContent.vue.cjs.map +1 -1
- package/components/shadcn/FieldContent.vue.js.map +1 -1
- package/components/shadcn/FieldDescription.vue.cjs.map +1 -1
- package/components/shadcn/FieldDescription.vue.js.map +1 -1
- package/components/shadcn/FieldError.vue.cjs.map +1 -1
- package/components/shadcn/FieldError.vue.js.map +1 -1
- package/components/shadcn/FieldGroup.vue.cjs.map +1 -1
- package/components/shadcn/FieldGroup.vue.js.map +1 -1
- package/components/shadcn/FieldLabel.vue.cjs.map +1 -1
- package/components/shadcn/FieldLabel.vue.js.map +1 -1
- package/components/shadcn/Input.vue.cjs.map +1 -1
- package/components/shadcn/Input.vue.js.map +1 -1
- package/components/shadcn/Label.vue.cjs.map +1 -1
- package/components/shadcn/Label.vue.js.map +1 -1
- package/components/shadcn/RadioGroup.vue.cjs.map +1 -1
- package/components/shadcn/RadioGroup.vue.js.map +1 -1
- package/components/shadcn/RadioGroupItem.vue.cjs.map +1 -1
- package/components/shadcn/RadioGroupItem.vue.js.map +1 -1
- package/components/shadcn/Select.vue.cjs.map +1 -1
- package/components/shadcn/Select.vue.js.map +1 -1
- package/components/shadcn/SelectContent.vue.cjs.map +1 -1
- package/components/shadcn/SelectContent.vue.js.map +1 -1
- package/components/shadcn/SelectGroup.vue.cjs.map +1 -1
- package/components/shadcn/SelectGroup.vue.js.map +1 -1
- package/components/shadcn/SelectItem.vue.cjs.map +1 -1
- package/components/shadcn/SelectItem.vue.js.map +1 -1
- package/components/shadcn/SelectLabel.vue.cjs.map +1 -1
- package/components/shadcn/SelectLabel.vue.js.map +1 -1
- package/components/shadcn/SelectScrollDownButton.vue2.cjs.map +1 -1
- package/components/shadcn/SelectScrollDownButton.vue2.js.map +1 -1
- package/components/shadcn/SelectScrollUpButton.vue2.cjs.map +1 -1
- package/components/shadcn/SelectScrollUpButton.vue2.js.map +1 -1
- package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
- package/components/shadcn/SelectTrigger.vue.js.map +1 -1
- package/components/shadcn/SelectValue.vue.cjs.map +1 -1
- package/components/shadcn/SelectValue.vue.js.map +1 -1
- package/components/shadcn/Separator.vue.cjs.map +1 -1
- package/components/shadcn/Separator.vue.js.map +1 -1
- package/components/shadcn/Switch.vue.cjs.map +1 -1
- package/components/shadcn/Switch.vue.js.map +1 -1
- package/components/shadcn/Tabs.vue.cjs.map +1 -1
- package/components/shadcn/Tabs.vue.js.map +1 -1
- package/components/shadcn/TabsContent.vue.cjs.map +1 -1
- package/components/shadcn/TabsContent.vue.js.map +1 -1
- package/components/shadcn/TabsTrigger.vue.cjs.map +1 -1
- package/components/shadcn/TabsTrigger.vue.js.map +1 -1
- package/components/shadcn/Textarea.vue.cjs.map +1 -1
- package/components/shadcn/Textarea.vue.js.map +1 -1
- package/components/shadcn/Toaster.vue.cjs.map +1 -1
- package/components/shadcn/Toaster.vue.js.map +1 -1
- package/components/shadcn/index.cjs.map +1 -1
- package/components/shadcn/index.js.map +1 -1
- package/components/shadcn/resizable/ResizableHandle.vue.cjs.map +1 -1
- package/components/shadcn/resizable/ResizableHandle.vue.js.map +1 -1
- package/components/shadcn/resizable/ResizablePanelGroup.vue.cjs.map +1 -1
- package/components/shadcn/resizable/ResizablePanelGroup.vue.js.map +1 -1
- package/components/templates/JLayout.vue.cjs.map +1 -1
- package/components/templates/JLayout.vue.js.map +1 -1
- package/components/templates/JLayoutSimple.vue.cjs +1 -1
- package/components/templates/JLayoutSimple.vue.cjs.map +1 -1
- package/components/templates/JLayoutSimple.vue.js +36 -30
- package/components/templates/JLayoutSimple.vue.js.map +1 -1
- package/index.cjs +1 -1
- package/index.js +22 -20
- package/lib/styleTypePreset.cjs.map +1 -1
- package/lib/styleTypePreset.js.map +1 -1
- package/lib/theme-utils.cjs.map +1 -1
- package/lib/theme-utils.js.map +1 -1
- package/package.json +1 -1
- package/tailwind.config.js +81 -81
- package/types/index.d.ts +119 -107
- package/types/sidebar.types.cjs +2 -0
- package/types/sidebar.types.cjs.map +1 -0
- package/types/sidebar.types.js +5 -0
- package/types/sidebar.types.js.map +1 -0
- package/assets/jwms-portal-frontend-BtHTA-UF.css +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent as D, computed as
|
|
1
|
+
import { defineComponent as D, computed as v, createElementBlock as u, openBlock as o, normalizeClass as x, unref as p, createElementVNode as n, withDirectives as T, createCommentVNode as i, createBlock as f, createVNode as b, Fragment as $, renderList as z, withCtx as m, toDisplayString as d, withModifiers as E, renderSlot as V, createTextVNode as B, vShow as F } from "vue";
|
|
2
2
|
import { ChevronDown as N, X as R } from "lucide-vue-next";
|
|
3
3
|
import J from "../atoms/JBadge.vue.js";
|
|
4
4
|
import k from "../atoms/JButton.vue.js";
|
|
@@ -7,7 +7,7 @@ import { cn as L } from "../../lib/utils.js";
|
|
|
7
7
|
const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { class: "flex items-center gap-2" }, q = {
|
|
8
8
|
key: 2,
|
|
9
9
|
class: "flex items-center gap-1 flex-wrap"
|
|
10
|
-
}, G = { class: "text-muted-foreground" }, H = ["onClick"], I = { class: "flex items-center gap-2" }, K = { class: "px-3 pb-3" },
|
|
10
|
+
}, G = { class: "text-muted-foreground" }, H = ["onClick"], I = { class: "flex items-center gap-2" }, K = { class: "px-3 pb-3" }, P = { class: "filter-fields-grid" }, te = /* @__PURE__ */ D({
|
|
11
11
|
__name: "JFilterBar",
|
|
12
12
|
props: {
|
|
13
13
|
class: {},
|
|
@@ -23,15 +23,15 @@ const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { clas
|
|
|
23
23
|
},
|
|
24
24
|
emits: ["update:collapsed", "update:filterValues", "search", "reset"],
|
|
25
25
|
setup(r, { emit: w }) {
|
|
26
|
-
const l = r, a = w, y =
|
|
27
|
-
function
|
|
26
|
+
const l = r, a = w, y = v(() => l.collapsible ? !l.collapsed : !0);
|
|
27
|
+
function _(e) {
|
|
28
28
|
return !!(e == null || typeof e == "string" && e.trim() === "" || Array.isArray(e) && e.length === 0);
|
|
29
29
|
}
|
|
30
|
-
const h =
|
|
30
|
+
const h = v(() => {
|
|
31
31
|
const e = [];
|
|
32
32
|
for (const [t, s] of Object.entries(l.filterDisplay)) {
|
|
33
33
|
const c = l.filterValues[t];
|
|
34
|
-
if (
|
|
34
|
+
if (_(c)) continue;
|
|
35
35
|
const g = s.displayValue ? s.displayValue(c) : String(c);
|
|
36
36
|
g.trim() !== "" && e.push({
|
|
37
37
|
key: t,
|
|
@@ -41,7 +41,7 @@ const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { clas
|
|
|
41
41
|
}
|
|
42
42
|
return e;
|
|
43
43
|
});
|
|
44
|
-
function
|
|
44
|
+
function C() {
|
|
45
45
|
a("update:collapsed", !l.collapsed);
|
|
46
46
|
}
|
|
47
47
|
function S() {
|
|
@@ -60,7 +60,7 @@ const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { clas
|
|
|
60
60
|
typeof s == "string" ? t[e] = "" : Array.isArray(s) ? t[e] = [] : t[e] = null, a("update:filterValues", t);
|
|
61
61
|
}
|
|
62
62
|
return (e, t) => (o(), u("div", {
|
|
63
|
-
class:
|
|
63
|
+
class: x(p(L)("j-filter-bar w-full rounded-sm border bg-card text-card-foreground", l.class))
|
|
64
64
|
}, [
|
|
65
65
|
n("div", M, [
|
|
66
66
|
n("div", X, [
|
|
@@ -68,10 +68,10 @@ const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { clas
|
|
|
68
68
|
key: 0,
|
|
69
69
|
type: "button",
|
|
70
70
|
class: "flex items-center justify-center h-6 w-6 rounded hover:bg-accent hover:text-accent-foreground transition-colors",
|
|
71
|
-
onClick:
|
|
71
|
+
onClick: C
|
|
72
72
|
}, [
|
|
73
73
|
b(p(N), {
|
|
74
|
-
class:
|
|
74
|
+
class: x([
|
|
75
75
|
"h-3.5 w-3.5 transition-transform",
|
|
76
76
|
y.value ? "rotate-0" : "-rotate-90"
|
|
77
77
|
])
|
|
@@ -131,7 +131,9 @@ const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { clas
|
|
|
131
131
|
])
|
|
132
132
|
]),
|
|
133
133
|
T(n("div", K, [
|
|
134
|
-
|
|
134
|
+
n("div", P, [
|
|
135
|
+
V(e.$slots, "filters", {}, void 0, !0)
|
|
136
|
+
])
|
|
135
137
|
], 512), [
|
|
136
138
|
[F, y.value]
|
|
137
139
|
])
|
|
@@ -139,6 +141,6 @@ const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { clas
|
|
|
139
141
|
}
|
|
140
142
|
});
|
|
141
143
|
export {
|
|
142
|
-
|
|
144
|
+
te as default
|
|
143
145
|
};
|
|
144
146
|
//# sourceMappingURL=JFilterBar.vue2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JFilterBar.vue2.js","sources":["../../../../src/components/organisms/JFilterBar.vue"],"sourcesContent":["<template>\r\n <div :class=\"cn('j-filter-bar w-full rounded-sm border bg-card text-card-foreground', props.class)\">\r\n <!-- Row 1: toolbar -->\r\n <div class=\"flex items-center justify-between px-3 py-1.5\">\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n v-if=\"collapsible\"\r\n type=\"button\"\r\n class=\"flex items-center justify-center h-6 w-6 rounded hover:bg-accent hover:text-accent-foreground transition-colors\"\r\n @click=\"toggleCollapsed\"\r\n >\r\n <ChevronDown\r\n :class=\"[\r\n 'h-3.5 w-3.5 transition-transform',\r\n isExpanded ? 'rotate-0' : '-rotate-90',\r\n ]\"\r\n />\r\n </button>\r\n <!-- 타이틀 -->\r\n <JLabel\r\n v-if=\"title\"\r\n :text=\"title\"\r\n class=\"text-sm font-semibold text-foreground\"\r\n />\r\n <!-- 선택된 필터 뱃지 표시 -->\r\n <div v-if=\"activeFilters.length > 0\" class=\"flex items-center gap-1 flex-wrap\">\r\n <JBadge\r\n v-for=\"filter in activeFilters\"\r\n :key=\"filter.key\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n class=\"flex items-center gap-1 cursor-default\"\r\n >\r\n <span class=\"text-muted-foreground\">{{ filter.label }}:</span>\r\n <span>{{ filter.value }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"ml-0.5 rounded-full hover:bg-gray-300 p-0.5 transition-colors\"\r\n @click.stop=\"removeFilter(filter.key)\"\r\n >\r\n <X class=\"h-3 w-3\" />\r\n </button>\r\n </JBadge>\r\n </div>\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <slot name=\"actions\" />\r\n <JButton\r\n v-if=\"showResetButton\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n @click=\"handleReset\"\r\n >\r\n {{ resetButtonText }}\r\n </JButton>\r\n <JButton\r\n v-if=\"showSearchButton\"\r\n styletype=\"primary\"\r\n size=\"sm\"\r\n @click=\"handleSearch\"\r\n >\r\n {{ searchButtonText }}\r\n </JButton>\r\n </div>\r\n </div>\r\n\r\n <!-- Row 2: filters -->\r\n <div v-show=\"isExpanded\" class=\"px-3 pb-3\">\r\n <slot name=\"filters\" />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { ChevronDown, X } from 'lucide-vue-next'\r\nimport JBadge from '@/components/atoms/JBadge.vue'\r\nimport JButton from '@/components/atoms/JButton.vue'\r\nimport JLabel from '@/components/atoms/JLabel.vue'\r\nimport { cn } from '@/lib/utils'\r\n\r\n/** 활성 필터 아이템 타입 */\r\nexport interface ActiveFilterItem {\r\n /** 필터 식별 키 */\r\n key: string\r\n /** 표시할 라벨 (필터명) */\r\n label: string\r\n /** 표시할 값 */\r\n value: string\r\n}\r\n\r\n/** 필터 설정 타입 */\r\nexport interface FilterDisplayItem {\r\n /** 표시할 라벨 */\r\n label: string\r\n /** 값을 표시용 문자열로 변환 (예: combo value -> label) */\r\n displayValue?: (value: unknown) => string\r\n}\r\n\r\nexport interface JFilterBarProps {\r\n /** 추가 클래스 (외부 커스터마이징용) */\r\n class?: string\r\n /** 필터바 타이틀 */\r\n title?: string\r\n /** 필터 접힘 상태 (v-model 지원) */\r\n collapsed?: boolean\r\n /** 접기/펼치기 가능 여부. false면 토글 버튼 숨김 & 필터 항상 표시 */\r\n collapsible?: boolean\r\n /** 필터 값 객체 (v-model:filterValues 지원) */\r\n filterValues?: Record<string, unknown>\r\n /** 필터 표시 설정 (label, displayValue 등) */\r\n filterDisplay?: Record<string, FilterDisplayItem>\r\n /** 초기화 버튼 표시 여부 */\r\n showResetButton?: boolean\r\n /** 조회 버튼 표시 여부 */\r\n showSearchButton?: boolean\r\n /** 초기화 버튼 텍스트 */\r\n resetButtonText?: string\r\n /** 조회 버튼 텍스트 */\r\n searchButtonText?: string\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFilterBarProps>(), {\r\n collapsed: true,\r\n collapsible: true,\r\n filterValues: () => ({}),\r\n filterDisplay: () => ({}),\r\n showResetButton: false,\r\n showSearchButton: false,\r\n resetButtonText: '초기화',\r\n searchButtonText: '조회',\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:collapsed': [value: boolean]\r\n 'update:filterValues': [value: Record<string, unknown>]\r\n /** 조회 버튼 클릭 */\r\n search: []\r\n /** 초기화 버튼 클릭 */\r\n reset: []\r\n}>()\r\n\r\nconst isExpanded = computed(() => {\r\n if (!props.collapsible) return true\r\n return !props.collapsed\r\n})\r\n\r\n/** 값이 비어있는지 확인 */\r\nfunction isEmpty(value: unknown): boolean {\r\n if (value === null || value === undefined) return true\r\n if (typeof value === 'string' && value.trim() === '') return true\r\n if (Array.isArray(value) && value.length === 0) return true\r\n return false\r\n}\r\n\r\n/** filterValues + filterDisplay 기반으로 활성 필터 목록 자동 생성 */\r\nconst activeFilters = computed<ActiveFilterItem[]>(() => {\r\n const filters: ActiveFilterItem[] = []\r\n\r\n for (const [key, config] of Object.entries(props.filterDisplay)) {\r\n const value = props.filterValues[key]\r\n if (isEmpty(value)) continue\r\n\r\n const displayValue = config.displayValue ? config.displayValue(value) : String(value)\r\n if (displayValue.trim() === '') continue\r\n\r\n filters.push({\r\n key,\r\n label: config.label,\r\n value: displayValue,\r\n })\r\n }\r\n\r\n return filters\r\n})\r\n\r\nfunction toggleCollapsed() {\r\n emit('update:collapsed', !props.collapsed)\r\n}\r\n\r\nfunction handleReset() {\r\n // filterValues의 모든 값을 초기화\r\n const resetValues: Record<string, unknown> = {}\r\n for (const key of Object.keys(props.filterValues)) {\r\n const currentValue = props.filterValues[key]\r\n if (typeof currentValue === 'string') {\r\n resetValues[key] = ''\r\n } else if (Array.isArray(currentValue)) {\r\n resetValues[key] = []\r\n } else {\r\n resetValues[key] = null\r\n }\r\n }\r\n emit('update:filterValues', resetValues)\r\n emit('reset')\r\n}\r\n\r\nfunction handleSearch() {\r\n emit('search')\r\n}\r\n\r\nfunction removeFilter(key: string) {\r\n // filterValues 업데이트 (해당 키 값을 초기화)\r\n const newValues = { ...props.filterValues }\r\n const currentValue = newValues[key]\r\n\r\n // 타입에 따라 적절한 초기값으로 설정\r\n if (typeof currentValue === 'string') {\r\n newValues[key] = ''\r\n } else if (Array.isArray(currentValue)) {\r\n newValues[key] = []\r\n } else {\r\n newValues[key] = null\r\n }\r\n\r\n emit('update:filterValues', newValues)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n/* ========================================\r\n 패턴 3: Tabs 아래 배치 시 연결 스타일\r\n ======================================== */\r\n\r\n:deep([data-state=\"active\"]) > .j-filter-bar {\r\n border-top: none;\r\n border-top-left-radius: 0;\r\n border-top-right-radius: 0;\r\n}\r\n\r\n:deep([role=\"tabpanel\"]) .j-filter-bar {\r\n border-top: none;\r\n}\r\n</style>\r\n"],"names":["props","__props","emit","__emit","isExpanded","computed","isEmpty","value","activeFilters","filters","key","config","displayValue","toggleCollapsed","handleReset","resetValues","currentValue","handleSearch","removeFilter","newValues","_createElementBlock","_normalizeClass","_unref","cn","_createElementVNode","_hoisted_1","_hoisted_2","_createVNode","ChevronDown","_createBlock","JLabel","_openBlock","_hoisted_3","_Fragment","_renderList","filter","JBadge","_hoisted_4","_toDisplayString","_withModifiers","$event","X","_hoisted_6","_renderSlot","_ctx","JButton","_withDirectives","_hoisted_7"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JFilterBar.vue2.js","sources":["../../../../src/components/organisms/JFilterBar.vue"],"sourcesContent":["<template>\n <div :class=\"cn('j-filter-bar w-full rounded-sm border bg-card text-card-foreground', props.class)\">\n <!-- Row 1: toolbar -->\n <div class=\"flex items-center justify-between px-3 py-1.5\">\n <div class=\"flex items-center gap-2\">\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"flex items-center justify-center h-6 w-6 rounded hover:bg-accent hover:text-accent-foreground transition-colors\"\n @click=\"toggleCollapsed\"\n >\n <ChevronDown\n :class=\"[\n 'h-3.5 w-3.5 transition-transform',\n isExpanded ? 'rotate-0' : '-rotate-90',\n ]\"\n />\n </button>\n <!-- 타이틀 -->\n <JLabel\n v-if=\"title\"\n :text=\"title\"\n class=\"text-sm font-semibold text-foreground\"\n />\n <!-- 선택된 필터 뱃지 표시 -->\n <div v-if=\"activeFilters.length > 0\" class=\"flex items-center gap-1 flex-wrap\">\n <JBadge\n v-for=\"filter in activeFilters\"\n :key=\"filter.key\"\n variant=\"secondary\"\n size=\"sm\"\n class=\"flex items-center gap-1 cursor-default\"\n >\n <span class=\"text-muted-foreground\">{{ filter.label }}:</span>\n <span>{{ filter.value }}</span>\n <button\n type=\"button\"\n class=\"ml-0.5 rounded-full hover:bg-gray-300 p-0.5 transition-colors\"\n @click.stop=\"removeFilter(filter.key)\"\n >\n <X class=\"h-3 w-3\" />\n </button>\n </JBadge>\n </div>\n </div>\n <div class=\"flex items-center gap-2\">\n <slot name=\"actions\" />\n <JButton\n v-if=\"showResetButton\"\n variant=\"secondary\"\n size=\"sm\"\n @click=\"handleReset\"\n >\n {{ resetButtonText }}\n </JButton>\n <JButton\n v-if=\"showSearchButton\"\n styletype=\"primary\"\n size=\"sm\"\n @click=\"handleSearch\"\n >\n {{ searchButtonText }}\n </JButton>\n </div>\n </div>\n\n <!-- Row 2: filters (반응형 그리드: max 4열, 자동 축소) -->\n <div v-show=\"isExpanded\" class=\"px-3 pb-3\">\n <div class=\"filter-fields-grid\">\n <slot name=\"filters\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { ChevronDown, X } from 'lucide-vue-next'\nimport JBadge from '@/components/atoms/JBadge.vue'\nimport JButton from '@/components/atoms/JButton.vue'\nimport JLabel from '@/components/atoms/JLabel.vue'\nimport { cn } from '@/lib/utils'\n\n/** 활성 필터 아이템 타입 */\nexport interface ActiveFilterItem {\n /** 필터 식별 키 */\n key: string\n /** 표시할 라벨 (필터명) */\n label: string\n /** 표시할 값 */\n value: string\n}\n\n/** 필터 설정 타입 */\nexport interface FilterDisplayItem {\n /** 표시할 라벨 */\n label: string\n /** 값을 표시용 문자열로 변환 (예: combo value -> label) */\n displayValue?: (value: unknown) => string\n}\n\nexport interface JFilterBarProps {\n /** 추가 클래스 (외부 커스터마이징용) */\n class?: string\n /** 필터바 타이틀 */\n title?: string\n /** 필터 접힘 상태 (v-model 지원) */\n collapsed?: boolean\n /** 접기/펼치기 가능 여부. false면 토글 버튼 숨김 & 필터 항상 표시 */\n collapsible?: boolean\n /** 필터 값 객체 (v-model:filterValues 지원) */\n filterValues?: Record<string, unknown>\n /** 필터 표시 설정 (label, displayValue 등) */\n filterDisplay?: Record<string, FilterDisplayItem>\n /** 초기화 버튼 표시 여부 */\n showResetButton?: boolean\n /** 조회 버튼 표시 여부 */\n showSearchButton?: boolean\n /** 초기화 버튼 텍스트 */\n resetButtonText?: string\n /** 조회 버튼 텍스트 */\n searchButtonText?: string\n}\n\nconst props = withDefaults(defineProps<JFilterBarProps>(), {\n collapsed: true,\n collapsible: true,\n filterValues: () => ({}),\n filterDisplay: () => ({}),\n showResetButton: false,\n showSearchButton: false,\n resetButtonText: '초기화',\n searchButtonText: '조회',\n})\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean]\n 'update:filterValues': [value: Record<string, unknown>]\n /** 조회 버튼 클릭 */\n search: []\n /** 초기화 버튼 클릭 */\n reset: []\n}>()\n\nconst isExpanded = computed(() => {\n if (!props.collapsible) return true\n return !props.collapsed\n})\n\n/** 값이 비어있는지 확인 */\nfunction isEmpty(value: unknown): boolean {\n if (value === null || value === undefined) return true\n if (typeof value === 'string' && value.trim() === '') return true\n if (Array.isArray(value) && value.length === 0) return true\n return false\n}\n\n/** filterValues + filterDisplay 기반으로 활성 필터 목록 자동 생성 */\nconst activeFilters = computed<ActiveFilterItem[]>(() => {\n const filters: ActiveFilterItem[] = []\n\n for (const [key, config] of Object.entries(props.filterDisplay)) {\n const value = props.filterValues[key]\n if (isEmpty(value)) continue\n\n const displayValue = config.displayValue ? config.displayValue(value) : String(value)\n if (displayValue.trim() === '') continue\n\n filters.push({\n key,\n label: config.label,\n value: displayValue,\n })\n }\n\n return filters\n})\n\nfunction toggleCollapsed() {\n emit('update:collapsed', !props.collapsed)\n}\n\nfunction handleReset() {\n // filterValues의 모든 값을 초기화\n const resetValues: Record<string, unknown> = {}\n for (const key of Object.keys(props.filterValues)) {\n const currentValue = props.filterValues[key]\n if (typeof currentValue === 'string') {\n resetValues[key] = ''\n } else if (Array.isArray(currentValue)) {\n resetValues[key] = []\n } else {\n resetValues[key] = null\n }\n }\n emit('update:filterValues', resetValues)\n emit('reset')\n}\n\nfunction handleSearch() {\n emit('search')\n}\n\nfunction removeFilter(key: string) {\n // filterValues 업데이트 (해당 키 값을 초기화)\n const newValues = { ...props.filterValues }\n const currentValue = newValues[key]\n\n // 타입에 따라 적절한 초기값으로 설정\n if (typeof currentValue === 'string') {\n newValues[key] = ''\n } else if (Array.isArray(currentValue)) {\n newValues[key] = []\n } else {\n newValues[key] = null\n }\n\n emit('update:filterValues', newValues)\n}\n</script>\n\n<style scoped>\n/* 필터 필드 반응형 그리드: max 4열, 자동 축소 (4 → 3 → 2 → 1) */\n.filter-fields-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(max(25% - 1.5rem, 260px), 1fr));\n gap: 0.5rem 2rem;\n --label-w: auto; /* 필터 컨텍스트: 라벨 너비를 텍스트 길이에 맞게 자동 조절 */\n}\n\n/* ========================================\n 패턴 3: Tabs 아래 배치 시 연결 스타일\n ======================================== */\n\n:deep([data-state=\"active\"]) > .j-filter-bar {\n border-top: none;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n:deep([role=\"tabpanel\"]) .j-filter-bar {\n border-top: none;\n}\n</style>\n"],"names":["props","__props","emit","__emit","isExpanded","computed","isEmpty","value","activeFilters","filters","key","config","displayValue","toggleCollapsed","handleReset","resetValues","currentValue","handleSearch","removeFilter","newValues","_createElementBlock","_normalizeClass","_unref","cn","_createElementVNode","_hoisted_1","_hoisted_2","_createVNode","ChevronDown","_createBlock","JLabel","_openBlock","_hoisted_3","_Fragment","_renderList","filter","JBadge","_hoisted_4","_toDisplayString","_withModifiers","$event","X","_hoisted_6","_renderSlot","_ctx","JButton","_withDirectives","_hoisted_7","_hoisted_8"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const o=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const o=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */const g=require("./JDynamicForm.vue.cjs");;/* empty css */;/* empty css */require("vue-router");;/* empty css */;/* empty css */;/* empty css */const h=require("../shadcn/Dialog.vue.cjs"),y=require("../shadcn/DialogContent.vue.cjs"),C=require("../shadcn/DialogHeader.vue.cjs"),V=require("../shadcn/DialogTitle.vue.cjs"),b=require("../shadcn/DialogBody.vue.cjs"),k=require("../shadcn/DialogFooter.vue.cjs"),w={class:"space-y-4"},D={key:0,class:"text-sm text-muted-foreground"},N=e.defineComponent({__name:"JFormModal",props:{open:{type:Boolean,default:!1},title:{},description:{},schema:{},modelValue:{},size:{default:"lg"},buttonType:{default:"OkCancel"},confirmText:{default:"확인"},cancelText:{default:"취소"},confirmVariant:{default:"default"},confirmDisabled:{type:Boolean,default:!1}},emits:["update:open","update:modelValue","confirm","cancel","submit","change","error"],setup(r,{expose:d,emit:s}){const i=r,u=s,a=e.ref(null),l=e.ref(i.modelValue||{}),n=e.ref(!1),m=e.computed(()=>({sm:"!max-w-sm",md:"!max-w-md",lg:"!max-w-2xl",xl:"!max-w-4xl","2xl":"!max-w-6xl",full:"!max-w-[95vw]"})[i.size]);e.watch(()=>i.modelValue,t=>{t!=null?l.value={...t}:l.value={}},{deep:!0});const f=t=>{l.value=t,u("update:modelValue",t)},q=t=>{u("change",t)},v=t=>{u("submit",t),n.value&&(u("confirm",t),n.value=!1)},p=t=>{u("error",t),n.value=!1},x=t=>{u("update:open",t)},c=()=>{n.value=!0,a.value&&a.value.submit()},_=()=>{u("cancel"),a.value&&a.value.reset()};return d({reset:()=>a.value?.reset(),submit:()=>a.value?.submit(),formState:e.computed(()=>a.value?.formState)}),(t,B)=>(e.openBlock(),e.createBlock(e.unref(h.default),{open:r.open,"onUpdate:open":x,class:e.normalizeClass(m.value)},{default:e.withCtx(()=>[e.createVNode(e.unref(y.default),null,{default:e.withCtx(()=>[r.title?(e.openBlock(),e.createBlock(e.unref(C.default),{key:0,class:"bg-muted/50 border-b"},{default:e.withCtx(()=>[e.createVNode(e.unref(V.default),null,{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.title),1)]),_:1})]),_:1})):e.createCommentVNode("",!0),e.createVNode(e.unref(b.default),{class:"max-h-[70vh] overflow-y-auto"},{default:e.withCtx(()=>[e.createElementVNode("div",w,[r.description?(e.openBlock(),e.createElementBlock("p",D,e.toDisplayString(r.description),1)):e.createCommentVNode("",!0),e.createVNode(e.unref(g.default),{ref_key:"dynamicFormRef",ref:a,schema:r.schema,"model-value":l.value,"onUpdate:modelValue":f,onSubmit:v,onChange:q,onError:p},null,8,["schema","model-value"]),e.renderSlot(t.$slots,"body")])]),_:3}),e.createVNode(e.unref(k.default),null,{default:e.withCtx(()=>[r.buttonType==="OkCancel"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(e.unref(o.default),{variant:"outline",onClick:_},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.cancelText),1)]),_:1}),e.createVNode(e.unref(o.default),{variant:r.confirmVariant,disabled:r.confirmDisabled,onClick:c},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.confirmText),1)]),_:1},8,["variant","disabled"])],64)):r.buttonType==="Ok"?(e.openBlock(),e.createBlock(e.unref(o.default),{key:1,variant:r.confirmVariant,disabled:r.confirmDisabled,onClick:c,class:"w-full"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.confirmText),1)]),_:1},8,["variant","disabled"])):e.createCommentVNode("",!0),e.renderSlot(t.$slots,"footer")]),_:3})]),_:3})]),_:3},8,["open","class"]))}});exports.default=N;
|
|
2
2
|
//# sourceMappingURL=JFormModal.vue.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JFormModal.vue.cjs","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"
|
|
1
|
+
{"version":3,"file":"JFormModal.vue.cjs","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
|
|
@@ -18,9 +18,6 @@ import "dompurify";
|
|
|
18
18
|
import "ag-grid-vue3";
|
|
19
19
|
import "ag-grid-community";
|
|
20
20
|
import "ag-grid-enterprise";
|
|
21
|
-
/* empty css */
|
|
22
|
-
/* empty css */
|
|
23
|
-
/* empty css */
|
|
24
21
|
/* empty css */
|
|
25
22
|
/* empty css */
|
|
26
23
|
/* empty css */
|
|
@@ -46,7 +43,7 @@ import A from "../shadcn/DialogFooter.vue.js";
|
|
|
46
43
|
const G = { class: "space-y-4" }, H = {
|
|
47
44
|
key: 0,
|
|
48
45
|
class: "text-sm text-muted-foreground"
|
|
49
|
-
},
|
|
46
|
+
}, Ne = /* @__PURE__ */ S({
|
|
50
47
|
__name: "JFormModal",
|
|
51
48
|
props: {
|
|
52
49
|
open: { type: Boolean, default: !1 },
|
|
@@ -63,7 +60,7 @@ const G = { class: "space-y-4" }, H = {
|
|
|
63
60
|
},
|
|
64
61
|
emits: ["update:open", "update:modelValue", "confirm", "cancel", "submit", "change", "error"],
|
|
65
62
|
setup(t, { expose: k, emit: g }) {
|
|
66
|
-
const d = t,
|
|
63
|
+
const d = t, m = g, l = f(null), c = f(d.modelValue || {}), u = f(!1), V = b(() => ({
|
|
67
64
|
sm: "!max-w-sm",
|
|
68
65
|
md: "!max-w-md",
|
|
69
66
|
lg: "!max-w-2xl",
|
|
@@ -75,24 +72,24 @@ const G = { class: "space-y-4" }, H = {
|
|
|
75
72
|
e != null ? c.value = { ...e } : c.value = {};
|
|
76
73
|
}, { deep: !0 });
|
|
77
74
|
const w = (e) => {
|
|
78
|
-
c.value = e,
|
|
75
|
+
c.value = e, m("update:modelValue", e);
|
|
79
76
|
}, F = (e) => {
|
|
80
|
-
|
|
77
|
+
m("change", e);
|
|
81
78
|
}, T = (e) => {
|
|
82
|
-
|
|
79
|
+
m("submit", e), u.value && (m("confirm", e), u.value = !1);
|
|
83
80
|
}, $ = (e) => {
|
|
84
|
-
|
|
81
|
+
m("error", e), u.value = !1;
|
|
85
82
|
}, z = (e) => {
|
|
86
|
-
|
|
83
|
+
m("update:open", e);
|
|
87
84
|
}, x = () => {
|
|
88
|
-
u.value = !0,
|
|
85
|
+
u.value = !0, l.value && l.value.submit();
|
|
89
86
|
}, B = () => {
|
|
90
|
-
|
|
87
|
+
m("cancel"), l.value && l.value.reset();
|
|
91
88
|
};
|
|
92
89
|
return k({
|
|
93
|
-
reset: () =>
|
|
94
|
-
submit: () =>
|
|
95
|
-
formState: b(() =>
|
|
90
|
+
reset: () => l.value?.reset(),
|
|
91
|
+
submit: () => l.value?.submit(),
|
|
92
|
+
formState: b(() => l.value?.formState)
|
|
96
93
|
}), (e, I) => (r(), p(o(M), {
|
|
97
94
|
open: t.open,
|
|
98
95
|
"onUpdate:open": z,
|
|
@@ -121,7 +118,7 @@ const G = { class: "space-y-4" }, H = {
|
|
|
121
118
|
t.description ? (r(), y("p", H, n(t.description), 1)) : v("", !0),
|
|
122
119
|
i(o(J), {
|
|
123
120
|
ref_key: "dynamicFormRef",
|
|
124
|
-
ref:
|
|
121
|
+
ref: l,
|
|
125
122
|
schema: t.schema,
|
|
126
123
|
"model-value": c.value,
|
|
127
124
|
"onUpdate:modelValue": w,
|
|
@@ -181,6 +178,6 @@ const G = { class: "space-y-4" }, H = {
|
|
|
181
178
|
}
|
|
182
179
|
});
|
|
183
180
|
export {
|
|
184
|
-
|
|
181
|
+
Ne as default
|
|
185
182
|
};
|
|
186
183
|
//# sourceMappingURL=JFormModal.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JFormModal.vue.js","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"
|
|
1
|
+
{"version":3,"file":"JFormModal.vue.js","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const u=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const u=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const q=require("../molecules/JFormField.vue.cjs");;/* empty css */;/* empty css */;/* empty css */;/* empty css */const y=require("../shadcn/Dialog.vue.cjs"),v=require("../shadcn/DialogContent.vue.cjs"),x=require("../shadcn/DialogHeader.vue.cjs"),g=require("../shadcn/DialogTitle.vue.cjs"),F=require("../shadcn/DialogBody.vue.cjs"),V=require("../shadcn/DialogFooter.vue.cjs"),b={class:"space-y-4"},C={key:0,class:"text-sm text-muted-foreground"},h={key:1},k=e.defineComponent({__name:"JModal",props:{open:{type:Boolean,default:!1},title:{},description:{},size:{default:"md"},showFormField:{type:Boolean,default:!1},formFieldLabel:{},formFieldError:{},formFieldRequired:{type:Boolean},formFieldInputType:{default:"text"},formFieldInputPlaceholder:{},formFieldValue:{},formFieldType:{default:"input"},buttonType:{default:"OkCancel"},confirmText:{default:"확인"},cancelText:{default:"취소"},confirmVariant:{default:"default"},confirmDisabled:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1}},emits:["update:open","confirm","cancel"],setup(t,{emit:d}){const l=t,i=d,a=e.ref(l.formFieldValue||""),c=e.computed(()=>`modal-input-${Math.random().toString(36).substr(2,9)}`),s=e.computed(()=>({sm:"!max-w-sm",md:"!max-w-md",lg:"!max-w-2xl",xl:"!max-w-4xl","2xl":"!max-w-6xl",full:"!max-w-[95vw]"})[l.size]);e.watch(()=>l.formFieldValue,r=>{r!==void 0&&(a.value=r)});const f=r=>{i("update:open",r)},o=()=>{const r=l.showFormField?a.value:void 0;i("confirm",r)},m=()=>{i("cancel"),a.value=l.formFieldValue||""};return(r,n)=>(e.openBlock(),e.createBlock(e.unref(y.default),{open:t.open,"onUpdate:open":f,class:e.normalizeClass(s.value)},{default:e.withCtx(()=>[e.createVNode(e.unref(v.default),null,{default:e.withCtx(()=>[t.title?(e.openBlock(),e.createBlock(e.unref(x.default),{key:0,class:"bg-muted/50 border-b"},{default:e.withCtx(()=>[e.createVNode(e.unref(g.default),null,{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.title),1)]),_:1})]),_:1})):e.createCommentVNode("",!0),e.createVNode(e.unref(F.default),null,{default:e.withCtx(()=>[e.createElementVNode("div",b,[t.description?(e.openBlock(),e.createElementBlock("p",C,e.toDisplayString(t.description),1)):e.createCommentVNode("",!0),t.showFormField?(e.openBlock(),e.createElementBlock("div",h,[e.createVNode(e.unref(q.default),{label:t.formFieldLabel,"error-msg":t.formFieldError,required:t.formFieldRequired,type:t.formFieldType,id:c.value,modelValue:a.value,"onUpdate:modelValue":n[0]||(n[0]=p=>a.value=p),"input-type":t.formFieldInputType,placeholder:t.formFieldInputPlaceholder,disabled:t.disabled},null,8,["label","error-msg","required","type","id","modelValue","input-type","placeholder","disabled"])])):e.createCommentVNode("",!0),e.renderSlot(r.$slots,"body")])]),_:3}),e.createVNode(e.unref(V.default),null,{default:e.withCtx(()=>[t.buttonType==="OkCancel"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(e.unref(u.default),{variant:"outline",size:"sm",onClick:m},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.cancelText),1)]),_:1}),e.createVNode(e.unref(u.default),{variant:t.confirmVariant,disabled:t.confirmDisabled,size:"sm",onClick:o},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.confirmText),1)]),_:1},8,["variant","disabled"])],64)):t.buttonType==="Ok"?(e.openBlock(),e.createBlock(e.unref(u.default),{key:1,variant:t.confirmVariant,disabled:t.confirmDisabled,size:"sm",onClick:o,class:"w-full"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.confirmText),1)]),_:1},8,["variant","disabled"])):e.createCommentVNode("",!0)]),_:1})]),_:3})]),_:3},8,["open","class"]))}});exports.default=k;
|
|
2
2
|
//# sourceMappingURL=JModal.vue.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JModal.vue.cjs","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\
|
|
1
|
+
{"version":3,"file":"JModal.vue.cjs","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\n <Dialog\n :open=\"open\"\n @update:open=\"onOpenChange\"\n :class=\"sizeClass\"\n >\n <DialogContent>\n <!-- Header -->\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\n <DialogTitle>\n {{ title }}\n </DialogTitle>\n </DialogHeader>\n\n <!-- Body -->\n <DialogBody>\n <div class=\"space-y-4\">\n <!-- Description -->\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\n {{ description }}\n </p>\n\n <!-- JFormField가 있는 경우 -->\n <div v-if=\"showFormField\">\n <JFormField\n :label=\"formFieldLabel\"\n :error-msg=\"formFieldError\"\n :required=\"formFieldRequired\"\n :type=\"formFieldType\"\n :id=\"inputId\"\n v-model=\"inputValue\"\n :input-type=\"formFieldInputType\"\n :placeholder=\"formFieldInputPlaceholder\"\n :disabled=\"disabled\"\n />\n </div>\n\n <!-- 커스텀 컨텐츠 슬롯 -->\n <slot name=\"body\" />\n </div>\n </DialogBody>\n\n <!-- Footer -->\n <DialogFooter>\n <!-- 확인/취소 버튼 -->\n <template v-if=\"buttonType === 'OkCancel'\">\n <JButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"handleCancel\"\n >\n {{ cancelText }}\n </JButton>\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n \n <!-- 확인 버튼만 -->\n <template v-else-if=\"buttonType === 'Ok'\">\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n class=\"w-full\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport {\n Dialog,\n DialogBody,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/shadcn'\nimport { JButton } from '@/components/atoms'\nimport { JFormField } from '@/components/molecules'\n\nexport interface JModalProps {\n // 모달 표시 여부\n open: boolean\n // 헤더\n title?: string\n description?: string\n // 모달 사이즈\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\n // 폼 필드 (JFormField)\n showFormField?: boolean\n formFieldLabel?: string\n formFieldError?: string\n formFieldRequired?: boolean\n // 입력 필드 설정\n formFieldInputType?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'\n formFieldInputPlaceholder?: string\n formFieldValue?: string\n formFieldType?: 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\n // 버튼 설정\n buttonType?: 'Ok' | 'OkCancel'\n confirmText?: string\n cancelText?: string\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\n confirmDisabled?: boolean\n // 기타\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<JModalProps>(), {\n open: false,\n size: 'md',\n showFormField: false,\n formFieldInputType: 'text',\n formFieldType: 'input',\n buttonType: 'OkCancel',\n confirmText: '확인',\n cancelText: '취소',\n confirmVariant: 'default',\n confirmDisabled: false,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean]\n 'confirm': [value?: string]\n 'cancel': []\n}>()\n\n// 입력값 관리\nconst inputValue = ref(props.formFieldValue || '')\n\n// 입력 필드 ID 생성\nconst inputId = computed(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`)\n\n// 사이즈 클래스 계산\nconst sizeClass = computed(() => {\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\n const sizeMap: Record<NonNullable<JModalProps['size']>, string> = {\n 'sm': '!max-w-sm',\n 'md': '!max-w-md',\n 'lg': '!max-w-2xl',\n 'xl': '!max-w-4xl',\n '2xl': '!max-w-6xl',\n 'full': '!max-w-[95vw]'\n }\n return sizeMap[props.size]\n})\n\n// props.formFieldValue 변경 감지\nwatch(() => props.formFieldValue, (newValue) => {\n if (newValue !== undefined) {\n inputValue.value = newValue\n }\n})\n\n// 모달 열기/닫기 핸들러\nconst onOpenChange = (value: boolean) => {\n emit('update:open', value)\n}\n\n// 확인 버튼 핸들러\nconst handleConfirm = () => {\n const value = props.showFormField ? inputValue.value : undefined\n emit('confirm', value)\n}\n\n// 취소 버튼 핸들러\nconst handleCancel = () => {\n emit('cancel')\n // 입력값 초기화\n inputValue.value = props.formFieldValue || ''\n}\n</script>\n"],"names":["props","__props","emit","__emit","inputValue","ref","inputId","computed","sizeClass","watch","newValue","onOpenChange","value","handleConfirm","handleCancel","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","_hoisted_3","JFormField","$event","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"+jEAyHA,MAAMA,EAAQC,EAcRC,EAAOC,EAOPC,EAAaC,EAAAA,IAAIL,EAAM,gBAAkB,EAAE,EAG3CM,EAAUC,EAAAA,SAAS,IAAM,eAAe,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,OAAO,EAAG,CAAC,CAAC,EAAE,EAGjFC,EAAYD,EAAAA,SAAS,KAEyC,CAChE,GAAM,YACN,GAAM,YACN,GAAM,aACN,GAAM,aACN,MAAO,aACP,KAAQ,eAAA,GAEKP,EAAM,IAAI,CAC1B,EAGDS,EAAAA,MAAM,IAAMT,EAAM,eAAiBU,GAAa,CAC1CA,IAAa,SACfN,EAAW,MAAQM,EAEvB,CAAC,EAGD,MAAMC,EAAgBC,GAAmB,CACvCV,EAAK,cAAeU,CAAK,CAC3B,EAGMC,EAAgB,IAAM,CAC1B,MAAMD,EAAQZ,EAAM,cAAgBI,EAAW,MAAQ,OACvDF,EAAK,UAAWU,CAAK,CACvB,EAGME,EAAe,IAAM,CACzBZ,EAAK,QAAQ,EAEbE,EAAW,MAAQJ,EAAM,gBAAkB,EAC7C,8BAvLEe,EAAAA,YA4ESC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CA3EN,KAAMhB,EAAA,KACN,gBAAaU,EACb,uBAAOH,EAAA,KAAS,CAAA,qBAEjB,IAsEgB,CAtEhBU,EAAAA,YAsEgBF,EAAAA,MAAAG,SAAA,EAAA,KAAA,mBApEd,IAIe,CAJKlB,EAAA,qBAApBc,EAAAA,YAIeC,EAAAA,MAAAI,EAAAA,OAAA,EAAA,OAJY,MAAM,sBAAA,qBAC/B,IAEc,CAFdF,EAAAA,YAEcF,EAAAA,MAAAK,SAAA,EAAA,KAAA,mBADZ,IAAW,qCAARpB,EAAA,KAAK,EAAA,CAAA,CAAA,8CAKZiB,EAAAA,YAyBaF,EAAAA,MAAAM,SAAA,EAAA,KAAA,mBAxBX,IAuBM,CAvBNC,EAAAA,mBAuBM,MAvBNC,EAuBM,CArBKvB,EAAA,2BAATwB,EAAAA,mBAEI,IAFJC,EAEIC,EAAAA,gBADC1B,EAAA,WAAW,EAAA,CAAA,+BAILA,EAAA,6BAAXwB,EAAAA,mBAYM,MAAAG,EAAA,CAXJV,cAUEF,EAAAA,MAAAa,EAAAA,OAAA,EAAA,CATC,MAAO5B,EAAA,eACP,YAAWA,EAAA,eACX,SAAUA,EAAA,kBACV,KAAMA,EAAA,cACN,GAAIK,EAAA,iBACIF,EAAA,2CAAAA,EAAU,MAAA0B,GAClB,aAAY7B,EAAA,mBACZ,YAAaA,EAAA,0BACb,SAAUA,EAAA,QAAA,yIAKf8B,aAAoBC,EAAA,OAAA,MAAA,CAAA,WAKxBd,EAAAA,YAgCeF,EAAAA,MAAAiB,SAAA,EAAA,KAAA,mBA9Bb,IAgBW,CAhBKhC,EAAA,aAAU,0BAA1BwB,EAAAA,mBAgBWS,WAAA,CAAA,IAAA,GAAA,CAfThB,cAMUF,EAAAA,MAAAmB,EAAAA,OAAA,EAAA,CALR,QAAQ,UACR,KAAK,KACJ,QAAOrB,CAAA,qBAER,IAAgB,qCAAbb,EAAA,UAAU,EAAA,CAAA,CAAA,SAEfiB,cAOUF,EAAAA,MAAAmB,EAAAA,OAAA,EAAA,CANP,QAASlC,EAAA,eACT,SAAUA,EAAA,gBACX,KAAK,KACJ,QAAOY,CAAA,qBAER,IAAiB,qCAAdZ,EAAA,WAAW,EAAA,CAAA,CAAA,wCAKGA,EAAA,aAAU,oBAC7Bc,EAAAA,YAQUC,QAAAmB,EAAAA,OAAA,EAAA,OAPP,QAASlC,EAAA,eACT,SAAUA,EAAA,gBACX,KAAK,KACJ,QAAOY,EACR,MAAM,QAAA,qBAEN,IAAiB,qCAAdZ,EAAA,WAAW,EAAA,CAAA,CAAA"}
|
|
@@ -18,9 +18,6 @@ import "dompurify";
|
|
|
18
18
|
import "ag-grid-vue3";
|
|
19
19
|
import "ag-grid-community";
|
|
20
20
|
import "ag-grid-enterprise";
|
|
21
|
-
/* empty css */
|
|
22
|
-
/* empty css */
|
|
23
|
-
/* empty css */
|
|
24
21
|
/* empty css */
|
|
25
22
|
/* empty css */
|
|
26
23
|
/* empty css */
|
|
@@ -39,7 +36,7 @@ import J from "../shadcn/DialogFooter.vue.js";
|
|
|
39
36
|
const S = { class: "space-y-4" }, L = {
|
|
40
37
|
key: 0,
|
|
41
38
|
class: "text-sm text-muted-foreground"
|
|
42
|
-
}, P = { key: 1 },
|
|
39
|
+
}, P = { key: 1 }, Ve = /* @__PURE__ */ T({
|
|
43
40
|
__name: "JModal",
|
|
44
41
|
props: {
|
|
45
42
|
open: { type: Boolean, default: !1 },
|
|
@@ -176,6 +173,6 @@ const S = { class: "space-y-4" }, L = {
|
|
|
176
173
|
}
|
|
177
174
|
});
|
|
178
175
|
export {
|
|
179
|
-
|
|
176
|
+
Ve as default
|
|
180
177
|
};
|
|
181
178
|
//# sourceMappingURL=JModal.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JModal.vue.js","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\
|
|
1
|
+
{"version":3,"file":"JModal.vue.js","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\n <Dialog\n :open=\"open\"\n @update:open=\"onOpenChange\"\n :class=\"sizeClass\"\n >\n <DialogContent>\n <!-- Header -->\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\n <DialogTitle>\n {{ title }}\n </DialogTitle>\n </DialogHeader>\n\n <!-- Body -->\n <DialogBody>\n <div class=\"space-y-4\">\n <!-- Description -->\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\n {{ description }}\n </p>\n\n <!-- JFormField가 있는 경우 -->\n <div v-if=\"showFormField\">\n <JFormField\n :label=\"formFieldLabel\"\n :error-msg=\"formFieldError\"\n :required=\"formFieldRequired\"\n :type=\"formFieldType\"\n :id=\"inputId\"\n v-model=\"inputValue\"\n :input-type=\"formFieldInputType\"\n :placeholder=\"formFieldInputPlaceholder\"\n :disabled=\"disabled\"\n />\n </div>\n\n <!-- 커스텀 컨텐츠 슬롯 -->\n <slot name=\"body\" />\n </div>\n </DialogBody>\n\n <!-- Footer -->\n <DialogFooter>\n <!-- 확인/취소 버튼 -->\n <template v-if=\"buttonType === 'OkCancel'\">\n <JButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"handleCancel\"\n >\n {{ cancelText }}\n </JButton>\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n \n <!-- 확인 버튼만 -->\n <template v-else-if=\"buttonType === 'Ok'\">\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n class=\"w-full\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport {\n Dialog,\n DialogBody,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/shadcn'\nimport { JButton } from '@/components/atoms'\nimport { JFormField } from '@/components/molecules'\n\nexport interface JModalProps {\n // 모달 표시 여부\n open: boolean\n // 헤더\n title?: string\n description?: string\n // 모달 사이즈\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\n // 폼 필드 (JFormField)\n showFormField?: boolean\n formFieldLabel?: string\n formFieldError?: string\n formFieldRequired?: boolean\n // 입력 필드 설정\n formFieldInputType?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'\n formFieldInputPlaceholder?: string\n formFieldValue?: string\n formFieldType?: 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\n // 버튼 설정\n buttonType?: 'Ok' | 'OkCancel'\n confirmText?: string\n cancelText?: string\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\n confirmDisabled?: boolean\n // 기타\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<JModalProps>(), {\n open: false,\n size: 'md',\n showFormField: false,\n formFieldInputType: 'text',\n formFieldType: 'input',\n buttonType: 'OkCancel',\n confirmText: '확인',\n cancelText: '취소',\n confirmVariant: 'default',\n confirmDisabled: false,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean]\n 'confirm': [value?: string]\n 'cancel': []\n}>()\n\n// 입력값 관리\nconst inputValue = ref(props.formFieldValue || '')\n\n// 입력 필드 ID 생성\nconst inputId = computed(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`)\n\n// 사이즈 클래스 계산\nconst sizeClass = computed(() => {\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\n const sizeMap: Record<NonNullable<JModalProps['size']>, string> = {\n 'sm': '!max-w-sm',\n 'md': '!max-w-md',\n 'lg': '!max-w-2xl',\n 'xl': '!max-w-4xl',\n '2xl': '!max-w-6xl',\n 'full': '!max-w-[95vw]'\n }\n return sizeMap[props.size]\n})\n\n// props.formFieldValue 변경 감지\nwatch(() => props.formFieldValue, (newValue) => {\n if (newValue !== undefined) {\n inputValue.value = newValue\n }\n})\n\n// 모달 열기/닫기 핸들러\nconst onOpenChange = (value: boolean) => {\n emit('update:open', value)\n}\n\n// 확인 버튼 핸들러\nconst handleConfirm = () => {\n const value = props.showFormField ? inputValue.value : undefined\n emit('confirm', value)\n}\n\n// 취소 버튼 핸들러\nconst handleCancel = () => {\n emit('cancel')\n // 입력값 초기화\n inputValue.value = props.formFieldValue || ''\n}\n</script>\n"],"names":["props","__props","emit","__emit","inputValue","ref","inputId","computed","sizeClass","watch","newValue","onOpenChange","value","handleConfirm","handleCancel","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","_hoisted_3","JFormField","$event","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JPageContainer.vue.cjs","sources":["../../../../src/components/organisms/JPageContainer.vue"],"sourcesContent":["<script setup lang=\"ts\">\
|
|
1
|
+
{"version":3,"file":"JPageContainer.vue.cjs","sources":["../../../../src/components/organisms/JPageContainer.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport JBreadcrumb from '@/components/molecules/JBreadcrumb.vue'\nimport JTitlebar from '@/components/molecules/JTitlebar.vue'\nimport { cn } from '@/lib/utils'\nimport type { BreadcrumbItem } from '@/components/molecules/JBreadcrumb.vue'\nimport type { TitlebarButton } from '@/components/molecules/JTitlebar.vue'\n\n/**\n * JPageContainer - 기본 페이지 컨테이너 컴포넌트 (organisms)\n * Page Container Component\n * \n * @description\n * 페이지의 기본 레이아웃을 담당하는 컨테이너 컴포넌트입니다.\n * 브레드크럼, 제목 영역(JTitlebar), 콘텐츠 영역을 포함합니다.\n * \n * @example\n * ```vue\n * <JPageContainer\n * :breadcrumb-items=\"breadcrumbItems\"\n * title=\"페이지 제목\"\n * :titlebar-buttons=\"buttons\"\n * >\n * <div>페이지 콘텐츠</div>\n * </JPageContainer>\n * ```\n */\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'minimal' // 최소 스타일\n\nconst props = withDefaults(\n defineProps<{\n /** 브레드크럼 아이템 목록 */\n breadcrumbItems?: BreadcrumbItem[]\n /** 브레드크럼 표시 여부 */\n showBreadcrumb?: boolean\n /** JTitlebar의 모든 props 전달 */\n title?: string\n icon?: string\n description?: string\n titlebarButtons?: TitlebarButton[]\n titlebarStyletype?: 'default' | 'primary' | 'accent' | 'neutral' | 'elevated'\n /** JTitlebar 표시 여부 */\n showTitlebar?: boolean\n /** 스타일 타입 */\n styletype?: StyleType\n /** 콘텐츠 영역 스크롤 가능 여부 */\n contentScroll?: boolean\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n breadcrumbItems: () => [],\n showBreadcrumb: true,\n showTitlebar: true,\n styletype: 'default',\n contentScroll: true,\n }\n)\n\nconst emit = defineEmits<{\n /** 브레드크럼 아이템 클릭 이벤트 */\n breadcrumbClick: [item: BreadcrumbItem, index: number]\n /** 타이틀바 버튼 클릭 이벤트 */\n titlebarButtonClick: [button: TitlebarButton]\n}>()\n\n/**\n * 스타일 프리셋\n */\nconst STYLE_PRESETS: Record<StyleType, {\n containerClass: string\n contentClass: string\n}> = {\n default: {\n containerClass: 'flex flex-col h-full w-full bg-background',\n contentClass: 'flex-1 p-3 pt-2 pb-2 gap-2 bg-background text-foreground',\n },\n minimal: {\n containerClass: 'flex flex-col h-full w-full bg-background',\n contentClass: 'flex-1 p-1 gap-1 bg-background text-foreground',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\n/**\n * 콘텐츠 클래스 (스크롤 포함)\n */\nconst contentClasses = computed(() => {\n return cn(\n preset.value.contentClass,\n props.contentScroll ? 'overflow-auto' : 'overflow-hidden'\n )\n})\n\n/**\n * 브레드크럼 아이템 클릭 핸들러\n */\nconst handleBreadcrumbClick = (item: BreadcrumbItem, index: number) => {\n emit('breadcrumbClick', item, index)\n}\n\n/**\n * 타이틀바 버튼 클릭 핸들러\n */\nconst handleTitlebarButtonClick = (button: TitlebarButton) => {\n emit('titlebarButtonClick', button)\n}\n</script>\n\n<template>\n <div :class=\"cn(preset.containerClass, props.class)\">\n <!-- 브레드크럼 -->\n <JBreadcrumb\n v-if=\"showBreadcrumb && breadcrumbItems && breadcrumbItems.length > 0\"\n :items=\"breadcrumbItems\"\n @item-click=\"handleBreadcrumbClick\"\n />\n\n <!-- 제목 영역 (JTitlebar) -->\n <JTitlebar\n v-if=\"showTitlebar\"\n :title=\"title\"\n :icon=\"icon\"\n :description=\"description\"\n :buttons=\"titlebarButtons\"\n :styletype=\"titlebarStyletype\"\n @button-click=\"handleTitlebarButtonClick\"\n >\n <template #buttons>\n <slot name=\"titlebar-buttons\" />\n </template>\n </JTitlebar>\n\n <!-- 콘텐츠 영역 -->\n <div :class=\"contentClasses\">\n <slot />\n </div>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","contentClasses","cn","handleBreadcrumbClick","item","index","handleTitlebarButtonClick","button","_createElementBlock","_normalizeClass","_unref","_createBlock","JBreadcrumb","JTitlebar","_renderSlot","_ctx","_createElementVNode"],"mappings":"6nBAgCA,MAAMA,EAAQC,EA8BRC,EAAOC,EAUPC,EAGD,CACH,QAAS,CACP,eAAgB,4CAChB,aAAc,0DAAA,EAEhB,QAAS,CACP,eAAgB,4CAChB,aAAc,gDAAA,CAChB,EAGIC,EAASC,EAAAA,SAAS,IACfF,EAAcJ,EAAM,SAAS,GAAKI,EAAc,OACxD,EAKKG,EAAiBD,EAAAA,SAAS,IACvBE,EAAAA,GACLH,EAAO,MAAM,aACbL,EAAM,cAAgB,gBAAkB,iBAAA,CAE3C,EAKKS,EAAwB,CAACC,EAAsBC,IAAkB,CACrET,EAAK,kBAAmBQ,EAAMC,CAAK,CACrC,EAKMC,EAA6BC,GAA2B,CAC5DX,EAAK,sBAAuBW,CAAM,CACpC,8BAIEC,EAAAA,mBA2BM,MAAA,CA3BA,MAAKC,EAAAA,eAAEC,EAAAA,YAAGX,EAAA,MAAO,eAAgBL,EAAM,KAAK,CAAA,CAAA,GAGxCC,EAAA,gBAAkBA,EAAA,iBAAmBA,EAAA,gBAAgB,OAAM,iBADnEgB,EAAAA,YAIEC,EAAAA,QAAA,OAFC,MAAOjB,EAAA,gBACP,YAAYQ,CAAA,iDAKPR,EAAA,4BADRgB,EAAAA,YAYYE,EAAAA,QAAA,OAVT,MAAOlB,EAAA,MACP,KAAMA,EAAA,KACN,YAAaA,EAAA,YACb,QAASA,EAAA,gBACT,UAAWA,EAAA,kBACX,cAAcW,CAAA,GAEJ,kBACT,IAAgC,CAAhCQ,aAAgCC,EAAA,OAAA,kBAAA,CAAA,6FAKpCC,EAAAA,mBAEM,MAAA,CAFA,uBAAOf,EAAA,KAAc,CAAA,GACzBa,aAAQC,EAAA,OAAA,SAAA,CAAA"}
|