@hashtagcms/admin-ui-kit 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/admin-ui-kit.min.css +14 -0
  4. package/dist/admin-ui-kit.min.js +2 -0
  5. package/dist/admin-ui-kit.min.js.LICENSE.txt +175 -0
  6. package/package.json +53 -0
  7. package/packages/components/README.md +92 -0
  8. package/packages/components/package.json +28 -0
  9. package/packages/components/src/action-bar.vue +237 -0
  10. package/packages/components/src/category-platform.vue +97 -0
  11. package/packages/components/src/category-settings.vue +815 -0
  12. package/packages/components/src/cms-module-dropdown.vue +78 -0
  13. package/packages/components/src/downlods.vue +21 -0
  14. package/packages/components/src/file-uploader.vue +188 -0
  15. package/packages/components/src/frontend-module-creator.vue +599 -0
  16. package/packages/components/src/global-site-button.vue +94 -0
  17. package/packages/components/src/homepage.vue +1087 -0
  18. package/packages/components/src/html-slot.vue +23 -0
  19. package/packages/components/src/image-gallery.vue +144 -0
  20. package/packages/components/src/index.js +53 -0
  21. package/packages/components/src/info-boxes.vue +68 -0
  22. package/packages/components/src/info-popup.vue +121 -0
  23. package/packages/components/src/language-button.vue +80 -0
  24. package/packages/components/src/language-copier.vue +177 -0
  25. package/packages/components/src/left-nav.vue +159 -0
  26. package/packages/components/src/library/copy-paste.vue +186 -0
  27. package/packages/components/src/library/info-box.vue +102 -0
  28. package/packages/components/src/library/left-menu-show-hide.vue +47 -0
  29. package/packages/components/src/library/loader.vue +141 -0
  30. package/packages/components/src/library/modal-box.vue +136 -0
  31. package/packages/components/src/library/split-button.vue +127 -0
  32. package/packages/components/src/library/timer-button.vue +43 -0
  33. package/packages/components/src/library/toast-box.vue +53 -0
  34. package/packages/components/src/menu-sorter.vue +265 -0
  35. package/packages/components/src/module-creator.vue +650 -0
  36. package/packages/components/src/module-permission.vue +334 -0
  37. package/packages/components/src/pagination.vue +125 -0
  38. package/packages/components/src/platform-button.vue +118 -0
  39. package/packages/components/src/search-bar.vue +144 -0
  40. package/packages/components/src/site-button.vue +42 -0
  41. package/packages/components/src/site-cloner.vue +150 -0
  42. package/packages/components/src/sitewise-copier.vue +234 -0
  43. package/packages/components/src/sitewise-data.vue +347 -0
  44. package/packages/components/src/sorter.vue +239 -0
  45. package/packages/components/src/tabular-view.vue +824 -0
  46. package/packages/components/src/title-bar.vue +76 -0
  47. package/packages/components/src/top-nav.vue +96 -0
  48. package/packages/helpers/README.md +88 -0
  49. package/packages/helpers/package.json +20 -0
  50. package/packages/helpers/src/admin-config.js +9 -0
  51. package/packages/helpers/src/common.js +89 -0
  52. package/packages/helpers/src/dashboard.js +16 -0
  53. package/packages/helpers/src/editor.js +163 -0
  54. package/packages/helpers/src/error-message-handler.js +50 -0
  55. package/packages/helpers/src/event-bus.js +4 -0
  56. package/packages/helpers/src/form.js +4 -0
  57. package/packages/helpers/src/fx.js +106 -0
  58. package/packages/helpers/src/humanize.js +14 -0
  59. package/packages/helpers/src/map.js +3 -0
  60. package/packages/styles/README.md +37 -0
  61. package/packages/styles/package.json +15 -0
  62. package/packages/styles/src/_action-bar.scss +35 -0
  63. package/packages/styles/src/_admin.scss +22 -0
  64. package/packages/styles/src/_animate.scss +1579 -0
  65. package/packages/styles/src/_badges.scss +34 -0
  66. package/packages/styles/src/_category-list.scss +14 -0
  67. package/packages/styles/src/_common.scss +163 -0
  68. package/packages/styles/src/_info-box.scss +96 -0
  69. package/packages/styles/src/_left-nav.scss +59 -0
  70. package/packages/styles/src/_loader.scss +82 -0
  71. package/packages/styles/src/_menu-sorter.scss +39 -0
  72. package/packages/styles/src/_model-creator.scss +48 -0
  73. package/packages/styles/src/_module-permission.scss +25 -0
  74. package/packages/styles/src/_page-manager.scss +63 -0
  75. package/packages/styles/src/_popover-modal.scss +20 -0
  76. package/packages/styles/src/_table-grid.scss +39 -0
  77. package/packages/styles/src/_toast.scss +20 -0
  78. package/packages/styles/src/_variables.scss +37 -0
  79. package/packages/styles/src/app.scss +2 -0
