@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,136 @@
1
+ <template>
2
+ <div :class="modelCss" tabindex="-1" aria-hidden="true" :style="style">
3
+ <div
4
+ :class="
5
+ 'modal-dialog modal-dialog-centered modal-dialog-scrollable ' +
6
+ dataModalCss
7
+ "
8
+ :style="modalWidth"
9
+ >
10
+ <div class="modal-content">
11
+ <div :class="titleCss + ' modal-header'">
12
+ <h5 class="modal-title" style="width: 100%">
13
+ <slot name="title">{{ title }}</slot>
14
+ </h5>
15
+ <button
16
+ type="button"
17
+ class="btn-close"
18
+ data-bs-dismiss="modal"
19
+ aria-label="Close"
20
+ @click="sendData(0)"
21
+ ></button>
22
+ </div>
23
+ <div :class="contentCss + ' modal-body'">
24
+ <slot name="content">{{ content }}</slot>
25
+ </div>
26
+ <div :class="footerCss + ' modal-footer'" v-show="showFooter">
27
+ <slot name="footer">{{ footerContent }}</slot>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ <div class="modal-backdrop fade show" :style="backDropStyle"></div>
33
+ </template>
34
+
35
+ <script>
36
+ export default {
37
+ emits: ["onClose"],
38
+ props: [
39
+ "dataShowModal",
40
+ "dataShowFooter",
41
+ "dataTitleCss",
42
+ "dataContentCss",
43
+ "dataFooterCss",
44
+ "dataModalCss",
45
+ "dataWidth",
46
+ ],
47
+ mounted() {
48
+ if (this.visible) {
49
+ this.open();
50
+ }
51
+ },
52
+ data() {
53
+ return {
54
+ modelCss: "modal modal-lg fade show",
55
+ titleCss:
56
+ typeof this.dataTitleCss === "undefined" ? "" : this.dataTitleCss,
57
+ contentCss:
58
+ typeof this.dataContentCss === "undefined" ? "" : this.dataContentCss,
59
+ footerCss:
60
+ typeof this.dataFooterCss === "undefined" ? "" : this.dataFooterCss,
61
+ visible:
62
+ this.dataShowModal !== undefined &&
63
+ this.dataShowModal.toString() === "true",
64
+ style: "",
65
+ toBeReturned: {},
66
+ title: "Alert",
67
+ content: "Modal Content",
68
+ footerContent: "",
69
+ backDropStyle: "display:none",
70
+ };
71
+ },
72
+ computed: {
73
+ showFooter() {
74
+ return (
75
+ (typeof this.dataShowFooter !== "undefined" &&
76
+ this.dataShowFooter.toString() === "true") ||
77
+ this.footerContent !== ""
78
+ );
79
+ },
80
+ modalWidth() {
81
+ if (typeof this.dataWidth != "undefined" && this.dataWidth !== "") {
82
+ return `width:${this.dataWidth}`;
83
+ } else {
84
+ return "";
85
+ }
86
+ },
87
+ },
88
+ methods: {
89
+ open(toBeReturned = {}) {
90
+ this.visible = true;
91
+ this.backDropStyle = this.style = "display:block";
92
+ this.modelCss = "modal modal-lg fade show animated bounceInDown";
93
+ this.toBeReturned = toBeReturned;
94
+ },
95
+ close() {
96
+ this.visible = false;
97
+ this.modelCss = "modal modal-lg animated bounceOutUp";
98
+ this.backDropStyle = "display:none";
99
+
100
+ if (typeof this.toBeReturned === "function") {
101
+ this.toBeReturned();
102
+ }
103
+ },
104
+ sendData(isOkay) {
105
+ this.close();
106
+ this.$emit("onClose", isOkay, this.toBeReturned);
107
+ },
108
+
109
+ show(message, position, callback, timeout) {
110
+ if (typeof message == "string") {
111
+ this.content = message;
112
+ } else {
113
+ if (message.title) {
114
+ this.title = message.title;
115
+ }
116
+ if (message.content) {
117
+ this.content = message.content;
118
+ }
119
+ if (message.footerContent) {
120
+ this.footerContent = message.footerContent;
121
+ }
122
+ }
123
+
124
+ //handle position
125
+ if (position) {
126
+ //align this
127
+ }
128
+
129
+ this.open(callback);
130
+ },
131
+ hide() {
132
+ this.close();
133
+ },
134
+ },
135
+ };
136
+ </script>
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <div class="dropdown">
3
+ <a
4
+ :class="'btn btn-secondary dropdown-toggle ' + btnCss"
5
+ href="#"
6
+ role="button"
7
+ data-bs-toggle="dropdown"
8
+ aria-expanded="false"
9
+ @click="toggleMenu()"
10
+ >
11
+ {{ current.label }}
12
+ </a>
13
+ <ul class="dropdown-menu shadow" :style="display" ref="dropdownMenu">
14
+ <li
15
+ :class="isActive(item)"
16
+ v-for="(item, index) in lists"
17
+ @click="setCurrent(index)"
18
+ >
19
+ {{ item.label }}
20
+ </li>
21
+ </ul>
22
+ </div>
23
+ </template>
24
+
25
+ <script>
26
+ export default {
27
+ mounted() {
28
+ this.normalizeData();
29
+ //console.log(this.lists);
30
+ },
31
+
32
+ props: [
33
+ "dataOptions",
34
+ "dataSelected",
35
+ "dataParser",
36
+ "dataOnChange",
37
+ "dataBtnCss",
38
+ ],
39
+ data() {
40
+ return {
41
+ display: "",
42
+ formatter: this.dataParser,
43
+ lists:
44
+ typeof this.dataOptions != "undefined" &&
45
+ typeof this.dataOptions == "string"
46
+ ? JSON.parse(this.dataOptions)
47
+ : this.dataOptions,
48
+ current: {},
49
+ selectedIndex:
50
+ typeof this.dataSelected == "undefined"
51
+ ? 0
52
+ : parseInt(this.dataSelected),
53
+ openCSS: "",
54
+ btnCss: typeof this.dataBtnCss == "undefined" ? "" : this.dataBtnCss,
55
+ };
56
+ },
57
+ computed: {
58
+ onChange() {
59
+ let method =
60
+ typeof this.dataOnChange == "undefined" ? null : this.dataOnChange;
61
+ if (typeof method == "string") {
62
+ return eval(method);
63
+ }
64
+ return method;
65
+ },
66
+ },
67
+ methods: {
68
+ toggleMenu() {
69
+ this.display = this.display === "" ? "display:block" : "";
70
+ if (this.display !== "") {
71
+ //this.openCSS = 'animated slideInDown';
72
+ this.bindDocumentClick();
73
+ }
74
+ },
75
+ isActive(item) {
76
+ if (this.current.value === item.value) {
77
+ return "dropdown-item active hand";
78
+ }
79
+ return "dropdown-item hand";
80
+ },
81
+ normalizeData() {
82
+ let formatter = this.formatter;
83
+ let arr = [];
84
+ this.lists.forEach(function (item, index) {
85
+ if (typeof formatter == "function") {
86
+ arr.push(formatter(item));
87
+ } else if (typeof index == "number") {
88
+ arr.push({ label: item, value: item });
89
+ }
90
+ });
91
+
92
+ this.lists = arr;
93
+ this.current = this.lists[this.selectedIndex];
94
+ },
95
+ setCurrent(index) {
96
+ this.current = this.lists[index];
97
+ this.current.index = index;
98
+
99
+ if (this.onChange != null && typeof this.onChange == "function") {
100
+ this.onChange(this.current);
101
+ }
102
+
103
+ this.$emit("change", this.current);
104
+ },
105
+ mangeShowHide(event) {
106
+ let element = this.$refs.dropdownMenu;
107
+ let target = event.target;
108
+
109
+ if (element !== target && !element.contains(target)) {
110
+ this.display = "";
111
+ this.unBindDocumentClick();
112
+ }
113
+ },
114
+ bindDocumentClick() {
115
+ document.addEventListener("mouseup", this.mangeShowHide);
116
+ },
117
+ unBindDocumentClick() {
118
+ document.removeEventListener("mouseup", this.mangeShowHide);
119
+ },
120
+ setData(data) {
121
+ this.lists = [];
122
+ this.lists = data;
123
+ this.normalizeData();
124
+ },
125
+ },
126
+ };
127
+ </script>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <a href="#" @click="goBack()" class="btn btn-outline-secondary"
3
+ ><slot>Back in </slot
4
+ ><span>{{ totalTime - timeRemaining }} {{ seconds }}</span></a
5
+ >
6
+ </template>
7
+
8
+ <script>
9
+ export default {
10
+ props: ["dataBackUrl", "dataTimeout"],
11
+ data() {
12
+ return {
13
+ totalTime:
14
+ typeof this.dataTimeout == "undefined" ? 5 : parseInt(this.dataTimeout),
15
+ timeRemaining: 0,
16
+ intervalId: 0,
17
+ seconds: "Seconds",
18
+ };
19
+ },
20
+ mounted() {
21
+ this.intervalId = setInterval(this.updateTime, 1000);
22
+ },
23
+ methods: {
24
+ goBack() {
25
+ //console.log(this.dataBackUrl);
26
+ clearInterval(this.intervalId);
27
+ window.location.href = this.dataBackUrl;
28
+ },
29
+
30
+ updateTime() {
31
+ if (this.timeRemaining >= this.totalTime) {
32
+ clearInterval(this.intervalId);
33
+ this.goBack();
34
+ } else {
35
+ this.timeRemaining++;
36
+ }
37
+
38
+ this.seconds =
39
+ this.totalTime - this.timeRemaining <= 1 ? "Second" : "Seconds";
40
+ },
41
+ },
42
+ };
43
+ </script>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <div class="toasterHolder jsToast shadow" v-show="showMe">
3
+ <div class="toasterContent">
4
+ {{ message }}
5
+ </div>
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+ export default {
11
+ mounted() {},
12
+ data() {
13
+ return {
14
+ showMe: false,
15
+ message: "Toast Content",
16
+ intervalId: 0,
17
+ };
18
+ },
19
+ methods: {
20
+ show(message = "", timeout = 3000, position) {
21
+ this.hide();
22
+ let $this = this;
23
+ this.showMe = true;
24
+ this.message = message !== "" ? message : "";
25
+ this.$nextTick(function () {
26
+ this.align(position);
27
+ });
28
+
29
+ this.intervalId = setTimeout(function () {
30
+ $this.hide();
31
+ }, timeout);
32
+ },
33
+ hide() {
34
+ this.showMe = false;
35
+ if (this.intervalId) {
36
+ clearInterval(this.intervalId);
37
+ }
38
+ },
39
+ align(position) {
40
+ let left =
41
+ position !== undefined
42
+ ? position.left
43
+ : window.innerWidth / 2 - this.$el.offsetWidth / 2;
44
+ let top =
45
+ position !== undefined
46
+ ? position.top
47
+ : window.innerHeight / 2 - this.$el.offsetHeight / 2 + window.scrollY;
48
+ this.$el.style.top = top + "px";
49
+ this.$el.style.left = left + "px";
50
+ },
51
+ },
52
+ };
53
+ </script>
@@ -0,0 +1,265 @@
1
+ <template>
2
+ <div>
3
+ <h4 v-if="showGroups">
4
+ Arrange Menus
5
+ <split-button
6
+ :data-options="groups"
7
+ @change="arrangeAgain"
8
+ :data-selected="selectedIndex"
9
+ >
10
+ </split-button>
11
+ </h4>
12
+ <ul class="sortable-list js_sortable">
13
+ <template v-for="(item, index) in allData">
14
+ <li
15
+ data-is-parent="true"
16
+ v-if="isParent(item)"
17
+ class="item"
18
+ :data-id="getId(item)"
19
+ >
20
+ <span v-html="getName(item)"></span>
21
+ <div v-if="hasChild(item)" class="inline">
22
+ <label :for="'item_' + index" class="accordion-header pull-right">
23
+ <span class="fa fa-ellipsis-v ellipsis"></span>
24
+ </label>
25
+ <input
26
+ :id="'item_' + index"
27
+ type="checkbox"
28
+ class="accordion-control"
29
+ />
30
+ <ul class="child accordion-body js_sortable">
31
+ <li
32
+ data-is-parent="false"
33
+ class="item"
34
+ v-for="child in item.child"
35
+ :data-id="getId(child)"
36
+ >
37
+ {{ getName(child) }}
38
+ </li>
39
+ </ul>
40
+ </div>
41
+ </li>
42
+ </template>
43
+ </ul>
44
+ <div class="center-align mt-3" v-if="allData.length > 1">
45
+ <input
46
+ type="button"
47
+ class="btn btn-success btn-from-submit"
48
+ value="Save"
49
+ @click="updateIndex()"
50
+ />
51
+ </div>
52
+ </div>
53
+ </template>
54
+
55
+ <script>
56
+ import AdminConfig from "@hashtagcms/helpers/admin-config";
57
+
58
+ import Sortable from "sortablejs";
59
+ import { Toast, Loader } from "@hashtagcms/helpers/common";
60
+
61
+ import SplitButton from "./library/split-button.vue";
62
+
63
+ export default {
64
+ components: {
65
+ "split-button": SplitButton,
66
+ },
67
+
68
+ mounted() {
69
+ this.enableSorting();
70
+ //console.log(this.controllerName);
71
+ //console.log(this.allData);
72
+ },
73
+
74
+ props: [
75
+ "dataAllData",
76
+ "dataFields",
77
+ "dataControllerName",
78
+ "dataControllerChildName",
79
+ "dataGroups",
80
+ "dataGroupName",
81
+ "dataShowGroups",
82
+ ],
83
+
84
+ data() {
85
+ return {
86
+ allData:
87
+ this.dataAllData && this.dataAllData !== "null"
88
+ ? JSON.parse(this.dataAllData)
89
+ : [],
90
+ groups:
91
+ this.dataGroups && this.dataGroups !== ""
92
+ ? JSON.parse(this.dataGroups)
93
+ : [],
94
+ groupName:
95
+ this.dataGroupName && this.dataGroupName !== ""
96
+ ? this.dataGroupName
97
+ : "",
98
+ showGroups: !!(this.dataShowGroups && this.dataShowGroups === "true"),
99
+ };
100
+ },
101
+ computed: {
102
+ fields() {
103
+ let fields =
104
+ this.dataFields && this.dataFields !== "null"
105
+ ? JSON.parse(this.dataFields)
106
+ : null;
107
+ if (fields === null) {
108
+ fields = {};
109
+ fields.id = "id";
110
+ fields.label = "name";
111
+ fields.isImage = false;
112
+ }
113
+ return fields;
114
+ },
115
+ controllerName() {
116
+ let cName =
117
+ typeof this.dataControllerName == "undefined"
118
+ ? ""
119
+ : this.dataControllerName.toLowerCase();
120
+ return cName.replace(/\s/g, "");
121
+ },
122
+ controlerChildName() {
123
+ let cName =
124
+ typeof this.dataControllerChildName == "undefined"
125
+ ? ""
126
+ : this.dataControllerChildName.toLowerCase();
127
+ return cName.replace(/\s/g, "");
128
+ },
129
+ selectedIndex() {
130
+ let index = 0;
131
+ for (let i = 0; i < this.groups.length; i++) {
132
+ if (this.groups[i] === this.groupName) {
133
+ index = i;
134
+ break;
135
+ }
136
+ }
137
+ return index;
138
+ },
139
+ },
140
+ methods: {
141
+ isParent(data) {
142
+ return data.parent_id === 0 || !data.parent_id;
143
+ },
144
+ arrangeAgain(data) {
145
+ window.location.href = AdminConfig.admin_path(
146
+ this.controllerName + "/sort/" + data.value,
147
+ );
148
+ },
149
+ hasChild(data) {
150
+ return data.child && data.child.length > 0;
151
+ },
152
+ getName(data) {
153
+ //Added media support
154
+ if (this.fields.isImage === true) {
155
+ let path = data[this.fields.label]
156
+ ? AdminConfig.get_media(data[this.fields.label])
157
+ : AdminConfig.get_media(data.lang[this.fields.label]);
158
+ return `<a href='${path}' target='_blank'><img height='30' src='${path}' /></a>`;
159
+ } else {
160
+ return data[this.fields.label]
161
+ ? data[this.fields.label]
162
+ : data.lang[this.fields.label];
163
+ }
164
+ },
165
+ getId(data) {
166
+ return data[this.fields.id];
167
+ },
168
+ enableSorting() {
169
+ let $this = this;
170
+ this.$nextTick(function () {
171
+ let list = document.querySelectorAll(".js_sortable");
172
+ list.forEach(function (current) {
173
+ Sortable.create(current, {
174
+ animation: 500,
175
+ ghostClass: "text-danger",
176
+ onUpdate: function (/**Event*/ evt) {
177
+ //console.log("onUpdate ", evt.item);
178
+ //let item = evt.item;
179
+ //let isParent = (item.getAttribute("data-is-parent") === "true");
180
+ //$this.updateIndex(isParent);
181
+ },
182
+ });
183
+ });
184
+ });
185
+ },
186
+ submit(requestType, url, data, controllerName) {
187
+ Loader.show(this, "Please wait. Saving sorting data...");
188
+ return new Promise((resolve, reject) => {
189
+ axios[requestType](url, data)
190
+ .then((response) => {
191
+ this.onSuccess(response, controllerName);
192
+ })
193
+ .catch((error) => {
194
+ this.onFailure(error.response);
195
+ })
196
+ .finally(() => {
197
+ Loader.hide(this);
198
+ });
199
+ });
200
+ },
201
+ updateIndex(isParent = false) {
202
+ let items = document.querySelectorAll(".item");
203
+ let datas = [];
204
+
205
+ let controllerName = this.controllerName;
206
+
207
+ let saveAll = true;
208
+
209
+ if (this.controlerChildName !== "") {
210
+ saveAll = false;
211
+ }
212
+
213
+ controllerName =
214
+ isParent === true
215
+ ? this.controllerName
216
+ : this.controlerChildName !== ""
217
+ ? this.controlerChildName
218
+ : this.controllerName;
219
+
220
+ let counter = 1;
221
+
222
+ console.log("saveAll " + saveAll);
223
+
224
+ items.forEach(function (current, index) {
225
+ if (saveAll === true) {
226
+ let id = current.getAttribute("data-id");
227
+ let position = counter;
228
+ datas.push({ position: position, where: { id: parseInt(id) } });
229
+ counter = counter + 1;
230
+ } else {
231
+ let isParentElement = current.getAttribute("data-is-parent");
232
+ let id = current.getAttribute("data-id");
233
+
234
+ if (isParent.toString() === isParentElement.toString()) {
235
+ let id = current.getAttribute("data-id");
236
+ let position = counter;
237
+ datas.push({ position: position, where: { id: parseInt(id) } });
238
+ counter = counter + 1;
239
+ }
240
+ }
241
+ });
242
+
243
+ let updateIndexUrl = AdminConfig.admin_path(
244
+ controllerName + "/updateIndex",
245
+ );
246
+
247
+ this.submit("post", updateIndexUrl, datas, controllerName);
248
+ },
249
+ onSuccess(res, controllerName) {
250
+ Toast.show(this, controllerName.toUpperCase() + " Sorted.");
251
+ },
252
+ onFailure(res) {
253
+ Toast.show(
254
+ this,
255
+ res?.statusText || "There is some error! Don't know the reason",
256
+ 5000,
257
+ );
258
+ console.log(res);
259
+ },
260
+ setData(data) {
261
+ this.allData = data;
262
+ },
263
+ },
264
+ };
265
+ </script>