admins-components 9.0.36 → 9.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,23 @@
1
1
  import e from "./admins-components6.js";
2
- import { Fragment as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, defineComponent as s, nextTick as c, normalizeClass as l, onBeforeUnmount as u, onMounted as d, openBlock as f, ref as p, renderList as m, toDisplayString as h, vModelText as g, watch as _, withDirectives as v, withModifiers as y } from "vue";
2
+ import { debounce as t } from "./admins-components15.js";
3
+ import { Fragment as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, defineComponent as c, nextTick as l, normalizeClass as u, onBeforeUnmount as d, onMounted as f, openBlock as p, ref as m, renderList as h, toDisplayString as g, watch as _, withModifiers as v } from "vue";
3
4
  //#region src/components/DropdownSelect.vue?vue&type=script&setup=true&lang.ts
4
- var b = { class: "ac-component" }, x = {
5
+ var y = { class: "ac-component" }, b = {
5
6
  key: 0,
6
7
  class: "c-truncate ds-value"
7
- }, S = {
8
+ }, x = {
8
9
  key: 1,
9
10
  class: "c-placeholder"
10
- }, C = {
11
+ }, S = {
11
12
  key: 0,
12
13
  class: "ds-filter"
13
- }, w = ["title"], T = { class: "ds-options c-scroll" }, E = ["onClick", "onKeydown"], D = {
14
+ }, ee = ["title"], C = ["value"], w = { class: "ds-options c-scroll" }, T = ["onClick", "onKeydown"], E = {
14
15
  key: 0,
15
16
  class: "ds-option ds-option--empty"
16
- }, O = {
17
+ }, D = {
17
18
  key: 1,
18
19
  class: "c-footer"
19
- }, k = {
20
+ }, O = {
20
21
  placeholder: "Select...",
21
22
  filterable: !0,
22
23
  clearable: !0,
@@ -24,160 +25,168 @@ var b = { class: "ac-component" }, x = {
24
25
  multiple: !1,
25
26
  lazy: !1,
26
27
  size: "normal"
27
- }, A = /* @__PURE__ */ s({
28
+ }, k = /* @__PURE__ */ c({
28
29
  __name: "DropdownSelect",
29
30
  props: {
30
31
  modelValue: { default: null },
31
32
  options: {},
32
- config: { default: () => ({ ...k }) }
33
+ config: { default: () => ({ ...O }) }
33
34
  },
34
- emits: ["update:modelValue"],
35
- setup(s, { expose: A, emit: j }) {
36
- let M = s, N = n(() => ({
37
- ...k,
38
- ...M.config
39
- })), P = j, F = p(!1), I = p(""), L = p(null), R = p(null), z = p([]), B = p(V(M.modelValue));
40
- function V(e) {
35
+ emits: ["update:modelValue", "filter-input"],
36
+ setup(c, { expose: k, emit: A }) {
37
+ let j = c, M = r(() => ({
38
+ ...O,
39
+ ...j.config
40
+ })), N = A, P = m(!1), F = m(""), I = m(null), L = m(null), R = m([]), z = m(B(j.modelValue));
41
+ function B(e) {
41
42
  return e == null ? [] : Array.isArray(e) ? [...e] : [e];
42
43
  }
43
- _(() => M.modelValue, (e) => {
44
- B.value = V(e);
45
- }), _(F, (e) => {
46
- e && (I.value = "", N.value.filterable && c(() => R.value?.focus()), N.value.lazy && (z.value = [...B.value]));
44
+ _(() => j.modelValue, (e) => {
45
+ z.value = B(e);
46
+ }), _(P, (e) => {
47
+ e && (F.value = "", M.value.filterable && l(() => L.value?.focus()), M.value.lazy && (R.value = [...z.value]));
47
48
  });
48
- let H = n(() => B.value.length === 0 ? null : N.value.multiple ? B.value.length > 2 ? `${B.value.length} kiválasztva` : B.value.map((e) => M.options.find((t) => t.value === e)?.label ?? e).join(", ") : M.options.find((e) => e.value === B.value[0])?.label ?? null), U = n(() => {
49
- let e = I.value.toLowerCase();
50
- return e ? M.options.filter((t) => t.label.toLowerCase().includes(e)) : M.options;
51
- }), W = n(() => U.value.filter((e) => e.value)), G = n(() => {
52
- if (W.value.length === 0) return !1;
53
- let e = N.value.lazy && F.value ? z.value : B.value;
54
- return W.value.every((t) => t.value && e.includes(t.value));
49
+ function V(e) {
50
+ F.value = e, H(e);
51
+ }
52
+ let H = t((e) => {
53
+ N("filter-input", e);
54
+ }), U = r(() => z.value.length === 0 ? null : M.value.multiple ? z.value.length > 2 ? `${z.value.length} kiválasztva` : z.value.map((e) => j.options.find((t) => t.value === e)?.label ?? e).join(", ") : j.options.find((e) => e.value === z.value[0])?.label ?? null), W = r(() => {
55
+ let e = F.value.toLowerCase();
56
+ return e ? j.options.filter((t) => t.label.toLowerCase().includes(e)) : j.options;
57
+ }), G = r(() => W.value.filter((e) => e.value)), K = r(() => {
58
+ if (G.value.length === 0) return !1;
59
+ let e = M.value.lazy && P.value ? R.value : z.value;
60
+ return G.value.every((t) => t.value && e.includes(t.value));
55
61
  });
56
- function K(e) {
57
- return (N.value.lazy && F.value ? z : B).value.includes(e);
62
+ function q(e) {
63
+ return (M.value.lazy && P.value ? R : z).value.includes(e);
58
64
  }
59
- function q() {
60
- let e = N.value.lazy && F.value ? z : B, t = W.value.map((e) => e.value);
61
- if (G.value) e.value = e.value.filter((e) => !t.includes(e));
65
+ function J() {
66
+ let e = M.value.lazy && P.value ? R : z, t = G.value.map((e) => e.value);
67
+ if (K.value) e.value = e.value.filter((e) => !t.includes(e));
62
68
  else {
63
69
  let n = t.filter((t) => !e.value.includes(t));
64
70
  e.value = [...e.value, ...n];
65
71
  }
66
- N.value.lazy || P("update:modelValue", B.value.length > 0 ? [...B.value] : null);
72
+ M.value.lazy || N("update:modelValue", z.value.length > 0 ? [...z.value] : null);
67
73
  }
68
- function J(e, t) {
74
+ function Y(e, t) {
69
75
  let n = e.indexOf(t);
70
76
  return n >= 0 ? e.filter((e, t) => t !== n) : [...e, t];
71
77
  }
72
- function Y(e) {
78
+ function X(e) {
73
79
  if (e.callback) {
74
- e.callback(), F.value = !1;
80
+ e.callback(), P.value = !1;
75
81
  return;
76
82
  }
77
83
  let t = e.value;
78
- t && (N.value.multiple ? N.value.lazy ? z.value = J(z.value, t) : (B.value = J(B.value, t), P("update:modelValue", B.value.length > 0 ? [...B.value] : null)) : (B.value = [t], P("update:modelValue", t), F.value = !1));
79
- }
80
- function X() {
81
- N.value.lazy && (B.value = [...z.value], P("update:modelValue", z.value.length > 0 ? [...z.value] : null)), F.value = !1;
84
+ t && (M.value.multiple ? M.value.lazy ? R.value = Y(R.value, t) : (z.value = Y(z.value, t), N("update:modelValue", z.value.length > 0 ? [...z.value] : null)) : (z.value = [t], N("update:modelValue", t), P.value = !1));
82
85
  }
83
86
  function Z() {
84
- N.value.lazy ? z.value = [] : (B.value = [], P("update:modelValue", null));
87
+ M.value.lazy && (z.value = [...R.value], N("update:modelValue", R.value.length > 0 ? [...R.value] : null)), P.value = !1;
88
+ }
89
+ function Q() {
90
+ M.value.lazy ? R.value = [] : (z.value = [], N("update:modelValue", null));
85
91
  }
86
- function Q(e, t) {
87
- e.key === " " ? (e.preventDefault(), Y(t)) : e.key === "Enter" && (e.preventDefault(), X());
92
+ function te(e, t) {
93
+ e.key === " " ? (e.preventDefault(), X(t)) : e.key === "Enter" && (e.preventDefault(), Z());
88
94
  }
89
95
  function $(e) {
90
- L.value && !L.value.contains(e.target) && (F.value = !1);
96
+ I.value && !I.value.contains(e.target) && (P.value = !1);
91
97
  }
92
- d(() => document.addEventListener("mousedown", $)), u(() => document.removeEventListener("mousedown", $));
93
- function ee() {
94
- F.value = !F.value, F.value && (I.value = "");
98
+ f(() => document.addEventListener("mousedown", $)), d(() => {
99
+ document.removeEventListener("mousedown", $);
100
+ });
101
+ function ne() {
102
+ P.value = !P.value, P.value && (F.value = "");
95
103
  }
96
- function te() {
97
- B.value = [], P("update:modelValue", null), F.value = !1;
104
+ function re() {
105
+ z.value = [], N("update:modelValue", null), P.value = !1;
98
106
  }
99
- function ne() {
100
- F.value = !0, N.value.filterable && c(() => R.value?.focus());
107
+ function ie() {
108
+ P.value = !0, M.value.filterable && l(() => L.value?.focus());
101
109
  }
102
- return A({ focusAndOpen: ne }), (n, s) => (f(), a("div", b, [o("div", {
110
+ return k({ focusAndOpen: ie }), (t, r) => (p(), o("div", y, [s("div", {
103
111
  ref_key: "wrapperRef",
104
- ref: L,
112
+ ref: I,
105
113
  class: "c-wrapper ds-wrapper"
106
- }, [o("div", {
107
- class: l(["c-input-row pointer", {
108
- "c-input-row--sm": N.value.size === "small",
109
- "c-input-row--lg": N.value.size === "large"
114
+ }, [s("div", {
115
+ class: u(["c-input-row pointer", {
116
+ "c-input-row--sm": M.value.size === "small",
117
+ "c-input-row--lg": M.value.size === "large"
110
118
  }]),
111
- onClick: s[1] ||= (e) => ee()
119
+ onClick: r[1] ||= (e) => ne()
112
120
  }, [
113
- H.value ? (f(), a("span", x, h(H.value), 1)) : (f(), a("span", S, h(N.value.placeholder), 1)),
114
- N.value.clearable && B.value.length > 0 ? (f(), a("button", {
121
+ U.value ? (p(), o("span", b, g(U.value), 1)) : (p(), o("span", x, g(M.value.placeholder), 1)),
122
+ M.value.clearable && z.value.length > 0 ? (p(), o("button", {
115
123
  key: 2,
116
124
  type: "button",
117
125
  class: "c-icon-btn c-icon-btn--clear ds-clear-btn",
118
- onClick: s[0] ||= y((e) => te(), ["stop"]),
126
+ onClick: r[0] ||= v((e) => re(), ["stop"]),
119
127
  "aria-label": "Törlés"
120
- }, [...s[6] ||= [o("i", { class: "fa-solid fa-fw fa-xmark" }, null, -1)]])) : i("", !0),
121
- o("span", { class: l(["c-icon-btn c-icon-btn--chevron mr-2", { "c-icon-btn--chevron-open": F.value }]) }, [...s[7] ||= [o("i", { class: "fa-solid fa-fw fa-chevron-down" }, null, -1)]], 2)
122
- ], 2), F.value ? (f(), a("div", {
128
+ }, [...r[6] ||= [s("i", { class: "fa-solid fa-fw fa-xmark" }, null, -1)]])) : a("", !0),
129
+ s("span", { class: u(["c-icon-btn c-icon-btn--chevron mr-2", { "c-icon-btn--chevron-open": P.value }]) }, [...r[7] ||= [s("i", { class: "fa-solid fa-fw fa-chevron-down" }, null, -1)]], 2)
130
+ ], 2), P.value ? (p(), o("div", {
123
131
  key: 0,
124
- class: l(["c-dropdown ds-dropdown ac-component", { "ds-dropdown--multiple": N.value.multiple }])
132
+ class: u(["c-dropdown ds-dropdown ac-component", { "ds-dropdown--multiple": M.value.multiple }])
125
133
  }, [
126
- N.value.filterable ? (f(), a("div", C, [
127
- N.value.multiple ? (f(), a("span", {
134
+ M.value.filterable ? (p(), o("div", S, [
135
+ M.value.multiple ? (p(), o("span", {
128
136
  key: 0,
129
- class: l(["c-checkbox ds-select-all-checkbox", { "c-checkbox--checked": G.value }]),
130
- onClick: s[2] ||= y((e) => q(), ["stop"]),
131
- title: G.value ? "Összes kijelölés törlése" : "Összes kijelölése"
132
- }, null, 10, w)) : i("", !0),
133
- v(o("input", {
137
+ class: u(["c-checkbox ds-select-all-checkbox", { "c-checkbox--checked": K.value }]),
138
+ onClick: r[2] ||= v((e) => J(), ["stop"]),
139
+ title: K.value ? "Összes kijelölés törlése" : "Összes kijelölése"
140
+ }, null, 10, ee)) : a("", !0),
141
+ s("input", {
134
142
  ref_key: "filterInputRef",
135
- ref: R,
143
+ ref: L,
136
144
  type: "text",
137
145
  id: "ds-filter-input",
138
146
  class: "c-focus ds-filter-input",
139
- "onUpdate:modelValue": s[3] ||= (e) => I.value = e,
147
+ value: F.value,
148
+ onInput: r[3] ||= (e) => V(e.target.value),
140
149
  placeholder: "Filter...",
141
- onClick: s[4] ||= y(() => {}, ["stop"])
142
- }, null, 512), [[g, I.value]]),
143
- I.value ? (f(), a("button", {
150
+ onClick: r[4] ||= v(() => {}, ["stop"])
151
+ }, null, 40, C),
152
+ F.value ? (p(), o("button", {
144
153
  key: 1,
145
154
  type: "button",
146
155
  class: "c-icon-btn c-icon-btn--clear ds-filter-clear",
147
- onClick: s[5] ||= y((e) => I.value = "", ["stop"]),
156
+ onClick: r[5] ||= v((e) => F.value = "", ["stop"]),
148
157
  "aria-label": "Szűrők törlése"
149
- }, [...s[8] ||= [o("i", { class: "fa-solid fa-xmark" }, null, -1)]])) : i("", !0)
150
- ])) : i("", !0),
151
- o("ul", T, [(f(!0), a(t, null, m(U.value, (e, t) => (f(), a("li", {
158
+ }, [...r[8] ||= [s("i", { class: "fa-solid fa-xmark" }, null, -1)]])) : a("", !0)
159
+ ])) : a("", !0),
160
+ s("ul", w, [(p(!0), o(n, null, h(W.value, (e, t) => (p(), o("li", {
152
161
  key: e.value ?? `cb-${t}`,
153
- class: l(["d-option ds-option", { "ds-option--selected": e.value && K(e.value) }]),
162
+ class: u(["d-option ds-option", { "ds-option--selected": e.value && q(e.value) }]),
154
163
  tabindex: "0",
155
- onClick: (t) => Y(e),
156
- onKeydown: (t) => Q(t, e)
164
+ onClick: (t) => X(e),
165
+ onKeydown: (t) => te(t, e)
157
166
  }, [
158
- N.value.multiple && e.value ? (f(), a("span", {
167
+ M.value.multiple && e.value ? (p(), o("span", {
159
168
  key: 0,
160
- class: l(["c-checkbox", { "c-checkbox--checked": K(e.value) }])
161
- }, null, 2)) : i("", !0),
162
- e.icon ? (f(), a("i", {
169
+ class: u(["c-checkbox", { "c-checkbox--checked": q(e.value) }])
170
+ }, null, 2)) : a("", !0),
171
+ e.icon ? (p(), o("i", {
163
172
  key: 1,
164
- class: l(["fa-fw", e.icon])
165
- }, null, 2)) : i("", !0),
166
- o("span", { class: l(["d-option__label", { "c-truncate": N.value.textEllipsis }]) }, h(e.label), 3)
167
- ], 42, E))), 128)), U.value.length === 0 ? (f(), a("li", D, " Nincs találat ")) : i("", !0)]),
168
- N.value.multiple || N.value.clearable && B.value.length > 0 ? (f(), a("div", O, [N.value.clearable ? (f(), r(e, {
173
+ class: u(["fa-fw", e.icon])
174
+ }, null, 2)) : a("", !0),
175
+ s("span", { class: u(["d-option__label", { "c-truncate": M.value.textEllipsis }]) }, g(e.label), 3)
176
+ ], 42, T))), 128)), W.value.length === 0 ? (p(), o("li", E, " Nincs találat ")) : a("", !0)]),
177
+ M.value.multiple || M.value.clearable && z.value.length > 0 ? (p(), o("div", D, [M.value.clearable ? (p(), i(e, {
169
178
  key: 0,
170
179
  label: "Törlés",
171
180
  outline: "",
172
- onClick: Z
173
- })) : i("", !0), N.value.multiple ? (f(), r(e, {
181
+ onClick: Q
182
+ })) : a("", !0), M.value.multiple ? (p(), i(e, {
174
183
  key: 1,
175
184
  label: "OK",
176
185
  type: "success",
177
- onClick: X
178
- })) : i("", !0)])) : i("", !0)
179
- ], 2)) : i("", !0)], 512)]));
186
+ onClick: Z
187
+ })) : a("", !0)])) : a("", !0)
188
+ ], 2)) : a("", !0)], 512)]));
180
189
  }
181
190
  });
182
191
  //#endregion
183
- export { A as default, k as dropdownSelectConfigDefaults };
192
+ export { k as default, O as dropdownSelectConfigDefaults };
@@ -1 +1 @@
1
- {"version":3,"file":"admins-components23.js","names":[],"sources":["../src/components/DropdownSelect.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface DropdownSelectConfig {\n placeholder?: string\n filterable?: boolean\n clearable?: boolean\n textEllipsis?: boolean\n multiple?: boolean\n lazy?: boolean\n size?: ControlSize\n}\n\nexport const dropdownSelectConfigDefaults: DropdownSelectConfig = {\n placeholder: 'Select...',\n filterable: true,\n clearable: true,\n textEllipsis: true,\n multiple: false,\n lazy: false,\n size: 'normal' as ControlSize,\n}\n\nexport interface DropdownOption {\n icon?: string\n value?: string\n label: string\n callback?: () => void\n}\n\nexport interface DropdownSelectProps {\n modelValue?: string | string[] | null\n options: DropdownOption[]\n config?: DropdownSelectConfig\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'\nimport Button from '@/components/Button.vue'\nimport type { ControlSize } from '@/types/types'\n\nconst props = withDefaults(defineProps<DropdownSelectProps>(), {\n modelValue: null,\n config: () => ({ ...dropdownSelectConfigDefaults }),\n})\n\nconst cfg = computed(() => ({ ...dropdownSelectConfigDefaults, ...props.config }))\n\nconst emit = defineEmits<{ 'update:modelValue': [value: string | string[] | null] }>()\n\n\n\nconst isOpen = ref(false)\nconst filterText = ref('')\nconst wrapperRef = ref<HTMLElement | null>(null)\nconst filterInputRef = ref<HTMLInputElement | null>(null)\nconst buffer = ref<string[]>([])\nconst selection = ref<string[]>(toArray(props.modelValue))\n\nfunction toArray(val: string | string[] | null | undefined): string[] {\n if (val == null) return []\n return Array.isArray(val) ? [...val] : [val]\n}\n\nwatch(\n () => props.modelValue,\n (v) => {\n selection.value = toArray(v)\n },\n)\n\nwatch(isOpen, (open) => {\n if (open) {\n filterText.value = ''\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n if (cfg.value.lazy) buffer.value = [...selection.value]\n }\n})\n\n// Display\nconst selectedLabel = computed(() => {\n if (selection.value.length === 0) return null\n if (!cfg.value.multiple)\n return props.options.find((o) => o.value === selection.value[0])?.label ?? null\n if (selection.value.length > 2) return `${selection.value.length} kiválasztva`\n return selection.value.map((v) => props.options.find((o) => o.value === v)?.label ?? v).join(', ')\n})\n\nconst filteredOptions = computed(() => {\n const q = filterText.value.toLowerCase()\n return q ? props.options.filter((o) => o.label.toLowerCase().includes(q)) : props.options\n})\n\nconst selectableOptions = computed(() => {\n return filteredOptions.value.filter((o) => o.value)\n})\n\nconst allOptionsSelected = computed(() => {\n if (selectableOptions.value.length === 0) return false\n const currentList = cfg.value.lazy && isOpen.value ? buffer.value : selection.value\n return selectableOptions.value.every((o) => o.value && currentList.includes(o.value))\n})\n\nfunction isSelected(value: string): boolean {\n return (cfg.value.lazy && isOpen.value ? buffer : selection).value.includes(value)\n}\n\nfunction toggleAllOptions() {\n const currentList = cfg.value.lazy && isOpen.value ? buffer : selection\n const selectableValues = selectableOptions.value.map((o) => o.value as string)\n\n if (allOptionsSelected.value) {\n currentList.value = currentList.value.filter((v) => !selectableValues.includes(v))\n } else {\n const toAdd = selectableValues.filter((v) => !currentList.value.includes(v))\n currentList.value = [...currentList.value, ...toAdd]\n }\n\n if (!cfg.value.lazy) {\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n}\n\n// Actions\nfunction toggleList(list: string[], value: string): string[] {\n const idx = list.indexOf(value)\n return idx >= 0 ? list.filter((_, i) => i !== idx) : [...list, value]\n}\n\nfunction selectOption(opt: DropdownOption) {\n if (opt.callback) {\n opt.callback()\n isOpen.value = false\n return\n }\n\n const value = opt.value\n if (!value) return\n\n if (cfg.value.multiple) {\n if (cfg.value.lazy) {\n buffer.value = toggleList(buffer.value, value)\n } else {\n selection.value = toggleList(selection.value, value)\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n } else {\n selection.value = [value]\n emit('update:modelValue', value)\n isOpen.value = false\n }\n}\n\nfunction confirm() {\n if (cfg.value.lazy) {\n selection.value = [...buffer.value]\n emit('update:modelValue', buffer.value.length > 0 ? [...buffer.value] : null)\n }\n isOpen.value = false\n}\n\nfunction clear() {\n if (cfg.value.lazy) {\n buffer.value = []\n } else {\n selection.value = []\n emit('update:modelValue', null)\n }\n}\n\nfunction onOptionKeydown(e: KeyboardEvent, opt: DropdownOption) {\n if (e.key === ' ') {\n e.preventDefault()\n selectOption(opt)\n } else if (e.key === 'Enter') {\n e.preventDefault()\n confirm()\n }\n}\n\nfunction onClickOutside(e: MouseEvent) {\n if (wrapperRef.value && !wrapperRef.value.contains(e.target as Node)) isOpen.value = false\n}\n\nonMounted(() => document.addEventListener('mousedown', onClickOutside))\nonBeforeUnmount(() => document.removeEventListener('mousedown', onClickOutside))\n\nfunction toggleOpen() {\n isOpen.value = !isOpen.value\n if (isOpen.value) filterText.value = ''\n}\n\nfunction clearInput() {\n selection.value = []\n emit('update:modelValue', null)\n isOpen.value = false\n}\n\nfunction focusAndOpen() {\n isOpen.value = true\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n}\n\ndefineExpose({ focusAndOpen })\n</script>\n\n<template>\n <div class=\"ac-component\">\n <div ref=\"wrapperRef\" class=\"c-wrapper ds-wrapper\">\n <div\n class=\"c-input-row pointer\"\n :class=\"{\n 'c-input-row--sm': cfg.size === 'small',\n 'c-input-row--lg': cfg.size === 'large',\n }\"\n @click=\"toggleOpen()\"\n >\n <span v-if=\"selectedLabel\" class=\"c-truncate ds-value\">{{ selectedLabel }}</span>\n <span v-else class=\"c-placeholder\">{{ cfg.placeholder }}</span>\n <button\n v-if=\"cfg.clearable && selection.length > 0\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-clear-btn\"\n @click.stop=\"clearInput()\"\n aria-label=\"Törlés\"\n >\n <i class=\"fa-solid fa-fw fa-xmark\"></i>\n </button>\n <span\n class=\"c-icon-btn c-icon-btn--chevron mr-2\"\n :class=\"{ 'c-icon-btn--chevron-open': isOpen }\"\n >\n <i class=\"fa-solid fa-fw fa-chevron-down\"></i>\n </span>\n </div>\n\n <div\n v-if=\"isOpen\"\n class=\"c-dropdown ds-dropdown ac-component\"\n :class=\"{ 'ds-dropdown--multiple': cfg.multiple }\"\n >\n <div v-if=\"cfg.filterable\" class=\"ds-filter\">\n <span\n v-if=\"cfg.multiple\"\n class=\"c-checkbox ds-select-all-checkbox\"\n :class=\"{ 'c-checkbox--checked': allOptionsSelected }\"\n @click.stop=\"toggleAllOptions()\"\n :title=\"allOptionsSelected ? 'Összes kijelölés törlése' : 'Összes kijelölése'\"\n ></span>\n <input\n ref=\"filterInputRef\"\n type=\"text\"\n id=\"ds-filter-input\"\n class=\"c-focus ds-filter-input\"\n v-model=\"filterText\"\n placeholder=\"Filter...\"\n @click.stop\n />\n <button\n v-if=\"filterText\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-filter-clear\"\n @click.stop=\"filterText = ''\"\n aria-label=\"Szűrők törlése\"\n >\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <ul class=\"ds-options c-scroll\">\n <li\n v-for=\"(opt, idx) in filteredOptions\"\n :key=\"opt.value ?? `cb-${idx}`\"\n class=\"d-option ds-option\"\n :class=\"{ 'ds-option--selected': opt.value && isSelected(opt.value) }\"\n tabindex=\"0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt)\"\n >\n <span\n v-if=\"cfg.multiple && opt.value\"\n class=\"c-checkbox\"\n :class=\"{ 'c-checkbox--checked': isSelected(opt.value) }\"\n ></span>\n <i v-if=\"opt.icon\" class=\"fa-fw\" :class=\"opt.icon\"></i>\n <span class=\"d-option__label\" :class=\"{ 'c-truncate': cfg.textEllipsis }\">{{\n opt.label\n }}</span>\n </li>\n <li v-if=\"filteredOptions.length === 0\" class=\"ds-option ds-option--empty\">\n Nincs találat\n </li>\n </ul>\n\n <div v-if=\"cfg.multiple || (cfg.clearable && selection.length > 0)\" class=\"c-footer\">\n <Button v-if=\"cfg.clearable\" label=\"Törlés\" outline @click=\"clear\" />\n <Button v-if=\"cfg.multiple\" label=\"OK\" type=\"success\" @click=\"confirm\" />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/dropdown-select.scss\"></style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"admins-components23.js","names":[],"sources":["../src/components/DropdownSelect.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface DropdownSelectConfig {\n placeholder?: string\n filterable?: boolean\n clearable?: boolean\n textEllipsis?: boolean\n multiple?: boolean\n lazy?: boolean\n size?: ControlSize\n}\n\nexport const dropdownSelectConfigDefaults: DropdownSelectConfig = {\n placeholder: 'Select...',\n filterable: true,\n clearable: true,\n textEllipsis: true,\n multiple: false,\n lazy: false,\n size: 'normal' as ControlSize\n}\n\nexport interface DropdownOption {\n icon?: string\n value?: string\n label: string\n callback?: () => void\n}\n\nexport interface DropdownSelectProps {\n modelValue?: string | string[] | null\n options: DropdownOption[]\n config?: DropdownSelectConfig\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'\nimport Button from '@/components/Button.vue'\nimport type { ControlSize } from '@/types/types'\nimport { debounce } from '@/utils/debounce'\n\nconst props = withDefaults(defineProps<DropdownSelectProps>(), {\n modelValue: null,\n config: () => ({ ...dropdownSelectConfigDefaults }),\n})\n\nconst cfg = computed(() => ({ ...dropdownSelectConfigDefaults, ...props.config }))\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | null]\n 'filter-input': [filterText: string]\n}>()\n\nconst isOpen = ref(false)\nconst filterText = ref('')\nconst wrapperRef = ref<HTMLElement | null>(null)\nconst filterInputRef = ref<HTMLInputElement | null>(null)\nconst buffer = ref<string[]>([])\nconst selection = ref<string[]>(toArray(props.modelValue))\n\nfunction toArray(val: string | string[] | null | undefined): string[] {\n if (val == null) return []\n return Array.isArray(val) ? [...val] : [val]\n}\n\nwatch(\n () => props.modelValue,\n (v) => {\n selection.value = toArray(v)\n },\n)\n\nwatch(isOpen, (open) => {\n if (open) {\n filterText.value = ''\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n if (cfg.value.lazy) buffer.value = [...selection.value]\n }\n})\n\nfunction onFilterInput(text: string) {\n filterText.value = text\n debouncedEmit(text)\n}\n\nconst debouncedEmit = debounce((raw: string) => {\n emit('filter-input', raw)\n})\n\n// Display\nconst selectedLabel = computed(() => {\n if (selection.value.length === 0) return null\n if (!cfg.value.multiple)\n return props.options.find((o) => o.value === selection.value[0])?.label ?? null\n if (selection.value.length > 2) return `${selection.value.length} kiválasztva`\n return selection.value.map((v) => props.options.find((o) => o.value === v)?.label ?? v).join(', ')\n})\n\nconst filteredOptions = computed(() => {\n const q = filterText.value.toLowerCase()\n return q ? props.options.filter((o) => o.label.toLowerCase().includes(q)) : props.options\n})\n\nconst selectableOptions = computed(() => {\n return filteredOptions.value.filter((o) => o.value)\n})\n\nconst allOptionsSelected = computed(() => {\n if (selectableOptions.value.length === 0) return false\n const currentList = cfg.value.lazy && isOpen.value ? buffer.value : selection.value\n return selectableOptions.value.every((o) => o.value && currentList.includes(o.value))\n})\n\nfunction isSelected(value: string): boolean {\n return (cfg.value.lazy && isOpen.value ? buffer : selection).value.includes(value)\n}\n\nfunction toggleAllOptions() {\n const currentList = cfg.value.lazy && isOpen.value ? buffer : selection\n const selectableValues = selectableOptions.value.map((o) => o.value as string)\n\n if (allOptionsSelected.value) {\n currentList.value = currentList.value.filter((v) => !selectableValues.includes(v))\n } else {\n const toAdd = selectableValues.filter((v) => !currentList.value.includes(v))\n currentList.value = [...currentList.value, ...toAdd]\n }\n\n if (!cfg.value.lazy) {\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n}\n\n// Actions\nfunction toggleList(list: string[], value: string): string[] {\n const idx = list.indexOf(value)\n return idx >= 0 ? list.filter((_, i) => i !== idx) : [...list, value]\n}\n\nfunction selectOption(opt: DropdownOption) {\n if (opt.callback) {\n opt.callback()\n isOpen.value = false\n return\n }\n\n const value = opt.value\n if (!value) return\n\n if (cfg.value.multiple) {\n if (cfg.value.lazy) {\n buffer.value = toggleList(buffer.value, value)\n } else {\n selection.value = toggleList(selection.value, value)\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n } else {\n selection.value = [value]\n emit('update:modelValue', value)\n isOpen.value = false\n }\n}\n\nfunction confirm() {\n if (cfg.value.lazy) {\n selection.value = [...buffer.value]\n emit('update:modelValue', buffer.value.length > 0 ? [...buffer.value] : null)\n }\n isOpen.value = false\n}\n\nfunction clear() {\n if (cfg.value.lazy) {\n buffer.value = []\n } else {\n selection.value = []\n emit('update:modelValue', null)\n }\n}\n\nfunction onOptionKeydown(e: KeyboardEvent, opt: DropdownOption) {\n if (e.key === ' ') {\n e.preventDefault()\n selectOption(opt)\n } else if (e.key === 'Enter') {\n e.preventDefault()\n confirm()\n }\n}\n\nfunction onClickOutside(e: MouseEvent) {\n if (wrapperRef.value && !wrapperRef.value.contains(e.target as Node)) isOpen.value = false\n}\n\nonMounted(() => document.addEventListener('mousedown', onClickOutside))\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', onClickOutside)\n})\n\nfunction toggleOpen() {\n isOpen.value = !isOpen.value\n if (isOpen.value) filterText.value = ''\n}\n\nfunction clearInput() {\n selection.value = []\n emit('update:modelValue', null)\n isOpen.value = false\n}\n\nfunction focusAndOpen() {\n isOpen.value = true\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n}\n\ndefineExpose({ focusAndOpen })\n</script>\n\n<template>\n <div class=\"ac-component\">\n <div ref=\"wrapperRef\" class=\"c-wrapper ds-wrapper\">\n <div\n class=\"c-input-row pointer\"\n :class=\"{\n 'c-input-row--sm': cfg.size === 'small',\n 'c-input-row--lg': cfg.size === 'large',\n }\"\n @click=\"toggleOpen()\"\n >\n <span v-if=\"selectedLabel\" class=\"c-truncate ds-value\">{{ selectedLabel }}</span>\n <span v-else class=\"c-placeholder\">{{ cfg.placeholder }}</span>\n <button\n v-if=\"cfg.clearable && selection.length > 0\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-clear-btn\"\n @click.stop=\"clearInput()\"\n aria-label=\"Törlés\"\n >\n <i class=\"fa-solid fa-fw fa-xmark\"></i>\n </button>\n <span\n class=\"c-icon-btn c-icon-btn--chevron mr-2\"\n :class=\"{ 'c-icon-btn--chevron-open': isOpen }\"\n >\n <i class=\"fa-solid fa-fw fa-chevron-down\"></i>\n </span>\n </div>\n\n <div\n v-if=\"isOpen\"\n class=\"c-dropdown ds-dropdown ac-component\"\n :class=\"{ 'ds-dropdown--multiple': cfg.multiple }\"\n >\n <div v-if=\"cfg.filterable\" class=\"ds-filter\">\n <span\n v-if=\"cfg.multiple\"\n class=\"c-checkbox ds-select-all-checkbox\"\n :class=\"{ 'c-checkbox--checked': allOptionsSelected }\"\n @click.stop=\"toggleAllOptions()\"\n :title=\"allOptionsSelected ? 'Összes kijelölés törlése' : 'Összes kijelölése'\"\n ></span>\n <input\n ref=\"filterInputRef\"\n type=\"text\"\n id=\"ds-filter-input\"\n class=\"c-focus ds-filter-input\"\n :value=\"filterText\"\n @input=\"onFilterInput(($event.target as HTMLInputElement).value)\"\n placeholder=\"Filter...\"\n @click.stop\n />\n <button\n v-if=\"filterText\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-filter-clear\"\n @click.stop=\"filterText = ''\"\n aria-label=\"Szűrők törlése\"\n >\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <ul class=\"ds-options c-scroll\">\n <li\n v-for=\"(opt, idx) in filteredOptions\"\n :key=\"opt.value ?? `cb-${idx}`\"\n class=\"d-option ds-option\"\n :class=\"{ 'ds-option--selected': opt.value && isSelected(opt.value) }\"\n tabindex=\"0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt)\"\n >\n <span\n v-if=\"cfg.multiple && opt.value\"\n class=\"c-checkbox\"\n :class=\"{ 'c-checkbox--checked': isSelected(opt.value) }\"\n ></span>\n <i v-if=\"opt.icon\" class=\"fa-fw\" :class=\"opt.icon\"></i>\n <span class=\"d-option__label\" :class=\"{ 'c-truncate': cfg.textEllipsis }\">{{\n opt.label\n }}</span>\n </li>\n <li v-if=\"filteredOptions.length === 0\" class=\"ds-option ds-option--empty\">\n Nincs találat\n </li>\n </ul>\n\n <div v-if=\"cfg.multiple || (cfg.clearable && selection.length > 0)\" class=\"c-footer\">\n <Button v-if=\"cfg.clearable\" label=\"Törlés\" outline @click=\"clear\" />\n <Button v-if=\"cfg.multiple\" label=\"OK\" type=\"success\" @click=\"confirm\" />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/dropdown-select.scss\"></style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;GAWa,IAAqD;CAChE,aAAa;CACb,YAAY;CACZ,WAAW;CACX,cAAc;CACd,UAAU;CACV,MAAM;CACN,MAAM;AACR;;;;;;;;;EAsBA,IAAM,IAAQ,GAKR,IAAM,SAAgB;GAAE,GAAG;GAA8B,GAAG,EAAM;EAAO,EAAE,GAE3E,IAAO,GAKP,IAAS,EAAI,EAAK,GAClB,IAAa,EAAI,EAAE,GACnB,IAAa,EAAwB,IAAI,GACzC,IAAiB,EAA6B,IAAI,GAClD,IAAS,EAAc,CAAC,CAAC,GACzB,IAAY,EAAc,EAAQ,EAAM,UAAU,CAAC;EAEzD,SAAS,EAAQ,GAAqD;GAEpE,OADI,KAAO,OAAa,CAAC,IAClB,MAAM,QAAQ,CAAG,IAAI,CAAC,GAAG,CAAG,IAAI,CAAC,CAAG;EAC7C;EASA,AAPA,QACQ,EAAM,aACX,MAAM;GACL,EAAU,QAAQ,EAAQ,CAAC;EAC7B,CACF,GAEA,EAAM,IAAS,MAAS;GACtB,AAAI,MACF,EAAW,QAAQ,IACf,EAAI,MAAM,cAAY,QAAe,EAAe,OAAO,MAAM,CAAC,GAClE,EAAI,MAAM,SAAM,EAAO,QAAQ,CAAC,GAAG,EAAU,KAAK;EAE1D,CAAC;EAED,SAAS,EAAc,GAAc;GAEnC,AADA,EAAW,QAAQ,GACnB,EAAc,CAAI;EACpB;EAEA,IAAM,IAAgB,GAAU,MAAgB;GAC9C,EAAK,gBAAgB,CAAG;EAC1B,CAAC,GAGK,IAAgB,QAChB,EAAU,MAAM,WAAW,IAAU,OACpC,EAAI,MAAM,WAEX,EAAU,MAAM,SAAS,IAAU,GAAG,EAAU,MAAM,OAAO,gBAC1D,EAAU,MAAM,KAAK,MAAM,EAAM,QAAQ,MAAM,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,EAAE,KAAK,IAAI,IAFxF,EAAM,QAAQ,MAAM,MAAM,EAAE,UAAU,EAAU,MAAM,EAAE,GAAG,SAAS,IAG9E,GAEK,IAAkB,QAAe;GACrC,IAAM,IAAI,EAAW,MAAM,YAAY;GACvC,OAAO,IAAI,EAAM,QAAQ,QAAQ,MAAM,EAAE,MAAM,YAAY,EAAE,SAAS,CAAC,CAAC,IAAI,EAAM;EACpF,CAAC,GAEK,IAAoB,QACjB,EAAgB,MAAM,QAAQ,MAAM,EAAE,KAAK,CACnD,GAEK,IAAqB,QAAe;GACxC,IAAI,EAAkB,MAAM,WAAW,GAAG,OAAO;GACjD,IAAM,IAAc,EAAI,MAAM,QAAQ,EAAO,QAAQ,EAAO,QAAQ,EAAU;GAC9E,OAAO,EAAkB,MAAM,OAAO,MAAM,EAAE,SAAS,EAAY,SAAS,EAAE,KAAK,CAAC;EACtF,CAAC;EAED,SAAS,EAAW,GAAwB;GAC1C,QAAQ,EAAI,MAAM,QAAQ,EAAO,QAAQ,IAAS,GAAW,MAAM,SAAS,CAAK;EACnF;EAEA,SAAS,IAAmB;GAC1B,IAAM,IAAc,EAAI,MAAM,QAAQ,EAAO,QAAQ,IAAS,GACxD,IAAmB,EAAkB,MAAM,KAAK,MAAM,EAAE,KAAe;GAE7E,IAAI,EAAmB,OACrB,EAAY,QAAQ,EAAY,MAAM,QAAQ,MAAM,CAAC,EAAiB,SAAS,CAAC,CAAC;QAC5E;IACL,IAAM,IAAQ,EAAiB,QAAQ,MAAM,CAAC,EAAY,MAAM,SAAS,CAAC,CAAC;IAC3E,EAAY,QAAQ,CAAC,GAAG,EAAY,OAAO,GAAG,CAAK;GACrD;GAEA,AAAK,EAAI,MAAM,QACb,EAAK,qBAAqB,EAAU,MAAM,SAAS,IAAI,CAAC,GAAG,EAAU,KAAK,IAAI,IAAI;EAEtF;EAGA,SAAS,EAAW,GAAgB,GAAyB;GAC3D,IAAM,IAAM,EAAK,QAAQ,CAAK;GAC9B,OAAO,KAAO,IAAI,EAAK,QAAQ,GAAG,MAAM,MAAM,CAAG,IAAI,CAAC,GAAG,GAAM,CAAK;EACtE;EAEA,SAAS,EAAa,GAAqB;GACzC,IAAI,EAAI,UAAU;IAEhB,AADA,EAAI,SAAS,GACb,EAAO,QAAQ;IACf;GACF;GAEA,IAAM,IAAQ,EAAI;GACb,MAED,EAAI,MAAM,WACR,EAAI,MAAM,OACZ,EAAO,QAAQ,EAAW,EAAO,OAAO,CAAK,KAE7C,EAAU,QAAQ,EAAW,EAAU,OAAO,CAAK,GACnD,EAAK,qBAAqB,EAAU,MAAM,SAAS,IAAI,CAAC,GAAG,EAAU,KAAK,IAAI,IAAI,MAGpF,EAAU,QAAQ,CAAC,CAAK,GACxB,EAAK,qBAAqB,CAAK,GAC/B,EAAO,QAAQ;EAEnB;EAEA,SAAS,IAAU;GAKjB,AAJI,EAAI,MAAM,SACZ,EAAU,QAAQ,CAAC,GAAG,EAAO,KAAK,GAClC,EAAK,qBAAqB,EAAO,MAAM,SAAS,IAAI,CAAC,GAAG,EAAO,KAAK,IAAI,IAAI,IAE9E,EAAO,QAAQ;EACjB;EAEA,SAAS,IAAQ;GACf,AAAI,EAAI,MAAM,OACZ,EAAO,QAAQ,CAAC,KAEhB,EAAU,QAAQ,CAAC,GACnB,EAAK,qBAAqB,IAAI;EAElC;EAEA,SAAS,GAAgB,GAAkB,GAAqB;GAC9D,AAAI,EAAE,QAAQ,OACZ,EAAE,eAAe,GACjB,EAAa,CAAG,KACP,EAAE,QAAQ,YACnB,EAAE,eAAe,GACjB,EAAQ;EAEZ;EAEA,SAAS,EAAe,GAAe;GACrC,AAAI,EAAW,SAAS,CAAC,EAAW,MAAM,SAAS,EAAE,MAAc,MAAG,EAAO,QAAQ;EACvF;EAGA,AADA,QAAgB,SAAS,iBAAiB,aAAa,CAAc,CAAC,GACtE,QAAsB;GACpB,SAAS,oBAAoB,aAAa,CAAc;EAC1D,CAAC;EAED,SAAS,KAAa;GAEpB,AADA,EAAO,QAAQ,CAAC,EAAO,OACnB,EAAO,UAAO,EAAW,QAAQ;EACvC;EAEA,SAAS,KAAa;GAGpB,AAFA,EAAU,QAAQ,CAAC,GACnB,EAAK,qBAAqB,IAAI,GAC9B,EAAO,QAAQ;EACjB;EAEA,SAAS,KAAe;GAEtB,AADA,EAAO,QAAQ,IACX,EAAI,MAAM,cAAY,QAAe,EAAe,OAAO,MAAM,CAAC;EACxE;SAEA,EAAa,EAAE,iBAAa,CAAC,mBAI3B,EA8FM,OA9FN,GA8FM,CA7FJ,EA4FM,OAAA;YA5FG;GAAJ,KAAI;GAAa,OAAM;MAC1B,EAyBM,OAAA;GAxBJ,OAAK,EAAA,CAAC,uBAAqB;uBACY,EAAA,MAAI,SAAI;uBAA2C,EAAA,MAAI,SAAI;;GAIjG,SAAK,AAAA,EAAA,QAAA,MAAE,GAAU;;GAEN,EAAA,SAAA,EAAA,GAAZ,EAAiF,QAAjF,GAAiF,EAAvB,EAAA,KAAa,GAAA,CAAA,MAAA,EAAA,GACvE,EAA+D,QAA/D,GAA+D,EAAzB,EAAA,MAAI,WAAW,GAAA,CAAA;GAE7C,EAAA,MAAI,aAAa,EAAA,MAAU,SAAM,KAAA,EAAA,GADzC,EAQS,UAAA;;IANP,MAAK;IACL,OAAM;IACL,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,GAAU,GAAA,CAAA,MAAA,CAAA;IACvB,cAAW;oBAEX,EAAuC,KAAA,EAApC,OAAM,0BAAyB,GAAA,MAAA,EAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;GAEpC,EAKO,QAAA,EAJL,OAAK,EAAA,CAAC,uCAAqC,EAAA,4BACL,EAAA,MAAM,CAAA,CAAA,EAAA,GAAA,CAAA,GAAA,AAAA,EAAA,OAAA,CAE5C,EAA8C,KAAA,EAA3C,OAAM,iCAAgC,GAAA,MAAA,EAAA,CAAA,CAAA,GAAA,CAAA;SAKrC,EAAA,SAAA,EAAA,GADR,EA+DM,OAAA;;GA7DJ,OAAK,EAAA,CAAC,uCAAqC,EAAA,yBACR,EAAA,MAAI,SAAQ,CAAA,CAAA;;GAEpC,EAAA,MAAI,cAAA,EAAA,GAAf,EA2BM,OA3BN,GA2BM;IAzBI,EAAA,MAAI,YAAA,EAAA,GADZ,EAMQ,QAAA;;KAJN,OAAK,EAAA,CAAC,qCAAmC,EAAA,uBACR,EAAA,MAAkB,CAAA,CAAA;KAClD,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAgB,GAAA,CAAA,MAAA,CAAA;KAC5B,OAAO,EAAA,QAAkB,6BAAA;;IAE5B,EASE,SAAA;cARI;KAAJ,KAAI;KACJ,MAAK;KACL,IAAG;KACH,OAAM;KACL,OAAO,EAAA;KACP,SAAK,AAAA,EAAA,QAAA,MAAE,EAAe,EAAO,OAA4B,KAAK;KAC/D,aAAY;KACX,SAAK,AAAA,EAAA,OAAA,QAAN,CAAA,GAAW,CAAA,MAAA,CAAA;;IAGL,EAAA,SAAA,EAAA,GADR,EAQS,UAAA;;KANP,MAAK;KACL,OAAM;KACL,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAA,QAAU,IAAA,CAAA,MAAA,CAAA;KACvB,cAAW;qBAEX,EAAiC,KAAA,EAA9B,OAAM,oBAAmB,GAAA,MAAA,EAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;;GAIhC,EAuBK,MAvBL,GAuBK,EAAA,EAAA,EAAA,GAtBH,EAkBK,GAAA,MAAA,EAjBkB,EAAA,QAAb,GAAK,YADf,EAkBK,MAAA;IAhBF,KAAK,EAAI,SAAK,MAAU;IACzB,OAAK,EAAA,CAAC,sBAAoB,EAAA,uBACO,EAAI,SAAS,EAAW,EAAI,KAAK,EAAA,CAAA,CAAA;IAClE,UAAS;IACR,UAAK,MAAE,EAAa,CAAG;IACvB,YAAO,MAAE,GAAgB,GAAQ,CAAG;;IAG7B,EAAA,MAAI,YAAY,EAAI,SAAA,EAAA,GAD5B,EAIQ,QAAA;;KAFN,OAAK,EAAA,CAAC,cAAY,EAAA,uBACe,EAAW,EAAI,KAAK,EAAA,CAAA,CAAA;;IAE9C,EAAI,QAAA,EAAA,GAAb,EAAuD,KAAA;;KAApC,OAAK,EAAA,CAAC,SAAgB,EAAI,IAAI,CAAA;;IACjD,EAES,QAAA,EAFH,OAAK,EAAA,CAAC,mBAAiB,EAAA,cAAyB,EAAA,MAAI,aAAY,CAAA,CAAA,EAAA,GAAA,EACpE,EAAI,KAAK,GAAA,CAAA;uBAGH,EAAA,MAAgB,WAAM,KAAA,EAAA,GAAhC,EAEK,MAFL,GAA2E,iBAE3E,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA;GAGS,EAAA,MAAI,YAAa,EAAA,MAAI,aAAa,EAAA,MAAU,SAAM,KAAA,EAAA,GAA7D,EAGM,OAHN,GAGM,CAFU,EAAA,MAAI,aAAA,EAAA,GAAlB,EAAqE,GAAA;;IAAxC,OAAM;IAAS,SAAA;IAAS,SAAO;oBAC9C,EAAA,MAAI,YAAA,EAAA,GAAlB,EAAyE,GAAA;;IAA7C,OAAM;IAAK,MAAK;IAAW,SAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"admins-components25.js","names":[],"sources":["../src/components/DropdownSelect.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface DropdownSelectConfig {\n placeholder?: string\n filterable?: boolean\n clearable?: boolean\n textEllipsis?: boolean\n multiple?: boolean\n lazy?: boolean\n size?: ControlSize\n}\n\nexport const dropdownSelectConfigDefaults: DropdownSelectConfig = {\n placeholder: 'Select...',\n filterable: true,\n clearable: true,\n textEllipsis: true,\n multiple: false,\n lazy: false,\n size: 'normal' as ControlSize,\n}\n\nexport interface DropdownOption {\n icon?: string\n value?: string\n label: string\n callback?: () => void\n}\n\nexport interface DropdownSelectProps {\n modelValue?: string | string[] | null\n options: DropdownOption[]\n config?: DropdownSelectConfig\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'\nimport Button from '@/components/Button.vue'\nimport type { ControlSize } from '@/types/types'\n\nconst props = withDefaults(defineProps<DropdownSelectProps>(), {\n modelValue: null,\n config: () => ({ ...dropdownSelectConfigDefaults }),\n})\n\nconst cfg = computed(() => ({ ...dropdownSelectConfigDefaults, ...props.config }))\n\nconst emit = defineEmits<{ 'update:modelValue': [value: string | string[] | null] }>()\n\n\n\nconst isOpen = ref(false)\nconst filterText = ref('')\nconst wrapperRef = ref<HTMLElement | null>(null)\nconst filterInputRef = ref<HTMLInputElement | null>(null)\nconst buffer = ref<string[]>([])\nconst selection = ref<string[]>(toArray(props.modelValue))\n\nfunction toArray(val: string | string[] | null | undefined): string[] {\n if (val == null) return []\n return Array.isArray(val) ? [...val] : [val]\n}\n\nwatch(\n () => props.modelValue,\n (v) => {\n selection.value = toArray(v)\n },\n)\n\nwatch(isOpen, (open) => {\n if (open) {\n filterText.value = ''\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n if (cfg.value.lazy) buffer.value = [...selection.value]\n }\n})\n\n// Display\nconst selectedLabel = computed(() => {\n if (selection.value.length === 0) return null\n if (!cfg.value.multiple)\n return props.options.find((o) => o.value === selection.value[0])?.label ?? null\n if (selection.value.length > 2) return `${selection.value.length} kiválasztva`\n return selection.value.map((v) => props.options.find((o) => o.value === v)?.label ?? v).join(', ')\n})\n\nconst filteredOptions = computed(() => {\n const q = filterText.value.toLowerCase()\n return q ? props.options.filter((o) => o.label.toLowerCase().includes(q)) : props.options\n})\n\nconst selectableOptions = computed(() => {\n return filteredOptions.value.filter((o) => o.value)\n})\n\nconst allOptionsSelected = computed(() => {\n if (selectableOptions.value.length === 0) return false\n const currentList = cfg.value.lazy && isOpen.value ? buffer.value : selection.value\n return selectableOptions.value.every((o) => o.value && currentList.includes(o.value))\n})\n\nfunction isSelected(value: string): boolean {\n return (cfg.value.lazy && isOpen.value ? buffer : selection).value.includes(value)\n}\n\nfunction toggleAllOptions() {\n const currentList = cfg.value.lazy && isOpen.value ? buffer : selection\n const selectableValues = selectableOptions.value.map((o) => o.value as string)\n\n if (allOptionsSelected.value) {\n currentList.value = currentList.value.filter((v) => !selectableValues.includes(v))\n } else {\n const toAdd = selectableValues.filter((v) => !currentList.value.includes(v))\n currentList.value = [...currentList.value, ...toAdd]\n }\n\n if (!cfg.value.lazy) {\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n}\n\n// Actions\nfunction toggleList(list: string[], value: string): string[] {\n const idx = list.indexOf(value)\n return idx >= 0 ? list.filter((_, i) => i !== idx) : [...list, value]\n}\n\nfunction selectOption(opt: DropdownOption) {\n if (opt.callback) {\n opt.callback()\n isOpen.value = false\n return\n }\n\n const value = opt.value\n if (!value) return\n\n if (cfg.value.multiple) {\n if (cfg.value.lazy) {\n buffer.value = toggleList(buffer.value, value)\n } else {\n selection.value = toggleList(selection.value, value)\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n } else {\n selection.value = [value]\n emit('update:modelValue', value)\n isOpen.value = false\n }\n}\n\nfunction confirm() {\n if (cfg.value.lazy) {\n selection.value = [...buffer.value]\n emit('update:modelValue', buffer.value.length > 0 ? [...buffer.value] : null)\n }\n isOpen.value = false\n}\n\nfunction clear() {\n if (cfg.value.lazy) {\n buffer.value = []\n } else {\n selection.value = []\n emit('update:modelValue', null)\n }\n}\n\nfunction onOptionKeydown(e: KeyboardEvent, opt: DropdownOption) {\n if (e.key === ' ') {\n e.preventDefault()\n selectOption(opt)\n } else if (e.key === 'Enter') {\n e.preventDefault()\n confirm()\n }\n}\n\nfunction onClickOutside(e: MouseEvent) {\n if (wrapperRef.value && !wrapperRef.value.contains(e.target as Node)) isOpen.value = false\n}\n\nonMounted(() => document.addEventListener('mousedown', onClickOutside))\nonBeforeUnmount(() => document.removeEventListener('mousedown', onClickOutside))\n\nfunction toggleOpen() {\n isOpen.value = !isOpen.value\n if (isOpen.value) filterText.value = ''\n}\n\nfunction clearInput() {\n selection.value = []\n emit('update:modelValue', null)\n isOpen.value = false\n}\n\nfunction focusAndOpen() {\n isOpen.value = true\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n}\n\ndefineExpose({ focusAndOpen })\n</script>\n\n<template>\n <div class=\"ac-component\">\n <div ref=\"wrapperRef\" class=\"c-wrapper ds-wrapper\">\n <div\n class=\"c-input-row pointer\"\n :class=\"{\n 'c-input-row--sm': cfg.size === 'small',\n 'c-input-row--lg': cfg.size === 'large',\n }\"\n @click=\"toggleOpen()\"\n >\n <span v-if=\"selectedLabel\" class=\"c-truncate ds-value\">{{ selectedLabel }}</span>\n <span v-else class=\"c-placeholder\">{{ cfg.placeholder }}</span>\n <button\n v-if=\"cfg.clearable && selection.length > 0\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-clear-btn\"\n @click.stop=\"clearInput()\"\n aria-label=\"Törlés\"\n >\n <i class=\"fa-solid fa-fw fa-xmark\"></i>\n </button>\n <span\n class=\"c-icon-btn c-icon-btn--chevron mr-2\"\n :class=\"{ 'c-icon-btn--chevron-open': isOpen }\"\n >\n <i class=\"fa-solid fa-fw fa-chevron-down\"></i>\n </span>\n </div>\n\n <div\n v-if=\"isOpen\"\n class=\"c-dropdown ds-dropdown ac-component\"\n :class=\"{ 'ds-dropdown--multiple': cfg.multiple }\"\n >\n <div v-if=\"cfg.filterable\" class=\"ds-filter\">\n <span\n v-if=\"cfg.multiple\"\n class=\"c-checkbox ds-select-all-checkbox\"\n :class=\"{ 'c-checkbox--checked': allOptionsSelected }\"\n @click.stop=\"toggleAllOptions()\"\n :title=\"allOptionsSelected ? 'Összes kijelölés törlése' : 'Összes kijelölése'\"\n ></span>\n <input\n ref=\"filterInputRef\"\n type=\"text\"\n id=\"ds-filter-input\"\n class=\"c-focus ds-filter-input\"\n v-model=\"filterText\"\n placeholder=\"Filter...\"\n @click.stop\n />\n <button\n v-if=\"filterText\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-filter-clear\"\n @click.stop=\"filterText = ''\"\n aria-label=\"Szűrők törlése\"\n >\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <ul class=\"ds-options c-scroll\">\n <li\n v-for=\"(opt, idx) in filteredOptions\"\n :key=\"opt.value ?? `cb-${idx}`\"\n class=\"d-option ds-option\"\n :class=\"{ 'ds-option--selected': opt.value && isSelected(opt.value) }\"\n tabindex=\"0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt)\"\n >\n <span\n v-if=\"cfg.multiple && opt.value\"\n class=\"c-checkbox\"\n :class=\"{ 'c-checkbox--checked': isSelected(opt.value) }\"\n ></span>\n <i v-if=\"opt.icon\" class=\"fa-fw\" :class=\"opt.icon\"></i>\n <span class=\"d-option__label\" :class=\"{ 'c-truncate': cfg.textEllipsis }\">{{\n opt.label\n }}</span>\n </li>\n <li v-if=\"filteredOptions.length === 0\" class=\"ds-option ds-option--empty\">\n Nincs találat\n </li>\n </ul>\n\n <div v-if=\"cfg.multiple || (cfg.clearable && selection.length > 0)\" class=\"c-footer\">\n <Button v-if=\"cfg.clearable\" label=\"Törlés\" outline @click=\"clear\" />\n <Button v-if=\"cfg.multiple\" label=\"OK\" type=\"success\" @click=\"confirm\" />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/dropdown-select.scss\"></style>\n"],"mappings":""}
1
+ {"version":3,"file":"admins-components25.js","names":[],"sources":["../src/components/DropdownSelect.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface DropdownSelectConfig {\n placeholder?: string\n filterable?: boolean\n clearable?: boolean\n textEllipsis?: boolean\n multiple?: boolean\n lazy?: boolean\n size?: ControlSize\n}\n\nexport const dropdownSelectConfigDefaults: DropdownSelectConfig = {\n placeholder: 'Select...',\n filterable: true,\n clearable: true,\n textEllipsis: true,\n multiple: false,\n lazy: false,\n size: 'normal' as ControlSize\n}\n\nexport interface DropdownOption {\n icon?: string\n value?: string\n label: string\n callback?: () => void\n}\n\nexport interface DropdownSelectProps {\n modelValue?: string | string[] | null\n options: DropdownOption[]\n config?: DropdownSelectConfig\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'\nimport Button from '@/components/Button.vue'\nimport type { ControlSize } from '@/types/types'\nimport { debounce } from '@/utils/debounce'\n\nconst props = withDefaults(defineProps<DropdownSelectProps>(), {\n modelValue: null,\n config: () => ({ ...dropdownSelectConfigDefaults }),\n})\n\nconst cfg = computed(() => ({ ...dropdownSelectConfigDefaults, ...props.config }))\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | null]\n 'filter-input': [filterText: string]\n}>()\n\nconst isOpen = ref(false)\nconst filterText = ref('')\nconst wrapperRef = ref<HTMLElement | null>(null)\nconst filterInputRef = ref<HTMLInputElement | null>(null)\nconst buffer = ref<string[]>([])\nconst selection = ref<string[]>(toArray(props.modelValue))\n\nfunction toArray(val: string | string[] | null | undefined): string[] {\n if (val == null) return []\n return Array.isArray(val) ? [...val] : [val]\n}\n\nwatch(\n () => props.modelValue,\n (v) => {\n selection.value = toArray(v)\n },\n)\n\nwatch(isOpen, (open) => {\n if (open) {\n filterText.value = ''\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n if (cfg.value.lazy) buffer.value = [...selection.value]\n }\n})\n\nfunction onFilterInput(text: string) {\n filterText.value = text\n debouncedEmit(text)\n}\n\nconst debouncedEmit = debounce((raw: string) => {\n emit('filter-input', raw)\n})\n\n// Display\nconst selectedLabel = computed(() => {\n if (selection.value.length === 0) return null\n if (!cfg.value.multiple)\n return props.options.find((o) => o.value === selection.value[0])?.label ?? null\n if (selection.value.length > 2) return `${selection.value.length} kiválasztva`\n return selection.value.map((v) => props.options.find((o) => o.value === v)?.label ?? v).join(', ')\n})\n\nconst filteredOptions = computed(() => {\n const q = filterText.value.toLowerCase()\n return q ? props.options.filter((o) => o.label.toLowerCase().includes(q)) : props.options\n})\n\nconst selectableOptions = computed(() => {\n return filteredOptions.value.filter((o) => o.value)\n})\n\nconst allOptionsSelected = computed(() => {\n if (selectableOptions.value.length === 0) return false\n const currentList = cfg.value.lazy && isOpen.value ? buffer.value : selection.value\n return selectableOptions.value.every((o) => o.value && currentList.includes(o.value))\n})\n\nfunction isSelected(value: string): boolean {\n return (cfg.value.lazy && isOpen.value ? buffer : selection).value.includes(value)\n}\n\nfunction toggleAllOptions() {\n const currentList = cfg.value.lazy && isOpen.value ? buffer : selection\n const selectableValues = selectableOptions.value.map((o) => o.value as string)\n\n if (allOptionsSelected.value) {\n currentList.value = currentList.value.filter((v) => !selectableValues.includes(v))\n } else {\n const toAdd = selectableValues.filter((v) => !currentList.value.includes(v))\n currentList.value = [...currentList.value, ...toAdd]\n }\n\n if (!cfg.value.lazy) {\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n}\n\n// Actions\nfunction toggleList(list: string[], value: string): string[] {\n const idx = list.indexOf(value)\n return idx >= 0 ? list.filter((_, i) => i !== idx) : [...list, value]\n}\n\nfunction selectOption(opt: DropdownOption) {\n if (opt.callback) {\n opt.callback()\n isOpen.value = false\n return\n }\n\n const value = opt.value\n if (!value) return\n\n if (cfg.value.multiple) {\n if (cfg.value.lazy) {\n buffer.value = toggleList(buffer.value, value)\n } else {\n selection.value = toggleList(selection.value, value)\n emit('update:modelValue', selection.value.length > 0 ? [...selection.value] : null)\n }\n } else {\n selection.value = [value]\n emit('update:modelValue', value)\n isOpen.value = false\n }\n}\n\nfunction confirm() {\n if (cfg.value.lazy) {\n selection.value = [...buffer.value]\n emit('update:modelValue', buffer.value.length > 0 ? [...buffer.value] : null)\n }\n isOpen.value = false\n}\n\nfunction clear() {\n if (cfg.value.lazy) {\n buffer.value = []\n } else {\n selection.value = []\n emit('update:modelValue', null)\n }\n}\n\nfunction onOptionKeydown(e: KeyboardEvent, opt: DropdownOption) {\n if (e.key === ' ') {\n e.preventDefault()\n selectOption(opt)\n } else if (e.key === 'Enter') {\n e.preventDefault()\n confirm()\n }\n}\n\nfunction onClickOutside(e: MouseEvent) {\n if (wrapperRef.value && !wrapperRef.value.contains(e.target as Node)) isOpen.value = false\n}\n\nonMounted(() => document.addEventListener('mousedown', onClickOutside))\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', onClickOutside)\n})\n\nfunction toggleOpen() {\n isOpen.value = !isOpen.value\n if (isOpen.value) filterText.value = ''\n}\n\nfunction clearInput() {\n selection.value = []\n emit('update:modelValue', null)\n isOpen.value = false\n}\n\nfunction focusAndOpen() {\n isOpen.value = true\n if (cfg.value.filterable) nextTick(() => filterInputRef.value?.focus())\n}\n\ndefineExpose({ focusAndOpen })\n</script>\n\n<template>\n <div class=\"ac-component\">\n <div ref=\"wrapperRef\" class=\"c-wrapper ds-wrapper\">\n <div\n class=\"c-input-row pointer\"\n :class=\"{\n 'c-input-row--sm': cfg.size === 'small',\n 'c-input-row--lg': cfg.size === 'large',\n }\"\n @click=\"toggleOpen()\"\n >\n <span v-if=\"selectedLabel\" class=\"c-truncate ds-value\">{{ selectedLabel }}</span>\n <span v-else class=\"c-placeholder\">{{ cfg.placeholder }}</span>\n <button\n v-if=\"cfg.clearable && selection.length > 0\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-clear-btn\"\n @click.stop=\"clearInput()\"\n aria-label=\"Törlés\"\n >\n <i class=\"fa-solid fa-fw fa-xmark\"></i>\n </button>\n <span\n class=\"c-icon-btn c-icon-btn--chevron mr-2\"\n :class=\"{ 'c-icon-btn--chevron-open': isOpen }\"\n >\n <i class=\"fa-solid fa-fw fa-chevron-down\"></i>\n </span>\n </div>\n\n <div\n v-if=\"isOpen\"\n class=\"c-dropdown ds-dropdown ac-component\"\n :class=\"{ 'ds-dropdown--multiple': cfg.multiple }\"\n >\n <div v-if=\"cfg.filterable\" class=\"ds-filter\">\n <span\n v-if=\"cfg.multiple\"\n class=\"c-checkbox ds-select-all-checkbox\"\n :class=\"{ 'c-checkbox--checked': allOptionsSelected }\"\n @click.stop=\"toggleAllOptions()\"\n :title=\"allOptionsSelected ? 'Összes kijelölés törlése' : 'Összes kijelölése'\"\n ></span>\n <input\n ref=\"filterInputRef\"\n type=\"text\"\n id=\"ds-filter-input\"\n class=\"c-focus ds-filter-input\"\n :value=\"filterText\"\n @input=\"onFilterInput(($event.target as HTMLInputElement).value)\"\n placeholder=\"Filter...\"\n @click.stop\n />\n <button\n v-if=\"filterText\"\n type=\"button\"\n class=\"c-icon-btn c-icon-btn--clear ds-filter-clear\"\n @click.stop=\"filterText = ''\"\n aria-label=\"Szűrők törlése\"\n >\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <ul class=\"ds-options c-scroll\">\n <li\n v-for=\"(opt, idx) in filteredOptions\"\n :key=\"opt.value ?? `cb-${idx}`\"\n class=\"d-option ds-option\"\n :class=\"{ 'ds-option--selected': opt.value && isSelected(opt.value) }\"\n tabindex=\"0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt)\"\n >\n <span\n v-if=\"cfg.multiple && opt.value\"\n class=\"c-checkbox\"\n :class=\"{ 'c-checkbox--checked': isSelected(opt.value) }\"\n ></span>\n <i v-if=\"opt.icon\" class=\"fa-fw\" :class=\"opt.icon\"></i>\n <span class=\"d-option__label\" :class=\"{ 'c-truncate': cfg.textEllipsis }\">{{\n opt.label\n }}</span>\n </li>\n <li v-if=\"filteredOptions.length === 0\" class=\"ds-option ds-option--empty\">\n Nincs találat\n </li>\n </ul>\n\n <div v-if=\"cfg.multiple || (cfg.clearable && selection.length > 0)\" class=\"c-footer\">\n <Button v-if=\"cfg.clearable\" label=\"Törlés\" outline @click=\"clear\" />\n <Button v-if=\"cfg.multiple\" label=\"OK\" type=\"success\" @click=\"confirm\" />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/dropdown-select.scss\"></style>\n"],"mappings":""}
@@ -105,6 +105,9 @@ var E = {
105
105
  function Y(e) {
106
106
  e.key === "Enter" && e.target?.tagName !== "TEXTAREA" && (e.preventDefault(), W());
107
107
  }
108
+ function X(e, t) {
109
+ e.dropdownFilterCallback && e.dropdownFilterCallback(t);
110
+ }
108
111
  return (s, c) => (x(), p(o, {
109
112
  open: v.open,
110
113
  title: "Szűrők",
@@ -186,11 +189,13 @@ var E = {
186
189
  clearable: !0,
187
190
  filterable: !0
188
191
  },
192
+ onFilterInput: (t) => X(e, t),
189
193
  "onUpdate:modelValue": (t) => B(e.key, t)
190
194
  }, null, 8, [
191
195
  "model-value",
192
196
  "options",
193
197
  "config",
198
+ "onFilterInput",
194
199
  "onUpdate:modelValue"
195
200
  ])], 64)) : m("", !0)], 2))), 128))], 32),
196
201
  g("div", A, [_(e, {
@@ -1 +1 @@
1
- {"version":3,"file":"admins-components82.js","names":[],"sources":["../src/components/data-table/DataFilters.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { DropdownOption } from '@/components/DropdownSelect.vue'\n\nexport interface FilterItem {\n type: FilterItemType\n key: string\n label?: string\n placeholder?: string\n value?: any\n options?: DropdownOption[]\n fullWidth?: boolean\n config?: Record<string, any>\n displayClass?: string\n transformer?: (value: any) => Record<string, any> | null | undefined\n}\n\nexport interface FilterResponse {\n values: Record<string, any>\n transformed: Record<string, any>\n}\n\nexport interface DataFiltersProps {\n items: FilterItem[]\n open?: boolean\n position?: SidebarPosition\n lazy?: boolean\n handleUrl?: boolean\n historyEnabled?: boolean\n storageKey?: string\n}\n\n\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport Sidebar, { type SidebarPosition } from '@/components/Sidebar.vue'\nimport DatePicker from '@/components/DatePicker.vue'\nimport DateRangePicker from '@/components/DateRangePicker.vue'\nimport DropdownSelect from '@/components/DropdownSelect.vue'\nimport TextInput, { type TextInputType } from '@/components/TextInput.vue'\nimport Button from '@/components/Button.vue'\nimport Checkbox from '@/components/Checkbox.vue'\nimport FiltersHistory from '@/components/data-table/FiltersHistory.vue'\nimport type { DatePickerConfig, DateRangePickerConfig } from '@/types/datepickers'\nimport type { FilterItemType, PickedDate, PickedUtcRange } from '@/types/types'\nimport {\n filterEmptyValues,\n getDefaultFilters,\n writeFilterParams,\n} from '@/utils/dataFilters'\n\nconst props = withDefaults(defineProps<DataFiltersProps>(), {\n open: false,\n position: 'left',\n lazy: true,\n handleUrl: false,\n historyEnabled: true,\n})\n\nconst emit = defineEmits<{\n close: []\n change: [response: FilterResponse]\n}>()\n\nconst values = ref<Record<string, any>>(getDefaultFilters(props.items, props.storageKey, false))\nconst filterRefs = ref<Record<string, any>>({})\n\nfunction setFilterRef(key: string, el: any) {\n if (el) filterRefs.value[key] = el\n else delete filterRefs.value[key]\n}\n\nfunction buildDatePickerConfig(item: FilterItem): DatePickerConfig {\n return {\n ...(item.config ?? {}),\n showTime: item.type === 'datetime',\n placeholder: item.placeholder ?? (item.type === 'datetime' ? 'Időpont' : 'Dátum'),\n }\n}\n\nfunction buildDateRangePickerConfig(item: FilterItem): DateRangePickerConfig {\n return {\n ...(item.config ?? {}),\n ...(!item.fullWidth ? { compact: true } : {}),\n showTime: item.type === 'datetimerange',\n }\n}\n\nfunction update(key: string, value: any) {\n values.value = { ...values.value, [key]: value }\n if (!props.lazy) emitChange()\n}\n\nconst hasActiveFilters = computed(() =>\n Object.values(values.value).some((v) => v !== null && v !== '' && v !== undefined),\n)\n\nfunction buildResponse(): FilterResponse {\n const transformed: Record<string, any> = {}\n for (const item of props.items) {\n if (item.type === 'separator') continue\n const val = values.value[item.key]\n if (item.transformer) Object.assign(transformed, item.transformer(val) ?? {})\n else transformed[item.key] = val\n }\n return { values: filterEmptyValues(values.value), transformed: filterEmptyValues(transformed) }\n}\n\nfunction emitChange() {\n if (props.handleUrl) writeFilterParams(props.items, values.value)\n emit('change', buildResponse())\n}\n\nfunction confirm() {\n emitChange()\n emit('close')\n}\n\nfunction clearAll() {\n values.value = {}\n emitChange()\n}\n\nfunction clearFilter(key: string) {\n values.value = { ...values.value, [key]: null }\n emitChange()\n}\n\nfunction focusFilter(key: string) {\n const el = (filterRefs.value as Record<string, any>)[key]\n if (!el) return\n\n if (typeof el.focusAndOpen === 'function') el.focusAndOpen()\n else if (typeof el.focus === 'function') el.focus()\n}\n\nfunction onHistoryLoad(loaded: Record<string, any>) {\n const next: Record<string, any> = { ...values.value }\n for (const item of props.items) {\n if (item.type === 'separator') continue\n if (item.key in loaded) next[item.key] = loaded[item.key] ?? null\n }\n values.value = next\n emitChange()\n}\n\ndefineExpose({ clearFilter, focusFilter })\n\nfunction handleFilterKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter') return\n\n // Allow Enter in textarea for line breaks\n const target = event.target as HTMLElement\n if (target?.tagName === 'TEXTAREA') return\n\n event.preventDefault()\n confirm()\n}\n</script>\n\n<template>\n <Sidebar :open=\"open\" title=\"Szűrők\" :position=\"position\" @close=\"emit('close')\">\n <div class=\"data-filters\" @keydown=\"handleFilterKeydown\">\n <div\n v-for=\"item in items\"\n :key=\"item.key\"\n class=\"data-filters__field\"\n :class=\"{ 'data-filters__field--full': item.fullWidth || item.type === 'separator' }\"\n >\n <hr v-if=\"item.type === 'separator'\" class=\"data-filters__separator\" />\n <template v-else-if=\"item.type === 'checkbox'\">\n <Checkbox\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as boolean) ?? false\"\n :label=\"item.label ?? item.key\"\n @update:model-value=\"(val) => update(item.key, val)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"['text', 'number', 'textarea'].includes(item.type)\">\n <TextInput\n :type=\"item.type as TextInputType\"\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as string) ?? ''\"\n :label=\"item.label ?? item.key\"\n :placeholder=\"item.placeholder\"\n @update:model-value=\"(val) => update(item.key, val || null)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"item.type === 'date' || item.type === 'datetime'\">\n <label class=\"c-label\" :for=\"`df-${item.key}`\">{{ item.label ?? item.key }}</label>\n <DatePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as PickedDate) ?? null\"\n :config=\"buildDatePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'daterange' || item.type === 'datetimerange'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DateRangePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as PickedUtcRange) ?? null\"\n :config=\"buildDateRangePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'dropdown'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DropdownSelect\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as string) ?? null\"\n :options=\"item.options ?? []\"\n :config=\"{\n ...(item.config ?? {}),\n placeholder: item.placeholder ?? 'Válassz...',\n clearable: true,\n filterable: true,\n }\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n </div>\n </div>\n <div class=\"data-filters__footer\">\n <Button\n icon=\"fa-solid fa-trash-can\"\n :disabled=\"!hasActiveFilters\"\n label=\"Szűrők törlése\"\n aria-label=\"Szűrők törlése\"\n size=\"small\"\n @click=\"clearAll\"\n />\n <Button label=\"Szűrés\" aria-label=\"Szűrés\" type=\"success\" @click=\"confirm\" />\n </div>\n <template v-if=\"historyEnabled\">\n <hr class=\"separator my-3\" />\n <FiltersHistory\n :items=\"items\"\n :values=\"values\"\n :storage-key=\"storageKey\"\n @load=\"onHistoryLoad\"\n />\n </template>\n </Sidebar>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/data-table/data-filters.scss\"></style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"admins-components82.js","names":[],"sources":["../src/components/data-table/DataFilters.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { DropdownOption } from '@/components/DropdownSelect.vue'\n\nexport interface FilterItem {\n type: FilterItemType\n key: string\n label?: string\n placeholder?: string\n value?: any\n options?: DropdownOption[]\n fullWidth?: boolean\n config?: Record<string, any>\n displayClass?: string\n transformer?: (value: any) => Record<string, any> | null | undefined\n dropdownFilterCallback?: (value: string) => void\n}\n\nexport interface FilterResponse {\n values: Record<string, any>\n transformed: Record<string, any>\n}\n\nexport interface DataFiltersProps {\n items: FilterItem[]\n open?: boolean\n position?: SidebarPosition\n lazy?: boolean\n handleUrl?: boolean\n historyEnabled?: boolean\n storageKey?: string\n}\n\n\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport Sidebar, { type SidebarPosition } from '@/components/Sidebar.vue'\nimport DatePicker from '@/components/DatePicker.vue'\nimport DateRangePicker from '@/components/DateRangePicker.vue'\nimport DropdownSelect from '@/components/DropdownSelect.vue'\nimport TextInput, { type TextInputType } from '@/components/TextInput.vue'\nimport Button from '@/components/Button.vue'\nimport Checkbox from '@/components/Checkbox.vue'\nimport FiltersHistory from '@/components/data-table/FiltersHistory.vue'\nimport type { DatePickerConfig, DateRangePickerConfig } from '@/types/datepickers'\nimport type { FilterItemType, PickedDate, PickedUtcRange } from '@/types/types'\nimport {\n filterEmptyValues,\n getDefaultFilters,\n writeFilterParams,\n} from '@/utils/dataFilters'\n\nconst props = withDefaults(defineProps<DataFiltersProps>(), {\n open: false,\n position: 'left',\n lazy: true,\n handleUrl: false,\n historyEnabled: true,\n})\n\nconst emit = defineEmits<{\n close: []\n change: [response: FilterResponse]\n}>()\n\nconst values = ref<Record<string, any>>(getDefaultFilters(props.items, props.storageKey, false))\nconst filterRefs = ref<Record<string, any>>({})\n\nfunction setFilterRef(key: string, el: any) {\n if (el) filterRefs.value[key] = el\n else delete filterRefs.value[key]\n}\n\nfunction buildDatePickerConfig(item: FilterItem): DatePickerConfig {\n return {\n ...(item.config ?? {}),\n showTime: item.type === 'datetime',\n placeholder: item.placeholder ?? (item.type === 'datetime' ? 'Időpont' : 'Dátum'),\n }\n}\n\nfunction buildDateRangePickerConfig(item: FilterItem): DateRangePickerConfig {\n return {\n ...(item.config ?? {}),\n ...(!item.fullWidth ? { compact: true } : {}),\n showTime: item.type === 'datetimerange',\n }\n}\n\nfunction update(key: string, value: any) {\n values.value = { ...values.value, [key]: value }\n if (!props.lazy) emitChange()\n}\n\nconst hasActiveFilters = computed(() =>\n Object.values(values.value).some((v) => v !== null && v !== '' && v !== undefined),\n)\n\nfunction buildResponse(): FilterResponse {\n const transformed: Record<string, any> = {}\n for (const item of props.items) {\n if (item.type === 'separator') continue\n const val = values.value[item.key]\n if (item.transformer) Object.assign(transformed, item.transformer(val) ?? {})\n else transformed[item.key] = val\n }\n return { values: filterEmptyValues(values.value), transformed: filterEmptyValues(transformed) }\n}\n\nfunction emitChange() {\n if (props.handleUrl) writeFilterParams(props.items, values.value)\n emit('change', buildResponse())\n}\n\nfunction confirm() {\n emitChange()\n emit('close')\n}\n\nfunction clearAll() {\n values.value = {}\n emitChange()\n}\n\nfunction clearFilter(key: string) {\n values.value = { ...values.value, [key]: null }\n emitChange()\n}\n\nfunction focusFilter(key: string) {\n const el = (filterRefs.value as Record<string, any>)[key]\n if (!el) return\n\n if (typeof el.focusAndOpen === 'function') el.focusAndOpen()\n else if (typeof el.focus === 'function') el.focus()\n}\n\nfunction onHistoryLoad(loaded: Record<string, any>) {\n const next: Record<string, any> = { ...values.value }\n for (const item of props.items) {\n if (item.type === 'separator') continue\n if (item.key in loaded) next[item.key] = loaded[item.key] ?? null\n }\n values.value = next\n emitChange()\n}\n\ndefineExpose({ clearFilter, focusFilter })\n\nfunction handleFilterKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter') return\n\n // Allow Enter in textarea for line breaks\n const target = event.target as HTMLElement\n if (target?.tagName === 'TEXTAREA') return\n\n event.preventDefault()\n confirm()\n}\n\nfunction handleDropdownFilterInput(item: FilterItem, text: string) {\n if (item.dropdownFilterCallback) item.dropdownFilterCallback(text)\n}\n</script>\n\n<template>\n <Sidebar :open=\"open\" title=\"Szűrők\" :position=\"position\" @close=\"emit('close')\">\n <div class=\"data-filters\" @keydown=\"handleFilterKeydown\">\n <div\n v-for=\"item in items\"\n :key=\"item.key\"\n class=\"data-filters__field\"\n :class=\"{ 'data-filters__field--full': item.fullWidth || item.type === 'separator' }\"\n >\n <hr v-if=\"item.type === 'separator'\" class=\"data-filters__separator\" />\n <template v-else-if=\"item.type === 'checkbox'\">\n <Checkbox\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as boolean) ?? false\"\n :label=\"item.label ?? item.key\"\n @update:model-value=\"(val) => update(item.key, val)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"['text', 'number', 'textarea'].includes(item.type)\">\n <TextInput\n :type=\"item.type as TextInputType\"\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as string) ?? ''\"\n :label=\"item.label ?? item.key\"\n :placeholder=\"item.placeholder\"\n @update:model-value=\"(val) => update(item.key, val || null)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"item.type === 'date' || item.type === 'datetime'\">\n <label class=\"c-label\" :for=\"`df-${item.key}`\">{{ item.label ?? item.key }}</label>\n <DatePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as PickedDate) ?? null\"\n :config=\"buildDatePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'daterange' || item.type === 'datetimerange'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DateRangePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as PickedUtcRange) ?? null\"\n :config=\"buildDateRangePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'dropdown'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DropdownSelect\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as string) ?? null\"\n :options=\"item.options ?? []\"\n :config=\"{\n ...(item.config ?? {}),\n placeholder: item.placeholder ?? 'Válassz...',\n clearable: true,\n filterable: true,\n }\"\n @filter-input=\"handleDropdownFilterInput(item, $event)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n </div>\n </div>\n <div class=\"data-filters__footer\">\n <Button\n icon=\"fa-solid fa-trash-can\"\n :disabled=\"!hasActiveFilters\"\n label=\"Szűrők törlése\"\n aria-label=\"Szűrők törlése\"\n size=\"small\"\n @click=\"clearAll\"\n />\n <Button label=\"Szűrés\" aria-label=\"Szűrés\" type=\"success\" @click=\"confirm\" />\n </div>\n <template v-if=\"historyEnabled\">\n <hr class=\"separator my-3\" />\n <FiltersHistory\n :items=\"items\"\n :values=\"values\"\n :storage-key=\"storageKey\"\n @load=\"onHistoryLoad\"\n />\n </template>\n </Sidebar>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/data-table/data-filters.scss\"></style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"admins-components84.js","names":[],"sources":["../src/components/data-table/DataFilters.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { DropdownOption } from '@/components/DropdownSelect.vue'\n\nexport interface FilterItem {\n type: FilterItemType\n key: string\n label?: string\n placeholder?: string\n value?: any\n options?: DropdownOption[]\n fullWidth?: boolean\n config?: Record<string, any>\n displayClass?: string\n transformer?: (value: any) => Record<string, any> | null | undefined\n}\n\nexport interface FilterResponse {\n values: Record<string, any>\n transformed: Record<string, any>\n}\n\nexport interface DataFiltersProps {\n items: FilterItem[]\n open?: boolean\n position?: SidebarPosition\n lazy?: boolean\n handleUrl?: boolean\n historyEnabled?: boolean\n storageKey?: string\n}\n\n\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport Sidebar, { type SidebarPosition } from '@/components/Sidebar.vue'\nimport DatePicker from '@/components/DatePicker.vue'\nimport DateRangePicker from '@/components/DateRangePicker.vue'\nimport DropdownSelect from '@/components/DropdownSelect.vue'\nimport TextInput, { type TextInputType } from '@/components/TextInput.vue'\nimport Button from '@/components/Button.vue'\nimport Checkbox from '@/components/Checkbox.vue'\nimport FiltersHistory from '@/components/data-table/FiltersHistory.vue'\nimport type { DatePickerConfig, DateRangePickerConfig } from '@/types/datepickers'\nimport type { FilterItemType, PickedDate, PickedUtcRange } from '@/types/types'\nimport {\n filterEmptyValues,\n getDefaultFilters,\n writeFilterParams,\n} from '@/utils/dataFilters'\n\nconst props = withDefaults(defineProps<DataFiltersProps>(), {\n open: false,\n position: 'left',\n lazy: true,\n handleUrl: false,\n historyEnabled: true,\n})\n\nconst emit = defineEmits<{\n close: []\n change: [response: FilterResponse]\n}>()\n\nconst values = ref<Record<string, any>>(getDefaultFilters(props.items, props.storageKey, false))\nconst filterRefs = ref<Record<string, any>>({})\n\nfunction setFilterRef(key: string, el: any) {\n if (el) filterRefs.value[key] = el\n else delete filterRefs.value[key]\n}\n\nfunction buildDatePickerConfig(item: FilterItem): DatePickerConfig {\n return {\n ...(item.config ?? {}),\n showTime: item.type === 'datetime',\n placeholder: item.placeholder ?? (item.type === 'datetime' ? 'Időpont' : 'Dátum'),\n }\n}\n\nfunction buildDateRangePickerConfig(item: FilterItem): DateRangePickerConfig {\n return {\n ...(item.config ?? {}),\n ...(!item.fullWidth ? { compact: true } : {}),\n showTime: item.type === 'datetimerange',\n }\n}\n\nfunction update(key: string, value: any) {\n values.value = { ...values.value, [key]: value }\n if (!props.lazy) emitChange()\n}\n\nconst hasActiveFilters = computed(() =>\n Object.values(values.value).some((v) => v !== null && v !== '' && v !== undefined),\n)\n\nfunction buildResponse(): FilterResponse {\n const transformed: Record<string, any> = {}\n for (const item of props.items) {\n if (item.type === 'separator') continue\n const val = values.value[item.key]\n if (item.transformer) Object.assign(transformed, item.transformer(val) ?? {})\n else transformed[item.key] = val\n }\n return { values: filterEmptyValues(values.value), transformed: filterEmptyValues(transformed) }\n}\n\nfunction emitChange() {\n if (props.handleUrl) writeFilterParams(props.items, values.value)\n emit('change', buildResponse())\n}\n\nfunction confirm() {\n emitChange()\n emit('close')\n}\n\nfunction clearAll() {\n values.value = {}\n emitChange()\n}\n\nfunction clearFilter(key: string) {\n values.value = { ...values.value, [key]: null }\n emitChange()\n}\n\nfunction focusFilter(key: string) {\n const el = (filterRefs.value as Record<string, any>)[key]\n if (!el) return\n\n if (typeof el.focusAndOpen === 'function') el.focusAndOpen()\n else if (typeof el.focus === 'function') el.focus()\n}\n\nfunction onHistoryLoad(loaded: Record<string, any>) {\n const next: Record<string, any> = { ...values.value }\n for (const item of props.items) {\n if (item.type === 'separator') continue\n if (item.key in loaded) next[item.key] = loaded[item.key] ?? null\n }\n values.value = next\n emitChange()\n}\n\ndefineExpose({ clearFilter, focusFilter })\n\nfunction handleFilterKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter') return\n\n // Allow Enter in textarea for line breaks\n const target = event.target as HTMLElement\n if (target?.tagName === 'TEXTAREA') return\n\n event.preventDefault()\n confirm()\n}\n</script>\n\n<template>\n <Sidebar :open=\"open\" title=\"Szűrők\" :position=\"position\" @close=\"emit('close')\">\n <div class=\"data-filters\" @keydown=\"handleFilterKeydown\">\n <div\n v-for=\"item in items\"\n :key=\"item.key\"\n class=\"data-filters__field\"\n :class=\"{ 'data-filters__field--full': item.fullWidth || item.type === 'separator' }\"\n >\n <hr v-if=\"item.type === 'separator'\" class=\"data-filters__separator\" />\n <template v-else-if=\"item.type === 'checkbox'\">\n <Checkbox\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as boolean) ?? false\"\n :label=\"item.label ?? item.key\"\n @update:model-value=\"(val) => update(item.key, val)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"['text', 'number', 'textarea'].includes(item.type)\">\n <TextInput\n :type=\"item.type as TextInputType\"\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as string) ?? ''\"\n :label=\"item.label ?? item.key\"\n :placeholder=\"item.placeholder\"\n @update:model-value=\"(val) => update(item.key, val || null)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"item.type === 'date' || item.type === 'datetime'\">\n <label class=\"c-label\" :for=\"`df-${item.key}`\">{{ item.label ?? item.key }}</label>\n <DatePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as PickedDate) ?? null\"\n :config=\"buildDatePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'daterange' || item.type === 'datetimerange'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DateRangePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as PickedUtcRange) ?? null\"\n :config=\"buildDateRangePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'dropdown'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DropdownSelect\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as string) ?? null\"\n :options=\"item.options ?? []\"\n :config=\"{\n ...(item.config ?? {}),\n placeholder: item.placeholder ?? 'Válassz...',\n clearable: true,\n filterable: true,\n }\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n </div>\n </div>\n <div class=\"data-filters__footer\">\n <Button\n icon=\"fa-solid fa-trash-can\"\n :disabled=\"!hasActiveFilters\"\n label=\"Szűrők törlése\"\n aria-label=\"Szűrők törlése\"\n size=\"small\"\n @click=\"clearAll\"\n />\n <Button label=\"Szűrés\" aria-label=\"Szűrés\" type=\"success\" @click=\"confirm\" />\n </div>\n <template v-if=\"historyEnabled\">\n <hr class=\"separator my-3\" />\n <FiltersHistory\n :items=\"items\"\n :values=\"values\"\n :storage-key=\"storageKey\"\n @load=\"onHistoryLoad\"\n />\n </template>\n </Sidebar>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/data-table/data-filters.scss\"></style>\n"],"mappings":""}
1
+ {"version":3,"file":"admins-components84.js","names":[],"sources":["../src/components/data-table/DataFilters.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { DropdownOption } from '@/components/DropdownSelect.vue'\n\nexport interface FilterItem {\n type: FilterItemType\n key: string\n label?: string\n placeholder?: string\n value?: any\n options?: DropdownOption[]\n fullWidth?: boolean\n config?: Record<string, any>\n displayClass?: string\n transformer?: (value: any) => Record<string, any> | null | undefined\n dropdownFilterCallback?: (value: string) => void\n}\n\nexport interface FilterResponse {\n values: Record<string, any>\n transformed: Record<string, any>\n}\n\nexport interface DataFiltersProps {\n items: FilterItem[]\n open?: boolean\n position?: SidebarPosition\n lazy?: boolean\n handleUrl?: boolean\n historyEnabled?: boolean\n storageKey?: string\n}\n\n\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport Sidebar, { type SidebarPosition } from '@/components/Sidebar.vue'\nimport DatePicker from '@/components/DatePicker.vue'\nimport DateRangePicker from '@/components/DateRangePicker.vue'\nimport DropdownSelect from '@/components/DropdownSelect.vue'\nimport TextInput, { type TextInputType } from '@/components/TextInput.vue'\nimport Button from '@/components/Button.vue'\nimport Checkbox from '@/components/Checkbox.vue'\nimport FiltersHistory from '@/components/data-table/FiltersHistory.vue'\nimport type { DatePickerConfig, DateRangePickerConfig } from '@/types/datepickers'\nimport type { FilterItemType, PickedDate, PickedUtcRange } from '@/types/types'\nimport {\n filterEmptyValues,\n getDefaultFilters,\n writeFilterParams,\n} from '@/utils/dataFilters'\n\nconst props = withDefaults(defineProps<DataFiltersProps>(), {\n open: false,\n position: 'left',\n lazy: true,\n handleUrl: false,\n historyEnabled: true,\n})\n\nconst emit = defineEmits<{\n close: []\n change: [response: FilterResponse]\n}>()\n\nconst values = ref<Record<string, any>>(getDefaultFilters(props.items, props.storageKey, false))\nconst filterRefs = ref<Record<string, any>>({})\n\nfunction setFilterRef(key: string, el: any) {\n if (el) filterRefs.value[key] = el\n else delete filterRefs.value[key]\n}\n\nfunction buildDatePickerConfig(item: FilterItem): DatePickerConfig {\n return {\n ...(item.config ?? {}),\n showTime: item.type === 'datetime',\n placeholder: item.placeholder ?? (item.type === 'datetime' ? 'Időpont' : 'Dátum'),\n }\n}\n\nfunction buildDateRangePickerConfig(item: FilterItem): DateRangePickerConfig {\n return {\n ...(item.config ?? {}),\n ...(!item.fullWidth ? { compact: true } : {}),\n showTime: item.type === 'datetimerange',\n }\n}\n\nfunction update(key: string, value: any) {\n values.value = { ...values.value, [key]: value }\n if (!props.lazy) emitChange()\n}\n\nconst hasActiveFilters = computed(() =>\n Object.values(values.value).some((v) => v !== null && v !== '' && v !== undefined),\n)\n\nfunction buildResponse(): FilterResponse {\n const transformed: Record<string, any> = {}\n for (const item of props.items) {\n if (item.type === 'separator') continue\n const val = values.value[item.key]\n if (item.transformer) Object.assign(transformed, item.transformer(val) ?? {})\n else transformed[item.key] = val\n }\n return { values: filterEmptyValues(values.value), transformed: filterEmptyValues(transformed) }\n}\n\nfunction emitChange() {\n if (props.handleUrl) writeFilterParams(props.items, values.value)\n emit('change', buildResponse())\n}\n\nfunction confirm() {\n emitChange()\n emit('close')\n}\n\nfunction clearAll() {\n values.value = {}\n emitChange()\n}\n\nfunction clearFilter(key: string) {\n values.value = { ...values.value, [key]: null }\n emitChange()\n}\n\nfunction focusFilter(key: string) {\n const el = (filterRefs.value as Record<string, any>)[key]\n if (!el) return\n\n if (typeof el.focusAndOpen === 'function') el.focusAndOpen()\n else if (typeof el.focus === 'function') el.focus()\n}\n\nfunction onHistoryLoad(loaded: Record<string, any>) {\n const next: Record<string, any> = { ...values.value }\n for (const item of props.items) {\n if (item.type === 'separator') continue\n if (item.key in loaded) next[item.key] = loaded[item.key] ?? null\n }\n values.value = next\n emitChange()\n}\n\ndefineExpose({ clearFilter, focusFilter })\n\nfunction handleFilterKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter') return\n\n // Allow Enter in textarea for line breaks\n const target = event.target as HTMLElement\n if (target?.tagName === 'TEXTAREA') return\n\n event.preventDefault()\n confirm()\n}\n\nfunction handleDropdownFilterInput(item: FilterItem, text: string) {\n if (item.dropdownFilterCallback) item.dropdownFilterCallback(text)\n}\n</script>\n\n<template>\n <Sidebar :open=\"open\" title=\"Szűrők\" :position=\"position\" @close=\"emit('close')\">\n <div class=\"data-filters\" @keydown=\"handleFilterKeydown\">\n <div\n v-for=\"item in items\"\n :key=\"item.key\"\n class=\"data-filters__field\"\n :class=\"{ 'data-filters__field--full': item.fullWidth || item.type === 'separator' }\"\n >\n <hr v-if=\"item.type === 'separator'\" class=\"data-filters__separator\" />\n <template v-else-if=\"item.type === 'checkbox'\">\n <Checkbox\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as boolean) ?? false\"\n :label=\"item.label ?? item.key\"\n @update:model-value=\"(val) => update(item.key, val)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"['text', 'number', 'textarea'].includes(item.type)\">\n <TextInput\n :type=\"item.type as TextInputType\"\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as string) ?? ''\"\n :label=\"item.label ?? item.key\"\n :placeholder=\"item.placeholder\"\n @update:model-value=\"(val) => update(item.key, val || null)\"\n v-bind=\"item.config\"\n />\n </template>\n <template v-else-if=\"item.type === 'date' || item.type === 'datetime'\">\n <label class=\"c-label\" :for=\"`df-${item.key}`\">{{ item.label ?? item.key }}</label>\n <DatePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :id=\"`df-${item.key}`\"\n :model-value=\"(values[item.key] as PickedDate) ?? null\"\n :config=\"buildDatePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'daterange' || item.type === 'datetimerange'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DateRangePicker\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as PickedUtcRange) ?? null\"\n :config=\"buildDateRangePickerConfig(item)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n <template v-else-if=\"item.type === 'dropdown'\">\n <span class=\"c-label\">{{ item.label ?? item.key }}</span>\n <DropdownSelect\n :ref=\"(el: any) => setFilterRef(item.key, el)\"\n :model-value=\"(values[item.key] as string) ?? null\"\n :options=\"item.options ?? []\"\n :config=\"{\n ...(item.config ?? {}),\n placeholder: item.placeholder ?? 'Válassz...',\n clearable: true,\n filterable: true,\n }\"\n @filter-input=\"handleDropdownFilterInput(item, $event)\"\n @update:model-value=\"update(item.key, $event)\"\n />\n </template>\n </div>\n </div>\n <div class=\"data-filters__footer\">\n <Button\n icon=\"fa-solid fa-trash-can\"\n :disabled=\"!hasActiveFilters\"\n label=\"Szűrők törlése\"\n aria-label=\"Szűrők törlése\"\n size=\"small\"\n @click=\"clearAll\"\n />\n <Button label=\"Szűrés\" aria-label=\"Szűrés\" type=\"success\" @click=\"confirm\" />\n </div>\n <template v-if=\"historyEnabled\">\n <hr class=\"separator my-3\" />\n <FiltersHistory\n :items=\"items\"\n :values=\"values\"\n :storage-key=\"storageKey\"\n @load=\"onHistoryLoad\"\n />\n </template>\n </Sidebar>\n</template>\n\n<style lang=\"scss\" src=\"@/styles/components/data-table/data-filters.scss\"></style>\n"],"mappings":""}
@@ -26,8 +26,10 @@ declare const __VLS_export: import('vue').DefineComponent<DropdownSelectProps, {
26
26
  focusAndOpen: () => void;
27
27
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
28
28
  "update:modelValue": (value: string | string[] | null) => any;
29
+ "filter-input": (filterText: string) => any;
29
30
  }, string, import('vue').PublicProps, Readonly<DropdownSelectProps> & Readonly<{
30
31
  "onUpdate:modelValue"?: ((value: string | string[] | null) => any) | undefined;
32
+ "onFilter-input"?: ((filterText: string) => any) | undefined;
31
33
  }>, {
32
34
  modelValue: string | string[] | null;
33
35
  config: DropdownSelectConfig;
@@ -12,6 +12,7 @@ export interface FilterItem {
12
12
  config?: Record<string, any>;
13
13
  displayClass?: string;
14
14
  transformer?: (value: any) => Record<string, any> | null | undefined;
15
+ dropdownFilterCallback?: (value: string) => void;
15
16
  }
16
17
  export interface FilterResponse {
17
18
  values: Record<string, any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "admins-components",
3
- "version": "9.0.36",
3
+ "version": "9.0.38",
4
4
  "type": "module",
5
5
  "module": "./dist/admins-components.js",
6
6
  "types": "./dist/index.d.ts",