@@ -0,0 +1,824 @@
1
+ <template>
2
+ <div class="clearfix">
3
+ <template v-if="!isZeroResult()">
4
+ <div v-if="layoutType === 'grid'" class="row">
5
+ <div
6
+ v-for="row in rows"
7
+ :id="'row_' + row.id"
8
+ :key="row.key"
9
+ class="col"
10
+ >
11
+ <table class="table border shadow-sm mt-2 table-grid">
12
+ <tr
13
+ v-for="(fields, index) in headings"
14
+ :class="getCssForRow(fields, index)"
15
+ >
16
+ <td :class="'header head_' + getFieldName(fields)">
17
+ {{ filterFieldsName(getFieldName(fields)) }}
18
+ </td>
19
+ <td>
20
+ <span
21
+ v-if="!isActionFieldKey(getFieldName(fields, 'key'))"
22
+ v-html="
23
+ getFieldValue(row, getFieldName(fields, 'key'), fields)
24
+ "
25
+ ></span>
26
+ <div
27
+ v-if="isActionFieldKey(getFieldName(fields, 'key'))"
28
+ class="actions"
29
+ v-html="getActionValue(row)"
30
+ ></div>
31
+ </td>
32
+ </tr>
33
+ </table>
34
+ </div>
35
+ </div>
36
+ <table
37
+ v-if="layoutType === 'table'"
38
+ class="table border shadow-sm mt-2 table-grid"
39
+ >
40
+ <thead>
41
+ <tr>
42
+ <th
43
+ v-for="fields in headings"
44
+ :class="'header head_' + filterSnakeCase(getFieldName(fields))"
45
+ >
46
+ {{ filterFieldsName(getFieldName(fields)) }}
47
+ </th>
48
+ </tr>
49
+ </thead>
50
+ <tbody>
51
+ <tr
52
+ v-for="row in rows"
53
+ :id="'row_' + row.id"
54
+ :key="row.key"
55
+ class="list-table-row"
56
+ >
57
+ <td v-for="fields in headings">
58
+ <div
59
+ v-if="isActionFieldKey(getFieldName(fields, 'key'))"
60
+ class="actions"
61
+ v-html="getActionValue(row)"
62
+ ></div>
63
+ <span
64
+ v-else
65
+ v-html="getFieldValue(row, getFieldName(fields, 'key'), fields)"
66
+ ></span>
67
+ </td>
68
+ </tr>
69
+ </tbody>
70
+ </table>
71
+ </template>
72
+ <delete-popup
73
+ ref="deleteBox"
74
+ :data-show-footer="true"
75
+ :data-show-modal="false"
76
+ @on-close="deleteNow"
77
+ >
78
+ <template v-slot:title>Alert</template>
79
+ <template v-slot:content>
80
+ <span class="text-danger">{{ alertMessage.current }}</span>
81
+ </template>
82
+
83
+ <template v-slot:footer>
84
+ <div class="row">
85
+ <div class="col-auto">
86
+ <div class="form-check pt-2">
87
+ <input
88
+ id="flexCheckDefault"
89
+ v-model="preventDeleteBox"
90
+ class="form-check-input"
91
+ type="checkbox"
92
+ value=""
93
+ />
94
+ <label class="form-check-label" for="flexCheckDefault">
95
+ Don't ask again
96
+ </label>
97
+ </div>
98
+ </div>
99
+ <div class="col-auto">
100
+ <button
101
+ v-show="isDelete"
102
+ class="btn btn-default"
103
+ data-dismiss="modal"
104
+ type="button"
105
+ @click="deleteNow(0)"
106
+ >
107
+ No
108
+ </button>
109
+ <button
110
+ v-show="isDelete"
111
+ class="btn btn-primary"
112
+ type="button"
113
+ @click="deleteNow(1)"
114
+ >
115
+ Yes
116
+ </button>
117
+ <button
118
+ v-show="!isDelete"
119
+ class="btn btn-primary"
120
+ type="button"
121
+ @click="closeDialog()"
122
+ >
123
+ Okay
124
+ </button>
125
+ </div>
126
+ </div>
127
+ </template>
128
+ </delete-popup>
129
+ <info-popup ref="infoPopup"></info-popup>
130
+
131
+ <div v-if="isZeroResult()" class="row">
132
+ <div class="col">
133
+ <div v-html="noResultsFoundText"></div>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </template>
138
+
139
+ <script>
140
+ import AdminConfig from "@hashtagcms/helpers/admin-config";
141
+ import axios from "axios";
142
+
143
+ import { Toast, queryBuilder } from "@hashtagcms/helpers/common";
144
+ import { Fx } from "@hashtagcms/helpers/fx";
145
+ import { EventBus } from "@hashtagcms/helpers/event-bus";
146
+ import ModalBox from "./library/modal-box.vue";
147
+ import InfoPopup from "./info-popup.vue";
148
+
149
+ export default {
150
+ components: {
151
+ "info-popup": InfoPopup,
152
+ "delete-popup": ModalBox,
153
+ },
154
+ mounted() {
155
+ this.highlight();
156
+ this.bindAction();
157
+ //already uppercase
158
+ if (this.showDeletePopup === "FALSE") {
159
+ this.preventDeleteBox = true;
160
+ }
161
+
162
+ EventBus.on("list-view-hide-spinner", () => {
163
+ this.showHideSpinner(undefined, "false");
164
+ });
165
+
166
+ EventBus.on("info-popup-open", () => {
167
+ this.removeAllSpinners();
168
+ });
169
+
170
+ //console.log("initing tablular view");
171
+ },
172
+ created() {
173
+ //console.log("created");
174
+ //console.log(this.headings);
175
+ //console.log("this.moreActions ",this.moreActions);
176
+ //console.log("this.actionFields ",this.actionFields);
177
+ //console.log("created tablular view");
178
+ },
179
+ props: [
180
+ "dataHeaders",
181
+ "dataList",
182
+ "dataActionFields",
183
+ "dataMoreActionFields",
184
+ "dataControllerName",
185
+ "dataActionAsAjax",
186
+ "dataActionCss",
187
+ "dataUserRights",
188
+ "dataMakeFieldAsLink",
189
+ "dataShowDeletePopup",
190
+ "dataEditHandledByOtherComponent",
191
+ "dataMinResultsNeeded",
192
+ "dataLayoutType",
193
+ "dataNoResultsFoundText",
194
+ ],
195
+
196
+ data() {
197
+ return {
198
+ /*headings:(this.dataHeaders ? JSON.parse(this.dataHeaders) : []),*/
199
+ //rows: (this.dataList ? JSON.parse(this.dataList) : []),
200
+ actionFields:
201
+ this.dataActionFields && this.dataActionFields.toString() !== "null"
202
+ ? JSON.parse(this.dataActionFields)
203
+ : [],
204
+ userRights: this.dataUserRights ? JSON.parse(this.dataUserRights) : [],
205
+ moreActions:
206
+ this.dataMoreActionFields &&
207
+ this.dataMoreActionFields.toString() !== "null"
208
+ ? JSON.parse(this.dataMoreActionFields)
209
+ : [],
210
+ actionAjax:
211
+ this.dataActionAsAjax && this.dataActionAsAjax.toString() !== "null"
212
+ ? JSON.parse(this.dataActionAsAjax)
213
+ : this.getDefaultValue("action_as_ajax", []),
214
+ actionIconCss:
215
+ this.dataActionCss && this.dataActionCss.toString() !== "null"
216
+ ? JSON.parse(this.dataActionCss)
217
+ : this.getDefaultValue("action_icon_css", []),
218
+ alertMessage: {
219
+ current: "Are you sure to delete this?",
220
+ delete: "Are you sure to delete this?",
221
+ permission: "Sorry! You don't have permission to delete this.",
222
+ },
223
+ isDelete: true,
224
+ currentActionItem: null,
225
+ preventDeleteBox: false,
226
+ makeFieldAsLink: this.dataMakeFieldAsLink
227
+ ? JSON.parse(this.dataMakeFieldAsLink)
228
+ : [],
229
+ fieldAsLinkCache: {},
230
+ showDeletePopup: this.dataShowDeletePopup
231
+ ? this.dataShowDeletePopup.toString().toUpperCase()
232
+ : "FALSE",
233
+ editHandledByOtherComponent:
234
+ typeof this.dataEditHandledByOtherComponent !== "undefined" ||
235
+ (this.dataEditHandledByOtherComponent &&
236
+ this.dataEditHandledByOtherComponent.toString() === "true"),
237
+ minResultsNeeded:
238
+ typeof this.dataMinResultsNeeded === "undefined" ||
239
+ this.dataMinResultsNeeded === ""
240
+ ? -1
241
+ : parseInt(this.dataMinResultsNeeded),
242
+ layoutType:
243
+ typeof this.dataLayoutType === "undefined" || this.dataLayoutType === ""
244
+ ? "table"
245
+ : this.dataLayoutType,
246
+ noResultsFoundText: this.dataNoResultsFoundText,
247
+ spinnerCss: ["fa-spinner", "fa-pulse", "fa-fw"],
248
+ };
249
+ },
250
+ computed: {
251
+ headings() {
252
+ let heading = this.dataHeaders ? JSON.parse(this.dataHeaders) : [];
253
+
254
+ let allHeadings = [];
255
+ if (heading.length > 0) {
256
+ heading.forEach(function (current, index) {
257
+ let label = current.label || current;
258
+ let key = current.key || current;
259
+ let isImage = !!(
260
+ current.isImage && current.isImage.toString() === "true"
261
+ );
262
+ let showAllScopes = !!(
263
+ current.showAllScopes && current.showAllScopes.toString() === "true"
264
+ );
265
+ allHeadings.push({ label, key, isImage, showAllScopes });
266
+ });
267
+ }
268
+
269
+ // console.log("allHeadings ",allHeadings)
270
+ return allHeadings;
271
+ },
272
+ rows() {
273
+ return this.dataList ? JSON.parse(this.dataList) : [];
274
+ },
275
+ },
276
+ methods: {
277
+ isActionFieldKey(key) {
278
+ //will have edit/delete/approve etc
279
+ key = key === undefined ? "" : key.toLowerCase();
280
+ return key === "action" || key === "moreactions";
281
+ },
282
+ isMakeFieldAsLink(key) {
283
+ //Making Cache for good performance
284
+
285
+ if (this.fieldAsLinkCache[key] !== undefined) {
286
+ return this.fieldAsLinkCache[key];
287
+ }
288
+
289
+ //console.log("searching... "+key);
290
+
291
+ let found = this.makeFieldAsLink.find(function (current, index) {
292
+ if (current.key === key || current.action === key) {
293
+ return current;
294
+ }
295
+ });
296
+ this.fieldAsLinkCache[key] = found === undefined ? -1 : found;
297
+ return this.fieldAsLinkCache[key];
298
+ },
299
+
300
+ getFieldName(key, prop, asFilterLabel) {
301
+ prop = prop ? prop : "label";
302
+ return typeof key == "string"
303
+ ? key
304
+ : key[prop] === undefined
305
+ ? key
306
+ : key[prop];
307
+ },
308
+ getFieldValue(row, key, fields) {
309
+ //console.log("calling ", key, row.id);
310
+ let $this = this;
311
+
312
+ //console.log("key", key, fields);
313
+
314
+ //data has something like lang.name
315
+ if (key.includes(".")) {
316
+ let extract = key.split(".");
317
+ let scope = extract[0];
318
+ let fieldName = extract[1];
319
+
320
+ scope = row[scope];
321
+
322
+ switch (Object.prototype.toString.call(scope)) {
323
+ case "[object Undefined]":
324
+ scope = "";
325
+ break;
326
+ case "[object Array]":
327
+ scope =
328
+ scope.length > 0
329
+ ? fields.showAllScopes
330
+ ? getScopeAllVals(scope, fieldName)
331
+ : scope[0][fieldName]
332
+ : scope[fieldName];
333
+ break;
334
+ case "[object Object]":
335
+ scope = scope[fieldName] || "";
336
+ break;
337
+ }
338
+
339
+ return scope;
340
+ }
341
+
342
+ //get value
343
+ return getActualValue(row, key, fields);
344
+
345
+ /**
346
+ * is action
347
+ * @param searchKey
348
+ * @returns {T}
349
+ */
350
+ function isAction(searchKey) {
351
+ return $this.makeFieldAsLink.find(function (current, index) {
352
+ if (current.key === searchKey) {
353
+ return current;
354
+ }
355
+ });
356
+ }
357
+
358
+ /**
359
+ * Get all scrope values
360
+ * @param scope
361
+ * @param fieldName
362
+ */
363
+ function getScopeAllVals(scope, fieldName) {
364
+ let values = [];
365
+ if (scope.length > 0) {
366
+ for (let i = 0, len = scope.length; i < len; i++) {
367
+ values.push(scope[i][fieldName]);
368
+ }
369
+ }
370
+ return values.join(",");
371
+ }
372
+
373
+ /**
374
+ * Get actual value
375
+ * @param row
376
+ * @param forKey
377
+ * @param fields
378
+ * @returns {*}
379
+ */
380
+ function getActualValue(row, forKey, fields) {
381
+ let withIcon = true;
382
+ //var actionAlias = {"id":"edit", "publish_status":"publish"};
383
+ let value = "";
384
+
385
+ let actionAlias = $this.isMakeFieldAsLink(forKey);
386
+
387
+ // check if this is action field
388
+ if (actionAlias !== undefined && actionAlias !== -1) {
389
+ //console.log(current=="edit" && this.actionFields.indexOf("edit")!=-1);
390
+ let current = forKey;
391
+ let actionName = actionAlias.action || current;
392
+
393
+ //console.log("actionName ",actionName, " ", current);
394
+ let title = actionName.charAt(0).toUpperCase() + actionName.slice(1);
395
+ //var path = (actionName=="edit") ? `${row.id}/${actionName}` : `${actionName}/${row.id}`;
396
+ let path = `${actionName}/${row.id}`;
397
+ path = AdminConfig.admin_path(`${$this.dataControllerName}/${path}`);
398
+
399
+ let iconOrValue = row[forKey];
400
+ let isAjaxCss = "";
401
+ let status = "";
402
+
403
+ // check if this is ajax : actionAjax
404
+ if ($this.isAjax(forKey)) {
405
+ isAjaxCss = $this.getAjaxCss(current);
406
+
407
+ isAjaxCss += " " + forKey + "_" + row[forKey]; //kind of "publish_1" or "publish_0";
408
+
409
+ if (withIcon) {
410
+ let icon_css = actionAlias["css_" + row[forKey]] || "";
411
+ iconOrValue = `<i class="js_icon ${icon_css}"></i>`;
412
+ }
413
+
414
+ //if this user has no rights - disable it
415
+ if (!$this.can(actionName)) {
416
+ isAjaxCss += " disabled";
417
+ }
418
+ status = row[forKey];
419
+ }
420
+
421
+ value = `<a class="${isAjaxCss}" data-value="${status}" data-rowid="${row.id}" data-action="${actionName}" title="${title}" href="${path}">${iconOrValue}</a>`;
422
+
423
+ //if edit and
424
+ if (forKey === "id" && $this.actionFields.indexOf("edit") === -1) {
425
+ value = iconOrValue;
426
+ }
427
+ } else {
428
+ value = row[forKey];
429
+ let media_path = AdminConfig.get("media_path");
430
+ value =
431
+ fields.isImage === false
432
+ ? value
433
+ : value !== "" && value != null
434
+ ? getImgOrVideo(value, media_path)
435
+ : value;
436
+ }
437
+
438
+ function getImgOrVideo(v, mediaPath) {
439
+ let imgs = [
440
+ "apng",
441
+ "avif",
442
+ "gif",
443
+ "jpg",
444
+ "jpeg",
445
+ "jfif",
446
+ "pjpeg",
447
+ "pjp",
448
+ "png",
449
+ "svg",
450
+ "webp",
451
+ "bmp",
452
+ "ico",
453
+ "cur",
454
+ "tif",
455
+ "tiff",
456
+ ];
457
+ let vids = ["mp4", "mov", "ogg"];
458
+ let ext = v.substring(v.lastIndexOf(".") + 1);
459
+ let str = "";
460
+ if (vids.indexOf(ext) >= 0) {
461
+ str = `<a class="table-links" href="${mediaPath}/${v}" target="_blank"><video height="30"><source src="${mediaPath}/${v}"></video></a>`;
462
+ } else if (imgs.indexOf(ext) >= 0) {
463
+ str = `<a class="table-links" href="${mediaPath}/${v}" target="_blank"><img height="30" src='${mediaPath}/${v}' /></a>`;
464
+ } else {
465
+ str = `<a class="table-links" href="${mediaPath}/${v}" target="_blank">${v}</a>`;
466
+ }
467
+ return str;
468
+ }
469
+
470
+ return value;
471
+ }
472
+ },
473
+ getActionValue(row, key) {
474
+ let html = [];
475
+
476
+ //this is last column things - edit/delete etc
477
+ if (this.actionFields.length > 0) {
478
+ for (let i = 0; i < this.actionFields.length; i++) {
479
+ let current = this.actionFields[i];
480
+ let isAjax = this.getAjaxCss(current);
481
+ let title = current.charAt(0).toUpperCase() + current.slice(1);
482
+
483
+ let path = "";
484
+
485
+ if (current === "edit") {
486
+ //path = AdminConfig.admin_path(`${this.dataControllerName}/${row.id}/${current}`);
487
+ path = AdminConfig.admin_path(
488
+ `${this.dataControllerName}/${current}/${row.id}`,
489
+ );
490
+ } else if (current === "delete") {
491
+ //console.log("this.minResultsNeeded <= this.rows.length ", this.minResultsNeeded , this.rows.length)
492
+
493
+ if (
494
+ this.minResultsNeeded !== -1 &&
495
+ this.minResultsNeeded >= this.rows.length
496
+ ) {
497
+ console.info(
498
+ `Hiding delete button, because ${this.minResultsNeeded} record(s) needed.`,
499
+ );
500
+ } else {
501
+ path = AdminConfig.admin_path(
502
+ `${this.dataControllerName}/destroy/${row.id}`,
503
+ );
504
+ }
505
+ } else {
506
+ path = AdminConfig.admin_path(
507
+ `${this.dataControllerName}/${current}/${row.id}`,
508
+ );
509
+ }
510
+
511
+ if (path !== "") {
512
+ let icon = `<i class="js_icon ${this.getIconCSS(current)}"></i>`;
513
+ let link = `<a class="${isAjax}" data-rowid="${row.id}" data-action="${current}" title="${title}" href="${path}" class="${current}">${icon}</a>`;
514
+ html.push(link);
515
+ }
516
+ }
517
+ }
518
+
519
+ if (this.moreActions.length > 0) {
520
+ for (let i = 0; i < this.moreActions.length; i++) {
521
+ let current = this.moreActions[i];
522
+
523
+ let isAjax = this.getAjaxCss(current);
524
+ let css = current["css"] || "";
525
+ let attributes = "";
526
+ if (current.hrefAttributes) {
527
+ for (let attr in current.hrefAttributes) {
528
+ if (current.hrefAttributes.hasOwnProperty(attr)) {
529
+ attributes += `${attr}='${current.hrefAttributes[attr]}' `;
530
+ }
531
+ }
532
+ }
533
+ let action = current.action;
534
+ let value = row[current.action_append_field] || "";
535
+ let title =
536
+ current.label.charAt(0).toUpperCase() + current.label.slice(1);
537
+ let path = AdminConfig.admin_path(
538
+ `${this.dataControllerName}/${action}/${value}`,
539
+ );
540
+ let icon = `<i class="js_icon ${current.icon_css}"></i>`;
541
+ let link = `<a class="${isAjax} ${css}" data-rowid="${row.id}" title="${title}" href="${path}" data-action="${action}" ${attributes}>${icon}</a>`;
542
+ html.push(link);
543
+ }
544
+ }
545
+
546
+ return html.join("&nbsp;");
547
+ },
548
+ can(rights) {
549
+ return this.userRights.indexOf(rights) >= 0;
550
+ },
551
+ isAjax(action) {
552
+ return this.actionAjax.indexOf(action) >= 0;
553
+ },
554
+ getAjaxCss(action) {
555
+ let css = "";
556
+ let action_css =
557
+ Object.prototype.toString.call(action) === "[object Object]"
558
+ ? action.action
559
+ : action;
560
+ if (this.isAjax(action)) {
561
+ css = "js_action js_ajax js_" + action_css;
562
+ } else {
563
+ css = "js_action js_" + action_css;
564
+ }
565
+
566
+ return css;
567
+ },
568
+ getDefaultValue(key, dv) {
569
+ return window.Laravel.htcmsAdminConfig(key) || dv;
570
+ },
571
+ getIconCSS(key) {
572
+ let action_icon_css = this.getDefaultValue("action_icon_css", "");
573
+
574
+ return action_icon_css[key] || "";
575
+ },
576
+ getTotalColumns() {
577
+ return this.headings.length;
578
+ },
579
+ getTotalRows() {
580
+ return this.rows.length;
581
+ },
582
+ isZeroResult() {
583
+ return this.rows.length === 0;
584
+ },
585
+ highlight() {
586
+ let id = queryBuilder.get("id");
587
+ if (id !== "") {
588
+ let row = "row_" + id;
589
+ Fx.scrollWinTo("#" + row, function () {
590
+ Fx.highlight(row);
591
+ });
592
+ }
593
+ },
594
+ deleteNow(isOk = 1) {
595
+ let $this = this;
596
+ let rowid = -1;
597
+ try {
598
+ if (isOk === 1) {
599
+ let target = this.currentActionItem;
600
+ if (this.can("delete")) {
601
+ rowid = "row_" + target.getAttribute("data-rowid");
602
+ let href = target.getAttribute("href");
603
+ //Delete in db
604
+ this.doAjax("delete", href, feedback);
605
+ } else {
606
+ //sorry you don't have permission.
607
+ Toast.show($this, "Sorry! You don't have permission to delete.");
608
+ //some issue - will fix this
609
+ setTimeout(function () {
610
+ $this.showHideSpinner($this.currentActionItem, false);
611
+ }, 1000);
612
+ }
613
+ } else {
614
+ $this.showHideSpinner($this.currentActionItem, false);
615
+ }
616
+ } catch (e) {
617
+ $this.showHideSpinner($this.currentActionItem, false);
618
+ Toast.show(
619
+ $this,
620
+ "I don't understand what you are trying to do.",
621
+ 5000,
622
+ );
623
+ }
624
+
625
+ //After delete
626
+ function feedback(res) {
627
+ if (res.status === 200) {
628
+ //delete from index
629
+ let index = $this.rows.findIndex(function (current) {
630
+ return current.id.toString() === res.data.id.toString();
631
+ });
632
+ if (index >= 0) {
633
+ Toast.show($this, "Record has been deleted", 2000);
634
+ if (document.getElementById(rowid)) {
635
+ document.getElementById(rowid).remove();
636
+ }
637
+ $this.rows.splice(index, 1);
638
+ $this.bindAction();
639
+ EventBus.emit("pagination-on-delete");
640
+ }
641
+ } else {
642
+ $this.showHideSpinner($this.currentActionItem, false);
643
+ Toast.show($this, "Ooops! Got some error!");
644
+ }
645
+ }
646
+
647
+ this.closeDialog();
648
+ },
649
+ showHideSpinner(event, show = true) {
650
+ let css = this.spinnerCss;
651
+ if (event) {
652
+ let current =
653
+ event instanceof HTMLAnchorElement ? event : event.currentTarget;
654
+ this.removeAllSpinners(); //remove old one
655
+ if (show === true) {
656
+ current.firstElementChild.classList.add(...css);
657
+ }
658
+ } else {
659
+ //remove all spinner
660
+ this.removeAllSpinners();
661
+ }
662
+ },
663
+ removeAllSpinners() {
664
+ let css = this.spinnerCss;
665
+ let allSpinners = document.querySelectorAll(".fa-spinner");
666
+ if (allSpinners.length > 0) {
667
+ allSpinners.forEach(function (current) {
668
+ current.classList.remove(...css);
669
+ });
670
+ }
671
+ },
672
+ closeDialog() {
673
+ this.$refs.deleteBox.close();
674
+ //this.currentActionItem = null;
675
+ },
676
+ doAjax(methodType = "get", url, success, fail) {
677
+ let $this = this;
678
+ return axios[methodType](url)
679
+ .then(function (res) {
680
+ if (success) {
681
+ success.apply(this, arguments);
682
+ //success(res);
683
+ }
684
+ })
685
+ .catch(function (res) {
686
+ if (fail) {
687
+ //fail(res);
688
+ fail.apply(fail, arguments);
689
+ } else {
690
+ //show default message
691
+ Toast.show($this, res.message, 5000);
692
+ }
693
+
694
+ $this.showHideSpinner($this.currentActionItem, false);
695
+ });
696
+ },
697
+ initAjaxAction(event) {
698
+ //@todo: action needs to handle in separate module
699
+ event.preventDefault();
700
+ event.stopPropagation();
701
+
702
+ let $this = this;
703
+ let current = event.currentTarget;
704
+
705
+ //console.log("current ",current);
706
+ let dataset = current.dataset;
707
+ let action = dataset.action;
708
+ let status = dataset["value"];
709
+ let href = current.getAttribute("href");
710
+ if (status) {
711
+ href = href + "/" + status;
712
+ }
713
+
714
+ this.currentActionItem = current;
715
+
716
+ switch (action) {
717
+ //handle special case
718
+ case "delete":
719
+ this.alertMessage.current = this.alertMessage.delete;
720
+ this.isDelete = true;
721
+ //prevent delete box is true then don't show delete box popup
722
+ if (this.preventDeleteBox === false) {
723
+ this.openDeleteAlert(current);
724
+ } else {
725
+ this.deleteNow(1);
726
+ }
727
+ //this.openPermissionAlert();
728
+ break;
729
+ case "showinfo":
730
+ let whatinfo = dataset.info;
731
+ let editable = dataset.editable;
732
+ let rowid = dataset.rowid;
733
+ let excludeFields = dataset.excludefields || [];
734
+ this.showInfo(whatinfo, rowid, excludeFields, editable);
735
+ break;
736
+
737
+ default:
738
+ this.doAjax(
739
+ "get",
740
+ href,
741
+ function (res) {
742
+ $this.showHideSpinner(current, false);
743
+
744
+ let actionFieldProp = $this.isMakeFieldAsLink(action);
745
+
746
+ //remove old class
747
+ let icon = current.getElementsByClassName("js_icon");
748
+ let icon_css = actionFieldProp["css_" + status];
749
+ if (icon.length > 0) {
750
+ icon = icon[0];
751
+ icon.classList.remove(...icon_css.split(" "));
752
+ }
753
+ //set new value
754
+ current.setAttribute("data-value", res.data.status);
755
+ //css handling
756
+ icon_css = actionFieldProp["css_" + res.data.status];
757
+ icon.classList.add(...icon_css.split(" "));
758
+ },
759
+ function (res) {
760
+ $this.showHideSpinner(current, false);
761
+ Toast.show(
762
+ $this,
763
+ res?.response?.data?.message || "Unknown Error!",
764
+ 3000,
765
+ );
766
+ },
767
+ );
768
+ break;
769
+ }
770
+ },
771
+ bindAction() {
772
+ let allElement = this.$el.getElementsByClassName("js_action");
773
+
774
+ //console.log(allElement);
775
+
776
+ for (let i = 0; i < allElement.length; i++) {
777
+ let current = allElement[i];
778
+ if (current.classList.contains("js_ajax")) {
779
+ current.addEventListener("click", this.initAjaxAction, false);
780
+ }
781
+ if (current.classList.contains("js_action")) {
782
+ current.addEventListener("click", this.showHideSpinner, false);
783
+ }
784
+ }
785
+
786
+ //handle edit
787
+ if (this.editHandledByOtherComponent === true) {
788
+ let editElements = this.$el.querySelectorAll("a[data-action='edit']");
789
+ editElements.forEach(function (current, index) {
790
+ current.addEventListener("click", function (event) {
791
+ event.preventDefault();
792
+ EventBus.emit("list-view-pre-edit", this);
793
+ });
794
+ });
795
+ }
796
+ },
797
+ openDeleteAlert(current) {
798
+ this.$refs.deleteBox.open(current);
799
+ },
800
+ openPermissionAlert() {
801
+ this.alertMessage.current = this.alertMessage.permission;
802
+ this.isDelete = false;
803
+ this.currentActionItem = null;
804
+ this.$refs.deleteBox.open();
805
+ },
806
+ filterFieldsName(value) {
807
+ value = value.replace(/\.|_/g, " ");
808
+ return value.charAt(0).toUpperCase() + value.slice(1);
809
+ },
810
+ filterSnakeCase(value) {
811
+ return value.replace(/\s|\./g, "_").toLowerCase();
812
+ },
813
+ getCssForRow: function (fields, index) {
814
+ if (fields.length - 1 === index) {
815
+ return "active";
816
+ }
817
+ return "";
818
+ },
819
+ showInfo(type, id, excludeFields, editable) {
820
+ this.$refs.infoPopup.showInfo(type, id, excludeFields, editable);
821
+ },
822
+ },
823
+ };
824
+ </script>