lkt-item-crud 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/build.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- declare function qe(t?: boolean): void;
2
- declare namespace Ae {
3
- function install(t: any, C?: {}): void;
1
+ declare function Ye(o?: boolean): void;
2
+ declare namespace Ze {
3
+ function install(o: any, g?: {}): void;
4
4
  }
5
- declare function We(t: any): void;
6
- declare function He(t: any): void;
7
- export { qe as debugLktItemCrud, Ae as default, We as setItemCrudDefaultDropIcon, He as setItemCrudDefaultSaveIcon };
5
+ declare function xe(o: any): void;
6
+ declare function _e(o: any): void;
7
+ export { Ye as debugLktItemCrud, Ze as default, xe as setItemCrudDefaultDropIcon, _e as setItemCrudDefaultSaveIcon };
package/dist/build.js CHANGED
@@ -1,63 +1,210 @@
1
- import { defineComponent as pe, useSlots as me, ref as s, computed as n, watch as y, nextTick as he, resolveComponent as J, openBlock as c, createBlock as N, resolveDynamicComponent as Ce, normalizeProps as ke, guardReactiveProps as be, withCtx as P, createElementVNode as Z, createElementBlock as B, unref as h, renderSlot as R, createCommentVNode as v, toDisplayString as De, withDirectives as V, createVNode as ee, vShow as T } from "vue";
2
- import { httpCall as ye } from "lkt-http-client";
3
- import { DataState as ae } from "lkt-data-state";
4
- import { execModal as Se, refreshModal as ge, closeModal as Me, openModal as Ie, reOpenModal as Be } from "lkt-modal";
5
- import { __ as _e } from "lkt-i18n";
6
- const L = class L {
1
+ import { defineComponent as pe, useSlots as ce, ref as v, watch as C, resolveComponent as Z, openBlock as c, createElementBlock as S, unref as f, withDirectives as I, renderSlot as k, vShow as T, createCommentVNode as m, createVNode as _, withCtx as E, createBlock as O, computed as s, nextTick as Ce, resolveDynamicComponent as ke, normalizeProps as ye, guardReactiveProps as De, createElementVNode as ge, toDisplayString as Se, createSlots as se } from "vue";
2
+ import { httpCall as we } from "lkt-http-client";
3
+ import { DataState as ie } from "lkt-data-state";
4
+ import { execModal as Be, refreshModal as Me, closeModal as Ie, openModal as Te, reOpenModal as Ue } from "lkt-modal";
5
+ import { __ as Ne } from "lkt-i18n";
6
+ const F = class F {
7
7
  };
8
- L.debugEnabled = !1, L.defaultSaveIcon = "", L.defaultDropIcon = "";
9
- let S = L;
10
- const u = (...t) => {
11
- S.debugEnabled && console.info("[LktItemCrud] ", ...t);
12
- }, qe = (t = !0) => {
13
- S.debugEnabled = t;
14
- }, j = (t) => {
15
- u("runModalCallback -> init", t);
16
- let C = t.modalKey ? t.modalKey : "_", _ = t.args ? t.args : {};
17
- switch (t.action) {
8
+ F.debugEnabled = !1, F.defaultSaveIcon = "", F.defaultDropIcon = "";
9
+ let U = F;
10
+ const i = (...o) => {
11
+ U.debugEnabled && console.info("[LktItemCrud] ", ...o);
12
+ }, Ye = (o = !0) => {
13
+ U.debugEnabled = o;
14
+ }, Y = (o) => {
15
+ i("runModalCallback -> init", o);
16
+ let g = o.modalKey ? o.modalKey : "_", B = o.args ? o.args : {};
17
+ switch (o.action) {
18
18
  case "reOpen":
19
- return Be(t.modalName, C, _);
19
+ return Ue(o.modalName, g, B);
20
20
  case "open":
21
- return Ie(t.modalName, C, _);
21
+ return Te(o.modalName, g, B);
22
22
  case "close":
23
- return Me(t.modalName, C);
23
+ return Ie(o.modalName, g);
24
24
  case "refresh":
25
- return ge(t.modalName, C, _);
25
+ return Me(o.modalName, g, B);
26
26
  case "exec":
27
- let e = t.method;
28
- return e ? Se(t.modalName, C, e, _) : void 0;
27
+ let e = o.method;
28
+ return e ? Be(o.modalName, g, e, B) : void 0;
29
29
  }
30
- }, we = { class: "lkt-item-crud" }, Ee = {
30
+ }, Re = { class: "lkt-item-crud-buttons" }, $e = {
31
+ key: 0,
32
+ class: "lkt-item-crud-buttons"
33
+ }, Ee = {
34
+ key: 1,
35
+ class: "lkt-item-crud-buttons"
36
+ }, Ve = {
37
+ key: 3,
38
+ class: "lkt-item-crud-buttons"
39
+ }, ve = /* @__PURE__ */ pe({
40
+ __name: "ButtonNav",
41
+ props: {
42
+ item: { default: () => ({}) },
43
+ editing: { type: Boolean, default: !1 },
44
+ loading: { type: Boolean },
45
+ createMode: { type: Boolean },
46
+ canUpdate: { type: Boolean },
47
+ canDrop: { type: Boolean },
48
+ showSwitchButton: { type: Boolean },
49
+ showSaveButton: { type: Boolean, default: !1 },
50
+ showDropButton: { type: Boolean },
51
+ ableToSave: { type: Boolean, default: !1 },
52
+ ableToDrop: { type: Boolean },
53
+ saveConfirm: {},
54
+ dropConfirm: {},
55
+ confirmData: {},
56
+ dropConfirmData: {},
57
+ saveResource: {},
58
+ dropResource: {},
59
+ saveData: {},
60
+ dropData: {},
61
+ saveText: {},
62
+ dropText: {},
63
+ saveIcon: {},
64
+ dropIcon: {},
65
+ editModeText: {}
66
+ },
67
+ emits: ["update:loading", "update:editing", "save", "drop"],
68
+ setup(o, { expose: g, emit: B }) {
69
+ const e = B, b = o, u = ce(), V = v(null), r = v(null), d = v(b.loading);
70
+ C(() => b.loading, (t) => d.value = t), C(d, (t) => e("update:loading", t));
71
+ const p = v(b.editing);
72
+ C(() => b.editing, (t) => p.value = t), C(p, (t) => e("update:editing", t));
73
+ const h = () => {
74
+ d.value = !0;
75
+ }, y = () => {
76
+ d.value = !1;
77
+ }, w = () => {
78
+ e("save");
79
+ }, D = () => {
80
+ e("drop");
81
+ };
82
+ return g({
83
+ doSave: () => {
84
+ V.value && typeof V.value.click == "function" && V.value.click();
85
+ },
86
+ doDrop: () => {
87
+ r.value && typeof r.value.click == "function" && r.value.click();
88
+ }
89
+ }), (t, L) => {
90
+ const n = Z("lkt-button");
91
+ return c(), S("div", Re, [
92
+ f(u)["prev-buttons-ever"] ? I((c(), S("div", $e, [
93
+ k(t.$slots, "prev-buttons-ever")
94
+ ], 512)), [
95
+ [T, !d.value]
96
+ ]) : m("", !0),
97
+ f(u)["prev-buttons"] ? I((c(), S("div", Ee, [
98
+ k(t.$slots, "prev-buttons")
99
+ ], 512)), [
100
+ [T, p.value && !d.value]
101
+ ]) : m("", !0),
102
+ I(_(n, {
103
+ ref_key: "saveButton",
104
+ ref: V,
105
+ palette: "success",
106
+ disabled: !t.ableToSave,
107
+ "confirm-modal": t.saveConfirm,
108
+ "confirm-data": t.confirmData,
109
+ resource: t.saveResource,
110
+ "resource-data": t.saveData,
111
+ text: f(u)["button-save"] ? "" : t.saveText,
112
+ icon: f(u)["button-save"] ? "" : t.saveIcon,
113
+ onLoading: h,
114
+ onLoaded: y,
115
+ onClick: w
116
+ }, {
117
+ default: E(() => [
118
+ f(u)["button-save"] ? k(t.$slots, "button-save", {
119
+ key: 0,
120
+ item: t.item,
121
+ editMode: p.value,
122
+ isCreate: t.createMode,
123
+ canUpdate: t.canUpdate,
124
+ canDrop: t.canDrop
125
+ }) : m("", !0)
126
+ ]),
127
+ _: 3
128
+ }, 8, ["disabled", "confirm-modal", "confirm-data", "resource", "resource-data", "text", "icon"]), [
129
+ [T, t.showSaveButton]
130
+ ]),
131
+ t.createMode ? m("", !0) : I((c(), O(n, {
132
+ key: 2,
133
+ ref_key: "dropButton",
134
+ ref: r,
135
+ palette: "danger",
136
+ disabled: !t.ableToDrop,
137
+ "confirm-modal": t.dropConfirm,
138
+ "confirm-data": t.dropConfirmData,
139
+ resource: t.dropResource,
140
+ "resource-data": t.dropData,
141
+ text: f(u)["button-drop"] ? "" : t.dropText,
142
+ icon: f(u)["button-drop"] ? "" : t.dropIcon,
143
+ onLoading: h,
144
+ onLoaded: y,
145
+ onClick: D
146
+ }, {
147
+ default: E(() => [
148
+ f(u)["button-drop"] ? k(t.$slots, "button-drop", {
149
+ key: 0,
150
+ item: t.item,
151
+ editMode: p.value,
152
+ isCreate: t.createMode,
153
+ canUpdate: t.canUpdate,
154
+ canDrop: t.canDrop
155
+ }) : m("", !0)
156
+ ]),
157
+ _: 3
158
+ }, 8, ["disabled", "confirm-modal", "confirm-data", "resource", "resource-data", "text", "icon"])), [
159
+ [T, t.showDropButton]
160
+ ]),
161
+ f(u).buttons ? I((c(), S("div", Ve, [
162
+ k(t.$slots, "buttons")
163
+ ], 512)), [
164
+ [T, p.value && !d.value]
165
+ ]) : m("", !0),
166
+ I(_(n, {
167
+ checked: p.value,
168
+ "onUpdate:checked": L[0] || (L[0] = (A) => p.value = A),
169
+ class: "lkt-item-crud--switch-mode-button",
170
+ "show-switch": "",
171
+ text: t.editModeText
172
+ }, null, 8, ["checked", "text"]), [
173
+ [T, t.showSwitchButton]
174
+ ])
175
+ ]);
176
+ };
177
+ }
178
+ });
179
+ var x = /* @__PURE__ */ ((o) => (o.Top = "top", o.Bottom = "bottom", o))(x || {}), j = /* @__PURE__ */ ((o) => (o.Changed = "changed", o.Always = "always", o))(j || {});
180
+ const Le = { class: "lkt-item-crud" }, Oe = {
31
181
  key: 0,
32
182
  class: "lkt-item-crud_header"
33
- }, Re = {
183
+ }, Ae = {
34
184
  key: 0,
35
185
  class: "lkt-item-crud_header-slot"
36
- }, Ue = {
186
+ }, ze = {
37
187
  key: 1,
38
188
  class: "lkt-item-crud_header-title"
39
- }, Ne = {
189
+ }, Ke = {
40
190
  key: 2,
41
191
  class: "lkt-item-crud_header-slot"
42
- }, Ve = { class: "lkt-item-crud-buttons" }, Te = {
43
- key: 1,
44
- class: "lkt-item-crud-buttons"
45
- }, Le = {
192
+ }, Fe = {
46
193
  key: 1,
47
194
  class: "lkt-item-crud_content"
48
- }, Oe = {
195
+ }, Pe = {
49
196
  key: 0,
50
197
  class: "lkt-grid-1"
51
- }, $e = /* @__PURE__ */ pe({
198
+ }, Je = /* @__PURE__ */ pe({
52
199
  __name: "LktItemCrud",
53
200
  props: {
54
201
  modelValue: { default: () => ({}) },
55
202
  title: { default: "" },
56
203
  editModeText: { default: "Edition Mode" },
57
204
  saveText: { default: "Save" },
58
- saveIcon: { default: () => S.defaultSaveIcon },
205
+ saveIcon: { default: () => U.defaultSaveIcon },
59
206
  dropText: { default: "Delete" },
60
- dropIcon: { default: () => S.defaultDropIcon },
207
+ dropIcon: { default: () => U.defaultDropIcon },
61
208
  hiddenSave: { type: Boolean, default: !1 },
62
209
  hiddenDrop: { type: Boolean, default: !1 },
63
210
  hiddenButtons: { type: Boolean, default: !1 },
@@ -90,6 +237,8 @@ const u = (...t) => {
90
237
  onUpdateModalCallbacks: { default: () => [] },
91
238
  onDropModalCallbacks: { default: () => [] },
92
239
  editing: { type: Boolean, default: !1 },
240
+ buttonNavPosition: { default: x.Top },
241
+ buttonNavVisibility: { default: j.Changed },
93
242
  size: { default: "" },
94
243
  preTitle: { default: "" },
95
244
  showClose: { type: Boolean, default: !0 },
@@ -103,79 +252,75 @@ const u = (...t) => {
103
252
  beforeClose: { type: Function, default: void 0 }
104
253
  },
105
254
  emits: ["update:modelValue", "update:isCreate", "update:editing", "read", "create", "update", "drop", "before-save", "perms", "error", "modified-data"],
106
- setup(t, { expose: C, emit: _ }) {
107
- const e = t, p = me(), i = _;
108
- let te = [];
109
- const d = s(!0), r = s(e.modelValue), U = s(te), f = s(e.editing), k = s(!1), g = s(!1), m = s(200), O = s(null), $ = s(null), b = s(new ae(r.value, e.dataStateConfig)), K = s(new ae(e.readData)), o = s(e.isCreate), x = s(!1), le = n(() => o.value ? e.createConfirm : e.updateConfirm), oe = n(() => o.value ? e.createConfirmData : e.updateConfirmData), q = n(() => o.value ? e.createResource : e.updateResource), ue = n(() => o.value ? { ...e.createData, ...JSON.parse(JSON.stringify(r.value)) } : { ...e.updateData, ...JSON.parse(JSON.stringify(r.value)) }), de = n(() => o.value ? e.createDisabled : e.updateDisabled), M = n(() => !o.value && U.value.includes("update")), I = n(() => !o.value && U.value.includes("drop")), z = async () => {
110
- u("fetchItem"), d.value = !0, m.value = -1, g.value = !1;
255
+ setup(o, { expose: g, emit: B }) {
256
+ const e = o, b = ce(), u = B;
257
+ let V = [];
258
+ const r = v(!0), d = v(e.modelValue), p = v(V), h = v(e.editing), y = v(!1), w = v(!1), D = v(200), ee = v(null), ae = v(null), t = v(new ie(d.value, e.dataStateConfig)), L = v(new ie(e.readData)), n = v(e.isCreate), A = v(!1), P = v(null), te = s(() => n.value ? e.createConfirm : e.updateConfirm), oe = s(() => n.value ? e.createConfirmData : e.updateConfirmData), q = s(() => n.value ? e.createResource : e.updateResource), le = s(() => n.value ? { ...e.createData, ...JSON.parse(JSON.stringify(d.value)) } : { ...e.updateData, ...JSON.parse(JSON.stringify(d.value)) }), fe = s(() => n.value ? e.createDisabled : e.updateDisabled), N = s(() => !n.value && Array.isArray(p.value) && p.value.includes("update")), R = s(() => !n.value && Array.isArray(p.value) && p.value.includes("drop")), J = async () => {
259
+ i("fetchItem"), r.value = !0, D.value = -1, w.value = !1;
111
260
  try {
112
- const a = await ye(e.readResource, e.readData);
113
- if (u("fetchItem -> response", a), d.value = !1, m.value = a.httpStatus, !a.success) {
114
- k.value = !1, m.value = a.httpStatus, i("error", a.httpStatus);
261
+ const a = await we(e.readResource, e.readData);
262
+ if (i("fetchItem -> response", a), r.value = !1, D.value = a.httpStatus, !a.success) {
263
+ y.value = !1, D.value = a.httpStatus, u("error", a.httpStatus);
115
264
  return;
116
265
  }
117
- k.value = !0, r.value = a.data, U.value = a.perms, b.value.increment(r.value).turnStoredIntoOriginal(), K.value.turnStoredIntoOriginal(), i("read", a);
266
+ y.value = !0, d.value = a.data, p.value = a.perms, t.value.increment(d.value).turnStoredIntoOriginal(), L.value.turnStoredIntoOriginal(), u("read", a);
118
267
  } catch {
119
- d.value = !1, k.value = !1, m.value = 404, i("error", 404);
268
+ r.value = !1, y.value = !1, D.value = 404, u("error", 404);
120
269
  return;
121
270
  }
122
271
  };
123
- y(() => e.modelValue, (a) => {
124
- r.value = a, b.value.increment(a);
125
- }, { deep: !0 }), y(r, (a) => {
126
- if (x.value = !0, u("item updated ->", r.value), typeof e.beforeEmitUpdate == "function") {
127
- u("item updated -> has beforeEmitUpdate");
128
- let l = e.beforeEmitUpdate(r.value);
129
- u("item updated -> override with: ", l), typeof l == "object" && (r.value = l);
272
+ C(() => e.modelValue, (a) => {
273
+ d.value = a, t.value.increment(a);
274
+ }, { deep: !0 }), C(d, (a) => {
275
+ if (A.value = !0, i("item updated ->", d.value), typeof e.beforeEmitUpdate == "function") {
276
+ i("item updated -> has beforeEmitUpdate");
277
+ let l = e.beforeEmitUpdate(d.value);
278
+ i("item updated -> override with: ", l), typeof l == "object" && (d.value = l);
130
279
  }
131
- i("update:modelValue", r.value), u("item updated -> update dataState"), b.value.increment(a), he(() => x.value = !1);
132
- }, { deep: !0 }), y(U, () => i("perms", U.value));
133
- const A = n(() => de.value || !o.value && !M.value || typeof e.saveValidator == "function" && !e.saveValidator(r.value) ? !1 : b.value.changed());
134
- y(A, (a) => i("modified-data", a)), y(o, (a) => i("update:isCreate", a)), y(() => e.readData, (a) => {
135
- K.value.increment(a), K.value.changed() && z();
136
- }), y(() => e.editing, (a) => {
137
- u("editing updated -> updating editMode", a), f.value = a;
138
- }), y(f, (a) => {
139
- u("editMode updated -> emit update", a), i("update:editing", a);
140
- }), e.readResource && !o.value ? z() : o.value && (k.value = !0, f.value = !0, d.value = !1);
141
- const re = (a, l) => {
142
- if (d.value = !1, m.value = l.httpStatus, !l.success) {
143
- g.value = !0, i("error", l.httpStatus);
280
+ u("update:modelValue", d.value), i("item updated -> update dataState"), t.value.increment(a), Ce(() => A.value = !1);
281
+ }, { deep: !0 }), C(p, () => u("perms", p.value));
282
+ const z = s(() => fe.value || !n.value && !N.value || typeof e.saveValidator == "function" && !e.saveValidator(d.value) ? !1 : t.value.changed()), H = s(() => !e.dropDisabled && R.value);
283
+ C(z, (a) => u("modified-data", a)), C(n, (a) => u("update:isCreate", a)), C(() => e.readData, (a) => {
284
+ L.value.increment(a), L.value.changed() && J();
285
+ }), C(() => e.editing, (a) => {
286
+ i("editing updated -> updating editMode", a), h.value = a;
287
+ }), C(h, (a) => {
288
+ i("editMode updated -> emit update", a), u("update:editing", a);
289
+ }), e.readResource && !n.value ? J() : n.value && (y.value = !0, h.value = !0, r.value = !1);
290
+ const de = (a, l) => {
291
+ if (r.value = !1, D.value = l.httpStatus, !l.success) {
292
+ w.value = !0, u("error", l.httpStatus);
144
293
  return;
145
294
  }
146
- g.value = !0, e.onDropModalCallbacks.length > 0 && (u("onDrop -> has onDropModalCallbacks"), e.onDropModalCallbacks.forEach((D) => {
147
- j(D);
148
- })), i("drop", l);
149
- }, ne = (a, l) => {
150
- if (u("onSave -> received response:", l), i("before-save"), q.value) {
151
- if (d.value = !1, m.value = l.httpStatus, !l.success) {
152
- g.value = !0, i("error", l.httpStatus);
295
+ w.value = !0, e.onDropModalCallbacks.length > 0 && (i("onDrop -> has onDropModalCallbacks"), e.onDropModalCallbacks.forEach(($) => {
296
+ Y($);
297
+ })), u("drop", l);
298
+ }, re = (a, l) => {
299
+ if (i("onSave -> received response:", l), u("before-save"), q.value) {
300
+ if (r.value = !1, D.value = l.httpStatus, !l.success) {
301
+ w.value = !0, u("error", l.httpStatus);
153
302
  return;
154
303
  }
155
- g.value = !0;
304
+ w.value = !0;
156
305
  }
157
- let D = o.value ? "create" : "update";
158
- o.value || (u("onSave -> turn stored data into original"), b.value.turnStoredIntoOriginal()), D === "create" ? typeof e.onCreate == "function" && (u("onSave -> trigger onCreate callback"), e.onCreate(l), e.onCreateModalCallbacks.length > 0 && (u("onSave -> has onCreateModalCallbacks"), e.onCreateModalCallbacks.forEach((w) => {
159
- j(w);
160
- }))) : typeof e.onUpdate == "function" && (u("onSave -> trigger onUpdate callback"), e.onUpdate(l), e.onUpdateModalCallbacks.length > 0 && (u("onSave -> has onUpdateModalCallbacks"), e.onUpdateModalCallbacks.forEach((w) => {
161
- j(w);
162
- }))), !e.insideModal && l.autoReloadId && (u("onSave -> autoReloadId detected: ", l.autoReloadId), e.readData.id = l.autoReloadId, u("onSave -> turning off create mode"), o.value = !1, z()), i(D, l);
163
- }, H = () => {
164
- d.value = !0, m.value = -1;
165
- }, W = () => {
166
- d.value = !1;
306
+ let $ = n.value ? "create" : "update";
307
+ n.value || (i("onSave -> turn stored data into original"), t.value.turnStoredIntoOriginal()), $ === "create" ? typeof e.onCreate == "function" && (i("onSave -> trigger onCreate callback"), e.onCreate(l), e.onCreateModalCallbacks.length > 0 && (i("onSave -> has onCreateModalCallbacks"), e.onCreateModalCallbacks.forEach((K) => {
308
+ Y(K);
309
+ }))) : typeof e.onUpdate == "function" && (i("onSave -> trigger onUpdate callback"), e.onUpdate(l), e.onUpdateModalCallbacks.length > 0 && (i("onSave -> has onUpdateModalCallbacks"), e.onUpdateModalCallbacks.forEach((K) => {
310
+ Y(K);
311
+ }))), !e.insideModal && l.autoReloadId && (i("onSave -> autoReloadId detected: ", l.autoReloadId), e.readData.id = l.autoReloadId, i("onSave -> turning off create mode"), n.value = !1, J()), u($, l);
167
312
  };
168
- C({
313
+ g({
169
314
  doDrop: () => {
170
- $.value && typeof $.value.click == "function" && $.value.click();
315
+ P.value && ae.value.doDrop();
171
316
  },
172
- doRefresh: z,
317
+ doRefresh: J,
173
318
  doSave: () => {
174
- O.value && typeof O.value.click == "function" && O.value.click();
319
+ P.value && ee.value.doSave();
175
320
  },
176
- hasModifiedData: () => b.value.changed()
321
+ hasModifiedData: () => t.value.changed()
177
322
  });
178
- const ie = n(() => b.value.changed() ? e.editedCloseConfirm : ""), G = n(() => !M.value && I.value ? !0 : !e.hiddenDrop && !d.value && f.value && k.value), Q = n(() => b.value.changed() ? !0 : d.value ? !1 : o.value ? !0 : !e.hiddenSave && f.value && k.value), X = n(() => e.hideSwitchEdition || !M.value && !I.value || !M.value && I.value ? !1 : !d.value && !o.value && k.value && !(e.dropDisabled && e.updateDisabled)), se = n(() => !e.hiddenButtons && (Q.value || G.value || X.value)), F = n(() => e.title.startsWith("__:") ? String(_e(e.title.substring(3))) : e.title), ce = n(() => d.value ? !1 : F.value.length > 0 || !!p["post-title"]), Y = n(() => e.insideModal ? "lkt-modal" : "section"), fe = n(() => Y.value === "lkt-modal" ? {
323
+ const me = s(() => t.value.changed() ? e.editedCloseConfirm : ""), W = s(() => !N.value && R.value ? !0 : !e.hiddenDrop && !r.value && h.value && y.value), G = s(() => t.value.changed() ? !0 : r.value ? !1 : n.value ? !0 : e.buttonNavVisibility === j.Always ? z.value : !e.hiddenSave && h.value && y.value), Q = s(() => e.hideSwitchEdition || !N.value && !R.value || !N.value && R.value ? !1 : !r.value && !n.value && y.value && !(e.dropDisabled && e.updateDisabled)), ue = s(() => e.buttonNavVisibility === j.Always && (z.value || H.value) || b["prev-buttons-ever"] ? !0 : !e.hiddenButtons && (G.value || W.value || Q.value)), X = s(() => e.title.startsWith("__:") ? String(Ne(e.title.substring(3))) : e.title), be = s(() => r.value ? !1 : X.value.length > 0 || !!b["post-title"]), ne = s(() => e.insideModal ? "lkt-modal" : "section"), he = s(() => ne.value === "lkt-modal" ? {
179
324
  "modal-name": e.modalName,
180
325
  "modal-key": e.modalKey,
181
326
  "z-index": e.zIndex,
@@ -184,149 +329,173 @@ const u = (...t) => {
184
329
  "before-close": e.beforeClose,
185
330
  "disabled-close": e.disabledClose,
186
331
  "disabled-veil-click": e.disabledVeilClick,
187
- "close-confirm": ie.value,
332
+ "close-confirm": me.value,
188
333
  "close-confirm-key": e.editedCloseConfirmKey,
189
334
  title: e.title,
190
335
  size: e.size
191
336
  } : {});
192
337
  return (a, l) => {
193
- const D = J("lkt-button"), w = J("lkt-http-info"), ve = J("lkt-loader");
194
- return c(), N(Ce(Y.value), ke(be(fe.value)), {
195
- default: P(() => [
196
- Z("article", we, [
197
- !a.insideModal && ce.value ? (c(), B("header", Ee, [
198
- h(p)["pre-title"] ? (c(), B("div", Re, [
199
- R(a.$slots, "pre-title", {
200
- item: r.value,
201
- loading: d.value
338
+ const $ = Z("lkt-http-info"), K = Z("lkt-loader");
339
+ return c(), O(ke(ne.value), ye(De(he.value)), {
340
+ default: E(() => [
341
+ ge("article", Le, [
342
+ !a.insideModal && be.value ? (c(), S("header", Oe, [
343
+ f(b)["pre-title"] ? (c(), S("div", Ae, [
344
+ k(a.$slots, "pre-title", {
345
+ item: d.value,
346
+ loading: r.value
202
347
  })
203
- ])) : v("", !0),
204
- F.value.length > 0 ? (c(), B("h1", Ue, De(F.value), 1)) : v("", !0),
205
- h(p)["post-title"] ? (c(), B("div", Ne, [
206
- R(a.$slots, "post-title", {
207
- item: r.value,
208
- loading: d.value
348
+ ])) : m("", !0),
349
+ X.value.length > 0 ? (c(), S("h1", ze, Se(X.value), 1)) : m("", !0),
350
+ f(b)["post-title"] ? (c(), S("div", Ke, [
351
+ k(a.$slots, "post-title", {
352
+ item: d.value,
353
+ loading: r.value
209
354
  })
210
- ])) : v("", !0)
211
- ])) : v("", !0),
212
- V(Z("div", Ve, [
213
- V(ee(D, {
214
- ref: (E) => O.value = E,
215
- palette: "success",
216
- disabled: !A.value,
217
- "confirm-modal": le.value,
218
- "confirm-data": oe.value,
219
- resource: q.value,
220
- "resource-data": ue.value,
221
- text: h(p)["button-save"] ? "" : a.saveText,
222
- icon: h(p)["button-save"] ? "" : a.saveIcon,
223
- onLoading: H,
224
- onLoaded: W,
225
- onClick: ne
226
- }, {
227
- default: P(() => [
228
- h(p)["button-save"] ? R(a.$slots, "button-save", {
229
- key: 0,
230
- item: r.value,
231
- editMode: f.value,
232
- isCreate: o.value,
233
- canUpdate: M.value,
234
- canDrop: I.value
235
- }) : v("", !0)
355
+ ])) : m("", !0)
356
+ ])) : m("", !0),
357
+ I(_(ve, {
358
+ ref_key: "buttonNav",
359
+ ref: P,
360
+ loading: r.value,
361
+ "onUpdate:loading": l[0] || (l[0] = (M) => r.value = M),
362
+ editing: h.value,
363
+ "onUpdate:editing": l[1] || (l[1] = (M) => h.value = M),
364
+ item: d.value,
365
+ "create-mode": n.value,
366
+ "can-update": N.value,
367
+ "can-drop": R.value,
368
+ "show-switch-button": Q.value,
369
+ "show-save-button": G.value,
370
+ "show-drop-button": W.value,
371
+ "able-to-save": z.value,
372
+ "able-to-drop": H.value,
373
+ "save-confirm": te.value,
374
+ "drop-confirm": a.dropConfirm,
375
+ "confirm-data": oe.value,
376
+ "drop-confirm-data": a.dropConfirmData,
377
+ "save-resource": q.value,
378
+ "drop-resource": a.dropResource,
379
+ "save-data": le.value,
380
+ "drop-data": a.dropData,
381
+ "save-text": a.saveText,
382
+ "drop-text": a.dropText,
383
+ "save-icon": a.saveIcon,
384
+ "drop-icon": a.dropIcon,
385
+ "edit-mode-text": a.editModeText,
386
+ onSave: re,
387
+ onDrop: de
388
+ }, se({ _: 2 }, [
389
+ f(b)["prev-buttons-ever"] ? {
390
+ name: "prev-buttons-ever",
391
+ fn: E(() => [
392
+ k(a.$slots, "prev-buttons-ever")
236
393
  ]),
237
- _: 3
238
- }, 8, ["disabled", "confirm-modal", "confirm-data", "resource", "resource-data", "text", "icon"]), [
239
- [T, Q.value]
240
- ]),
241
- o.value ? v("", !0) : V((c(), N(D, {
242
- key: 0,
243
- ref: (E) => $.value = E,
244
- palette: "danger",
245
- disabled: a.dropDisabled || !I.value,
246
- "confirm-modal": a.dropConfirm,
247
- "confirm-data": a.dropConfirmData,
248
- resource: a.dropResource,
249
- "resource-data": a.dropData,
250
- text: h(p)["button-drop"] ? "" : a.dropText,
251
- icon: h(p)["button-drop"] ? "" : a.dropIcon,
252
- onLoading: H,
253
- onLoaded: W,
254
- onClick: re
255
- }, {
256
- default: P(() => [
257
- h(p)["button-drop"] ? R(a.$slots, "button-drop", {
258
- key: 0,
259
- item: r.value,
260
- editMode: f.value,
261
- isCreate: o.value,
262
- canUpdate: M.value,
263
- canDrop: I.value
264
- }) : v("", !0)
394
+ key: "0"
395
+ } : void 0,
396
+ f(b)["prev-buttons"] ? {
397
+ name: "prev-buttons-ever",
398
+ fn: E(() => [
399
+ k(a.$slots, "prev-buttons")
265
400
  ]),
266
- _: 3
267
- }, 8, ["disabled", "confirm-modal", "confirm-data", "resource", "resource-data", "text", "icon"])), [
268
- [T, G.value]
269
- ]),
270
- h(p).buttons ? V((c(), B("div", Te, [
271
- R(a.$slots, "buttons")
272
- ], 512)), [
273
- [T, f.value]
274
- ]) : v("", !0),
275
- V(ee(D, {
276
- checked: f.value,
277
- "onUpdate:checked": l[0] || (l[0] = (E) => f.value = E),
278
- class: "lkt-item-crud--switch-mode-button",
279
- "show-switch": "",
280
- text: a.editModeText
281
- }, null, 8, ["checked", "text"]), [
282
- [T, X.value]
283
- ])
284
- ], 512), [
285
- [T, se.value]
401
+ key: "1"
402
+ } : void 0
403
+ ]), 1032, ["loading", "editing", "item", "create-mode", "can-update", "can-drop", "show-switch-button", "show-save-button", "show-drop-button", "able-to-save", "able-to-drop", "save-confirm", "drop-confirm", "confirm-data", "drop-confirm-data", "save-resource", "drop-resource", "save-data", "drop-data", "save-text", "drop-text", "save-icon", "drop-icon", "edit-mode-text"]), [
404
+ [T, ue.value && a.buttonNavPosition === "top"]
286
405
  ]),
287
- d.value ? v("", !0) : (c(), B("div", Le, [
288
- k.value ? (c(), B("div", Oe, [
289
- g.value ? (c(), N(w, {
406
+ r.value ? m("", !0) : (c(), S("div", Fe, [
407
+ y.value ? (c(), S("div", Pe, [
408
+ w.value ? (c(), O($, {
290
409
  key: 0,
291
- code: m.value,
410
+ code: D.value,
292
411
  quick: "",
293
- palette: m.value === 200 ? "success" : "danger",
412
+ palette: D.value === 200 ? "success" : "danger",
294
413
  "can-close": "",
295
- onClose: l[1] || (l[1] = (E) => g.value = !1)
296
- }, null, 8, ["code", "palette"])) : v("", !0),
297
- R(a.$slots, "item", {
298
- item: r.value,
299
- loading: d.value,
300
- editMode: f.value,
301
- isCreate: o.value,
302
- canUpdate: M.value,
303
- canDrop: I.value,
304
- itemBeingEdited: x.value
414
+ onClose: l[2] || (l[2] = (M) => w.value = !1)
415
+ }, null, 8, ["code", "palette"])) : m("", !0),
416
+ k(a.$slots, "item", {
417
+ item: d.value,
418
+ loading: r.value,
419
+ editMode: h.value,
420
+ isCreate: n.value,
421
+ canUpdate: N.value,
422
+ canDrop: R.value,
423
+ itemBeingEdited: A.value
305
424
  })
306
- ])) : (c(), N(w, {
425
+ ])) : (c(), O($, {
307
426
  key: 1,
308
- code: m.value
427
+ code: D.value
309
428
  }, null, 8, ["code"]))
310
429
  ])),
311
- d.value ? (c(), N(ve, { key: 2 })) : v("", !0)
430
+ r.value ? (c(), O(K, { key: 2 })) : m("", !0),
431
+ a.buttonNavPosition === f(x).Bottom ? I((c(), O(ve, {
432
+ key: 3,
433
+ ref_key: "buttonNav",
434
+ ref: P,
435
+ loading: r.value,
436
+ "onUpdate:loading": l[3] || (l[3] = (M) => r.value = M),
437
+ editing: h.value,
438
+ "onUpdate:editing": l[4] || (l[4] = (M) => h.value = M),
439
+ item: d.value,
440
+ "create-mode": n.value,
441
+ "can-update": N.value,
442
+ "can-drop": R.value,
443
+ "show-switch-button": Q.value,
444
+ "show-save-button": G.value,
445
+ "show-drop-button": W.value,
446
+ "able-to-save": z.value,
447
+ "able-to-drop": H.value,
448
+ "save-confirm": te.value,
449
+ "drop-confirm": a.dropConfirm,
450
+ "confirm-data": oe.value,
451
+ "drop-confirm-data": a.dropConfirmData,
452
+ "save-resource": q.value,
453
+ "drop-resource": a.dropResource,
454
+ "save-data": le.value,
455
+ "drop-data": a.dropData,
456
+ "save-text": a.saveText,
457
+ "drop-text": a.dropText,
458
+ "save-icon": a.saveIcon,
459
+ "drop-icon": a.dropIcon,
460
+ "edit-mode-text": a.editModeText,
461
+ onSave: re,
462
+ onDrop: de
463
+ }, se({ _: 2 }, [
464
+ f(b)["prev-buttons-ever"] ? {
465
+ name: "prev-buttons-ever",
466
+ fn: E(() => [
467
+ k(a.$slots, "prev-buttons-ever")
468
+ ]),
469
+ key: "0"
470
+ } : void 0,
471
+ f(b)["prev-buttons"] ? {
472
+ name: "prev-buttons-ever",
473
+ fn: E(() => [
474
+ k(a.$slots, "prev-buttons")
475
+ ]),
476
+ key: "1"
477
+ } : void 0
478
+ ]), 1032, ["loading", "editing", "item", "create-mode", "can-update", "can-drop", "show-switch-button", "show-save-button", "show-drop-button", "able-to-save", "able-to-drop", "save-confirm", "drop-confirm", "confirm-data", "drop-confirm-data", "save-resource", "drop-resource", "save-data", "drop-data", "save-text", "drop-text", "save-icon", "drop-icon", "edit-mode-text"])), [
479
+ [T, ue.value]
480
+ ]) : m("", !0)
312
481
  ])
313
482
  ]),
314
483
  _: 3
315
484
  }, 16);
316
485
  };
317
486
  }
318
- }), Ae = {
319
- install: (t, C = {}) => {
320
- t.component("lkt-item-crud") === void 0 && t.component("lkt-item-crud", $e);
487
+ }), Ze = {
488
+ install: (o, g = {}) => {
489
+ o.component("lkt-item-crud") === void 0 && o.component("lkt-item-crud", Je);
321
490
  }
322
- }, He = (t) => {
323
- S.defaultSaveIcon = t;
324
- }, We = (t) => {
325
- S.defaultDropIcon = t;
491
+ }, _e = (o) => {
492
+ U.defaultSaveIcon = o;
493
+ }, xe = (o) => {
494
+ U.defaultDropIcon = o;
326
495
  };
327
496
  export {
328
- qe as debugLktItemCrud,
329
- Ae as default,
330
- We as setItemCrudDefaultDropIcon,
331
- He as setItemCrudDefaultSaveIcon
497
+ Ye as debugLktItemCrud,
498
+ Ze as default,
499
+ xe as setItemCrudDefaultDropIcon,
500
+ _e as setItemCrudDefaultSaveIcon
332
501
  };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .lkt-item-crud{display:flex;flex-direction:column;gap:var(--lkt-item-crud-gap)}.lkt-item-crud_content{display:flex;flex-direction:column;gap:15px}.lkt-item-crud-buttons{position:sticky;top:calc(-1 * var(--lkt-item-crud-gap));display:flex;align-items:center;gap:var(--lkt-item-crud-gap-buttons);transition:all linear .15s;background:transparent;z-index:2}.lkt-item-crud-buttons>:last-child{margin-left:auto}.lkt-item-crud-buttons>.lkt-item-crud-buttons{padding:0}
1
+ .lkt-item-crud{display:flex;flex-direction:column;gap:var(--lkt-item-crud-gap);text-align:var(--lkt-item-crud-text-align)}.lkt-item-crud_content{display:flex;flex-direction:column;gap:15px}.lkt-item-crud-buttons{position:sticky;top:calc(-1 * var(--lkt-item-crud-gap));display:flex;align-items:center;gap:var(--lkt-item-crud-gap-buttons);transition:all linear .15s;background:transparent;z-index:2}.lkt-item-crud-buttons>:last-child{margin-left:auto}.lkt-item-crud-buttons>.lkt-item-crud-buttons{padding:0}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lkt-item-crud",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "module": "./dist/build.js",
@@ -0,0 +1,146 @@
1
+ <script setup lang="ts">
2
+ import { ref, useSlots, watch } from 'vue';
3
+ import { LktObject } from 'lkt-ts-interfaces';
4
+
5
+ const emit = defineEmits(['update:loading', 'update:editing', 'save', 'drop']);
6
+
7
+ const props = withDefaults(defineProps<{
8
+ item: LktObject,
9
+ editing?: boolean
10
+ loading?: boolean
11
+ createMode?: boolean
12
+ canUpdate?: boolean
13
+ canDrop?: boolean
14
+ showSwitchButton?: boolean
15
+ showSaveButton?: boolean
16
+ showDropButton?: boolean
17
+ ableToSave?: boolean
18
+ ableToDrop?: boolean
19
+ saveConfirm?: string
20
+ dropConfirm?: string
21
+ confirmData?: LktObject
22
+ dropConfirmData?: LktObject
23
+ saveResource?: string
24
+ dropResource?: string
25
+ saveData?: LktObject
26
+ dropData?: LktObject
27
+ saveText?: string
28
+ dropText?: string
29
+ saveIcon?: string
30
+ dropIcon?: string
31
+ editModeText?: string
32
+
33
+ }>(), {
34
+ item: () => ({}),
35
+ editing: false,
36
+ isLoading: false,
37
+ showSaveButton: false,
38
+ ableToSave: false,
39
+ });
40
+
41
+ const slots = useSlots();
42
+
43
+ const saveButton = ref(<HTMLButtonElement|null>null);
44
+ const dropButton = ref(<HTMLButtonElement|null>null);
45
+
46
+ const isLoading = ref(props.loading);
47
+ watch(() => props.loading, v => isLoading.value = v);
48
+ watch(isLoading, v => emit('update:loading', v));
49
+
50
+ const isEditing = ref(props.editing);
51
+ watch(() => props.editing, v => isEditing.value = v);
52
+ watch(isEditing, v => emit('update:editing', v));
53
+
54
+ const onButtonLoading = () => {
55
+ isLoading.value = true;
56
+ },
57
+ onButtonLoaded = () => {
58
+ isLoading.value = false;
59
+ },
60
+ onSave = () => {
61
+ emit('save');
62
+ },
63
+ onDrop = () => {
64
+ emit('drop');
65
+ };
66
+
67
+ const doSave = () => {
68
+ if (saveButton.value && typeof saveButton.value.click === 'function') saveButton.value.click();
69
+ },
70
+ doDrop = () => {
71
+ if (dropButton.value && typeof dropButton.value.click === 'function') dropButton.value.click();
72
+ };
73
+
74
+ defineExpose({
75
+ doSave,
76
+ doDrop,
77
+ })
78
+
79
+ </script>
80
+
81
+ <template>
82
+ <div class="lkt-item-crud-buttons">
83
+
84
+ <div class="lkt-item-crud-buttons" v-if="slots['prev-buttons-ever']" v-show="!isLoading">
85
+ <slot name="prev-buttons-ever" />
86
+ </div>
87
+
88
+ <div class="lkt-item-crud-buttons" v-if="slots['prev-buttons']" v-show="isEditing && !isLoading">
89
+ <slot name="prev-buttons" />
90
+ </div>
91
+
92
+ <lkt-button
93
+ ref="saveButton"
94
+ v-show="showSaveButton"
95
+ palette="success"
96
+ :disabled="!ableToSave"
97
+ :confirm-modal="saveConfirm"
98
+ :confirm-data="confirmData"
99
+ :resource="saveResource"
100
+ :resource-data="saveData"
101
+ :text="slots['button-save'] ? '' : saveText"
102
+ :icon="slots['button-save'] ? '' : saveIcon"
103
+ v-on:loading="onButtonLoading"
104
+ v-on:loaded="onButtonLoaded"
105
+ v-on:click="onSave">
106
+ <slot v-if="!!slots['button-save']" name="button-save" :item="item"
107
+ :edit-mode="isEditing"
108
+ :is-create="createMode"
109
+ :can-update="canUpdate"
110
+ :can-drop="canDrop"></slot>
111
+ </lkt-button>
112
+
113
+ <lkt-button
114
+ ref="dropButton"
115
+ v-show="showDropButton"
116
+ v-if="!createMode"
117
+ palette="danger"
118
+ :disabled="!ableToDrop"
119
+ :confirm-modal="dropConfirm"
120
+ :confirm-data="dropConfirmData"
121
+ :resource="dropResource"
122
+ :resource-data="dropData"
123
+ :text="slots['button-drop'] ? '' : dropText"
124
+ :icon="slots['button-drop'] ? '' : dropIcon"
125
+ v-on:loading="onButtonLoading"
126
+ v-on:loaded="onButtonLoaded"
127
+ v-on:click="onDrop">
128
+ <slot v-if="!!slots['button-drop']" name="button-drop" :item="item"
129
+ :edit-mode="isEditing"
130
+ :is-create="createMode"
131
+ :can-update="canUpdate"
132
+ :can-drop="canDrop"></slot>
133
+ </lkt-button>
134
+
135
+ <div class="lkt-item-crud-buttons" v-if="slots.buttons" v-show="isEditing && !isLoading">
136
+ <slot name="buttons" />
137
+ </div>
138
+
139
+ <lkt-button
140
+ v-show="showSwitchButton"
141
+ v-model:checked="isEditing"
142
+ class="lkt-item-crud--switch-mode-button"
143
+ show-switch
144
+ :text="editModeText" />
145
+ </div>
146
+ </template>
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { ref, watch, useSlots, computed, nextTick } from 'vue';
2
+ import { computed, nextTick, ref, useSlots, watch } from 'vue';
3
3
  import { httpCall, HTTPResponse } from 'lkt-http-client';
4
4
  import { DataState } from 'lkt-data-state';
5
5
  import { debug } from '../functions/debug';
@@ -8,6 +8,9 @@
8
8
  import { runModalCallback } from '../functions/modalCallbacks';
9
9
  import { __ } from 'lkt-i18n';
10
10
  import { Settings } from '../settings/Settings';
11
+ import ButtonNav from '../components/ButtonNav.vue';
12
+ import { ButtonNavPosition } from '../enums/ButtonNavPosition';
13
+ import { ButtonNavVisibility } from '../enums/ButtonNavVisibility';
11
14
 
12
15
  const props = withDefaults(defineProps<{
13
16
  modelValue: LktObject
@@ -49,6 +52,8 @@
49
52
  onUpdateModalCallbacks: ModalCallbackConfig[]
50
53
  onDropModalCallbacks: ModalCallbackConfig[]
51
54
  editing: boolean
55
+ buttonNavPosition?: ButtonNavPosition
56
+ buttonNavVisibility?: ButtonNavVisibility
52
57
 
53
58
  // Modal props
54
59
  size: string
@@ -60,8 +65,8 @@
60
65
  modalKey: string
61
66
  zIndex: number
62
67
  editedCloseConfirm: string
63
- editedCloseConfirmKey: string|number
64
- beforeClose: Function|undefined
68
+ editedCloseConfirmKey: string | number
69
+ beforeClose: Function | undefined
65
70
 
66
71
  }>(), {
67
72
  modelValue: () => ({}),
@@ -103,6 +108,8 @@
103
108
  onUpdateModalCallbacks: () => [],
104
109
  onDropModalCallbacks: () => [],
105
110
  editing: false,
111
+ buttonNavPosition: ButtonNavPosition.Top,
112
+ buttonNavVisibility: ButtonNavVisibility.Changed,
106
113
 
107
114
  // Modal props
108
115
  size: '',
@@ -138,6 +145,8 @@
138
145
  createMode = ref(props.isCreate),
139
146
  itemBeingEdited = ref(false);
140
147
 
148
+ const buttonNav = ref(null);
149
+
141
150
  const saveConfirm = computed(() => {
142
151
  return createMode.value
143
152
  ? props.createConfirm
@@ -164,8 +173,8 @@
164
173
  ? props.createDisabled
165
174
  : props.updateDisabled;
166
175
  }),
167
- canUpdate = computed(() => !createMode.value && perms.value.includes('update')),
168
- canDrop = computed(() => !createMode.value && perms.value.includes('drop'));
176
+ canUpdate = computed(() => !createMode.value && Array.isArray(perms.value) && perms.value.includes('update')),
177
+ canDrop = computed(() => !createMode.value && Array.isArray(perms.value) && perms.value.includes('drop'));
169
178
 
170
179
  const fetchItem = async () => {
171
180
  debug('fetchItem');
@@ -229,6 +238,10 @@
229
238
 
230
239
  return dataState.value.changed();
231
240
  });
241
+
242
+ const ableToDrop = computed(() => {
243
+ return !props.dropDisabled && canDrop.value;
244
+ });
232
245
  watch(ableToSave, (v) => emit('modified-data', v));
233
246
  watch(createMode, (v) => emit('update:isCreate', v));
234
247
 
@@ -323,20 +336,13 @@
323
336
  }
324
337
  emit(emits, r);
325
338
  },
326
- onButtonLoading = () => {
327
- isLoading.value = true;
328
- httpStatus.value = -1;
329
- },
330
- onButtonLoaded = () => {
331
- isLoading.value = false;
332
- },
333
339
  doSave = () => {
334
340
  // @ts-ignore
335
- if (saveButton.value && typeof saveButton.value.click === 'function') saveButton.value.click();
341
+ if (buttonNav.value) saveButton.value.doSave();
336
342
  },
337
343
  doDrop = () => {
338
344
  // @ts-ignore
339
- if (dropButton.value && typeof dropButton.value.click === 'function') dropButton.value.click();
345
+ if (buttonNav.value) dropButton.value.doDrop();
340
346
  };
341
347
 
342
348
  defineExpose({
@@ -347,10 +353,9 @@
347
353
  });
348
354
 
349
355
 
350
-
351
356
  const closeConfirm = computed(() => {
352
357
  return dataState.value.changed() ? props.editedCloseConfirm : '';
353
- })
358
+ });
354
359
 
355
360
  const showDropButton = computed(() => {
356
361
  if (!canUpdate.value && canDrop.value) return true;
@@ -367,6 +372,10 @@
367
372
 
368
373
  if (createMode.value) return true;
369
374
 
375
+ if (props.buttonNavVisibility === ButtonNavVisibility.Always) {
376
+ return ableToSave.value;
377
+ }
378
+
370
379
  return !props.hiddenSave
371
380
  && editMode.value
372
381
  && httpSuccessRead.value;
@@ -382,6 +391,8 @@
382
391
  && !(props.dropDisabled && props.updateDisabled);
383
392
  }),
384
393
  showButtons = computed(() => {
394
+ if (props.buttonNavVisibility === ButtonNavVisibility.Always && (ableToSave.value || ableToDrop.value)) return true;
395
+ if (slots['prev-buttons-ever']) return true;
385
396
  return !props.hiddenButtons && (showSaveButton.value || showDropButton.value || showSwitchButton.value);
386
397
  }),
387
398
  computedTitle = computed(() => {
@@ -395,29 +406,29 @@
395
406
 
396
407
  return computedTitle.value.length > 0 || !!slots['post-title'];
397
408
  }),
398
- computedContainerTag = computed(() => {
399
- if (props.insideModal) return 'lkt-modal';
400
- return 'section';
401
- }),
402
- computedContainerAttrs = computed(() => {
403
- if (computedContainerTag.value === 'lkt-modal') {
404
- return {
405
- 'modal-name': props.modalName,
406
- 'modal-key': props.modalKey,
407
- 'z-index': props.zIndex,
408
- 'pre-title': props.preTitle,
409
- 'show-close': props.showClose,
410
- 'before-close': props.beforeClose,
411
- 'disabled-close': props.disabledClose,
412
- 'disabled-veil-click': props.disabledVeilClick,
413
- 'close-confirm': closeConfirm.value,
414
- 'close-confirm-key': props.editedCloseConfirmKey,
415
- title: props.title,
416
- size: props.size,
409
+ computedContainerTag = computed(() => {
410
+ if (props.insideModal) return 'lkt-modal';
411
+ return 'section';
412
+ }),
413
+ computedContainerAttrs = computed(() => {
414
+ if (computedContainerTag.value === 'lkt-modal') {
415
+ return {
416
+ 'modal-name': props.modalName,
417
+ 'modal-key': props.modalKey,
418
+ 'z-index': props.zIndex,
419
+ 'pre-title': props.preTitle,
420
+ 'show-close': props.showClose,
421
+ 'before-close': props.beforeClose,
422
+ 'disabled-close': props.disabledClose,
423
+ 'disabled-veil-click': props.disabledVeilClick,
424
+ 'close-confirm': closeConfirm.value,
425
+ 'close-confirm-key': props.editedCloseConfirmKey,
426
+ title: props.title,
427
+ size: props.size,
428
+ };
417
429
  }
418
- }
419
- return {};
420
- });
430
+ return {};
431
+ });
421
432
  </script>
422
433
 
423
434
  <template>
@@ -428,82 +439,105 @@
428
439
  <article class="lkt-item-crud">
429
440
  <header class="lkt-item-crud_header" v-if="!insideModal && displayHeader">
430
441
  <div class="lkt-item-crud_header-slot" v-if="slots['pre-title']">
431
- <slot name="pre-title" :item="item" :loading="isLoading"></slot>
442
+ <slot name="pre-title" :item="item" :loading="isLoading"/>
432
443
  </div>
433
444
  <h1 class="lkt-item-crud_header-title" v-if="computedTitle.length > 0">{{ computedTitle }}</h1>
434
445
  <div class="lkt-item-crud_header-slot" v-if="slots['post-title']">
435
- <slot name="post-title" :item="item" :loading="isLoading"></slot>
446
+ <slot name="post-title" :item="item" :loading="isLoading"/>
436
447
  </div>
437
448
  </header>
438
- <div class="lkt-item-crud-buttons" v-show="showButtons">
439
- <lkt-button
440
- :ref="(el:any) => saveButton = el"
441
- v-show="showSaveButton"
442
- palette="success"
443
- :disabled="!ableToSave"
444
- :confirm-modal="saveConfirm"
445
- :confirm-data="confirmData"
446
- :resource="saveResource"
447
- :resource-data="saveData"
448
- :text="slots['button-save'] ? '' : saveText"
449
- :icon="slots['button-save'] ? '' : saveIcon"
450
- v-on:loading="onButtonLoading"
451
- v-on:loaded="onButtonLoaded"
452
- v-on:click="onSave">
453
- <slot v-if="!!slots['button-save']" name="button-save" :item="item"
454
- :edit-mode="editMode"
455
- :is-create="createMode"
456
- :can-update="canUpdate"
457
- :can-drop="canDrop"></slot>
458
- </lkt-button>
459
-
460
- <lkt-button
461
- :ref="(el:any) => dropButton = el"
462
- v-show="showDropButton"
463
- v-if="!createMode"
464
- palette="danger"
465
- :disabled="dropDisabled || !canDrop"
466
- :confirm-modal="dropConfirm"
467
- :confirm-data="dropConfirmData"
468
- :resource="dropResource"
469
- :resource-data="dropData"
470
- :text="slots['button-drop'] ? '' : dropText"
471
- :icon="slots['button-drop'] ? '' : dropIcon"
472
- v-on:loading="onButtonLoading"
473
- v-on:loaded="onButtonLoaded"
474
- v-on:click="onDrop">
475
- <slot v-if="!!slots['button-drop']" name="button-drop" :item="item"
476
- :edit-mode="editMode"
477
- :is-create="createMode"
478
- :can-update="canUpdate"
479
- :can-drop="canDrop"></slot>
480
- </lkt-button>
481
449
 
482
- <div class="lkt-item-crud-buttons" v-if="slots.buttons" v-show="editMode">
483
- <slot name="buttons"/>
484
- </div>
450
+ <button-nav
451
+ ref="buttonNav"
452
+ v-show="showButtons && buttonNavPosition === 'top'"
453
+ v-model:loading="isLoading"
454
+ v-model:editing="editMode"
455
+ :item="item"
456
+ :create-mode="createMode"
457
+ :can-update="canUpdate"
458
+ :can-drop="canDrop"
459
+ :show-switch-button="showSwitchButton"
460
+ :show-save-button="showSaveButton"
461
+ :show-drop-button="showDropButton"
462
+ :able-to-save="ableToSave"
463
+ :able-to-drop="ableToDrop"
464
+ :save-confirm="saveConfirm"
465
+ :drop-confirm="dropConfirm"
466
+ :confirm-data="confirmData"
467
+ :drop-confirm-data="dropConfirmData"
468
+ :save-resource="saveResource"
469
+ :drop-resource="dropResource"
470
+ :save-data="saveData"
471
+ :drop-data="dropData"
472
+ :save-text="saveText"
473
+ :drop-text="dropText"
474
+ :save-icon="saveIcon"
475
+ :drop-icon="dropIcon"
476
+ :edit-mode-text="editModeText"
477
+ @save="onSave"
478
+ @drop="onDrop"
479
+ >
480
+ <template #prev-buttons-ever v-if="slots['prev-buttons-ever']">
481
+ <slot name="prev-buttons-ever" />
482
+ </template>
483
+ <template #prev-buttons-ever v-if="slots['prev-buttons']">
484
+ <slot name="prev-buttons" />
485
+ </template>
486
+ </button-nav>
485
487
 
486
- <lkt-button
487
- v-show="showSwitchButton"
488
- v-model:checked="editMode"
489
- class="lkt-item-crud--switch-mode-button"
490
- show-switch
491
- :text="editModeText"/>
492
- </div>
493
488
  <div class="lkt-item-crud_content" v-if="!isLoading">
494
489
  <div v-if="httpSuccessRead" class="lkt-grid-1">
495
490
  <lkt-http-info :code="httpStatus" v-if="showStoreMessage" quick
496
491
  :palette="httpStatus === 200 ? 'success' : 'danger'" can-close
497
- v-on:close="showStoreMessage = false"></lkt-http-info>
492
+ v-on:close="showStoreMessage = false"/>
498
493
  <slot name="item" :item="item" :loading="isLoading" :edit-mode="editMode"
499
494
  :is-create="createMode"
500
495
  :can-update="canUpdate"
501
496
  :can-drop="canDrop"
502
497
  :item-being-edited="itemBeingEdited"></slot>
503
498
  </div>
504
- <lkt-http-info :code="httpStatus" v-else></lkt-http-info>
499
+ <lkt-http-info :code="httpStatus" v-else/>
505
500
  </div>
506
- <lkt-loader v-if="isLoading"></lkt-loader>
501
+ <lkt-loader v-if="isLoading" />
502
+
503
+ <button-nav
504
+ ref="buttonNav"
505
+ v-if="buttonNavPosition === ButtonNavPosition.Bottom"
506
+ v-show="showButtons"
507
+ v-model:loading="isLoading"
508
+ v-model:editing="editMode"
509
+ :item="item"
510
+ :create-mode="createMode"
511
+ :can-update="canUpdate"
512
+ :can-drop="canDrop"
513
+ :show-switch-button="showSwitchButton"
514
+ :show-save-button="showSaveButton"
515
+ :show-drop-button="showDropButton"
516
+ :able-to-save="ableToSave"
517
+ :able-to-drop="ableToDrop"
518
+ :save-confirm="saveConfirm"
519
+ :drop-confirm="dropConfirm"
520
+ :confirm-data="confirmData"
521
+ :drop-confirm-data="dropConfirmData"
522
+ :save-resource="saveResource"
523
+ :drop-resource="dropResource"
524
+ :save-data="saveData"
525
+ :drop-data="dropData"
526
+ :save-text="saveText"
527
+ :drop-text="dropText"
528
+ :save-icon="saveIcon"
529
+ :drop-icon="dropIcon"
530
+ :edit-mode-text="editModeText"
531
+ @save="onSave"
532
+ @drop="onDrop"
533
+ >
534
+ <template #prev-buttons-ever v-if="slots['prev-buttons-ever']">
535
+ <slot name="prev-buttons-ever" />
536
+ </template>
537
+ <template #prev-buttons-ever v-if="slots['prev-buttons']">
538
+ <slot name="prev-buttons" />
539
+ </template>
540
+ </button-nav>
507
541
  </article>
508
542
  </component>
509
543
  </template>