@tager/admin-banners 0.2.0 → 0.3.2

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 (77) hide show
  1. package/dist/constants/menu.d.ts +4 -1
  2. package/dist/constants/paths.d.ts +8 -15
  3. package/dist/constants/routes.d.ts +3 -4
  4. package/dist/hooks/index.d.ts +2 -0
  5. package/dist/hooks/useFetchBanner.d.ts +8 -0
  6. package/dist/hooks/useFetchBanners.d.ts +6 -0
  7. package/dist/hooks/useFetchZones.d.ts +6 -0
  8. package/dist/index.esm.js +3202 -875
  9. package/dist/index.umd.js +3216 -886
  10. package/dist/locales/en.d.ts +39 -0
  11. package/dist/locales/ru.d.ts +3 -0
  12. package/dist/{index.d.ts → main.d.ts} +1 -0
  13. package/dist/router/index.d.ts +4 -0
  14. package/dist/services/requests.d.ts +22 -35
  15. package/dist/typings/banners.d.ts +40 -0
  16. package/dist/typings/common.d.ts +1 -0
  17. package/dist/typings/model.d.ts +103 -15
  18. package/dist/typings/zones.d.ts +5 -0
  19. package/dist/utils/common.d.ts +2 -0
  20. package/dist/views/Banners/BannerForm/BannerForm.helpers.d.ts +5 -0
  21. package/dist/views/Banners/BannerForm/BannerForm.vue.d.ts +81 -0
  22. package/dist/views/Banners/BannerForm/index.d.ts +1 -0
  23. package/dist/views/Banners/BannerList/BannerList.helpers.d.ts +5 -0
  24. package/dist/views/Banners/BannerList/BannerList.vue.d.ts +55 -0
  25. package/dist/views/Banners/BannerList/hooks/index.d.ts +1 -0
  26. package/dist/views/Banners/BannerList/hooks/useAdvancedSearch.d.ts +21 -0
  27. package/dist/views/Banners/BannerList/index.d.ts +1 -0
  28. package/dist/views/Zones/ZoneList/ZoneList.helpers.d.ts +5 -0
  29. package/dist/views/Zones/ZoneList/ZoneList.vue.d.ts +28 -0
  30. package/dist/views/Zones/ZoneList/index.d.ts +1 -0
  31. package/package.json +32 -23
  32. package/src/config/config.json +1 -1
  33. package/src/constants/menu.ts +24 -10
  34. package/src/constants/paths.ts +10 -27
  35. package/src/constants/routes.ts +27 -49
  36. package/src/dev.ts +22 -34
  37. package/src/hooks/index.ts +2 -0
  38. package/src/hooks/useFetchBanner.ts +41 -0
  39. package/src/hooks/useFetchBanners.ts +23 -0
  40. package/src/hooks/useFetchZones.ts +23 -0
  41. package/src/locales/en.ts +43 -0
  42. package/src/locales/ru.ts +45 -0
  43. package/src/main.ts +12 -0
  44. package/src/router/index.ts +38 -0
  45. package/src/services/requests.ts +35 -86
  46. package/src/typings/banners.ts +44 -0
  47. package/src/typings/common.ts +1 -0
  48. package/src/typings/model.ts +119 -16
  49. package/src/typings/shims-vue.d.ts +1 -0
  50. package/src/typings/translate.d.ts +10 -0
  51. package/src/typings/zones.ts +5 -0
  52. package/src/utils/common.ts +13 -0
  53. package/src/views/App.vue +7 -7
  54. package/src/views/Banners/BannerForm/BannerForm.helpers.ts +38 -0
  55. package/src/views/Banners/BannerForm/BannerForm.vue +236 -0
  56. package/src/views/Banners/BannerForm/index.ts +1 -0
  57. package/src/views/Banners/BannerList/BannerList.helpers.ts +93 -0
  58. package/src/views/Banners/BannerList/BannerList.vue +233 -0
  59. package/src/views/Banners/BannerList/hooks/index.ts +1 -0
  60. package/src/views/Banners/BannerList/hooks/useAdvancedSearch.ts +152 -0
  61. package/src/views/Banners/BannerList/index.ts +1 -0
  62. package/src/views/Home.vue +37 -0
  63. package/src/views/Zones/ZoneList/ZoneList.helpers.ts +34 -0
  64. package/src/views/Zones/ZoneList/ZoneList.vue +75 -0
  65. package/src/views/Zones/ZoneList/index.ts +1 -0
  66. package/dist/views/BannerAreaForm.vue.d.ts +0 -22
  67. package/dist/views/BannerAreaList.vue.d.ts +0 -17
  68. package/dist/views/BannerItemForm.vue.d.ts +0 -27
  69. package/dist/views/BannerItemList.vue.d.ts +0 -22
  70. package/src/index.ts +0 -3
  71. package/src/locales/en.js +0 -3
  72. package/src/locales/ru.js +0 -3
  73. package/src/views/BannerAreaForm.vue +0 -173
  74. package/src/views/BannerAreaList.vue +0 -176
  75. package/src/views/BannerItemForm.vue +0 -231
  76. package/src/views/BannerItemList.vue +0 -221
  77. package/typings/index.d.ts +0 -15
package/dist/index.umd.js CHANGED
@@ -1,181 +1,177 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('@tager/admin-services'), require('path-to-regexp'), require('@tager/admin-ui')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'vue', '@tager/admin-services', 'path-to-regexp', '@tager/admin-ui'], factory) :
4
- (global = global || self, factory(global.TagerAdminBlog = {}, global.Vue, global.adminServices, global.pathToRegexp, global.adminUi));
5
- }(this, (function (exports, Vue, adminServices, pathToRegexp, adminUi) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tager/admin-services'), require('@vue/composition-api'), require('@tager/admin-ui'), require('path-to-regexp')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@tager/admin-services', '@vue/composition-api', '@tager/admin-ui', 'path-to-regexp'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TagerAdminBanners = {}, global.adminServices, global.compositionApi, global.adminUi, global.pathToRegexp));
5
+ }(this, (function (exports, adminServices, compositionApi, adminUi, pathToRegexp) { 'use strict';
6
6
 
7
- Vue = Vue && Object.prototype.hasOwnProperty.call(Vue, 'default') ? Vue['default'] : Vue;
7
+ const EN = {
8
+ home: 'Home',
9
+ zone: 'Banner zone',
10
+ zones: 'Banner zones',
11
+ banners: 'Banners',
12
+ bannerForm: 'Banner Form',
13
+ createBanner: 'Create Banner',
14
+ updateBanner: 'Update Banner',
15
+ link: 'Link',
16
+ image: 'Image',
17
+ openNewTab: 'Open new tab',
18
+ period: 'Period',
19
+ from: 'From',
20
+ to: 'To',
21
+ disabled: 'Disabled',
22
+ comment: 'Comment',
23
+ status: 'Status',
24
+ bannerZoneIsDeleted: 'Banner zone is deleted',
25
+ newTab: 'New Tab',
26
+ yes: 'Yes',
27
+ no: 'No',
28
+ edit: 'Edit',
29
+ remove: 'Remove',
30
+ actions: 'actions',
31
+ date: 'Date',
32
+ success: 'Success',
33
+ error: 'Error',
34
+ statuses: {
35
+ waiting: 'Waiting',
36
+ archived: 'Archived',
37
+ active: 'Active',
38
+ disabled: 'Disabled',
39
+ },
40
+ bannerWasSuccessfullyCreated: 'Banner was successfully created',
41
+ bannerWasSuccessfullyUpdated: 'Banner was successfully updated',
42
+ bannerCreationWasFailed: 'Banner creation was failed',
43
+ bannerUpdateWasFailed: 'Banner update was failed',
44
+ };
8
45
 
9
- /** Banner area */
10
- function getBannerAreaList() {
11
- return adminServices.request.get({ path: '/admin/market-boards' });
12
- }
13
- function getBannerAreaById(areaId) {
14
- return adminServices.request.get({ path: `/admin/market-boards/${areaId}` });
15
- }
16
- function getBannerAreaByAlias(areaAlias) {
17
- return adminServices.request.get({ path: `/admin/market-boards/${areaAlias}` });
18
- }
19
- function createBannerArea(payload) {
20
- return adminServices.request.post({ path: '/admin/market-boards', body: payload });
21
- }
22
- function updateBannerArea(areaId, payload) {
23
- return adminServices.request.put({ path: `/admin/market-boards/${areaId}`, body: payload });
24
- }
25
- function deleteBannerArea(areaId) {
26
- return adminServices.request.delete({ path: `/admin/market-boards/${areaId}` });
46
+ const RU = {
47
+ home: 'Главная',
48
+ zone: 'Баннерная зона',
49
+ zones: 'Баннерные зоны',
50
+ banners: 'Баннеры',
51
+ bannerForm: 'Форма баннера',
52
+ createBanner: 'Добавить баннер',
53
+ updateBanner: 'Редактировать баннер',
54
+ link: 'Ссылка',
55
+ image: 'Картинка',
56
+ openNewTab: 'Открывать в новой вкладке',
57
+ period: 'Срок действия',
58
+ from: 'От',
59
+ to: 'До',
60
+ disabled: 'Выключен',
61
+ comment: 'Комментарий',
62
+ status: 'Статус',
63
+ bannerZoneIsDeleted: 'Баннерная зона удалена',
64
+ newTab: 'Новая вкладка',
65
+ yes: 'Да',
66
+ no: 'Нет',
67
+ edit: 'Редактировать',
68
+ remove: 'Удалить',
69
+ actions: 'Действия',
70
+ date: 'Дата',
71
+ success: 'Успех',
72
+ error: 'Ошибка',
73
+ statuses: {
74
+ waiting: 'В ожидании',
75
+ archived: 'Архивный',
76
+ active: 'Активный',
77
+ disabled: 'Отключен',
78
+ },
79
+ bannerWasSuccessfullyCreated: 'Баннер успешно создан',
80
+ bannerWasSuccessfullyUpdated: 'Баннер успешно обновлен',
81
+ bannerCreationWasFailed: 'Не удалось создать баннер',
82
+ bannerUpdateWasFailed: 'Не удалось обновить баннер',
83
+ };
84
+
85
+ /** Zones **/
86
+ function getZones(params) {
87
+ return adminServices.request.get({ path: '/admin/adv/zones', params });
27
88
  }
28
- /** Banners */
29
- function getBannerItemList(areaId) {
30
- return adminServices.request.get({ path: `/admin/market-boards/${areaId}/items` });
89
+ /** Banners **/
90
+ function getBanners(params) {
91
+ return adminServices.request.get({ path: '/admin/adv', params });
31
92
  }
32
- function getBannerItemById(bannerItemId) {
33
- return adminServices.request.get({ path: `/admin/market-boards/items/${bannerItemId}` });
93
+ function getBanner(bannerId) {
94
+ return adminServices.request.get({ path: `/admin/adv/${bannerId}` });
34
95
  }
35
- function createBannerItem(areaId, payload) {
36
- return adminServices.request.post({
37
- path: `/admin/market-boards/${areaId}/items`,
38
- body: payload,
39
- });
96
+ function createBanner(payload) {
97
+ return adminServices.request.post({ path: '/admin/adv', body: payload });
40
98
  }
41
- function updateBannerItem(bannerItemId, payload) {
99
+ function updateBanner(bannerId, payload) {
42
100
  return adminServices.request.put({
43
- path: `/admin/market-boards/items/${bannerItemId}`,
101
+ path: `/admin/adv/${bannerId}`,
44
102
  body: payload,
45
103
  });
46
104
  }
47
- function deleteBannerItem(bannerItemId) {
48
- return adminServices.request.delete({ path: `/admin/market-boards/items/${bannerItemId}` });
105
+ function deleteBanner(bannerId) {
106
+ return adminServices.request.delete({ path: `/admin/adv/${bannerId}` });
49
107
  }
50
- function moveBannerItem(bannerItemId, direction) {
51
- return adminServices.request.post({
52
- path: `/admin/market-boards/items/${bannerItemId}/${direction}`,
53
- });
108
+ function getBannerCount() {
109
+ return adminServices.request.get({ path: '/admin/adv/count' });
54
110
  }
55
111
 
56
- const BANNER_ROUTE_PATHS = {
57
- AREA_LIST: '/banners',
58
- AREA_FORM: '/banners/:areaId',
59
- ITEM_LIST: '/banners/:areaAlias/items',
60
- ITEM_FORM: '/banners/:areaAlias/items/:itemId',
112
+ const BANNERS_ROUTE_PATHS = {
113
+ ZONE_LIST: '/banners/zones',
114
+ BANNER_LIST: '/banners',
115
+ BANNER_FORM: '/banners/:bannerId',
61
116
  };
62
- function getBannerAreaListUrl() {
63
- return BANNER_ROUTE_PATHS.AREA_LIST;
64
- }
65
- function getBannerAreaFormUrl(params) {
66
- return pathToRegexp.compile(BANNER_ROUTE_PATHS.AREA_FORM)({
67
- areaId: params.areaId,
68
- });
117
+ function getBannersZoneListUrl() {
118
+ return BANNERS_ROUTE_PATHS.ZONE_LIST;
69
119
  }
70
- function getBannerItemListUrl(params) {
71
- return pathToRegexp.compile(BANNER_ROUTE_PATHS.ITEM_LIST)({
72
- areaAlias: params.areaAlias,
73
- });
120
+ function getBannersBannerListUrl() {
121
+ return BANNERS_ROUTE_PATHS.BANNER_LIST;
74
122
  }
75
- function getBannerItemFormUrl(params) {
76
- return pathToRegexp.compile(BANNER_ROUTE_PATHS.ITEM_FORM)({
77
- areaAlias: params.areaAlias,
78
- itemId: params.itemId,
79
- });
123
+ function getBannersBannerFormUrl(params) {
124
+ return pathToRegexp.compile(BANNERS_ROUTE_PATHS.BANNER_FORM)(params);
80
125
  }
81
126
 
82
- const COLUMN_DEFS = [
83
- {
84
- id: 1,
85
- name: 'ID',
86
- field: 'id',
87
- style: { width: '50px', textAlign: 'center' },
88
- headStyle: { width: '50px', textAlign: 'center' },
89
- },
90
- { id: 2, name: 'Alias', field: 'alias' },
91
- { id: 3, name: 'Label', field: 'label' },
92
- { id: 4, name: 'Scenario', field: 'scenario' },
93
- {
94
- id: 6,
95
- name: 'Banner Items',
96
- field: 'linkToBannerItems',
97
- style: { whiteSpace: 'nowrap', width: '120px', textAlign: 'center' },
98
- headStyle: { whiteSpace: 'nowrap', width: '120px', textAlign: 'center' },
99
- },
100
- {
101
- id: 8,
102
- name: 'Actions',
103
- field: 'actions',
104
- style: { whiteSpace: 'nowrap', width: '110px', textAlign: 'center' },
105
- headStyle: { whiteSpace: 'nowrap', width: '110px', textAlign: 'center' },
106
- },
107
- ];
108
- var script = Vue.extend({
109
- name: 'BannerAreaList',
110
- data() {
111
- return {
112
- columnDefs: COLUMN_DEFS,
113
- rowData: [],
114
- deletingBannerAreaIdList: [],
115
- isRowDataLoading: false,
116
- errorMessage: null,
117
- };
118
- },
119
- mounted() {
120
- this.refreshBannerAreaList();
121
- },
122
- methods: {
123
- getBannerAreaUrl(areaId) {
124
- return getBannerAreaFormUrl({ areaId });
127
+ function getColumnDefs(t) {
128
+ return [
129
+ {
130
+ id: 0,
131
+ name: 'ID',
132
+ field: 'id',
133
+ style: { width: '50px', textAlign: 'center' },
134
+ headStyle: { width: '50px', textAlign: 'center' },
125
135
  },
126
- refreshBannerAreaList() {
127
- this.isRowDataLoading = true;
128
- return getBannerAreaList()
129
- .then((response) => {
130
- this.rowData = response.data;
131
- this.errorMessage = null;
132
- })
133
- .catch((error) => {
134
- console.error(error);
135
- this.rowData = [];
136
- this.errorMessage = adminServices.getMessageFromError(error);
137
- })
138
- .finally(() => {
139
- this.isRowDataLoading = false;
140
- });
141
- },
142
- handleBannerAreaDelete(bannerArea) {
143
- const shouldDeleteBannerArea = confirm(`Are you sure you want to delete banner area "${bannerArea.label}"`);
144
- if (!shouldDeleteBannerArea)
145
- return;
146
- this.deletingBannerAreaIdList.push(bannerArea.id);
147
- deleteBannerArea(bannerArea.id)
148
- .then((response) => {
149
- if (response.success) {
150
- this.refreshBannerAreaList().then(() => {
151
- this.deletingBannerAreaIdList.filter((id) => id !== bannerArea.id);
152
- });
153
- this.$toast({
154
- variant: 'success',
155
- title: 'Success',
156
- body: 'Banner area was successfully removed',
157
- });
158
- }
159
- else {
160
- this.$toast({
161
- variant: 'danger',
162
- title: 'Error',
163
- body: 'Banner area deletion was failed',
164
- });
165
- }
166
- })
167
- .catch((error) => {
168
- console.error(error);
169
- this.$toast({
170
- variant: 'danger',
171
- title: 'Error',
172
- body: 'Banner area deletion was failed',
173
- });
174
- });
136
+ {
137
+ id: 1,
138
+ name: t('banners:name'),
139
+ field: 'name',
140
+ type: 'name',
175
141
  },
176
- getLinkToBannerItems(areaAlias) {
177
- return getBannerItemListUrl({ areaAlias });
142
+ {
143
+ id: 2,
144
+ name: t('banners:banners'),
145
+ field: 'bannersCount',
146
+ style: { whiteSpace: 'nowrap', width: '130px' },
178
147
  },
148
+ ];
149
+ }
150
+ function getLinkToBannersByZone(zoneId) {
151
+ return `${getBannersBannerListUrl()}?filter[zone]=${zoneId}`;
152
+ }
153
+
154
+ var script = compositionApi.defineComponent({
155
+ name: 'ZoneList',
156
+ setup(props, context) {
157
+ const { fetchEntityList: fetchZones, isLoading: isZonesLoading, rowData, errorMessage, handleChange, } = adminUi.useDataTable({
158
+ fetchEntityList: getZones,
159
+ initialValue: [],
160
+ context,
161
+ resourceName: 'Banner Zones',
162
+ });
163
+ compositionApi.onMounted(() => {
164
+ fetchZones();
165
+ });
166
+ const columnDefs = compositionApi.computed(() => getColumnDefs(context.root.$t));
167
+ return {
168
+ columnDefs,
169
+ isRowDataLoading: isZonesLoading,
170
+ rowData,
171
+ errorMessage,
172
+ handleChange,
173
+ getLinkToBannersByZone,
174
+ };
179
175
  },
180
176
  });
181
177
 
@@ -254,59 +250,6 @@
254
250
  return script;
255
251
  }
256
252
 
257
- const isOldIE = typeof navigator !== 'undefined' &&
258
- /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());
259
- function createInjector(context) {
260
- return (id, style) => addStyle(id, style);
261
- }
262
- let HEAD;
263
- const styles = {};
264
- function addStyle(id, css) {
265
- const group = isOldIE ? css.media || 'default' : id;
266
- const style = styles[group] || (styles[group] = { ids: new Set(), styles: [] });
267
- if (!style.ids.has(id)) {
268
- style.ids.add(id);
269
- let code = css.source;
270
- if (css.map) {
271
- // https://developer.chrome.com/devtools/docs/javascript-debugging
272
- // this makes source maps inside style tags work properly in Chrome
273
- code += '\n/*# sourceURL=' + css.map.sources[0] + ' */';
274
- // http://stackoverflow.com/a/26603875
275
- code +=
276
- '\n/*# sourceMappingURL=data:application/json;base64,' +
277
- btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) +
278
- ' */';
279
- }
280
- if (!style.element) {
281
- style.element = document.createElement('style');
282
- style.element.type = 'text/css';
283
- if (css.media)
284
- style.element.setAttribute('media', css.media);
285
- if (HEAD === undefined) {
286
- HEAD = document.head || document.getElementsByTagName('head')[0];
287
- }
288
- HEAD.appendChild(style.element);
289
- }
290
- if ('styleSheet' in style.element) {
291
- style.styles.push(code);
292
- style.element.styleSheet.cssText = style.styles
293
- .filter(Boolean)
294
- .join('\n');
295
- }
296
- else {
297
- const index = style.ids.size - 1;
298
- const textNode = document.createTextNode(code);
299
- const nodes = style.element.childNodes;
300
- if (nodes[index])
301
- style.element.removeChild(nodes[index]);
302
- if (nodes.length)
303
- style.element.insertBefore(textNode, nodes[index]);
304
- else
305
- style.element.appendChild(textNode);
306
- }
307
- }
308
- }
309
-
310
253
  /* script */
311
254
  const __vue_script__ = script;
312
255
 
@@ -316,82 +259,45 @@
316
259
  var _h = _vm.$createElement;
317
260
  var _c = _vm._self._c || _h;
318
261
  return _c("page", {
319
- attrs: {
320
- title: "Banner Areas",
321
- "header-buttons": [
322
- { text: "New banner area", href: _vm.getBannerAreaUrl("create") },
323
- ],
324
- },
262
+ attrs: { title: _vm.$t("banners:zones") },
325
263
  scopedSlots: _vm._u([
326
264
  {
327
265
  key: "content",
328
266
  fn: function () {
329
267
  return [
330
- _c("base-table", {
268
+ _c("data-table", {
331
269
  attrs: {
332
270
  "column-defs": _vm.columnDefs,
333
271
  "row-data": _vm.rowData,
334
272
  loading: _vm.isRowDataLoading,
335
273
  "error-message": _vm.errorMessage,
274
+ "data-table": "banners-zones",
275
+ "use-search": false,
276
+ "use-pagination": false,
336
277
  },
278
+ on: { change: _vm.handleChange },
337
279
  scopedSlots: _vm._u([
338
280
  {
339
- key: "cell(link-to-banner-items)",
281
+ key: "cell(banners-count)",
340
282
  fn: function (ref) {
341
283
  var row = ref.row;
342
284
  return [
343
285
  _c(
344
- "base-button",
286
+ "count-button",
345
287
  {
346
288
  attrs: {
347
- href: _vm.getLinkToBannerItems(row.alias),
289
+ href: _vm.getLinkToBannersByZone(row.id),
348
290
  variant: "outline-secondary",
291
+ count: row.bannersCount,
349
292
  },
350
293
  },
351
- [_vm._v("\n Banner Items\n ")]
352
- ),
353
- ]
354
- },
355
- },
356
- {
357
- key: "cell(actions)",
358
- fn: function (ref) {
359
- var row = ref.row;
360
- return [
361
- _c(
362
- "base-button",
363
- {
364
- attrs: {
365
- variant: "icon",
366
- title: "Edit",
367
- disabled: _vm.deletingBannerAreaIdList.includes(
368
- row.id
369
- ),
370
- href: _vm.getBannerAreaUrl(row.id),
371
- },
372
- },
373
- [_c("svg-icon", { attrs: { name: "edit" } })],
374
- 1
375
- ),
376
- _vm._v(" "),
377
- _c(
378
- "base-button",
379
- {
380
- attrs: {
381
- variant: "icon",
382
- title: "Remove",
383
- disabled: _vm.deletingBannerAreaIdList.includes(
384
- row.id
385
- ),
386
- },
387
- on: {
388
- click: function ($event) {
389
- return _vm.handleBannerAreaDelete(row)
390
- },
391
- },
392
- },
393
- [_c("svg-icon", { attrs: { name: "delete" } })],
394
- 1
294
+ [
295
+ _vm._v(
296
+ "\n " +
297
+ _vm._s(_vm.$t("banners:banners")) +
298
+ "\n "
299
+ ),
300
+ ]
395
301
  ),
396
302
  ]
397
303
  },
@@ -409,17 +315,15 @@
409
315
  __vue_render__._withStripped = true;
410
316
 
411
317
  /* style */
412
- const __vue_inject_styles__ = function (inject) {
413
- if (!inject) return
414
- inject("data-v-60c3bc88_0", { source: ".actions-cell button[data-v-60c3bc88]:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n/*# sourceMappingURL=BannerAreaList.vue.map */", map: {"version":3,"sources":["D:\\Work\\tager-admin-banners\\src\\views\\BannerAreaList.vue","BannerAreaList.vue"],"names":[],"mappings":"AA2KA;EACA,oBAAA;AC1KA;;AAEA,6CAA6C","file":"BannerAreaList.vue","sourcesContent":["<template>\n <page\n title=\"Banner Areas\"\n :header-buttons=\"[\n { text: 'New banner area', href: getBannerAreaUrl('create') },\n ]\"\n >\n <template v-slot:content>\n <base-table\n :column-defs=\"columnDefs\"\n :row-data=\"rowData\"\n :loading=\"isRowDataLoading\"\n :error-message=\"errorMessage\"\n >\n <template v-slot:cell(link-to-banner-items)=\"{ row }\">\n <base-button\n :href=\"getLinkToBannerItems(row.alias)\"\n variant=\"outline-secondary\"\n >\n Banner Items\n </base-button>\n </template>\n\n <template v-slot:cell(actions)=\"{ row }\">\n <base-button\n variant=\"icon\"\n title=\"Edit\"\n :disabled=\"deletingBannerAreaIdList.includes(row.id)\"\n :href=\"getBannerAreaUrl(row.id)\"\n >\n <svg-icon name=\"edit\"></svg-icon>\n </base-button>\n <base-button\n variant=\"icon\"\n title=\"Remove\"\n :disabled=\"deletingBannerAreaIdList.includes(row.id)\"\n @click=\"handleBannerAreaDelete(row)\"\n >\n <svg-icon name=\"delete\"></svg-icon>\n </base-button>\n </template>\n </base-table>\n </template>\n </page>\n</template>\n\n<script lang=\"ts\">\nimport Vue from 'vue';\nimport { ColumnDefinition } from '@tager/admin-ui';\nimport { getMessageFromError, Nullable } from '@tager/admin-services';\n\nimport { BannerArea } from '../typings/model';\nimport { deleteBannerArea, getBannerAreaList } from '../services/requests';\nimport { getBannerAreaFormUrl, getBannerItemListUrl } from '../constants/paths';\n\nconst COLUMN_DEFS: Array<ColumnDefinition<BannerArea>> = [\n {\n id: 1,\n name: 'ID',\n field: 'id',\n style: { width: '50px', textAlign: 'center' },\n headStyle: { width: '50px', textAlign: 'center' },\n },\n { id: 2, name: 'Alias', field: 'alias' },\n { id: 3, name: 'Label', field: 'label' },\n { id: 4, name: 'Scenario', field: 'scenario' },\n {\n id: 6,\n name: 'Banner Items',\n field: 'linkToBannerItems',\n style: { whiteSpace: 'nowrap', width: '120px', textAlign: 'center' },\n headStyle: { whiteSpace: 'nowrap', width: '120px', textAlign: 'center' },\n },\n {\n id: 8,\n name: 'Actions',\n field: 'actions',\n style: { whiteSpace: 'nowrap', width: '110px', textAlign: 'center' },\n headStyle: { whiteSpace: 'nowrap', width: '110px', textAlign: 'center' },\n },\n];\n\nexport default Vue.extend({\n name: 'BannerAreaList',\n data(): {\n columnDefs: Array<ColumnDefinition<BannerArea>>;\n rowData: Array<BannerArea>;\n deletingBannerAreaIdList: Array<number>;\n isRowDataLoading: boolean;\n errorMessage: Nullable<string>;\n } {\n return {\n columnDefs: COLUMN_DEFS,\n rowData: [],\n deletingBannerAreaIdList: [],\n isRowDataLoading: false,\n errorMessage: null,\n };\n },\n mounted(): void {\n this.refreshBannerAreaList();\n },\n methods: {\n getBannerAreaUrl(areaId: number | string): string {\n return getBannerAreaFormUrl({ areaId });\n },\n refreshBannerAreaList(): Promise<void> {\n this.isRowDataLoading = true;\n\n return getBannerAreaList()\n .then((response) => {\n this.rowData = response.data;\n this.errorMessage = null;\n })\n .catch((error) => {\n console.error(error);\n this.rowData = [];\n this.errorMessage = getMessageFromError(error);\n })\n .finally(() => {\n this.isRowDataLoading = false;\n });\n },\n handleBannerAreaDelete(bannerArea: BannerArea) {\n const shouldDeleteBannerArea = confirm(\n `Are you sure you want to delete banner area \"${bannerArea.label}\"`\n );\n\n if (!shouldDeleteBannerArea) return;\n\n this.deletingBannerAreaIdList.push(bannerArea.id);\n\n deleteBannerArea(bannerArea.id)\n .then((response) => {\n if (response.success) {\n this.refreshBannerAreaList().then(() => {\n this.deletingBannerAreaIdList.filter(\n (id) => id !== bannerArea.id\n );\n });\n this.$toast({\n variant: 'success',\n title: 'Success',\n body: 'Banner area was successfully removed',\n });\n } else {\n this.$toast({\n variant: 'danger',\n title: 'Error',\n body: 'Banner area deletion was failed',\n });\n }\n })\n .catch((error) => {\n console.error(error);\n this.$toast({\n variant: 'danger',\n title: 'Error',\n body: 'Banner area deletion was failed',\n });\n });\n },\n getLinkToBannerItems(areaAlias: string) {\n return getBannerItemListUrl({ areaAlias });\n },\n },\n});\n</script>\n\n<style scoped lang=\"scss\">\n.actions-cell {\n button:not(:last-child) {\n margin-right: 0.5rem;\n }\n}\n</style>\n",".actions-cell button:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n/*# sourceMappingURL=BannerAreaList.vue.map */"]}, media: undefined });
415
-
416
- };
318
+ const __vue_inject_styles__ = undefined;
417
319
  /* scoped */
418
- const __vue_scope_id__ = "data-v-60c3bc88";
320
+ const __vue_scope_id__ = undefined;
419
321
  /* module identifier */
420
322
  const __vue_module_identifier__ = undefined;
421
323
  /* functional template */
422
324
  const __vue_is_functional_template__ = false;
325
+ /* style inject */
326
+
423
327
  /* style inject SSR */
424
328
 
425
329
  /* style inject shadow dom */
@@ -434,368 +338,2691 @@
434
338
  __vue_is_functional_template__,
435
339
  __vue_module_identifier__,
436
340
  false,
437
- createInjector,
341
+ undefined,
438
342
  undefined,
439
343
  undefined
440
344
  );
441
345
 
442
- const initialValues = {
443
- alias: '',
444
- label: '',
445
- scenario: '',
446
- };
447
- var script$1 = Vue.extend({
448
- name: 'BannerAreaForm',
449
- data() {
450
- return {
451
- values: Object.assign({}, initialValues),
452
- errors: {},
453
- isContentLoading: false,
454
- };
455
- },
456
- computed: {
457
- areaId() {
458
- return this.$route.params.areaId;
459
- },
460
- isCreation() {
461
- return this.areaId === 'create';
462
- },
463
- },
464
- watch: {
465
- areaId() {
466
- this.updateValues();
467
- },
468
- },
469
- mounted() {
470
- this.updateValues();
471
- },
472
- methods: {
473
- convertReviewToInitialValues(bannerArea) {
474
- return {
475
- alias: bannerArea.alias,
476
- label: bannerArea.label,
477
- scenario: bannerArea.scenario,
478
- };
479
- },
480
- updateValues() {
481
- if (this.isCreation) {
482
- this.values = Object.assign({}, initialValues);
483
- }
484
- else {
485
- this.isContentLoading = true;
486
- getBannerAreaById(this.areaId)
487
- .then((response) => {
488
- this.values = this.convertReviewToInitialValues(response.data);
489
- })
490
- .catch(console.error)
491
- .finally(() => {
492
- this.isContentLoading = false;
493
- });
494
- }
495
- },
496
- submitForm() {
497
- const body = {
498
- label: this.values.label,
499
- alias: this.values.alias,
500
- scenario: this.values.scenario,
501
- };
502
- const requestPromise = this.isCreation
503
- ? createBannerArea(body)
504
- : updateBannerArea(this.areaId, body);
505
- requestPromise
506
- .then(() => {
507
- this.errors = {};
508
- this.$router.push(getBannerAreaListUrl());
509
- this.$toast({
510
- variant: 'success',
511
- title: 'Success',
512
- body: `Banner Area was successfully ${this.isCreation ? 'created' : 'updated'}`,
513
- });
514
- })
515
- .catch((error) => {
516
- console.error(error);
517
- this.errors = adminServices.convertRequestErrorToMap(error);
518
- this.$toast({
519
- variant: 'danger',
520
- title: 'Error',
521
- body: `Blog bannerArea ${this.isCreation ? 'creation' : 'update'} was failed`,
522
- });
523
- });
524
- },
525
- getAreaListUrl: getBannerAreaListUrl,
526
- },
527
- });
346
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
528
347
 
529
- /* script */
530
- const __vue_script__$1 = script$1;
348
+ function createCommonjsModule(fn, basedir, module) {
349
+ return module = {
350
+ path: basedir,
351
+ exports: {},
352
+ require: function (path, base) {
353
+ return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
354
+ }
355
+ }, fn(module, module.exports), module.exports;
356
+ }
531
357
 
532
- /* template */
533
- var __vue_render__$1 = function () {
534
- var _vm = this;
535
- var _h = _vm.$createElement;
536
- var _c = _vm._self._c || _h;
537
- return _c("page", {
538
- attrs: {
539
- title: _vm.isCreation ? "Create Banner Area" : "Update Banner Area",
540
- "is-content-loading": _vm.isContentLoading,
541
- footer: { onSubmit: _vm.submitForm, backHref: _vm.getAreaListUrl() },
542
- },
543
- scopedSlots: _vm._u([
544
- {
545
- key: "content",
546
- fn: function () {
547
- return [
548
- _c(
549
- "form",
550
- {
551
- attrs: { novalidate: "" },
552
- on: {
553
- submit: function ($event) {
554
- $event.preventDefault();
555
- return _vm.submitForm($event)
556
- },
557
- },
558
- },
559
- [
560
- _c("form-field", {
561
- attrs: {
562
- name: "alias",
563
- label: "Alias",
564
- error: _vm.errors.alias,
565
- },
566
- model: {
567
- value: _vm.values.alias,
568
- callback: function ($$v) {
569
- _vm.$set(_vm.values, "alias", $$v);
570
- },
571
- expression: "values.alias",
572
- },
573
- }),
574
- _vm._v(" "),
575
- _c("form-field", {
576
- attrs: {
577
- name: "label",
578
- label: "Label",
579
- error: _vm.errors.label,
580
- },
581
- model: {
582
- value: _vm.values.label,
583
- callback: function ($$v) {
584
- _vm.$set(_vm.values, "label", $$v);
585
- },
586
- expression: "values.label",
587
- },
588
- }),
589
- _vm._v(" "),
590
- _c("form-field", {
591
- attrs: {
592
- name: "scenario",
593
- label: "Scenario",
594
- error: _vm.errors.scenario,
595
- },
596
- model: {
597
- value: _vm.values.scenario,
598
- callback: function ($$v) {
599
- _vm.$set(_vm.values, "scenario", $$v);
600
- },
601
- expression: "values.scenario",
602
- },
603
- }),
604
- ],
605
- 1
606
- ),
607
- ]
608
- },
609
- proxy: true,
610
- },
611
- ]),
612
- })
613
- };
614
- var __vue_staticRenderFns__$1 = [];
615
- __vue_render__$1._withStripped = true;
358
+ function commonjsRequire () {
359
+ throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
360
+ }
616
361
 
617
- /* style */
618
- const __vue_inject_styles__$1 = function (inject) {
619
- if (!inject) return
620
- inject("data-v-78a20f0f_0", { source: ".bottom[data-v-78a20f0f] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.save-button[data-v-78a20f0f] {\n min-width: 100px;\n}\n.alias-field-inner[data-v-78a20f0f] {\n display: flex;\n align-items: center;\n}\n.alias-field-inner span[data-v-78a20f0f] {\n font-size: 0.9em;\n margin-right: 10px;\n}\n\n/*# sourceMappingURL=BannerAreaForm.vue.map */", map: {"version":3,"sources":["D:\\Work\\tager-admin-banners\\src\\views\\BannerAreaForm.vue","BannerAreaForm.vue"],"names":[],"mappings":"AAyJA;EACA,aAAA;EACA,8BAAA;EACA,mBAAA;ACxJA;AD2JA;EACA,gBAAA;ACxJA;AD2JA;EACA,aAAA;EACA,mBAAA;ACxJA;AD0JA;EACA,gBAAA;EACA,kBAAA;ACxJA;;AAEA,6CAA6C","file":"BannerAreaForm.vue","sourcesContent":["<template>\n <page\n :title=\"isCreation ? 'Create Banner Area' : 'Update Banner Area'\"\n :is-content-loading=\"isContentLoading\"\n :footer=\"{ onSubmit: submitForm, backHref: getAreaListUrl() }\"\n >\n <template v-slot:content>\n <form novalidate @submit.prevent=\"submitForm\">\n <form-field\n v-model=\"values.alias\"\n name=\"alias\"\n label=\"Alias\"\n :error=\"errors.alias\"\n />\n\n <form-field\n v-model=\"values.label\"\n name=\"label\"\n label=\"Label\"\n :error=\"errors.label\"\n />\n\n <form-field\n v-model=\"values.scenario\"\n name=\"scenario\"\n label=\"Scenario\"\n :error=\"errors.scenario\"\n />\n </form>\n </template>\n </page>\n</template>\n\n<script lang=\"ts\">\nimport Vue from 'vue';\nimport { convertRequestErrorToMap } from '@tager/admin-services';\n\nimport {\n BannerAreaCreatePayload,\n createBannerArea,\n getBannerAreaById,\n updateBannerArea,\n} from '../services/requests';\nimport { BannerArea } from '../typings/model';\nimport { getBannerAreaListUrl } from '../constants/paths';\n\ntype FormValues = {\n alias: string;\n label: string;\n scenario: string;\n};\n\nconst initialValues: FormValues = {\n alias: '',\n label: '',\n scenario: '',\n};\n\nexport default Vue.extend({\n name: 'BannerAreaForm',\n data(): {\n values: FormValues;\n errors: Record<string, string>;\n isContentLoading: boolean;\n } {\n return {\n values: { ...initialValues },\n errors: {},\n isContentLoading: false,\n };\n },\n computed: {\n areaId(): string {\n return this.$route.params.areaId;\n },\n isCreation(): boolean {\n return this.areaId === 'create';\n },\n },\n watch: {\n areaId() {\n this.updateValues();\n },\n },\n mounted(): void {\n this.updateValues();\n },\n methods: {\n convertReviewToInitialValues(bannerArea: BannerArea): FormValues {\n return {\n alias: bannerArea.alias,\n label: bannerArea.label,\n scenario: bannerArea.scenario,\n };\n },\n updateValues() {\n if (this.isCreation) {\n this.values = { ...initialValues };\n } else {\n this.isContentLoading = true;\n\n getBannerAreaById(this.areaId)\n .then((response) => {\n this.values = this.convertReviewToInitialValues(response.data);\n })\n .catch(console.error)\n .finally(() => {\n this.isContentLoading = false;\n });\n }\n },\n submitForm() {\n const body: BannerAreaCreatePayload = {\n label: this.values.label,\n alias: this.values.alias,\n scenario: this.values.scenario,\n };\n\n const requestPromise = this.isCreation\n ? createBannerArea(body)\n : updateBannerArea(this.areaId, body);\n\n requestPromise\n .then(() => {\n this.errors = {};\n this.$router.push(getBannerAreaListUrl());\n\n this.$toast({\n variant: 'success',\n title: 'Success',\n body: `Banner Area was successfully ${\n this.isCreation ? 'created' : 'updated'\n }`,\n });\n })\n .catch((error) => {\n console.error(error);\n this.errors = convertRequestErrorToMap(error);\n this.$toast({\n variant: 'danger',\n title: 'Error',\n body: `Blog bannerArea ${\n this.isCreation ? 'creation' : 'update'\n } was failed`,\n });\n });\n },\n getAreaListUrl: getBannerAreaListUrl,\n },\n});\n</script>\n\n<style scoped lang=\"scss\">\n.bottom {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.save-button {\n min-width: 100px;\n}\n\n.alias-field-inner {\n display: flex;\n align-items: center;\n\n span {\n font-size: 0.9em;\n margin-right: 10px;\n }\n}\n</style>\n",".bottom {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.save-button {\n min-width: 100px;\n}\n\n.alias-field-inner {\n display: flex;\n align-items: center;\n}\n.alias-field-inner span {\n font-size: 0.9em;\n margin-right: 10px;\n}\n\n/*# sourceMappingURL=BannerAreaForm.vue.map */"]}, media: undefined });
362
+ var lodash_isequal = createCommonjsModule(function (module, exports) {
363
+ /**
364
+ * Lodash (Custom Build) <https://lodash.com/>
365
+ * Build: `lodash modularize exports="npm" -o ./`
366
+ * Copyright JS Foundation and other contributors <https://js.foundation/>
367
+ * Released under MIT license <https://lodash.com/license>
368
+ * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
369
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
370
+ */
621
371
 
622
- };
623
- /* scoped */
624
- const __vue_scope_id__$1 = "data-v-78a20f0f";
625
- /* module identifier */
626
- const __vue_module_identifier__$1 = undefined;
627
- /* functional template */
628
- const __vue_is_functional_template__$1 = false;
629
- /* style inject SSR */
630
-
631
- /* style inject shadow dom */
632
-
372
+ /** Used as the size to enable large array optimizations. */
373
+ var LARGE_ARRAY_SIZE = 200;
633
374
 
634
-
635
- const __vue_component__$1 = /*#__PURE__*/normalizeComponent(
636
- { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 },
637
- __vue_inject_styles__$1,
638
- __vue_script__$1,
639
- __vue_scope_id__$1,
640
- __vue_is_functional_template__$1,
641
- __vue_module_identifier__$1,
642
- false,
643
- createInjector,
644
- undefined,
645
- undefined
646
- );
375
+ /** Used to stand-in for `undefined` hash values. */
376
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
647
377
 
648
- const COLUMN_DEFS$1 = [
649
- {
650
- id: 2,
651
- name: 'Image',
652
- field: 'image',
653
- type: 'image',
654
- },
655
- {
656
- id: 1,
657
- name: 'Title',
658
- field: 'title',
659
- },
660
- { id: 3, name: 'Text', field: 'text', type: 'html' },
661
- { id: 4, name: 'Button: Label', field: 'buttonLabel' },
662
- { id: 5, name: 'Button: Link', field: 'buttonLink' },
663
- {
664
- id: 6,
665
- name: 'Button: Is new tab?',
666
- field: 'buttonIsNewTab',
667
- format: ({ row }) => adminUi.formatBoolean(row.buttonIsNewTab),
668
- },
669
- {
670
- id: 7,
671
- name: 'Actions',
672
- field: 'actions',
673
- style: { whiteSpace: 'nowrap', width: '205px' },
674
- headStyle: { whiteSpace: 'nowrap', width: '205px' },
675
- },
676
- ];
677
- var script$2 = Vue.extend({
678
- name: 'BannerItemList',
679
- data() {
680
- return {
681
- bannerArea: null,
682
- columnDefs: COLUMN_DEFS$1,
683
- rowData: [],
684
- deletingBannerItemIdList: [],
685
- isBannerItemMoving: false,
686
- isRowDataLoading: false,
687
- errorMessage: null,
688
- };
689
- },
690
- computed: {
691
- areaAlias() {
692
- return this.$route.params.areaAlias;
378
+ /** Used to compose bitmasks for value comparisons. */
379
+ var COMPARE_PARTIAL_FLAG = 1,
380
+ COMPARE_UNORDERED_FLAG = 2;
381
+
382
+ /** Used as references for various `Number` constants. */
383
+ var MAX_SAFE_INTEGER = 9007199254740991;
384
+
385
+ /** `Object#toString` result references. */
386
+ var argsTag = '[object Arguments]',
387
+ arrayTag = '[object Array]',
388
+ asyncTag = '[object AsyncFunction]',
389
+ boolTag = '[object Boolean]',
390
+ dateTag = '[object Date]',
391
+ errorTag = '[object Error]',
392
+ funcTag = '[object Function]',
393
+ genTag = '[object GeneratorFunction]',
394
+ mapTag = '[object Map]',
395
+ numberTag = '[object Number]',
396
+ nullTag = '[object Null]',
397
+ objectTag = '[object Object]',
398
+ promiseTag = '[object Promise]',
399
+ proxyTag = '[object Proxy]',
400
+ regexpTag = '[object RegExp]',
401
+ setTag = '[object Set]',
402
+ stringTag = '[object String]',
403
+ symbolTag = '[object Symbol]',
404
+ undefinedTag = '[object Undefined]',
405
+ weakMapTag = '[object WeakMap]';
406
+
407
+ var arrayBufferTag = '[object ArrayBuffer]',
408
+ dataViewTag = '[object DataView]',
409
+ float32Tag = '[object Float32Array]',
410
+ float64Tag = '[object Float64Array]',
411
+ int8Tag = '[object Int8Array]',
412
+ int16Tag = '[object Int16Array]',
413
+ int32Tag = '[object Int32Array]',
414
+ uint8Tag = '[object Uint8Array]',
415
+ uint8ClampedTag = '[object Uint8ClampedArray]',
416
+ uint16Tag = '[object Uint16Array]',
417
+ uint32Tag = '[object Uint32Array]';
418
+
419
+ /**
420
+ * Used to match `RegExp`
421
+ * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
422
+ */
423
+ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
424
+
425
+ /** Used to detect host constructors (Safari). */
426
+ var reIsHostCtor = /^\[object .+?Constructor\]$/;
427
+
428
+ /** Used to detect unsigned integer values. */
429
+ var reIsUint = /^(?:0|[1-9]\d*)$/;
430
+
431
+ /** Used to identify `toStringTag` values of typed arrays. */
432
+ var typedArrayTags = {};
433
+ typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
434
+ typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
435
+ typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
436
+ typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
437
+ typedArrayTags[uint32Tag] = true;
438
+ typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
439
+ typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
440
+ typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
441
+ typedArrayTags[errorTag] = typedArrayTags[funcTag] =
442
+ typedArrayTags[mapTag] = typedArrayTags[numberTag] =
443
+ typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
444
+ typedArrayTags[setTag] = typedArrayTags[stringTag] =
445
+ typedArrayTags[weakMapTag] = false;
446
+
447
+ /** Detect free variable `global` from Node.js. */
448
+ var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
449
+
450
+ /** Detect free variable `self`. */
451
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
452
+
453
+ /** Used as a reference to the global object. */
454
+ var root = freeGlobal || freeSelf || Function('return this')();
455
+
456
+ /** Detect free variable `exports`. */
457
+ var freeExports = exports && !exports.nodeType && exports;
458
+
459
+ /** Detect free variable `module`. */
460
+ var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
461
+
462
+ /** Detect the popular CommonJS extension `module.exports`. */
463
+ var moduleExports = freeModule && freeModule.exports === freeExports;
464
+
465
+ /** Detect free variable `process` from Node.js. */
466
+ var freeProcess = moduleExports && freeGlobal.process;
467
+
468
+ /** Used to access faster Node.js helpers. */
469
+ var nodeUtil = (function() {
470
+ try {
471
+ return freeProcess && freeProcess.binding && freeProcess.binding('util');
472
+ } catch (e) {}
473
+ }());
474
+
475
+ /* Node.js helper references. */
476
+ var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
477
+
478
+ /**
479
+ * A specialized version of `_.filter` for arrays without support for
480
+ * iteratee shorthands.
481
+ *
482
+ * @private
483
+ * @param {Array} [array] The array to iterate over.
484
+ * @param {Function} predicate The function invoked per iteration.
485
+ * @returns {Array} Returns the new filtered array.
486
+ */
487
+ function arrayFilter(array, predicate) {
488
+ var index = -1,
489
+ length = array == null ? 0 : array.length,
490
+ resIndex = 0,
491
+ result = [];
492
+
493
+ while (++index < length) {
494
+ var value = array[index];
495
+ if (predicate(value, index, array)) {
496
+ result[resIndex++] = value;
497
+ }
498
+ }
499
+ return result;
500
+ }
501
+
502
+ /**
503
+ * Appends the elements of `values` to `array`.
504
+ *
505
+ * @private
506
+ * @param {Array} array The array to modify.
507
+ * @param {Array} values The values to append.
508
+ * @returns {Array} Returns `array`.
509
+ */
510
+ function arrayPush(array, values) {
511
+ var index = -1,
512
+ length = values.length,
513
+ offset = array.length;
514
+
515
+ while (++index < length) {
516
+ array[offset + index] = values[index];
517
+ }
518
+ return array;
519
+ }
520
+
521
+ /**
522
+ * A specialized version of `_.some` for arrays without support for iteratee
523
+ * shorthands.
524
+ *
525
+ * @private
526
+ * @param {Array} [array] The array to iterate over.
527
+ * @param {Function} predicate The function invoked per iteration.
528
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
529
+ * else `false`.
530
+ */
531
+ function arraySome(array, predicate) {
532
+ var index = -1,
533
+ length = array == null ? 0 : array.length;
534
+
535
+ while (++index < length) {
536
+ if (predicate(array[index], index, array)) {
537
+ return true;
538
+ }
539
+ }
540
+ return false;
541
+ }
542
+
543
+ /**
544
+ * The base implementation of `_.times` without support for iteratee shorthands
545
+ * or max array length checks.
546
+ *
547
+ * @private
548
+ * @param {number} n The number of times to invoke `iteratee`.
549
+ * @param {Function} iteratee The function invoked per iteration.
550
+ * @returns {Array} Returns the array of results.
551
+ */
552
+ function baseTimes(n, iteratee) {
553
+ var index = -1,
554
+ result = Array(n);
555
+
556
+ while (++index < n) {
557
+ result[index] = iteratee(index);
558
+ }
559
+ return result;
560
+ }
561
+
562
+ /**
563
+ * The base implementation of `_.unary` without support for storing metadata.
564
+ *
565
+ * @private
566
+ * @param {Function} func The function to cap arguments for.
567
+ * @returns {Function} Returns the new capped function.
568
+ */
569
+ function baseUnary(func) {
570
+ return function(value) {
571
+ return func(value);
572
+ };
573
+ }
574
+
575
+ /**
576
+ * Checks if a `cache` value for `key` exists.
577
+ *
578
+ * @private
579
+ * @param {Object} cache The cache to query.
580
+ * @param {string} key The key of the entry to check.
581
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
582
+ */
583
+ function cacheHas(cache, key) {
584
+ return cache.has(key);
585
+ }
586
+
587
+ /**
588
+ * Gets the value at `key` of `object`.
589
+ *
590
+ * @private
591
+ * @param {Object} [object] The object to query.
592
+ * @param {string} key The key of the property to get.
593
+ * @returns {*} Returns the property value.
594
+ */
595
+ function getValue(object, key) {
596
+ return object == null ? undefined : object[key];
597
+ }
598
+
599
+ /**
600
+ * Converts `map` to its key-value pairs.
601
+ *
602
+ * @private
603
+ * @param {Object} map The map to convert.
604
+ * @returns {Array} Returns the key-value pairs.
605
+ */
606
+ function mapToArray(map) {
607
+ var index = -1,
608
+ result = Array(map.size);
609
+
610
+ map.forEach(function(value, key) {
611
+ result[++index] = [key, value];
612
+ });
613
+ return result;
614
+ }
615
+
616
+ /**
617
+ * Creates a unary function that invokes `func` with its argument transformed.
618
+ *
619
+ * @private
620
+ * @param {Function} func The function to wrap.
621
+ * @param {Function} transform The argument transform.
622
+ * @returns {Function} Returns the new function.
623
+ */
624
+ function overArg(func, transform) {
625
+ return function(arg) {
626
+ return func(transform(arg));
627
+ };
628
+ }
629
+
630
+ /**
631
+ * Converts `set` to an array of its values.
632
+ *
633
+ * @private
634
+ * @param {Object} set The set to convert.
635
+ * @returns {Array} Returns the values.
636
+ */
637
+ function setToArray(set) {
638
+ var index = -1,
639
+ result = Array(set.size);
640
+
641
+ set.forEach(function(value) {
642
+ result[++index] = value;
643
+ });
644
+ return result;
645
+ }
646
+
647
+ /** Used for built-in method references. */
648
+ var arrayProto = Array.prototype,
649
+ funcProto = Function.prototype,
650
+ objectProto = Object.prototype;
651
+
652
+ /** Used to detect overreaching core-js shims. */
653
+ var coreJsData = root['__core-js_shared__'];
654
+
655
+ /** Used to resolve the decompiled source of functions. */
656
+ var funcToString = funcProto.toString;
657
+
658
+ /** Used to check objects for own properties. */
659
+ var hasOwnProperty = objectProto.hasOwnProperty;
660
+
661
+ /** Used to detect methods masquerading as native. */
662
+ var maskSrcKey = (function() {
663
+ var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
664
+ return uid ? ('Symbol(src)_1.' + uid) : '';
665
+ }());
666
+
667
+ /**
668
+ * Used to resolve the
669
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
670
+ * of values.
671
+ */
672
+ var nativeObjectToString = objectProto.toString;
673
+
674
+ /** Used to detect if a method is native. */
675
+ var reIsNative = RegExp('^' +
676
+ funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
677
+ .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
678
+ );
679
+
680
+ /** Built-in value references. */
681
+ var Buffer = moduleExports ? root.Buffer : undefined,
682
+ Symbol = root.Symbol,
683
+ Uint8Array = root.Uint8Array,
684
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
685
+ splice = arrayProto.splice,
686
+ symToStringTag = Symbol ? Symbol.toStringTag : undefined;
687
+
688
+ /* Built-in method references for those with the same name as other `lodash` methods. */
689
+ var nativeGetSymbols = Object.getOwnPropertySymbols,
690
+ nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
691
+ nativeKeys = overArg(Object.keys, Object);
692
+
693
+ /* Built-in method references that are verified to be native. */
694
+ var DataView = getNative(root, 'DataView'),
695
+ Map = getNative(root, 'Map'),
696
+ Promise = getNative(root, 'Promise'),
697
+ Set = getNative(root, 'Set'),
698
+ WeakMap = getNative(root, 'WeakMap'),
699
+ nativeCreate = getNative(Object, 'create');
700
+
701
+ /** Used to detect maps, sets, and weakmaps. */
702
+ var dataViewCtorString = toSource(DataView),
703
+ mapCtorString = toSource(Map),
704
+ promiseCtorString = toSource(Promise),
705
+ setCtorString = toSource(Set),
706
+ weakMapCtorString = toSource(WeakMap);
707
+
708
+ /** Used to convert symbols to primitives and strings. */
709
+ var symbolProto = Symbol ? Symbol.prototype : undefined,
710
+ symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
711
+
712
+ /**
713
+ * Creates a hash object.
714
+ *
715
+ * @private
716
+ * @constructor
717
+ * @param {Array} [entries] The key-value pairs to cache.
718
+ */
719
+ function Hash(entries) {
720
+ var index = -1,
721
+ length = entries == null ? 0 : entries.length;
722
+
723
+ this.clear();
724
+ while (++index < length) {
725
+ var entry = entries[index];
726
+ this.set(entry[0], entry[1]);
727
+ }
728
+ }
729
+
730
+ /**
731
+ * Removes all key-value entries from the hash.
732
+ *
733
+ * @private
734
+ * @name clear
735
+ * @memberOf Hash
736
+ */
737
+ function hashClear() {
738
+ this.__data__ = nativeCreate ? nativeCreate(null) : {};
739
+ this.size = 0;
740
+ }
741
+
742
+ /**
743
+ * Removes `key` and its value from the hash.
744
+ *
745
+ * @private
746
+ * @name delete
747
+ * @memberOf Hash
748
+ * @param {Object} hash The hash to modify.
749
+ * @param {string} key The key of the value to remove.
750
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
751
+ */
752
+ function hashDelete(key) {
753
+ var result = this.has(key) && delete this.__data__[key];
754
+ this.size -= result ? 1 : 0;
755
+ return result;
756
+ }
757
+
758
+ /**
759
+ * Gets the hash value for `key`.
760
+ *
761
+ * @private
762
+ * @name get
763
+ * @memberOf Hash
764
+ * @param {string} key The key of the value to get.
765
+ * @returns {*} Returns the entry value.
766
+ */
767
+ function hashGet(key) {
768
+ var data = this.__data__;
769
+ if (nativeCreate) {
770
+ var result = data[key];
771
+ return result === HASH_UNDEFINED ? undefined : result;
772
+ }
773
+ return hasOwnProperty.call(data, key) ? data[key] : undefined;
774
+ }
775
+
776
+ /**
777
+ * Checks if a hash value for `key` exists.
778
+ *
779
+ * @private
780
+ * @name has
781
+ * @memberOf Hash
782
+ * @param {string} key The key of the entry to check.
783
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
784
+ */
785
+ function hashHas(key) {
786
+ var data = this.__data__;
787
+ return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
788
+ }
789
+
790
+ /**
791
+ * Sets the hash `key` to `value`.
792
+ *
793
+ * @private
794
+ * @name set
795
+ * @memberOf Hash
796
+ * @param {string} key The key of the value to set.
797
+ * @param {*} value The value to set.
798
+ * @returns {Object} Returns the hash instance.
799
+ */
800
+ function hashSet(key, value) {
801
+ var data = this.__data__;
802
+ this.size += this.has(key) ? 0 : 1;
803
+ data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
804
+ return this;
805
+ }
806
+
807
+ // Add methods to `Hash`.
808
+ Hash.prototype.clear = hashClear;
809
+ Hash.prototype['delete'] = hashDelete;
810
+ Hash.prototype.get = hashGet;
811
+ Hash.prototype.has = hashHas;
812
+ Hash.prototype.set = hashSet;
813
+
814
+ /**
815
+ * Creates an list cache object.
816
+ *
817
+ * @private
818
+ * @constructor
819
+ * @param {Array} [entries] The key-value pairs to cache.
820
+ */
821
+ function ListCache(entries) {
822
+ var index = -1,
823
+ length = entries == null ? 0 : entries.length;
824
+
825
+ this.clear();
826
+ while (++index < length) {
827
+ var entry = entries[index];
828
+ this.set(entry[0], entry[1]);
829
+ }
830
+ }
831
+
832
+ /**
833
+ * Removes all key-value entries from the list cache.
834
+ *
835
+ * @private
836
+ * @name clear
837
+ * @memberOf ListCache
838
+ */
839
+ function listCacheClear() {
840
+ this.__data__ = [];
841
+ this.size = 0;
842
+ }
843
+
844
+ /**
845
+ * Removes `key` and its value from the list cache.
846
+ *
847
+ * @private
848
+ * @name delete
849
+ * @memberOf ListCache
850
+ * @param {string} key The key of the value to remove.
851
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
852
+ */
853
+ function listCacheDelete(key) {
854
+ var data = this.__data__,
855
+ index = assocIndexOf(data, key);
856
+
857
+ if (index < 0) {
858
+ return false;
859
+ }
860
+ var lastIndex = data.length - 1;
861
+ if (index == lastIndex) {
862
+ data.pop();
863
+ } else {
864
+ splice.call(data, index, 1);
865
+ }
866
+ --this.size;
867
+ return true;
868
+ }
869
+
870
+ /**
871
+ * Gets the list cache value for `key`.
872
+ *
873
+ * @private
874
+ * @name get
875
+ * @memberOf ListCache
876
+ * @param {string} key The key of the value to get.
877
+ * @returns {*} Returns the entry value.
878
+ */
879
+ function listCacheGet(key) {
880
+ var data = this.__data__,
881
+ index = assocIndexOf(data, key);
882
+
883
+ return index < 0 ? undefined : data[index][1];
884
+ }
885
+
886
+ /**
887
+ * Checks if a list cache value for `key` exists.
888
+ *
889
+ * @private
890
+ * @name has
891
+ * @memberOf ListCache
892
+ * @param {string} key The key of the entry to check.
893
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
894
+ */
895
+ function listCacheHas(key) {
896
+ return assocIndexOf(this.__data__, key) > -1;
897
+ }
898
+
899
+ /**
900
+ * Sets the list cache `key` to `value`.
901
+ *
902
+ * @private
903
+ * @name set
904
+ * @memberOf ListCache
905
+ * @param {string} key The key of the value to set.
906
+ * @param {*} value The value to set.
907
+ * @returns {Object} Returns the list cache instance.
908
+ */
909
+ function listCacheSet(key, value) {
910
+ var data = this.__data__,
911
+ index = assocIndexOf(data, key);
912
+
913
+ if (index < 0) {
914
+ ++this.size;
915
+ data.push([key, value]);
916
+ } else {
917
+ data[index][1] = value;
918
+ }
919
+ return this;
920
+ }
921
+
922
+ // Add methods to `ListCache`.
923
+ ListCache.prototype.clear = listCacheClear;
924
+ ListCache.prototype['delete'] = listCacheDelete;
925
+ ListCache.prototype.get = listCacheGet;
926
+ ListCache.prototype.has = listCacheHas;
927
+ ListCache.prototype.set = listCacheSet;
928
+
929
+ /**
930
+ * Creates a map cache object to store key-value pairs.
931
+ *
932
+ * @private
933
+ * @constructor
934
+ * @param {Array} [entries] The key-value pairs to cache.
935
+ */
936
+ function MapCache(entries) {
937
+ var index = -1,
938
+ length = entries == null ? 0 : entries.length;
939
+
940
+ this.clear();
941
+ while (++index < length) {
942
+ var entry = entries[index];
943
+ this.set(entry[0], entry[1]);
944
+ }
945
+ }
946
+
947
+ /**
948
+ * Removes all key-value entries from the map.
949
+ *
950
+ * @private
951
+ * @name clear
952
+ * @memberOf MapCache
953
+ */
954
+ function mapCacheClear() {
955
+ this.size = 0;
956
+ this.__data__ = {
957
+ 'hash': new Hash,
958
+ 'map': new (Map || ListCache),
959
+ 'string': new Hash
960
+ };
961
+ }
962
+
963
+ /**
964
+ * Removes `key` and its value from the map.
965
+ *
966
+ * @private
967
+ * @name delete
968
+ * @memberOf MapCache
969
+ * @param {string} key The key of the value to remove.
970
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
971
+ */
972
+ function mapCacheDelete(key) {
973
+ var result = getMapData(this, key)['delete'](key);
974
+ this.size -= result ? 1 : 0;
975
+ return result;
976
+ }
977
+
978
+ /**
979
+ * Gets the map value for `key`.
980
+ *
981
+ * @private
982
+ * @name get
983
+ * @memberOf MapCache
984
+ * @param {string} key The key of the value to get.
985
+ * @returns {*} Returns the entry value.
986
+ */
987
+ function mapCacheGet(key) {
988
+ return getMapData(this, key).get(key);
989
+ }
990
+
991
+ /**
992
+ * Checks if a map value for `key` exists.
993
+ *
994
+ * @private
995
+ * @name has
996
+ * @memberOf MapCache
997
+ * @param {string} key The key of the entry to check.
998
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
999
+ */
1000
+ function mapCacheHas(key) {
1001
+ return getMapData(this, key).has(key);
1002
+ }
1003
+
1004
+ /**
1005
+ * Sets the map `key` to `value`.
1006
+ *
1007
+ * @private
1008
+ * @name set
1009
+ * @memberOf MapCache
1010
+ * @param {string} key The key of the value to set.
1011
+ * @param {*} value The value to set.
1012
+ * @returns {Object} Returns the map cache instance.
1013
+ */
1014
+ function mapCacheSet(key, value) {
1015
+ var data = getMapData(this, key),
1016
+ size = data.size;
1017
+
1018
+ data.set(key, value);
1019
+ this.size += data.size == size ? 0 : 1;
1020
+ return this;
1021
+ }
1022
+
1023
+ // Add methods to `MapCache`.
1024
+ MapCache.prototype.clear = mapCacheClear;
1025
+ MapCache.prototype['delete'] = mapCacheDelete;
1026
+ MapCache.prototype.get = mapCacheGet;
1027
+ MapCache.prototype.has = mapCacheHas;
1028
+ MapCache.prototype.set = mapCacheSet;
1029
+
1030
+ /**
1031
+ *
1032
+ * Creates an array cache object to store unique values.
1033
+ *
1034
+ * @private
1035
+ * @constructor
1036
+ * @param {Array} [values] The values to cache.
1037
+ */
1038
+ function SetCache(values) {
1039
+ var index = -1,
1040
+ length = values == null ? 0 : values.length;
1041
+
1042
+ this.__data__ = new MapCache;
1043
+ while (++index < length) {
1044
+ this.add(values[index]);
1045
+ }
1046
+ }
1047
+
1048
+ /**
1049
+ * Adds `value` to the array cache.
1050
+ *
1051
+ * @private
1052
+ * @name add
1053
+ * @memberOf SetCache
1054
+ * @alias push
1055
+ * @param {*} value The value to cache.
1056
+ * @returns {Object} Returns the cache instance.
1057
+ */
1058
+ function setCacheAdd(value) {
1059
+ this.__data__.set(value, HASH_UNDEFINED);
1060
+ return this;
1061
+ }
1062
+
1063
+ /**
1064
+ * Checks if `value` is in the array cache.
1065
+ *
1066
+ * @private
1067
+ * @name has
1068
+ * @memberOf SetCache
1069
+ * @param {*} value The value to search for.
1070
+ * @returns {number} Returns `true` if `value` is found, else `false`.
1071
+ */
1072
+ function setCacheHas(value) {
1073
+ return this.__data__.has(value);
1074
+ }
1075
+
1076
+ // Add methods to `SetCache`.
1077
+ SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
1078
+ SetCache.prototype.has = setCacheHas;
1079
+
1080
+ /**
1081
+ * Creates a stack cache object to store key-value pairs.
1082
+ *
1083
+ * @private
1084
+ * @constructor
1085
+ * @param {Array} [entries] The key-value pairs to cache.
1086
+ */
1087
+ function Stack(entries) {
1088
+ var data = this.__data__ = new ListCache(entries);
1089
+ this.size = data.size;
1090
+ }
1091
+
1092
+ /**
1093
+ * Removes all key-value entries from the stack.
1094
+ *
1095
+ * @private
1096
+ * @name clear
1097
+ * @memberOf Stack
1098
+ */
1099
+ function stackClear() {
1100
+ this.__data__ = new ListCache;
1101
+ this.size = 0;
1102
+ }
1103
+
1104
+ /**
1105
+ * Removes `key` and its value from the stack.
1106
+ *
1107
+ * @private
1108
+ * @name delete
1109
+ * @memberOf Stack
1110
+ * @param {string} key The key of the value to remove.
1111
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1112
+ */
1113
+ function stackDelete(key) {
1114
+ var data = this.__data__,
1115
+ result = data['delete'](key);
1116
+
1117
+ this.size = data.size;
1118
+ return result;
1119
+ }
1120
+
1121
+ /**
1122
+ * Gets the stack value for `key`.
1123
+ *
1124
+ * @private
1125
+ * @name get
1126
+ * @memberOf Stack
1127
+ * @param {string} key The key of the value to get.
1128
+ * @returns {*} Returns the entry value.
1129
+ */
1130
+ function stackGet(key) {
1131
+ return this.__data__.get(key);
1132
+ }
1133
+
1134
+ /**
1135
+ * Checks if a stack value for `key` exists.
1136
+ *
1137
+ * @private
1138
+ * @name has
1139
+ * @memberOf Stack
1140
+ * @param {string} key The key of the entry to check.
1141
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1142
+ */
1143
+ function stackHas(key) {
1144
+ return this.__data__.has(key);
1145
+ }
1146
+
1147
+ /**
1148
+ * Sets the stack `key` to `value`.
1149
+ *
1150
+ * @private
1151
+ * @name set
1152
+ * @memberOf Stack
1153
+ * @param {string} key The key of the value to set.
1154
+ * @param {*} value The value to set.
1155
+ * @returns {Object} Returns the stack cache instance.
1156
+ */
1157
+ function stackSet(key, value) {
1158
+ var data = this.__data__;
1159
+ if (data instanceof ListCache) {
1160
+ var pairs = data.__data__;
1161
+ if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
1162
+ pairs.push([key, value]);
1163
+ this.size = ++data.size;
1164
+ return this;
1165
+ }
1166
+ data = this.__data__ = new MapCache(pairs);
1167
+ }
1168
+ data.set(key, value);
1169
+ this.size = data.size;
1170
+ return this;
1171
+ }
1172
+
1173
+ // Add methods to `Stack`.
1174
+ Stack.prototype.clear = stackClear;
1175
+ Stack.prototype['delete'] = stackDelete;
1176
+ Stack.prototype.get = stackGet;
1177
+ Stack.prototype.has = stackHas;
1178
+ Stack.prototype.set = stackSet;
1179
+
1180
+ /**
1181
+ * Creates an array of the enumerable property names of the array-like `value`.
1182
+ *
1183
+ * @private
1184
+ * @param {*} value The value to query.
1185
+ * @param {boolean} inherited Specify returning inherited property names.
1186
+ * @returns {Array} Returns the array of property names.
1187
+ */
1188
+ function arrayLikeKeys(value, inherited) {
1189
+ var isArr = isArray(value),
1190
+ isArg = !isArr && isArguments(value),
1191
+ isBuff = !isArr && !isArg && isBuffer(value),
1192
+ isType = !isArr && !isArg && !isBuff && isTypedArray(value),
1193
+ skipIndexes = isArr || isArg || isBuff || isType,
1194
+ result = skipIndexes ? baseTimes(value.length, String) : [],
1195
+ length = result.length;
1196
+
1197
+ for (var key in value) {
1198
+ if ((inherited || hasOwnProperty.call(value, key)) &&
1199
+ !(skipIndexes && (
1200
+ // Safari 9 has enumerable `arguments.length` in strict mode.
1201
+ key == 'length' ||
1202
+ // Node.js 0.10 has enumerable non-index properties on buffers.
1203
+ (isBuff && (key == 'offset' || key == 'parent')) ||
1204
+ // PhantomJS 2 has enumerable non-index properties on typed arrays.
1205
+ (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
1206
+ // Skip index properties.
1207
+ isIndex(key, length)
1208
+ ))) {
1209
+ result.push(key);
1210
+ }
1211
+ }
1212
+ return result;
1213
+ }
1214
+
1215
+ /**
1216
+ * Gets the index at which the `key` is found in `array` of key-value pairs.
1217
+ *
1218
+ * @private
1219
+ * @param {Array} array The array to inspect.
1220
+ * @param {*} key The key to search for.
1221
+ * @returns {number} Returns the index of the matched value, else `-1`.
1222
+ */
1223
+ function assocIndexOf(array, key) {
1224
+ var length = array.length;
1225
+ while (length--) {
1226
+ if (eq(array[length][0], key)) {
1227
+ return length;
1228
+ }
1229
+ }
1230
+ return -1;
1231
+ }
1232
+
1233
+ /**
1234
+ * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
1235
+ * `keysFunc` and `symbolsFunc` to get the enumerable property names and
1236
+ * symbols of `object`.
1237
+ *
1238
+ * @private
1239
+ * @param {Object} object The object to query.
1240
+ * @param {Function} keysFunc The function to get the keys of `object`.
1241
+ * @param {Function} symbolsFunc The function to get the symbols of `object`.
1242
+ * @returns {Array} Returns the array of property names and symbols.
1243
+ */
1244
+ function baseGetAllKeys(object, keysFunc, symbolsFunc) {
1245
+ var result = keysFunc(object);
1246
+ return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
1247
+ }
1248
+
1249
+ /**
1250
+ * The base implementation of `getTag` without fallbacks for buggy environments.
1251
+ *
1252
+ * @private
1253
+ * @param {*} value The value to query.
1254
+ * @returns {string} Returns the `toStringTag`.
1255
+ */
1256
+ function baseGetTag(value) {
1257
+ if (value == null) {
1258
+ return value === undefined ? undefinedTag : nullTag;
1259
+ }
1260
+ return (symToStringTag && symToStringTag in Object(value))
1261
+ ? getRawTag(value)
1262
+ : objectToString(value);
1263
+ }
1264
+
1265
+ /**
1266
+ * The base implementation of `_.isArguments`.
1267
+ *
1268
+ * @private
1269
+ * @param {*} value The value to check.
1270
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
1271
+ */
1272
+ function baseIsArguments(value) {
1273
+ return isObjectLike(value) && baseGetTag(value) == argsTag;
1274
+ }
1275
+
1276
+ /**
1277
+ * The base implementation of `_.isEqual` which supports partial comparisons
1278
+ * and tracks traversed objects.
1279
+ *
1280
+ * @private
1281
+ * @param {*} value The value to compare.
1282
+ * @param {*} other The other value to compare.
1283
+ * @param {boolean} bitmask The bitmask flags.
1284
+ * 1 - Unordered comparison
1285
+ * 2 - Partial comparison
1286
+ * @param {Function} [customizer] The function to customize comparisons.
1287
+ * @param {Object} [stack] Tracks traversed `value` and `other` objects.
1288
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1289
+ */
1290
+ function baseIsEqual(value, other, bitmask, customizer, stack) {
1291
+ if (value === other) {
1292
+ return true;
1293
+ }
1294
+ if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
1295
+ return value !== value && other !== other;
1296
+ }
1297
+ return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
1298
+ }
1299
+
1300
+ /**
1301
+ * A specialized version of `baseIsEqual` for arrays and objects which performs
1302
+ * deep comparisons and tracks traversed objects enabling objects with circular
1303
+ * references to be compared.
1304
+ *
1305
+ * @private
1306
+ * @param {Object} object The object to compare.
1307
+ * @param {Object} other The other object to compare.
1308
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1309
+ * @param {Function} customizer The function to customize comparisons.
1310
+ * @param {Function} equalFunc The function to determine equivalents of values.
1311
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
1312
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
1313
+ */
1314
+ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
1315
+ var objIsArr = isArray(object),
1316
+ othIsArr = isArray(other),
1317
+ objTag = objIsArr ? arrayTag : getTag(object),
1318
+ othTag = othIsArr ? arrayTag : getTag(other);
1319
+
1320
+ objTag = objTag == argsTag ? objectTag : objTag;
1321
+ othTag = othTag == argsTag ? objectTag : othTag;
1322
+
1323
+ var objIsObj = objTag == objectTag,
1324
+ othIsObj = othTag == objectTag,
1325
+ isSameTag = objTag == othTag;
1326
+
1327
+ if (isSameTag && isBuffer(object)) {
1328
+ if (!isBuffer(other)) {
1329
+ return false;
1330
+ }
1331
+ objIsArr = true;
1332
+ objIsObj = false;
1333
+ }
1334
+ if (isSameTag && !objIsObj) {
1335
+ stack || (stack = new Stack);
1336
+ return (objIsArr || isTypedArray(object))
1337
+ ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
1338
+ : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
1339
+ }
1340
+ if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
1341
+ var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
1342
+ othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
1343
+
1344
+ if (objIsWrapped || othIsWrapped) {
1345
+ var objUnwrapped = objIsWrapped ? object.value() : object,
1346
+ othUnwrapped = othIsWrapped ? other.value() : other;
1347
+
1348
+ stack || (stack = new Stack);
1349
+ return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
1350
+ }
1351
+ }
1352
+ if (!isSameTag) {
1353
+ return false;
1354
+ }
1355
+ stack || (stack = new Stack);
1356
+ return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
1357
+ }
1358
+
1359
+ /**
1360
+ * The base implementation of `_.isNative` without bad shim checks.
1361
+ *
1362
+ * @private
1363
+ * @param {*} value The value to check.
1364
+ * @returns {boolean} Returns `true` if `value` is a native function,
1365
+ * else `false`.
1366
+ */
1367
+ function baseIsNative(value) {
1368
+ if (!isObject(value) || isMasked(value)) {
1369
+ return false;
1370
+ }
1371
+ var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
1372
+ return pattern.test(toSource(value));
1373
+ }
1374
+
1375
+ /**
1376
+ * The base implementation of `_.isTypedArray` without Node.js optimizations.
1377
+ *
1378
+ * @private
1379
+ * @param {*} value The value to check.
1380
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
1381
+ */
1382
+ function baseIsTypedArray(value) {
1383
+ return isObjectLike(value) &&
1384
+ isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
1385
+ }
1386
+
1387
+ /**
1388
+ * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
1389
+ *
1390
+ * @private
1391
+ * @param {Object} object The object to query.
1392
+ * @returns {Array} Returns the array of property names.
1393
+ */
1394
+ function baseKeys(object) {
1395
+ if (!isPrototype(object)) {
1396
+ return nativeKeys(object);
1397
+ }
1398
+ var result = [];
1399
+ for (var key in Object(object)) {
1400
+ if (hasOwnProperty.call(object, key) && key != 'constructor') {
1401
+ result.push(key);
1402
+ }
1403
+ }
1404
+ return result;
1405
+ }
1406
+
1407
+ /**
1408
+ * A specialized version of `baseIsEqualDeep` for arrays with support for
1409
+ * partial deep comparisons.
1410
+ *
1411
+ * @private
1412
+ * @param {Array} array The array to compare.
1413
+ * @param {Array} other The other array to compare.
1414
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1415
+ * @param {Function} customizer The function to customize comparisons.
1416
+ * @param {Function} equalFunc The function to determine equivalents of values.
1417
+ * @param {Object} stack Tracks traversed `array` and `other` objects.
1418
+ * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
1419
+ */
1420
+ function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
1421
+ var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
1422
+ arrLength = array.length,
1423
+ othLength = other.length;
1424
+
1425
+ if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
1426
+ return false;
1427
+ }
1428
+ // Assume cyclic values are equal.
1429
+ var stacked = stack.get(array);
1430
+ if (stacked && stack.get(other)) {
1431
+ return stacked == other;
1432
+ }
1433
+ var index = -1,
1434
+ result = true,
1435
+ seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
1436
+
1437
+ stack.set(array, other);
1438
+ stack.set(other, array);
1439
+
1440
+ // Ignore non-index properties.
1441
+ while (++index < arrLength) {
1442
+ var arrValue = array[index],
1443
+ othValue = other[index];
1444
+
1445
+ if (customizer) {
1446
+ var compared = isPartial
1447
+ ? customizer(othValue, arrValue, index, other, array, stack)
1448
+ : customizer(arrValue, othValue, index, array, other, stack);
1449
+ }
1450
+ if (compared !== undefined) {
1451
+ if (compared) {
1452
+ continue;
1453
+ }
1454
+ result = false;
1455
+ break;
1456
+ }
1457
+ // Recursively compare arrays (susceptible to call stack limits).
1458
+ if (seen) {
1459
+ if (!arraySome(other, function(othValue, othIndex) {
1460
+ if (!cacheHas(seen, othIndex) &&
1461
+ (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
1462
+ return seen.push(othIndex);
1463
+ }
1464
+ })) {
1465
+ result = false;
1466
+ break;
1467
+ }
1468
+ } else if (!(
1469
+ arrValue === othValue ||
1470
+ equalFunc(arrValue, othValue, bitmask, customizer, stack)
1471
+ )) {
1472
+ result = false;
1473
+ break;
1474
+ }
1475
+ }
1476
+ stack['delete'](array);
1477
+ stack['delete'](other);
1478
+ return result;
1479
+ }
1480
+
1481
+ /**
1482
+ * A specialized version of `baseIsEqualDeep` for comparing objects of
1483
+ * the same `toStringTag`.
1484
+ *
1485
+ * **Note:** This function only supports comparing values with tags of
1486
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
1487
+ *
1488
+ * @private
1489
+ * @param {Object} object The object to compare.
1490
+ * @param {Object} other The other object to compare.
1491
+ * @param {string} tag The `toStringTag` of the objects to compare.
1492
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1493
+ * @param {Function} customizer The function to customize comparisons.
1494
+ * @param {Function} equalFunc The function to determine equivalents of values.
1495
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
1496
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
1497
+ */
1498
+ function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
1499
+ switch (tag) {
1500
+ case dataViewTag:
1501
+ if ((object.byteLength != other.byteLength) ||
1502
+ (object.byteOffset != other.byteOffset)) {
1503
+ return false;
1504
+ }
1505
+ object = object.buffer;
1506
+ other = other.buffer;
1507
+
1508
+ case arrayBufferTag:
1509
+ if ((object.byteLength != other.byteLength) ||
1510
+ !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
1511
+ return false;
1512
+ }
1513
+ return true;
1514
+
1515
+ case boolTag:
1516
+ case dateTag:
1517
+ case numberTag:
1518
+ // Coerce booleans to `1` or `0` and dates to milliseconds.
1519
+ // Invalid dates are coerced to `NaN`.
1520
+ return eq(+object, +other);
1521
+
1522
+ case errorTag:
1523
+ return object.name == other.name && object.message == other.message;
1524
+
1525
+ case regexpTag:
1526
+ case stringTag:
1527
+ // Coerce regexes to strings and treat strings, primitives and objects,
1528
+ // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
1529
+ // for more details.
1530
+ return object == (other + '');
1531
+
1532
+ case mapTag:
1533
+ var convert = mapToArray;
1534
+
1535
+ case setTag:
1536
+ var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
1537
+ convert || (convert = setToArray);
1538
+
1539
+ if (object.size != other.size && !isPartial) {
1540
+ return false;
1541
+ }
1542
+ // Assume cyclic values are equal.
1543
+ var stacked = stack.get(object);
1544
+ if (stacked) {
1545
+ return stacked == other;
1546
+ }
1547
+ bitmask |= COMPARE_UNORDERED_FLAG;
1548
+
1549
+ // Recursively compare objects (susceptible to call stack limits).
1550
+ stack.set(object, other);
1551
+ var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
1552
+ stack['delete'](object);
1553
+ return result;
1554
+
1555
+ case symbolTag:
1556
+ if (symbolValueOf) {
1557
+ return symbolValueOf.call(object) == symbolValueOf.call(other);
1558
+ }
1559
+ }
1560
+ return false;
1561
+ }
1562
+
1563
+ /**
1564
+ * A specialized version of `baseIsEqualDeep` for objects with support for
1565
+ * partial deep comparisons.
1566
+ *
1567
+ * @private
1568
+ * @param {Object} object The object to compare.
1569
+ * @param {Object} other The other object to compare.
1570
+ * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1571
+ * @param {Function} customizer The function to customize comparisons.
1572
+ * @param {Function} equalFunc The function to determine equivalents of values.
1573
+ * @param {Object} stack Tracks traversed `object` and `other` objects.
1574
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
1575
+ */
1576
+ function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
1577
+ var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
1578
+ objProps = getAllKeys(object),
1579
+ objLength = objProps.length,
1580
+ othProps = getAllKeys(other),
1581
+ othLength = othProps.length;
1582
+
1583
+ if (objLength != othLength && !isPartial) {
1584
+ return false;
1585
+ }
1586
+ var index = objLength;
1587
+ while (index--) {
1588
+ var key = objProps[index];
1589
+ if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
1590
+ return false;
1591
+ }
1592
+ }
1593
+ // Assume cyclic values are equal.
1594
+ var stacked = stack.get(object);
1595
+ if (stacked && stack.get(other)) {
1596
+ return stacked == other;
1597
+ }
1598
+ var result = true;
1599
+ stack.set(object, other);
1600
+ stack.set(other, object);
1601
+
1602
+ var skipCtor = isPartial;
1603
+ while (++index < objLength) {
1604
+ key = objProps[index];
1605
+ var objValue = object[key],
1606
+ othValue = other[key];
1607
+
1608
+ if (customizer) {
1609
+ var compared = isPartial
1610
+ ? customizer(othValue, objValue, key, other, object, stack)
1611
+ : customizer(objValue, othValue, key, object, other, stack);
1612
+ }
1613
+ // Recursively compare objects (susceptible to call stack limits).
1614
+ if (!(compared === undefined
1615
+ ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
1616
+ : compared
1617
+ )) {
1618
+ result = false;
1619
+ break;
1620
+ }
1621
+ skipCtor || (skipCtor = key == 'constructor');
1622
+ }
1623
+ if (result && !skipCtor) {
1624
+ var objCtor = object.constructor,
1625
+ othCtor = other.constructor;
1626
+
1627
+ // Non `Object` object instances with different constructors are not equal.
1628
+ if (objCtor != othCtor &&
1629
+ ('constructor' in object && 'constructor' in other) &&
1630
+ !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
1631
+ typeof othCtor == 'function' && othCtor instanceof othCtor)) {
1632
+ result = false;
1633
+ }
1634
+ }
1635
+ stack['delete'](object);
1636
+ stack['delete'](other);
1637
+ return result;
1638
+ }
1639
+
1640
+ /**
1641
+ * Creates an array of own enumerable property names and symbols of `object`.
1642
+ *
1643
+ * @private
1644
+ * @param {Object} object The object to query.
1645
+ * @returns {Array} Returns the array of property names and symbols.
1646
+ */
1647
+ function getAllKeys(object) {
1648
+ return baseGetAllKeys(object, keys, getSymbols);
1649
+ }
1650
+
1651
+ /**
1652
+ * Gets the data for `map`.
1653
+ *
1654
+ * @private
1655
+ * @param {Object} map The map to query.
1656
+ * @param {string} key The reference key.
1657
+ * @returns {*} Returns the map data.
1658
+ */
1659
+ function getMapData(map, key) {
1660
+ var data = map.__data__;
1661
+ return isKeyable(key)
1662
+ ? data[typeof key == 'string' ? 'string' : 'hash']
1663
+ : data.map;
1664
+ }
1665
+
1666
+ /**
1667
+ * Gets the native function at `key` of `object`.
1668
+ *
1669
+ * @private
1670
+ * @param {Object} object The object to query.
1671
+ * @param {string} key The key of the method to get.
1672
+ * @returns {*} Returns the function if it's native, else `undefined`.
1673
+ */
1674
+ function getNative(object, key) {
1675
+ var value = getValue(object, key);
1676
+ return baseIsNative(value) ? value : undefined;
1677
+ }
1678
+
1679
+ /**
1680
+ * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
1681
+ *
1682
+ * @private
1683
+ * @param {*} value The value to query.
1684
+ * @returns {string} Returns the raw `toStringTag`.
1685
+ */
1686
+ function getRawTag(value) {
1687
+ var isOwn = hasOwnProperty.call(value, symToStringTag),
1688
+ tag = value[symToStringTag];
1689
+
1690
+ try {
1691
+ value[symToStringTag] = undefined;
1692
+ var unmasked = true;
1693
+ } catch (e) {}
1694
+
1695
+ var result = nativeObjectToString.call(value);
1696
+ if (unmasked) {
1697
+ if (isOwn) {
1698
+ value[symToStringTag] = tag;
1699
+ } else {
1700
+ delete value[symToStringTag];
1701
+ }
1702
+ }
1703
+ return result;
1704
+ }
1705
+
1706
+ /**
1707
+ * Creates an array of the own enumerable symbols of `object`.
1708
+ *
1709
+ * @private
1710
+ * @param {Object} object The object to query.
1711
+ * @returns {Array} Returns the array of symbols.
1712
+ */
1713
+ var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
1714
+ if (object == null) {
1715
+ return [];
1716
+ }
1717
+ object = Object(object);
1718
+ return arrayFilter(nativeGetSymbols(object), function(symbol) {
1719
+ return propertyIsEnumerable.call(object, symbol);
1720
+ });
1721
+ };
1722
+
1723
+ /**
1724
+ * Gets the `toStringTag` of `value`.
1725
+ *
1726
+ * @private
1727
+ * @param {*} value The value to query.
1728
+ * @returns {string} Returns the `toStringTag`.
1729
+ */
1730
+ var getTag = baseGetTag;
1731
+
1732
+ // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
1733
+ if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
1734
+ (Map && getTag(new Map) != mapTag) ||
1735
+ (Promise && getTag(Promise.resolve()) != promiseTag) ||
1736
+ (Set && getTag(new Set) != setTag) ||
1737
+ (WeakMap && getTag(new WeakMap) != weakMapTag)) {
1738
+ getTag = function(value) {
1739
+ var result = baseGetTag(value),
1740
+ Ctor = result == objectTag ? value.constructor : undefined,
1741
+ ctorString = Ctor ? toSource(Ctor) : '';
1742
+
1743
+ if (ctorString) {
1744
+ switch (ctorString) {
1745
+ case dataViewCtorString: return dataViewTag;
1746
+ case mapCtorString: return mapTag;
1747
+ case promiseCtorString: return promiseTag;
1748
+ case setCtorString: return setTag;
1749
+ case weakMapCtorString: return weakMapTag;
1750
+ }
1751
+ }
1752
+ return result;
1753
+ };
1754
+ }
1755
+
1756
+ /**
1757
+ * Checks if `value` is a valid array-like index.
1758
+ *
1759
+ * @private
1760
+ * @param {*} value The value to check.
1761
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1762
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1763
+ */
1764
+ function isIndex(value, length) {
1765
+ length = length == null ? MAX_SAFE_INTEGER : length;
1766
+ return !!length &&
1767
+ (typeof value == 'number' || reIsUint.test(value)) &&
1768
+ (value > -1 && value % 1 == 0 && value < length);
1769
+ }
1770
+
1771
+ /**
1772
+ * Checks if `value` is suitable for use as unique object key.
1773
+ *
1774
+ * @private
1775
+ * @param {*} value The value to check.
1776
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
1777
+ */
1778
+ function isKeyable(value) {
1779
+ var type = typeof value;
1780
+ return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
1781
+ ? (value !== '__proto__')
1782
+ : (value === null);
1783
+ }
1784
+
1785
+ /**
1786
+ * Checks if `func` has its source masked.
1787
+ *
1788
+ * @private
1789
+ * @param {Function} func The function to check.
1790
+ * @returns {boolean} Returns `true` if `func` is masked, else `false`.
1791
+ */
1792
+ function isMasked(func) {
1793
+ return !!maskSrcKey && (maskSrcKey in func);
1794
+ }
1795
+
1796
+ /**
1797
+ * Checks if `value` is likely a prototype object.
1798
+ *
1799
+ * @private
1800
+ * @param {*} value The value to check.
1801
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
1802
+ */
1803
+ function isPrototype(value) {
1804
+ var Ctor = value && value.constructor,
1805
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
1806
+
1807
+ return value === proto;
1808
+ }
1809
+
1810
+ /**
1811
+ * Converts `value` to a string using `Object.prototype.toString`.
1812
+ *
1813
+ * @private
1814
+ * @param {*} value The value to convert.
1815
+ * @returns {string} Returns the converted string.
1816
+ */
1817
+ function objectToString(value) {
1818
+ return nativeObjectToString.call(value);
1819
+ }
1820
+
1821
+ /**
1822
+ * Converts `func` to its source code.
1823
+ *
1824
+ * @private
1825
+ * @param {Function} func The function to convert.
1826
+ * @returns {string} Returns the source code.
1827
+ */
1828
+ function toSource(func) {
1829
+ if (func != null) {
1830
+ try {
1831
+ return funcToString.call(func);
1832
+ } catch (e) {}
1833
+ try {
1834
+ return (func + '');
1835
+ } catch (e) {}
1836
+ }
1837
+ return '';
1838
+ }
1839
+
1840
+ /**
1841
+ * Performs a
1842
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
1843
+ * comparison between two values to determine if they are equivalent.
1844
+ *
1845
+ * @static
1846
+ * @memberOf _
1847
+ * @since 4.0.0
1848
+ * @category Lang
1849
+ * @param {*} value The value to compare.
1850
+ * @param {*} other The other value to compare.
1851
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1852
+ * @example
1853
+ *
1854
+ * var object = { 'a': 1 };
1855
+ * var other = { 'a': 1 };
1856
+ *
1857
+ * _.eq(object, object);
1858
+ * // => true
1859
+ *
1860
+ * _.eq(object, other);
1861
+ * // => false
1862
+ *
1863
+ * _.eq('a', 'a');
1864
+ * // => true
1865
+ *
1866
+ * _.eq('a', Object('a'));
1867
+ * // => false
1868
+ *
1869
+ * _.eq(NaN, NaN);
1870
+ * // => true
1871
+ */
1872
+ function eq(value, other) {
1873
+ return value === other || (value !== value && other !== other);
1874
+ }
1875
+
1876
+ /**
1877
+ * Checks if `value` is likely an `arguments` object.
1878
+ *
1879
+ * @static
1880
+ * @memberOf _
1881
+ * @since 0.1.0
1882
+ * @category Lang
1883
+ * @param {*} value The value to check.
1884
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
1885
+ * else `false`.
1886
+ * @example
1887
+ *
1888
+ * _.isArguments(function() { return arguments; }());
1889
+ * // => true
1890
+ *
1891
+ * _.isArguments([1, 2, 3]);
1892
+ * // => false
1893
+ */
1894
+ var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
1895
+ return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
1896
+ !propertyIsEnumerable.call(value, 'callee');
1897
+ };
1898
+
1899
+ /**
1900
+ * Checks if `value` is classified as an `Array` object.
1901
+ *
1902
+ * @static
1903
+ * @memberOf _
1904
+ * @since 0.1.0
1905
+ * @category Lang
1906
+ * @param {*} value The value to check.
1907
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
1908
+ * @example
1909
+ *
1910
+ * _.isArray([1, 2, 3]);
1911
+ * // => true
1912
+ *
1913
+ * _.isArray(document.body.children);
1914
+ * // => false
1915
+ *
1916
+ * _.isArray('abc');
1917
+ * // => false
1918
+ *
1919
+ * _.isArray(_.noop);
1920
+ * // => false
1921
+ */
1922
+ var isArray = Array.isArray;
1923
+
1924
+ /**
1925
+ * Checks if `value` is array-like. A value is considered array-like if it's
1926
+ * not a function and has a `value.length` that's an integer greater than or
1927
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
1928
+ *
1929
+ * @static
1930
+ * @memberOf _
1931
+ * @since 4.0.0
1932
+ * @category Lang
1933
+ * @param {*} value The value to check.
1934
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
1935
+ * @example
1936
+ *
1937
+ * _.isArrayLike([1, 2, 3]);
1938
+ * // => true
1939
+ *
1940
+ * _.isArrayLike(document.body.children);
1941
+ * // => true
1942
+ *
1943
+ * _.isArrayLike('abc');
1944
+ * // => true
1945
+ *
1946
+ * _.isArrayLike(_.noop);
1947
+ * // => false
1948
+ */
1949
+ function isArrayLike(value) {
1950
+ return value != null && isLength(value.length) && !isFunction(value);
1951
+ }
1952
+
1953
+ /**
1954
+ * Checks if `value` is a buffer.
1955
+ *
1956
+ * @static
1957
+ * @memberOf _
1958
+ * @since 4.3.0
1959
+ * @category Lang
1960
+ * @param {*} value The value to check.
1961
+ * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
1962
+ * @example
1963
+ *
1964
+ * _.isBuffer(new Buffer(2));
1965
+ * // => true
1966
+ *
1967
+ * _.isBuffer(new Uint8Array(2));
1968
+ * // => false
1969
+ */
1970
+ var isBuffer = nativeIsBuffer || stubFalse;
1971
+
1972
+ /**
1973
+ * Performs a deep comparison between two values to determine if they are
1974
+ * equivalent.
1975
+ *
1976
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
1977
+ * date objects, error objects, maps, numbers, `Object` objects, regexes,
1978
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
1979
+ * by their own, not inherited, enumerable properties. Functions and DOM
1980
+ * nodes are compared by strict equality, i.e. `===`.
1981
+ *
1982
+ * @static
1983
+ * @memberOf _
1984
+ * @since 0.1.0
1985
+ * @category Lang
1986
+ * @param {*} value The value to compare.
1987
+ * @param {*} other The other value to compare.
1988
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1989
+ * @example
1990
+ *
1991
+ * var object = { 'a': 1 };
1992
+ * var other = { 'a': 1 };
1993
+ *
1994
+ * _.isEqual(object, other);
1995
+ * // => true
1996
+ *
1997
+ * object === other;
1998
+ * // => false
1999
+ */
2000
+ function isEqual(value, other) {
2001
+ return baseIsEqual(value, other);
2002
+ }
2003
+
2004
+ /**
2005
+ * Checks if `value` is classified as a `Function` object.
2006
+ *
2007
+ * @static
2008
+ * @memberOf _
2009
+ * @since 0.1.0
2010
+ * @category Lang
2011
+ * @param {*} value The value to check.
2012
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
2013
+ * @example
2014
+ *
2015
+ * _.isFunction(_);
2016
+ * // => true
2017
+ *
2018
+ * _.isFunction(/abc/);
2019
+ * // => false
2020
+ */
2021
+ function isFunction(value) {
2022
+ if (!isObject(value)) {
2023
+ return false;
2024
+ }
2025
+ // The use of `Object#toString` avoids issues with the `typeof` operator
2026
+ // in Safari 9 which returns 'object' for typed arrays and other constructors.
2027
+ var tag = baseGetTag(value);
2028
+ return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
2029
+ }
2030
+
2031
+ /**
2032
+ * Checks if `value` is a valid array-like length.
2033
+ *
2034
+ * **Note:** This method is loosely based on
2035
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
2036
+ *
2037
+ * @static
2038
+ * @memberOf _
2039
+ * @since 4.0.0
2040
+ * @category Lang
2041
+ * @param {*} value The value to check.
2042
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
2043
+ * @example
2044
+ *
2045
+ * _.isLength(3);
2046
+ * // => true
2047
+ *
2048
+ * _.isLength(Number.MIN_VALUE);
2049
+ * // => false
2050
+ *
2051
+ * _.isLength(Infinity);
2052
+ * // => false
2053
+ *
2054
+ * _.isLength('3');
2055
+ * // => false
2056
+ */
2057
+ function isLength(value) {
2058
+ return typeof value == 'number' &&
2059
+ value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
2060
+ }
2061
+
2062
+ /**
2063
+ * Checks if `value` is the
2064
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
2065
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
2066
+ *
2067
+ * @static
2068
+ * @memberOf _
2069
+ * @since 0.1.0
2070
+ * @category Lang
2071
+ * @param {*} value The value to check.
2072
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
2073
+ * @example
2074
+ *
2075
+ * _.isObject({});
2076
+ * // => true
2077
+ *
2078
+ * _.isObject([1, 2, 3]);
2079
+ * // => true
2080
+ *
2081
+ * _.isObject(_.noop);
2082
+ * // => true
2083
+ *
2084
+ * _.isObject(null);
2085
+ * // => false
2086
+ */
2087
+ function isObject(value) {
2088
+ var type = typeof value;
2089
+ return value != null && (type == 'object' || type == 'function');
2090
+ }
2091
+
2092
+ /**
2093
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
2094
+ * and has a `typeof` result of "object".
2095
+ *
2096
+ * @static
2097
+ * @memberOf _
2098
+ * @since 4.0.0
2099
+ * @category Lang
2100
+ * @param {*} value The value to check.
2101
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
2102
+ * @example
2103
+ *
2104
+ * _.isObjectLike({});
2105
+ * // => true
2106
+ *
2107
+ * _.isObjectLike([1, 2, 3]);
2108
+ * // => true
2109
+ *
2110
+ * _.isObjectLike(_.noop);
2111
+ * // => false
2112
+ *
2113
+ * _.isObjectLike(null);
2114
+ * // => false
2115
+ */
2116
+ function isObjectLike(value) {
2117
+ return value != null && typeof value == 'object';
2118
+ }
2119
+
2120
+ /**
2121
+ * Checks if `value` is classified as a typed array.
2122
+ *
2123
+ * @static
2124
+ * @memberOf _
2125
+ * @since 3.0.0
2126
+ * @category Lang
2127
+ * @param {*} value The value to check.
2128
+ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
2129
+ * @example
2130
+ *
2131
+ * _.isTypedArray(new Uint8Array);
2132
+ * // => true
2133
+ *
2134
+ * _.isTypedArray([]);
2135
+ * // => false
2136
+ */
2137
+ var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
2138
+
2139
+ /**
2140
+ * Creates an array of the own enumerable property names of `object`.
2141
+ *
2142
+ * **Note:** Non-object values are coerced to objects. See the
2143
+ * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
2144
+ * for more details.
2145
+ *
2146
+ * @static
2147
+ * @since 0.1.0
2148
+ * @memberOf _
2149
+ * @category Object
2150
+ * @param {Object} object The object to query.
2151
+ * @returns {Array} Returns the array of property names.
2152
+ * @example
2153
+ *
2154
+ * function Foo() {
2155
+ * this.a = 1;
2156
+ * this.b = 2;
2157
+ * }
2158
+ *
2159
+ * Foo.prototype.c = 3;
2160
+ *
2161
+ * _.keys(new Foo);
2162
+ * // => ['a', 'b'] (iteration order is not guaranteed)
2163
+ *
2164
+ * _.keys('hi');
2165
+ * // => ['0', '1']
2166
+ */
2167
+ function keys(object) {
2168
+ return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
2169
+ }
2170
+
2171
+ /**
2172
+ * This method returns a new empty array.
2173
+ *
2174
+ * @static
2175
+ * @memberOf _
2176
+ * @since 4.13.0
2177
+ * @category Util
2178
+ * @returns {Array} Returns the new empty array.
2179
+ * @example
2180
+ *
2181
+ * var arrays = _.times(2, _.stubArray);
2182
+ *
2183
+ * console.log(arrays);
2184
+ * // => [[], []]
2185
+ *
2186
+ * console.log(arrays[0] === arrays[1]);
2187
+ * // => false
2188
+ */
2189
+ function stubArray() {
2190
+ return [];
2191
+ }
2192
+
2193
+ /**
2194
+ * This method returns `false`.
2195
+ *
2196
+ * @static
2197
+ * @memberOf _
2198
+ * @since 4.13.0
2199
+ * @category Util
2200
+ * @returns {boolean} Returns `false`.
2201
+ * @example
2202
+ *
2203
+ * _.times(2, _.stubFalse);
2204
+ * // => [false, false]
2205
+ */
2206
+ function stubFalse() {
2207
+ return false;
2208
+ }
2209
+
2210
+ module.exports = isEqual;
2211
+ });
2212
+
2213
+ /**
2214
+ * lodash (Custom Build) <https://lodash.com/>
2215
+ * Build: `lodash modularize exports="npm" -o ./`
2216
+ * Copyright jQuery Foundation and other contributors <https://jquery.org/>
2217
+ * Released under MIT license <https://lodash.com/license>
2218
+ * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
2219
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
2220
+ */
2221
+
2222
+ /** Used as references for various `Number` constants. */
2223
+ var INFINITY = 1 / 0,
2224
+ MAX_SAFE_INTEGER = 9007199254740991;
2225
+
2226
+ /** `Object#toString` result references. */
2227
+ var argsTag = '[object Arguments]',
2228
+ funcTag = '[object Function]',
2229
+ genTag = '[object GeneratorFunction]',
2230
+ symbolTag = '[object Symbol]';
2231
+
2232
+ /** Detect free variable `global` from Node.js. */
2233
+ var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
2234
+
2235
+ /** Detect free variable `self`. */
2236
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
2237
+
2238
+ /** Used as a reference to the global object. */
2239
+ var root = freeGlobal || freeSelf || Function('return this')();
2240
+
2241
+ /**
2242
+ * A faster alternative to `Function#apply`, this function invokes `func`
2243
+ * with the `this` binding of `thisArg` and the arguments of `args`.
2244
+ *
2245
+ * @private
2246
+ * @param {Function} func The function to invoke.
2247
+ * @param {*} thisArg The `this` binding of `func`.
2248
+ * @param {Array} args The arguments to invoke `func` with.
2249
+ * @returns {*} Returns the result of `func`.
2250
+ */
2251
+ function apply(func, thisArg, args) {
2252
+ switch (args.length) {
2253
+ case 0: return func.call(thisArg);
2254
+ case 1: return func.call(thisArg, args[0]);
2255
+ case 2: return func.call(thisArg, args[0], args[1]);
2256
+ case 3: return func.call(thisArg, args[0], args[1], args[2]);
2257
+ }
2258
+ return func.apply(thisArg, args);
2259
+ }
2260
+
2261
+ /**
2262
+ * A specialized version of `_.map` for arrays without support for iteratee
2263
+ * shorthands.
2264
+ *
2265
+ * @private
2266
+ * @param {Array} [array] The array to iterate over.
2267
+ * @param {Function} iteratee The function invoked per iteration.
2268
+ * @returns {Array} Returns the new mapped array.
2269
+ */
2270
+ function arrayMap(array, iteratee) {
2271
+ var index = -1,
2272
+ length = array ? array.length : 0,
2273
+ result = Array(length);
2274
+
2275
+ while (++index < length) {
2276
+ result[index] = iteratee(array[index], index, array);
2277
+ }
2278
+ return result;
2279
+ }
2280
+
2281
+ /**
2282
+ * Appends the elements of `values` to `array`.
2283
+ *
2284
+ * @private
2285
+ * @param {Array} array The array to modify.
2286
+ * @param {Array} values The values to append.
2287
+ * @returns {Array} Returns `array`.
2288
+ */
2289
+ function arrayPush(array, values) {
2290
+ var index = -1,
2291
+ length = values.length,
2292
+ offset = array.length;
2293
+
2294
+ while (++index < length) {
2295
+ array[offset + index] = values[index];
2296
+ }
2297
+ return array;
2298
+ }
2299
+
2300
+ /** Used for built-in method references. */
2301
+ var objectProto = Object.prototype;
2302
+
2303
+ /** Used to check objects for own properties. */
2304
+ var hasOwnProperty = objectProto.hasOwnProperty;
2305
+
2306
+ /**
2307
+ * Used to resolve the
2308
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
2309
+ * of values.
2310
+ */
2311
+ var objectToString = objectProto.toString;
2312
+
2313
+ /** Built-in value references. */
2314
+ var Symbol = root.Symbol,
2315
+ propertyIsEnumerable = objectProto.propertyIsEnumerable,
2316
+ spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
2317
+
2318
+ /* Built-in method references for those with the same name as other `lodash` methods. */
2319
+ var nativeMax = Math.max;
2320
+
2321
+ /**
2322
+ * The base implementation of `_.flatten` with support for restricting flattening.
2323
+ *
2324
+ * @private
2325
+ * @param {Array} array The array to flatten.
2326
+ * @param {number} depth The maximum recursion depth.
2327
+ * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2328
+ * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2329
+ * @param {Array} [result=[]] The initial result value.
2330
+ * @returns {Array} Returns the new flattened array.
2331
+ */
2332
+ function baseFlatten(array, depth, predicate, isStrict, result) {
2333
+ var index = -1,
2334
+ length = array.length;
2335
+
2336
+ predicate || (predicate = isFlattenable);
2337
+ result || (result = []);
2338
+
2339
+ while (++index < length) {
2340
+ var value = array[index];
2341
+ if (depth > 0 && predicate(value)) {
2342
+ if (depth > 1) {
2343
+ // Recursively flatten arrays (susceptible to call stack limits).
2344
+ baseFlatten(value, depth - 1, predicate, isStrict, result);
2345
+ } else {
2346
+ arrayPush(result, value);
2347
+ }
2348
+ } else if (!isStrict) {
2349
+ result[result.length] = value;
2350
+ }
2351
+ }
2352
+ return result;
2353
+ }
2354
+
2355
+ /**
2356
+ * The base implementation of `_.pick` without support for individual
2357
+ * property identifiers.
2358
+ *
2359
+ * @private
2360
+ * @param {Object} object The source object.
2361
+ * @param {string[]} props The property identifiers to pick.
2362
+ * @returns {Object} Returns the new object.
2363
+ */
2364
+ function basePick(object, props) {
2365
+ object = Object(object);
2366
+ return basePickBy(object, props, function(value, key) {
2367
+ return key in object;
2368
+ });
2369
+ }
2370
+
2371
+ /**
2372
+ * The base implementation of `_.pickBy` without support for iteratee shorthands.
2373
+ *
2374
+ * @private
2375
+ * @param {Object} object The source object.
2376
+ * @param {string[]} props The property identifiers to pick from.
2377
+ * @param {Function} predicate The function invoked per property.
2378
+ * @returns {Object} Returns the new object.
2379
+ */
2380
+ function basePickBy(object, props, predicate) {
2381
+ var index = -1,
2382
+ length = props.length,
2383
+ result = {};
2384
+
2385
+ while (++index < length) {
2386
+ var key = props[index],
2387
+ value = object[key];
2388
+
2389
+ if (predicate(value, key)) {
2390
+ result[key] = value;
2391
+ }
2392
+ }
2393
+ return result;
2394
+ }
2395
+
2396
+ /**
2397
+ * The base implementation of `_.rest` which doesn't validate or coerce arguments.
2398
+ *
2399
+ * @private
2400
+ * @param {Function} func The function to apply a rest parameter to.
2401
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
2402
+ * @returns {Function} Returns the new function.
2403
+ */
2404
+ function baseRest(func, start) {
2405
+ start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
2406
+ return function() {
2407
+ var args = arguments,
2408
+ index = -1,
2409
+ length = nativeMax(args.length - start, 0),
2410
+ array = Array(length);
2411
+
2412
+ while (++index < length) {
2413
+ array[index] = args[start + index];
2414
+ }
2415
+ index = -1;
2416
+ var otherArgs = Array(start + 1);
2417
+ while (++index < start) {
2418
+ otherArgs[index] = args[index];
2419
+ }
2420
+ otherArgs[start] = array;
2421
+ return apply(func, this, otherArgs);
2422
+ };
2423
+ }
2424
+
2425
+ /**
2426
+ * Checks if `value` is a flattenable `arguments` object or array.
2427
+ *
2428
+ * @private
2429
+ * @param {*} value The value to check.
2430
+ * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
2431
+ */
2432
+ function isFlattenable(value) {
2433
+ return isArray(value) || isArguments(value) ||
2434
+ !!(spreadableSymbol && value && value[spreadableSymbol]);
2435
+ }
2436
+
2437
+ /**
2438
+ * Converts `value` to a string key if it's not a string or symbol.
2439
+ *
2440
+ * @private
2441
+ * @param {*} value The value to inspect.
2442
+ * @returns {string|symbol} Returns the key.
2443
+ */
2444
+ function toKey(value) {
2445
+ if (typeof value == 'string' || isSymbol(value)) {
2446
+ return value;
2447
+ }
2448
+ var result = (value + '');
2449
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
2450
+ }
2451
+
2452
+ /**
2453
+ * Checks if `value` is likely an `arguments` object.
2454
+ *
2455
+ * @static
2456
+ * @memberOf _
2457
+ * @since 0.1.0
2458
+ * @category Lang
2459
+ * @param {*} value The value to check.
2460
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
2461
+ * else `false`.
2462
+ * @example
2463
+ *
2464
+ * _.isArguments(function() { return arguments; }());
2465
+ * // => true
2466
+ *
2467
+ * _.isArguments([1, 2, 3]);
2468
+ * // => false
2469
+ */
2470
+ function isArguments(value) {
2471
+ // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
2472
+ return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
2473
+ (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
2474
+ }
2475
+
2476
+ /**
2477
+ * Checks if `value` is classified as an `Array` object.
2478
+ *
2479
+ * @static
2480
+ * @memberOf _
2481
+ * @since 0.1.0
2482
+ * @category Lang
2483
+ * @param {*} value The value to check.
2484
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
2485
+ * @example
2486
+ *
2487
+ * _.isArray([1, 2, 3]);
2488
+ * // => true
2489
+ *
2490
+ * _.isArray(document.body.children);
2491
+ * // => false
2492
+ *
2493
+ * _.isArray('abc');
2494
+ * // => false
2495
+ *
2496
+ * _.isArray(_.noop);
2497
+ * // => false
2498
+ */
2499
+ var isArray = Array.isArray;
2500
+
2501
+ /**
2502
+ * Checks if `value` is array-like. A value is considered array-like if it's
2503
+ * not a function and has a `value.length` that's an integer greater than or
2504
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
2505
+ *
2506
+ * @static
2507
+ * @memberOf _
2508
+ * @since 4.0.0
2509
+ * @category Lang
2510
+ * @param {*} value The value to check.
2511
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
2512
+ * @example
2513
+ *
2514
+ * _.isArrayLike([1, 2, 3]);
2515
+ * // => true
2516
+ *
2517
+ * _.isArrayLike(document.body.children);
2518
+ * // => true
2519
+ *
2520
+ * _.isArrayLike('abc');
2521
+ * // => true
2522
+ *
2523
+ * _.isArrayLike(_.noop);
2524
+ * // => false
2525
+ */
2526
+ function isArrayLike(value) {
2527
+ return value != null && isLength(value.length) && !isFunction(value);
2528
+ }
2529
+
2530
+ /**
2531
+ * This method is like `_.isArrayLike` except that it also checks if `value`
2532
+ * is an object.
2533
+ *
2534
+ * @static
2535
+ * @memberOf _
2536
+ * @since 4.0.0
2537
+ * @category Lang
2538
+ * @param {*} value The value to check.
2539
+ * @returns {boolean} Returns `true` if `value` is an array-like object,
2540
+ * else `false`.
2541
+ * @example
2542
+ *
2543
+ * _.isArrayLikeObject([1, 2, 3]);
2544
+ * // => true
2545
+ *
2546
+ * _.isArrayLikeObject(document.body.children);
2547
+ * // => true
2548
+ *
2549
+ * _.isArrayLikeObject('abc');
2550
+ * // => false
2551
+ *
2552
+ * _.isArrayLikeObject(_.noop);
2553
+ * // => false
2554
+ */
2555
+ function isArrayLikeObject(value) {
2556
+ return isObjectLike(value) && isArrayLike(value);
2557
+ }
2558
+
2559
+ /**
2560
+ * Checks if `value` is classified as a `Function` object.
2561
+ *
2562
+ * @static
2563
+ * @memberOf _
2564
+ * @since 0.1.0
2565
+ * @category Lang
2566
+ * @param {*} value The value to check.
2567
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
2568
+ * @example
2569
+ *
2570
+ * _.isFunction(_);
2571
+ * // => true
2572
+ *
2573
+ * _.isFunction(/abc/);
2574
+ * // => false
2575
+ */
2576
+ function isFunction(value) {
2577
+ // The use of `Object#toString` avoids issues with the `typeof` operator
2578
+ // in Safari 8-9 which returns 'object' for typed array and other constructors.
2579
+ var tag = isObject(value) ? objectToString.call(value) : '';
2580
+ return tag == funcTag || tag == genTag;
2581
+ }
2582
+
2583
+ /**
2584
+ * Checks if `value` is a valid array-like length.
2585
+ *
2586
+ * **Note:** This method is loosely based on
2587
+ * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
2588
+ *
2589
+ * @static
2590
+ * @memberOf _
2591
+ * @since 4.0.0
2592
+ * @category Lang
2593
+ * @param {*} value The value to check.
2594
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
2595
+ * @example
2596
+ *
2597
+ * _.isLength(3);
2598
+ * // => true
2599
+ *
2600
+ * _.isLength(Number.MIN_VALUE);
2601
+ * // => false
2602
+ *
2603
+ * _.isLength(Infinity);
2604
+ * // => false
2605
+ *
2606
+ * _.isLength('3');
2607
+ * // => false
2608
+ */
2609
+ function isLength(value) {
2610
+ return typeof value == 'number' &&
2611
+ value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
2612
+ }
2613
+
2614
+ /**
2615
+ * Checks if `value` is the
2616
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
2617
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
2618
+ *
2619
+ * @static
2620
+ * @memberOf _
2621
+ * @since 0.1.0
2622
+ * @category Lang
2623
+ * @param {*} value The value to check.
2624
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
2625
+ * @example
2626
+ *
2627
+ * _.isObject({});
2628
+ * // => true
2629
+ *
2630
+ * _.isObject([1, 2, 3]);
2631
+ * // => true
2632
+ *
2633
+ * _.isObject(_.noop);
2634
+ * // => true
2635
+ *
2636
+ * _.isObject(null);
2637
+ * // => false
2638
+ */
2639
+ function isObject(value) {
2640
+ var type = typeof value;
2641
+ return !!value && (type == 'object' || type == 'function');
2642
+ }
2643
+
2644
+ /**
2645
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
2646
+ * and has a `typeof` result of "object".
2647
+ *
2648
+ * @static
2649
+ * @memberOf _
2650
+ * @since 4.0.0
2651
+ * @category Lang
2652
+ * @param {*} value The value to check.
2653
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
2654
+ * @example
2655
+ *
2656
+ * _.isObjectLike({});
2657
+ * // => true
2658
+ *
2659
+ * _.isObjectLike([1, 2, 3]);
2660
+ * // => true
2661
+ *
2662
+ * _.isObjectLike(_.noop);
2663
+ * // => false
2664
+ *
2665
+ * _.isObjectLike(null);
2666
+ * // => false
2667
+ */
2668
+ function isObjectLike(value) {
2669
+ return !!value && typeof value == 'object';
2670
+ }
2671
+
2672
+ /**
2673
+ * Checks if `value` is classified as a `Symbol` primitive or object.
2674
+ *
2675
+ * @static
2676
+ * @memberOf _
2677
+ * @since 4.0.0
2678
+ * @category Lang
2679
+ * @param {*} value The value to check.
2680
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
2681
+ * @example
2682
+ *
2683
+ * _.isSymbol(Symbol.iterator);
2684
+ * // => true
2685
+ *
2686
+ * _.isSymbol('abc');
2687
+ * // => false
2688
+ */
2689
+ function isSymbol(value) {
2690
+ return typeof value == 'symbol' ||
2691
+ (isObjectLike(value) && objectToString.call(value) == symbolTag);
2692
+ }
2693
+
2694
+ /**
2695
+ * Creates an object composed of the picked `object` properties.
2696
+ *
2697
+ * @static
2698
+ * @since 0.1.0
2699
+ * @memberOf _
2700
+ * @category Object
2701
+ * @param {Object} object The source object.
2702
+ * @param {...(string|string[])} [props] The property identifiers to pick.
2703
+ * @returns {Object} Returns the new object.
2704
+ * @example
2705
+ *
2706
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
2707
+ *
2708
+ * _.pick(object, ['a', 'c']);
2709
+ * // => { 'a': 1, 'c': 3 }
2710
+ */
2711
+ var pick = baseRest(function(object, props) {
2712
+ return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
2713
+ });
2714
+
2715
+ var lodash_pick = pick;
2716
+
2717
+ function useFetchZones(params) {
2718
+ const [fetchZones, resource] = adminServices.useResource({
2719
+ fetchResource: getZones,
2720
+ initialValue: [],
2721
+ context: params.context,
2722
+ resourceName: 'Banner zones',
2723
+ });
2724
+ compositionApi.onMounted(() => {
2725
+ fetchZones();
2726
+ });
2727
+ return resource;
2728
+ }
2729
+
2730
+ var Status;
2731
+ (function (Status) {
2732
+ Status["Waiting"] = "WAITING";
2733
+ Status["Archived"] = "ARCHIVED";
2734
+ Status["Active"] = "ACTIVE";
2735
+ Status["Disabled"] = "DISABLED";
2736
+ })(Status || (Status = {}));
2737
+
2738
+ function getStatus(type, t) {
2739
+ switch (type) {
2740
+ case Status.Waiting:
2741
+ return t('banners:statuses.waiting');
2742
+ case Status.Archived:
2743
+ return t('banners:statuses.archived');
2744
+ case Status.Active:
2745
+ return t('banners:statuses.active');
2746
+ case Status.Disabled:
2747
+ return t('banners:statuses.disabled');
2748
+ default:
2749
+ return '';
2750
+ }
2751
+ }
2752
+ function getColumnDefs$1(t) {
2753
+ return [
2754
+ {
2755
+ id: 0,
2756
+ name: '#',
2757
+ field: 'id',
2758
+ style: { width: '50px', textAlign: 'center' },
2759
+ headStyle: { width: '50px', textAlign: 'center' },
693
2760
  },
694
- pageTitle() {
695
- return this.bannerArea ? `"${this.bannerArea.label}" banners` : 'Banners';
2761
+ {
2762
+ id: 1,
2763
+ name: t('banners:zone'),
2764
+ field: 'bannerZone',
2765
+ format: ({ row }) => row.bannerZone ? row.bannerZone : t('banners:bannerZoneIsDeleted'),
696
2766
  },
697
- },
698
- watch: {
699
- areaAlias() {
700
- this.refreshBannerItemList();
2767
+ {
2768
+ id: 2,
2769
+ name: t('banners:status'),
2770
+ field: 'status',
2771
+ format: ({ row }) => getStatus(row.status, t),
2772
+ style: { width: '120px' },
2773
+ headStyle: { width: '120px' },
701
2774
  },
702
- },
703
- mounted() {
704
- this.refreshBannerItemList();
705
- },
706
- methods: {
707
- refreshBannerItemList() {
708
- this.isRowDataLoading = true;
709
- return getBannerAreaByAlias(this.areaAlias)
710
- .then((response) => {
711
- this.bannerArea = response.data;
712
- return getBannerItemList(this.bannerArea.id);
713
- })
714
- .then((response) => {
715
- this.rowData = response.data;
716
- this.errorMessage = null;
717
- })
718
- .catch((error) => {
719
- console.error(error);
720
- this.rowData = [];
721
- this.errorMessage = adminServices.getMessageFromError(error);
722
- })
723
- .finally(() => {
724
- this.isRowDataLoading = false;
725
- });
2775
+ {
2776
+ id: 3,
2777
+ name: t('banners:period'),
2778
+ field: 'dateStart',
2779
+ format: ({ row }) => `${row.dateStart ? `${t('banners:from')} ${row.dateStart}` : ''} ${row.dateEnd ? `${t('banners:to')} ${row.dateEnd}` : ''}`,
726
2780
  },
727
- moveBannerItem(bannerItemId, direction) {
728
- this.isBannerItemMoving = true;
729
- moveBannerItem(bannerItemId, direction)
730
- .then((response) => {
731
- if (response.success) {
732
- return this.refreshBannerItemList();
733
- }
734
- })
735
- .catch(console.error)
736
- .finally(() => {
737
- this.isBannerItemMoving = false;
738
- });
2781
+ {
2782
+ id: 4,
2783
+ name: t('banners:image'),
2784
+ field: 'image',
2785
+ type: 'image',
739
2786
  },
740
- handleBannerItemDelete(bannerItem) {
741
- const shouldDeleteBannerItem = confirm(`Are you sure you want to delete banner item "${bannerItem.title}"`);
742
- if (shouldDeleteBannerItem) {
743
- this.deletingBannerItemIdList.push(bannerItem.id);
744
- deleteBannerItem(bannerItem.id)
745
- .then((response) => {
746
- if (response.success) {
747
- this.refreshBannerItemList().then(() => {
748
- this.deletingBannerItemIdList.filter((id) => id !== bannerItem.id);
749
- });
750
- this.$toast({
751
- variant: 'success',
752
- title: 'Success',
753
- body: 'Banner Item was successfully removed',
754
- });
755
- }
756
- else {
757
- this.$toast({
758
- variant: 'danger',
759
- title: 'Error',
760
- body: 'Banner Item deletion was failed',
761
- });
762
- }
763
- })
764
- .catch((error) => {
765
- console.error(error);
766
- this.$toast({
767
- variant: 'danger',
768
- title: 'Error',
769
- body: 'Banner Item deletion was failed',
770
- });
2787
+ {
2788
+ id: 5,
2789
+ name: t('banners:link'),
2790
+ field: 'link',
2791
+ type: 'name',
2792
+ format: ({ row }) => {
2793
+ var _a, _b;
2794
+ return ({
2795
+ adminLink: {
2796
+ url: (_a = row.link) !== null && _a !== void 0 ? _a : '',
2797
+ text: (_b = row.link) !== null && _b !== void 0 ? _b : '',
2798
+ },
2799
+ paramList: [
2800
+ {
2801
+ name: t('banners:newTab'),
2802
+ value: row.openNewTab ? t('banners:yes') : t('banners:no'),
2803
+ },
2804
+ ],
771
2805
  });
772
- }
2806
+ },
773
2807
  },
774
- getLinkToBannerItemForm(bannerItemId) {
775
- var _a, _b;
776
- return getBannerItemFormUrl({
777
- areaAlias: (_b = (_a = this.bannerArea) === null || _a === void 0 ? void 0 : _a.alias) !== null && _b !== void 0 ? _b : 'unknowm',
778
- itemId: bannerItemId,
779
- });
2808
+ {
2809
+ id: 6,
2810
+ name: t('banners:comment'),
2811
+ field: 'comment',
2812
+ },
2813
+ {
2814
+ id: 7,
2815
+ name: t('banners:actions'),
2816
+ field: 'actions',
2817
+ style: { whiteSpace: 'nowrap', width: '100px' },
2818
+ headStyle: { whiteSpace: 'nowrap', width: '100px' },
780
2819
  },
2820
+ ];
2821
+ }
2822
+
2823
+ var FilterTypes;
2824
+ (function (FilterTypes) {
2825
+ FilterTypes["Zone"] = "zone";
2826
+ FilterTypes["Date"] = "date";
2827
+ FilterTypes["Status"] = "status";
2828
+ })(FilterTypes || (FilterTypes = {}));
2829
+ function useAdvancedSearch({ context, t, zoneList }) {
2830
+ /** Zone **/
2831
+ const zonesOptionList = compositionApi.computed(() => zoneList.value.map(({ id, name }) => ({
2832
+ value: id,
2833
+ label: name,
2834
+ })));
2835
+ const initialZoneFilter = compositionApi.computed(() => {
2836
+ const queryValue = adminUi.getFilterParamAsStringArray(context.root.$route.query, FilterTypes.Zone);
2837
+ return zonesOptionList.value.filter(({ value }) => queryValue.some((selected) => selected === value));
2838
+ });
2839
+ const zoneFilter = compositionApi.ref(initialZoneFilter.value);
2840
+ compositionApi.watch(initialZoneFilter, () => {
2841
+ zoneFilter.value = initialZoneFilter.value;
2842
+ });
2843
+ /** Date **/
2844
+ const initialDateFilter = compositionApi.computed(() => { var _a; return (_a = adminUi.getFilterParamAsString(context.root.$route.query, FilterTypes.Date)) !== null && _a !== void 0 ? _a : ''; });
2845
+ const dateFilter = compositionApi.ref(initialDateFilter.value);
2846
+ compositionApi.watch(initialDateFilter, () => {
2847
+ dateFilter.value = initialDateFilter.value;
2848
+ });
2849
+ /** Status **/
2850
+ const statusesOptionList = compositionApi.computed(() => Object.entries(Status).map(([_, value]) => ({
2851
+ value: value,
2852
+ label: getStatus(value, t),
2853
+ })));
2854
+ const initialStatusFilter = compositionApi.computed(() => {
2855
+ const queryValue = adminUi.getFilterParamAsStringArray(context.root.$route.query, FilterTypes.Status);
2856
+ return statusesOptionList.value.filter(({ value }) => queryValue.some((selected) => selected === value));
2857
+ });
2858
+ const statusFilter = compositionApi.ref(initialStatusFilter.value);
2859
+ compositionApi.watch(initialStatusFilter, () => {
2860
+ statusFilter.value = initialStatusFilter.value;
2861
+ });
2862
+ /** Params **/
2863
+ const filterParams = compositionApi.computed(() => adminUi.getFilterParams({
2864
+ [FilterTypes.Zone]: zoneFilter.value.map(({ value }) => value),
2865
+ [FilterTypes.Date]: dateFilter.value,
2866
+ [FilterTypes.Status]: statusFilter.value.map(({ value }) => value),
2867
+ }));
2868
+ /** Tag removal handler **/
2869
+ const tagRemovalHandler = (event) => {
2870
+ if (event.name === FilterTypes.Zone) {
2871
+ zoneFilter.value = zoneFilter.value.filter(({ value }) => value !== event.value);
2872
+ }
2873
+ if (event.name === FilterTypes.Date) {
2874
+ dateFilter.value = '';
2875
+ }
2876
+ if (event.name === FilterTypes.Status) {
2877
+ statusFilter.value = statusFilter.value.filter(({ value }) => value !== event.value);
2878
+ }
2879
+ };
2880
+ /** Tags **/
2881
+ const tags = compositionApi.computed(() => []);
2882
+ return {
2883
+ zoneFilter,
2884
+ zonesOptionList,
2885
+ dateFilter,
2886
+ statusFilter,
2887
+ statusesOptionList,
2888
+ filterParams,
2889
+ tags,
2890
+ tagRemovalHandler,
2891
+ };
2892
+ }
2893
+
2894
+ var script$1 = compositionApi.defineComponent({
2895
+ name: 'BannerList',
2896
+ setup(props, context) {
2897
+ const { t } = adminUi.useTranslation(context);
2898
+ const { loading: isZonesLoading, data: zoneList } = useFetchZones({
2899
+ context,
2900
+ });
2901
+ const { zoneFilter, zonesOptionList, dateFilter, statusFilter, statusesOptionList, filterParams, tags, tagRemovalHandler, } = useAdvancedSearch({
2902
+ context,
2903
+ t,
2904
+ zoneList,
2905
+ });
2906
+ const { fetchEntityList: fetchBanners, isLoading: isBannersLoading, rowData, errorMessage, handleChange, searchQuery, pageNumber, pageCount, pageSize, } = adminUi.useDataTable({
2907
+ fetchEntityList: (params) => getBanners(Object.assign({ query: params.searchQuery, pageNumber: params.pageNumber, pageSize: params.pageSize }, filterParams.value)),
2908
+ initialValue: [],
2909
+ context,
2910
+ resourceName: 'Banners',
2911
+ });
2912
+ compositionApi.watch(filterParams, () => {
2913
+ if (isZonesLoading.value) {
2914
+ return;
2915
+ }
2916
+ const newQuery = Object.assign(Object.assign({}, lodash_pick(context.root.$route.query, ['query', 'pageNumber'])), filterParams.value);
2917
+ if (!lodash_isequal(context.root.$route.query, newQuery)) {
2918
+ context.root.$router.replace({ query: newQuery });
2919
+ fetchBanners();
2920
+ }
2921
+ });
2922
+ const { isDeleting, handleResourceDelete } = adminServices.useResourceDelete({
2923
+ deleteResource: deleteBanner,
2924
+ resourceName: 'Banner',
2925
+ onSuccess: fetchBanners,
2926
+ context,
2927
+ });
2928
+ const isBusy = (bannerId) => {
2929
+ return isDeleting(bannerId) || isBannersLoading.value;
2930
+ };
2931
+ const columnDefs = compositionApi.computed(() => getColumnDefs$1(context.root.$t));
2932
+ const isRowDataLoading = compositionApi.computed(() => isBannersLoading.value || isZonesLoading.value);
2933
+ return {
2934
+ columnDefs,
2935
+ isRowDataLoading,
2936
+ rowData,
2937
+ errorMessage,
2938
+ handleChange,
2939
+ getBannersBannerFormUrl,
2940
+ searchQuery,
2941
+ pageNumber,
2942
+ pageCount,
2943
+ pageSize,
2944
+ isBusy,
2945
+ handleResourceDelete,
2946
+ // Advanced search
2947
+ zoneFilter,
2948
+ zonesOptionList,
2949
+ dateFilter,
2950
+ statusFilter,
2951
+ statusesOptionList,
2952
+ tags,
2953
+ tagRemovalHandler,
2954
+ };
781
2955
  },
782
2956
  });
783
2957
 
2958
+ const isOldIE = typeof navigator !== 'undefined' &&
2959
+ /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());
2960
+ function createInjector(context) {
2961
+ return (id, style) => addStyle(id, style);
2962
+ }
2963
+ let HEAD;
2964
+ const styles = {};
2965
+ function addStyle(id, css) {
2966
+ const group = isOldIE ? css.media || 'default' : id;
2967
+ const style = styles[group] || (styles[group] = { ids: new Set(), styles: [] });
2968
+ if (!style.ids.has(id)) {
2969
+ style.ids.add(id);
2970
+ let code = css.source;
2971
+ if (css.map) {
2972
+ // https://developer.chrome.com/devtools/docs/javascript-debugging
2973
+ // this makes source maps inside style tags work properly in Chrome
2974
+ code += '\n/*# sourceURL=' + css.map.sources[0] + ' */';
2975
+ // http://stackoverflow.com/a/26603875
2976
+ code +=
2977
+ '\n/*# sourceMappingURL=data:application/json;base64,' +
2978
+ btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) +
2979
+ ' */';
2980
+ }
2981
+ if (!style.element) {
2982
+ style.element = document.createElement('style');
2983
+ style.element.type = 'text/css';
2984
+ if (css.media)
2985
+ style.element.setAttribute('media', css.media);
2986
+ if (HEAD === undefined) {
2987
+ HEAD = document.head || document.getElementsByTagName('head')[0];
2988
+ }
2989
+ HEAD.appendChild(style.element);
2990
+ }
2991
+ if ('styleSheet' in style.element) {
2992
+ style.styles.push(code);
2993
+ style.element.styleSheet.cssText = style.styles
2994
+ .filter(Boolean)
2995
+ .join('\n');
2996
+ }
2997
+ else {
2998
+ const index = style.ids.size - 1;
2999
+ const textNode = document.createTextNode(code);
3000
+ const nodes = style.element.childNodes;
3001
+ if (nodes[index])
3002
+ style.element.removeChild(nodes[index]);
3003
+ if (nodes.length)
3004
+ style.element.insertBefore(textNode, nodes[index]);
3005
+ else
3006
+ style.element.appendChild(textNode);
3007
+ }
3008
+ }
3009
+ }
3010
+
784
3011
  /* script */
785
- const __vue_script__$2 = script$2;
3012
+ const __vue_script__$1 = script$1;
786
3013
 
787
3014
  /* template */
788
- var __vue_render__$2 = function () {
3015
+ var __vue_render__$1 = function () {
789
3016
  var _vm = this;
790
3017
  var _h = _vm.$createElement;
791
3018
  var _c = _vm._self._c || _h;
792
3019
  return _c("page", {
793
3020
  attrs: {
794
- title: _vm.pageTitle,
3021
+ title: _vm.$t("banners:banners"),
795
3022
  "header-buttons": [
796
3023
  {
797
- text: "New Banner Item",
798
- href: _vm.getLinkToBannerItemForm("create"),
3024
+ text: _vm.$t("banners:createBanner"),
3025
+ href: _vm.getBannersBannerFormUrl({ bannerId: "create" }),
799
3026
  },
800
3027
  ],
801
3028
  },
@@ -804,72 +3031,116 @@
804
3031
  key: "content",
805
3032
  fn: function () {
806
3033
  return [
807
- _c("base-table", {
3034
+ _c("data-table", {
808
3035
  attrs: {
809
3036
  "column-defs": _vm.columnDefs,
810
3037
  "row-data": _vm.rowData,
811
3038
  loading: _vm.isRowDataLoading,
812
3039
  "error-message": _vm.errorMessage,
813
- enumerable: "",
3040
+ "data-table": "banners",
3041
+ "use-search": true,
3042
+ "use-pagination": true,
3043
+ "search-query": _vm.searchQuery,
3044
+ pagination: {
3045
+ pageNumber: _vm.pageNumber,
3046
+ pageCount: _vm.pageCount,
3047
+ pageSize: _vm.pageSize,
3048
+ disabled: _vm.isRowDataLoading,
3049
+ },
814
3050
  },
3051
+ on: { change: _vm.handleChange },
815
3052
  scopedSlots: _vm._u([
816
3053
  {
817
- key: "cell(actions)",
818
- fn: function (ref) {
819
- var row = ref.row;
820
- var rowIndex = ref.rowIndex;
3054
+ key: "filters",
3055
+ fn: function () {
821
3056
  return [
822
3057
  _c(
823
- "base-button",
824
- {
825
- attrs: {
826
- variant: "icon",
827
- title: "Edit",
828
- disabled: _vm.deletingBannerItemIdList.includes(
829
- row.id
830
- ),
831
- href: _vm.getLinkToBannerItemForm(row.id),
832
- },
833
- },
834
- [_c("svg-icon", { attrs: { name: "edit" } })],
835
- 1
836
- ),
837
- _vm._v(" "),
838
- _c(
839
- "base-button",
3058
+ "advanced-search",
840
3059
  {
841
- attrs: {
842
- variant: "icon",
843
- title: "Move up",
844
- disabled: rowIndex === 0 || _vm.isBannerItemMoving,
845
- },
846
- on: {
847
- click: function ($event) {
848
- return _vm.moveBannerItem(row.id, "up")
849
- },
850
- },
3060
+ attrs: { tags: _vm.tags },
3061
+ on: { "click:tag": _vm.tagRemovalHandler },
851
3062
  },
852
- [_c("svg-icon", { attrs: { name: "north" } })],
853
- 1
3063
+ [
3064
+ _c(
3065
+ "div",
3066
+ { staticClass: "filters" },
3067
+ [
3068
+ _c("form-field-multi-select", {
3069
+ staticClass: "filter",
3070
+ attrs: {
3071
+ options: _vm.zonesOptionList,
3072
+ name: "zoneFilter",
3073
+ searchable: true,
3074
+ label: _vm.$t("banners:zone"),
3075
+ },
3076
+ model: {
3077
+ value: _vm.zoneFilter,
3078
+ callback: function ($$v) {
3079
+ _vm.zoneFilter = $$v;
3080
+ },
3081
+ expression: "zoneFilter",
3082
+ },
3083
+ }),
3084
+ _vm._v(" "),
3085
+ _c("form-field", {
3086
+ staticClass: "filter",
3087
+ attrs: {
3088
+ label: _vm.$t("banners:date"),
3089
+ name: "dateFilter",
3090
+ type: "date",
3091
+ },
3092
+ model: {
3093
+ value: _vm.dateFilter,
3094
+ callback: function ($$v) {
3095
+ _vm.dateFilter = $$v;
3096
+ },
3097
+ expression: "dateFilter",
3098
+ },
3099
+ }),
3100
+ _vm._v(" "),
3101
+ _c("form-field-multi-select", {
3102
+ staticClass: "filter",
3103
+ attrs: {
3104
+ options: _vm.statusesOptionList,
3105
+ name: "statusFilter",
3106
+ searchable: true,
3107
+ label: _vm.$t("banners:status"),
3108
+ },
3109
+ model: {
3110
+ value: _vm.statusFilter,
3111
+ callback: function ($$v) {
3112
+ _vm.statusFilter = $$v;
3113
+ },
3114
+ expression: "statusFilter",
3115
+ },
3116
+ }),
3117
+ ],
3118
+ 1
3119
+ ),
3120
+ ]
854
3121
  ),
855
- _vm._v(" "),
3122
+ ]
3123
+ },
3124
+ proxy: true,
3125
+ },
3126
+ {
3127
+ key: "cell(actions)",
3128
+ fn: function (ref) {
3129
+ var row = ref.row;
3130
+ return [
856
3131
  _c(
857
3132
  "base-button",
858
3133
  {
859
3134
  attrs: {
860
3135
  variant: "icon",
861
- title: "Move down",
862
- disabled:
863
- rowIndex === _vm.rowData.length - 1 ||
864
- _vm.isBannerItemMoving,
865
- },
866
- on: {
867
- click: function ($event) {
868
- return _vm.moveBannerItem(row.id, "down")
869
- },
3136
+ title: _vm.$t("banners:edit"),
3137
+ disabled: _vm.isBusy(row.id),
3138
+ href: _vm.getBannersBannerFormUrl({
3139
+ bannerId: row.id,
3140
+ }),
870
3141
  },
871
3142
  },
872
- [_c("svg-icon", { attrs: { name: "south" } })],
3143
+ [_c("svg-icon", { attrs: { name: "edit" } })],
873
3144
  1
874
3145
  ),
875
3146
  _vm._v(" "),
@@ -878,14 +3149,12 @@
878
3149
  {
879
3150
  attrs: {
880
3151
  variant: "icon",
881
- title: "Remove",
882
- disabled: _vm.deletingBannerItemIdList.includes(
883
- row.id
884
- ),
3152
+ title: _vm.$t("banners:remove"),
3153
+ disabled: _vm.isBusy(row.id),
885
3154
  },
886
3155
  on: {
887
3156
  click: function ($event) {
888
- return _vm.handleBannerItemDelete(row)
3157
+ return _vm.handleResourceDelete(row.id)
889
3158
  },
890
3159
  },
891
3160
  },
@@ -904,169 +3173,175 @@
904
3173
  ]),
905
3174
  })
906
3175
  };
907
- var __vue_staticRenderFns__$2 = [];
908
- __vue_render__$2._withStripped = true;
3176
+ var __vue_staticRenderFns__$1 = [];
3177
+ __vue_render__$1._withStripped = true;
909
3178
 
910
3179
  /* style */
911
- const __vue_inject_styles__$2 = function (inject) {
3180
+ const __vue_inject_styles__$1 = function (inject) {
912
3181
  if (!inject) return
913
- inject("data-v-0834d29c_0", { source: "\n\n/*# sourceMappingURL=BannerItemList.vue.map */", map: {"version":3,"sources":["BannerItemList.vue"],"names":[],"mappings":";;AAEA,6CAA6C","file":"BannerItemList.vue"}, media: undefined });
3182
+ inject("data-v-92c7e846_0", { source: ".filters {\n display: flex;\n margin: 0 -10px;\n}\n.filters:not(:first-child) {\n margin-top: 10px;\n}\n.filters .filter {\n padding: 10px 10px 0;\n width: 50%;\n margin: 0;\n}\n\n/*# sourceMappingURL=BannerList.vue.map */", map: {"version":3,"sources":["/home/runner/work/tager-admin-banners/tager-admin-banners/src/views/Banners/BannerList/BannerList.vue","BannerList.vue"],"names":[],"mappings":"AA0NA;EACA,aAAA;EACA,eAAA;ACzNA;AD2NA;EACA,gBAAA;ACzNA;AD4NA;EACA,oBAAA;EACA,UAAA;EACA,SAAA;AC1NA;;AAEA,yCAAyC","file":"BannerList.vue","sourcesContent":["<template>\n <page\n :title=\"$t('banners:banners')\"\n :header-buttons=\"[\n {\n text: $t('banners:createBanner'),\n href: getBannersBannerFormUrl({ bannerId: 'create' }),\n },\n ]\"\n >\n <template v-slot:content>\n <data-table\n :column-defs=\"columnDefs\"\n :row-data=\"rowData\"\n :loading=\"isRowDataLoading\"\n :error-message=\"errorMessage\"\n data-table=\"banners\"\n :use-search=\"true\"\n :use-pagination=\"true\"\n :search-query=\"searchQuery\"\n :pagination=\"{\n pageNumber,\n pageCount,\n pageSize,\n disabled: isRowDataLoading,\n }\"\n @change=\"handleChange\"\n >\n <template v-slot:filters>\n <advanced-search :tags=\"tags\" @click:tag=\"tagRemovalHandler\">\n <div class=\"filters\">\n <form-field-multi-select\n v-model=\"zoneFilter\"\n :options=\"zonesOptionList\"\n name=\"zoneFilter\"\n :searchable=\"true\"\n :label=\"$t('banners:zone')\"\n class=\"filter\"\n />\n\n <form-field\n v-model=\"dateFilter\"\n :label=\"$t('banners:date')\"\n name=\"dateFilter\"\n type=\"date\"\n class=\"filter\"\n />\n\n <form-field-multi-select\n v-model=\"statusFilter\"\n :options=\"statusesOptionList\"\n name=\"statusFilter\"\n :searchable=\"true\"\n :label=\"$t('banners:status')\"\n class=\"filter\"\n />\n </div>\n </advanced-search>\n </template>\n\n <template v-slot:cell(actions)=\"{ row }\">\n <base-button\n variant=\"icon\"\n :title=\"$t('banners:edit')\"\n :disabled=\"isBusy(row.id)\"\n :href=\"getBannersBannerFormUrl({ bannerId: row.id })\"\n >\n <svg-icon name=\"edit\" />\n </base-button>\n\n <base-button\n variant=\"icon\"\n :title=\"$t('banners:remove')\"\n :disabled=\"isBusy(row.id)\"\n @click=\"handleResourceDelete(row.id)\"\n >\n <svg-icon name=\"delete\" />\n </base-button>\n </template>\n </data-table>\n </template>\n </page>\n</template>\n\n<script lang=\"ts\">\nimport {\n computed,\n defineComponent,\n SetupContext,\n watch,\n} from '@vue/composition-api';\nimport isEqual from 'lodash.isequal';\nimport pick from 'lodash.pick';\n\nimport {\n ColumnDefinition,\n useDataTable,\n useTranslation,\n} from '@tager/admin-ui';\nimport { useResourceDelete } from '@tager/admin-services';\n\nimport { deleteBanner, getBanners } from '../../../services/requests';\nimport { Banner } from '../../../typings/banners';\nimport { getBannersBannerFormUrl } from '../../../constants/paths';\nimport { useFetchZones } from '../../../hooks';\n\nimport { getColumnDefs } from './BannerList.helpers';\nimport { useAdvancedSearch } from './hooks';\n\nexport default defineComponent({\n name: 'BannerList',\n setup(props, context: SetupContext) {\n const { t } = useTranslation(context);\n const { loading: isZonesLoading, data: zoneList } = useFetchZones({\n context,\n });\n\n const {\n zoneFilter,\n zonesOptionList,\n dateFilter,\n statusFilter,\n statusesOptionList,\n filterParams,\n tags,\n tagRemovalHandler,\n } = useAdvancedSearch({\n context,\n t,\n zoneList,\n });\n\n const {\n fetchEntityList: fetchBanners,\n isLoading: isBannersLoading,\n rowData,\n errorMessage,\n handleChange,\n searchQuery,\n pageNumber,\n pageCount,\n pageSize,\n } = useDataTable<Banner>({\n fetchEntityList: (params) =>\n getBanners({\n query: params.searchQuery,\n pageNumber: params.pageNumber,\n pageSize: params.pageSize,\n ...filterParams.value,\n }),\n initialValue: [],\n context,\n resourceName: 'Banners',\n });\n\n watch(filterParams, () => {\n if (isZonesLoading.value) {\n return;\n }\n\n const newQuery = {\n ...pick(context.root.$route.query, ['query', 'pageNumber']),\n ...filterParams.value,\n };\n\n if (!isEqual(context.root.$route.query, newQuery)) {\n context.root.$router.replace({ query: newQuery });\n fetchBanners();\n }\n });\n\n const { isDeleting, handleResourceDelete } = useResourceDelete({\n deleteResource: deleteBanner,\n resourceName: 'Banner',\n onSuccess: fetchBanners,\n context,\n });\n\n const isBusy = (bannerId: number): boolean => {\n return isDeleting(bannerId) || isBannersLoading.value;\n };\n\n const columnDefs = computed<ColumnDefinition<Banner>[]>(() =>\n getColumnDefs(context.root.$t)\n );\n\n const isRowDataLoading = computed<boolean>(\n () => isBannersLoading.value || isZonesLoading.value\n );\n\n return {\n columnDefs,\n isRowDataLoading,\n rowData,\n errorMessage,\n handleChange,\n getBannersBannerFormUrl,\n searchQuery,\n pageNumber,\n pageCount,\n pageSize,\n isBusy,\n handleResourceDelete,\n\n // Advanced search\n zoneFilter,\n zonesOptionList,\n dateFilter,\n statusFilter,\n statusesOptionList,\n tags,\n tagRemovalHandler,\n };\n },\n});\n</script>\n\n<style lang=\"scss\">\n.filters {\n display: flex;\n margin: 0 -10px;\n\n &:not(:first-child) {\n margin-top: 10px;\n }\n\n .filter {\n padding: 10px 10px 0;\n width: 50%;\n margin: 0;\n }\n}\n</style>\n",".filters {\n display: flex;\n margin: 0 -10px;\n}\n.filters:not(:first-child) {\n margin-top: 10px;\n}\n.filters .filter {\n padding: 10px 10px 0;\n width: 50%;\n margin: 0;\n}\n\n/*# sourceMappingURL=BannerList.vue.map */"]}, media: undefined });
914
3183
 
915
3184
  };
916
3185
  /* scoped */
917
- const __vue_scope_id__$2 = "data-v-0834d29c";
3186
+ const __vue_scope_id__$1 = undefined;
918
3187
  /* module identifier */
919
- const __vue_module_identifier__$2 = undefined;
3188
+ const __vue_module_identifier__$1 = undefined;
920
3189
  /* functional template */
921
- const __vue_is_functional_template__$2 = false;
3190
+ const __vue_is_functional_template__$1 = false;
922
3191
  /* style inject SSR */
923
3192
 
924
3193
  /* style inject shadow dom */
925
3194
 
926
3195
 
927
3196
 
928
- const __vue_component__$2 = /*#__PURE__*/normalizeComponent(
929
- { render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 },
930
- __vue_inject_styles__$2,
931
- __vue_script__$2,
932
- __vue_scope_id__$2,
933
- __vue_is_functional_template__$2,
934
- __vue_module_identifier__$2,
3197
+ const __vue_component__$1 = /*#__PURE__*/normalizeComponent(
3198
+ { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 },
3199
+ __vue_inject_styles__$1,
3200
+ __vue_script__$1,
3201
+ __vue_scope_id__$1,
3202
+ __vue_is_functional_template__$1,
3203
+ __vue_module_identifier__$1,
935
3204
  false,
936
3205
  createInjector,
937
3206
  undefined,
938
3207
  undefined
939
3208
  );
940
3209
 
941
- const INITIAL_VALUES = {
942
- title: '',
943
- text: '',
944
- buttonLink: '',
945
- buttonLabel: '',
946
- buttonIsNewTab: false,
947
- image: null,
948
- };
949
- var script$3 = Vue.extend({
950
- name: 'BannerItemForm',
951
- data() {
952
- return {
953
- values: Object.assign({}, INITIAL_VALUES),
954
- errors: {},
955
- isContentLoading: false,
956
- bannerArea: null,
957
- };
958
- },
959
- computed: {
960
- itemId() {
961
- return this.$route.params.itemId;
962
- },
963
- areaAlias() {
964
- return this.$route.params.areaAlias;
965
- },
966
- isCreation() {
967
- return this.itemId === 'create';
968
- },
969
- bannerItemListUrl() {
970
- var _a, _b;
971
- return getBannerItemListUrl({
972
- areaAlias: (_b = (_a = this.bannerArea) === null || _a === void 0 ? void 0 : _a.alias) !== null && _b !== void 0 ? _b : 'unknown',
973
- });
974
- },
975
- },
976
- watch: {
977
- itemId() {
978
- this.updateValues();
979
- },
980
- areaAlias() {
981
- this.updateValues();
982
- },
983
- },
984
- mounted() {
985
- this.updateValues();
986
- },
987
- methods: {
988
- updateValues() {
989
- this.isContentLoading = true;
990
- Promise.all([
991
- getBannerAreaByAlias(this.areaAlias)
992
- .then((response) => {
993
- this.bannerArea = response.data;
994
- })
995
- .catch(console.error),
996
- this.isCreation
997
- ? new Promise((resolve) => {
998
- this.values = Object.assign({}, INITIAL_VALUES);
999
- resolve();
1000
- })
1001
- : getBannerItemById(this.itemId)
1002
- .then((response) => {
1003
- this.values = this.convertReviewToInitialValues(response.data);
1004
- })
1005
- .catch(console.error),
1006
- ]).finally(() => {
1007
- this.isContentLoading = false;
1008
- });
1009
- },
1010
- convertReviewToInitialValues(bannerItem) {
1011
- var _a;
1012
- return {
1013
- title: bannerItem.title,
1014
- text: bannerItem.text,
1015
- buttonLink: (_a = bannerItem.buttonLink) !== null && _a !== void 0 ? _a : '',
1016
- buttonLabel: bannerItem.buttonLabel,
1017
- buttonIsNewTab: bannerItem.buttonIsNewTab,
1018
- image: bannerItem.image,
1019
- };
1020
- },
1021
- submitForm() {
1022
- var _a, _b, _c, _d;
1023
- const creationBody = {
1024
- title: this.values.title,
1025
- text: this.values.text,
1026
- buttonLink: this.values.buttonLink.trim() || null,
1027
- buttonLabel: this.values.buttonLabel,
1028
- buttonIsNewTab: this.values.buttonIsNewTab,
1029
- image: (_b = (_a = this.values.image) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null,
1030
- };
1031
- const requestPromise = this.isCreation
1032
- ? createBannerItem((_d = (_c = this.bannerArea) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : 'unknown', creationBody)
1033
- : updateBannerItem(this.itemId, creationBody);
3210
+ function useFetchBanner({ context, bannerId, isCreation, }) {
3211
+ const [fetchBanner, resource] = adminServices.useResource({
3212
+ fetchResource: () => getBanner(bannerId.value),
3213
+ initialValue: null,
3214
+ context,
3215
+ resourceName: 'Banner',
3216
+ });
3217
+ compositionApi.onMounted(() => {
3218
+ if (isCreation.value) {
3219
+ return;
3220
+ }
3221
+ fetchBanner();
3222
+ });
3223
+ compositionApi.watch(bannerId, () => {
3224
+ if (isCreation.value) {
3225
+ return;
3226
+ }
3227
+ fetchBanner();
3228
+ });
3229
+ return resource;
3230
+ }
3231
+
3232
+ function convertBannerToFormValues(banner, zonesOptionList) {
3233
+ var _a, _b, _c, _d, _e, _f;
3234
+ const foundZone = zonesOptionList.find(({ value }) => value === (banner === null || banner === void 0 ? void 0 : banner.bannerZone));
3235
+ return {
3236
+ link: (_a = banner === null || banner === void 0 ? void 0 : banner.link) !== null && _a !== void 0 ? _a : '',
3237
+ image: (banner === null || banner === void 0 ? void 0 : banner.image) ? { id: adminServices.createId(), file: banner.image } : null,
3238
+ bannerZone: foundZone !== null && foundZone !== void 0 ? foundZone : null,
3239
+ openNewTab: (_b = banner === null || banner === void 0 ? void 0 : banner.openNewTab) !== null && _b !== void 0 ? _b : false,
3240
+ dateStart: (_c = banner === null || banner === void 0 ? void 0 : banner.dateStart) !== null && _c !== void 0 ? _c : '',
3241
+ dateEnd: (_d = banner === null || banner === void 0 ? void 0 : banner.dateEnd) !== null && _d !== void 0 ? _d : '',
3242
+ disabled: (_e = banner === null || banner === void 0 ? void 0 : banner.disabled) !== null && _e !== void 0 ? _e : false,
3243
+ comment: (_f = banner === null || banner === void 0 ? void 0 : banner.comment) !== null && _f !== void 0 ? _f : '',
3244
+ };
3245
+ }
3246
+ function convertBannerFormValuesToPayload(values) {
3247
+ var _a, _b, _c, _d;
3248
+ return Object.assign(Object.assign({}, values), { image: (_b = (_a = values.image) === null || _a === void 0 ? void 0 : _a.file.id) !== null && _b !== void 0 ? _b : null, bannerZone: (_d = (_c = values.bannerZone) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '' });
3249
+ }
3250
+
3251
+ var script$2 = compositionApi.defineComponent({
3252
+ name: 'BannerForm',
3253
+ components: { FormFooter: adminUi.FormFooter },
3254
+ setup(props, context) {
3255
+ const bannerId = compositionApi.computed(() => context.root.$route.params.bannerId);
3256
+ const isCreation = compositionApi.computed(() => bannerId.value === 'create');
3257
+ /** Zones **/
3258
+ const { data: zones, loading: isZonesLoading } = useFetchZones({ context });
3259
+ const zonesOptionList = compositionApi.computed(() => zones.value.map((zone) => ({
3260
+ value: zone.id,
3261
+ label: zone.name,
3262
+ })));
3263
+ /** Banner **/
3264
+ const { data: banner, loading: isBannerLoading } = useFetchBanner({
3265
+ context,
3266
+ bannerId,
3267
+ isCreation,
3268
+ });
3269
+ /** Form State **/
3270
+ const isSubmitting = compositionApi.ref(false);
3271
+ const values = compositionApi.ref(convertBannerToFormValues(banner.value, zonesOptionList.value));
3272
+ const errors = compositionApi.ref({});
3273
+ compositionApi.watch([banner, zones], () => {
3274
+ values.value = convertBannerToFormValues(banner.value, zonesOptionList.value);
3275
+ });
3276
+ const submitForm = (event) => {
3277
+ isSubmitting.value = true;
3278
+ const body = convertBannerFormValuesToPayload(values.value);
3279
+ const requestPromise = isCreation.value
3280
+ ? createBanner(body)
3281
+ : updateBanner(bannerId.value, body);
1034
3282
  requestPromise
1035
- .then(() => {
1036
- this.errors = {};
1037
- this.$router.push(this.bannerItemListUrl);
1038
- this.$toast({
3283
+ .then(({ data }) => {
3284
+ errors.value = {};
3285
+ if (event.type === 'create') {
3286
+ context.root.$router.push(getBannersBannerFormUrl({ bannerId: String(data.id) }));
3287
+ }
3288
+ if (event.type === 'create_exit' || event.type === 'save_exit') {
3289
+ context.root.$router.push(getBannersBannerListUrl());
3290
+ }
3291
+ if (event.type === 'create_create-another') {
3292
+ values.value = convertBannerToFormValues(null, zonesOptionList.value);
3293
+ }
3294
+ context.root.$toast({
1039
3295
  variant: 'success',
1040
- title: 'Success',
1041
- body: `Banner item has been successfully ${this.isCreation ? 'created' : 'updated'}`,
3296
+ title: context.root.$t('banners:success'),
3297
+ body: isCreation.value
3298
+ ? context.root.$t('banners:bannerWasSuccessfullyCreated')
3299
+ : context.root.$t('banners:bannerWasSuccessfullyUpdated'),
1042
3300
  });
1043
3301
  })
1044
3302
  .catch((error) => {
1045
3303
  console.error(error);
1046
- this.errors = adminServices.convertRequestErrorToMap(error);
1047
- this.$toast({
3304
+ errors.value = adminServices.convertRequestErrorToMap(error);
3305
+ context.root.$toast({
1048
3306
  variant: 'danger',
1049
- title: 'Error',
1050
- body: `Banner item ${this.isCreation ? 'creation' : 'update'} has been failed`,
3307
+ title: context.root.$t('banners:error'),
3308
+ body: isCreation.value
3309
+ ? context.root.$t('banners:bannerCreationWasFailed')
3310
+ : context.root.$t('banners:bannerUpdateWasFailed'),
1051
3311
  });
3312
+ })
3313
+ .finally(() => {
3314
+ isSubmitting.value = false;
1052
3315
  });
1053
- },
3316
+ };
3317
+ const isContentLoading = compositionApi.computed(() => isBannerLoading.value || isZonesLoading.value);
3318
+ return {
3319
+ isCreation,
3320
+ isContentLoading,
3321
+ isSubmitting,
3322
+ values,
3323
+ errors,
3324
+ submitForm,
3325
+ bannerListUrl: getBannersBannerListUrl(),
3326
+ zonesOptionList,
3327
+ };
1054
3328
  },
1055
3329
  });
1056
3330
 
1057
3331
  /* script */
1058
- const __vue_script__$3 = script$3;
3332
+ const __vue_script__$2 = script$2;
1059
3333
 
1060
3334
  /* template */
1061
- var __vue_render__$3 = function () {
3335
+ var __vue_render__$2 = function () {
1062
3336
  var _vm = this;
1063
3337
  var _h = _vm.$createElement;
1064
3338
  var _c = _vm._self._c || _h;
1065
3339
  return _c("page", {
1066
3340
  attrs: {
1067
- title: _vm.isCreation ? "Create Banner Item" : "Update Banner Item",
3341
+ title: _vm.isCreation
3342
+ ? _vm.$t("banners:createBanner")
3343
+ : _vm.$t("banners:updateBanner"),
1068
3344
  "is-content-loading": _vm.isContentLoading,
1069
- footer: { onSubmit: _vm.submitForm, backHref: _vm.bannerItemListUrl },
1070
3345
  },
1071
3346
  scopedSlots: _vm._u([
1072
3347
  {
@@ -1080,46 +3355,33 @@
1080
3355
  on: {
1081
3356
  submit: function ($event) {
1082
3357
  $event.preventDefault();
3358
+ return _vm.submitForm($event)
1083
3359
  },
1084
3360
  },
1085
3361
  },
1086
3362
  [
1087
- _c("form-field", {
1088
- attrs: {
1089
- name: "title",
1090
- label: "Title",
1091
- error: _vm.errors.title,
1092
- type: "textarea",
1093
- },
1094
- model: {
1095
- value: _vm.values.title,
1096
- callback: function ($$v) {
1097
- _vm.$set(_vm.values, "title", $$v);
1098
- },
1099
- expression: "values.title",
1100
- },
1101
- }),
1102
- _vm._v(" "),
1103
- _c("form-field-rich-text-input", {
3363
+ _c("form-field-select", {
1104
3364
  attrs: {
1105
- name: "text",
1106
- label: "Text",
1107
- error: _vm.errors.text,
3365
+ name: "bannerZone",
3366
+ label: _vm.$t("banners:zone"),
3367
+ options: _vm.zonesOptionList,
3368
+ error: _vm.errors.bannerZone,
1108
3369
  },
1109
3370
  model: {
1110
- value: _vm.values.text,
3371
+ value: _vm.values.bannerZone,
1111
3372
  callback: function ($$v) {
1112
- _vm.$set(_vm.values, "text", $$v);
3373
+ _vm.$set(_vm.values, "bannerZone", $$v);
1113
3374
  },
1114
- expression: "values.text",
3375
+ expression: "values.bannerZone",
1115
3376
  },
1116
3377
  }),
1117
3378
  _vm._v(" "),
1118
3379
  _c("form-field-file-input", {
1119
3380
  attrs: {
1120
- label: "Image",
1121
3381
  name: "image",
1122
3382
  "file-type": "image",
3383
+ label: _vm.$t("banners:image"),
3384
+ error: _vm.errors.file,
1123
3385
  },
1124
3386
  model: {
1125
3387
  value: _vm.values.image,
@@ -1132,46 +3394,103 @@
1132
3394
  _vm._v(" "),
1133
3395
  _c("form-field", {
1134
3396
  attrs: {
1135
- name: "buttonLabel",
1136
- label: "Button: Label",
1137
- error: _vm.errors.buttonLabel,
3397
+ name: "link",
3398
+ label: _vm.$t("banners:link"),
3399
+ error: _vm.errors.name,
1138
3400
  },
1139
3401
  model: {
1140
- value: _vm.values.buttonLabel,
3402
+ value: _vm.values.link,
1141
3403
  callback: function ($$v) {
1142
- _vm.$set(_vm.values, "buttonLabel", $$v);
3404
+ _vm.$set(_vm.values, "link", $$v);
1143
3405
  },
1144
- expression: "values.buttonLabel",
3406
+ expression: "values.link",
1145
3407
  },
1146
3408
  }),
1147
3409
  _vm._v(" "),
1148
- _c("form-field", {
3410
+ _c("form-field-checkbox", {
1149
3411
  attrs: {
1150
- name: "buttonLink",
1151
- label: "Button: Link",
1152
- error: _vm.errors.buttonLink,
3412
+ name: "openNewTab",
3413
+ label: _vm.$t("banners:openNewTab"),
3414
+ error: _vm.errors.openNewTab,
1153
3415
  },
1154
3416
  model: {
1155
- value: _vm.values.buttonLink,
3417
+ value: _vm.values.openNewTab,
1156
3418
  callback: function ($$v) {
1157
- _vm.$set(_vm.values, "buttonLink", $$v);
3419
+ _vm.$set(_vm.values, "openNewTab", $$v);
1158
3420
  },
1159
- expression: "values.buttonLink",
3421
+ expression: "values.openNewTab",
1160
3422
  },
1161
3423
  }),
1162
3424
  _vm._v(" "),
3425
+ _c("input-label", [_vm._v(_vm._s(_vm.$t("banners:period")))]),
3426
+ _vm._v(" "),
3427
+ _c(
3428
+ "div",
3429
+ { staticClass: "date" },
3430
+ [
3431
+ _c("form-field", {
3432
+ attrs: {
3433
+ label: _vm.$t("banners:from"),
3434
+ name: "dateStart",
3435
+ type: "date",
3436
+ max: _vm.values.dateEnd,
3437
+ },
3438
+ model: {
3439
+ value: _vm.values.dateStart,
3440
+ callback: function ($$v) {
3441
+ _vm.$set(_vm.values, "dateStart", $$v);
3442
+ },
3443
+ expression: "values.dateStart",
3444
+ },
3445
+ }),
3446
+ _vm._v(" "),
3447
+ _c("form-field", {
3448
+ attrs: {
3449
+ label: _vm.$t("banners:to"),
3450
+ name: "dateEnd",
3451
+ type: "date",
3452
+ min: _vm.values.dateStart,
3453
+ },
3454
+ model: {
3455
+ value: _vm.values.dateEnd,
3456
+ callback: function ($$v) {
3457
+ _vm.$set(_vm.values, "dateEnd", $$v);
3458
+ },
3459
+ expression: "values.dateEnd",
3460
+ },
3461
+ }),
3462
+ ],
3463
+ 1
3464
+ ),
3465
+ _vm._v(" "),
1163
3466
  _c("form-field-checkbox", {
1164
3467
  attrs: {
1165
- name: "buttonIsNewTab",
1166
- label: "Button: Is new tab?",
1167
- error: _vm.errors.buttonIsNewTab,
3468
+ name: "disabled",
3469
+ label: _vm.$t("banners:disabled"),
3470
+ error: _vm.errors.disabled,
3471
+ },
3472
+ model: {
3473
+ value: _vm.values.disabled,
3474
+ callback: function ($$v) {
3475
+ _vm.$set(_vm.values, "disabled", $$v);
3476
+ },
3477
+ expression: "values.disabled",
3478
+ },
3479
+ }),
3480
+ _vm._v(" "),
3481
+ _c("form-field", {
3482
+ attrs: {
3483
+ name: "comment",
3484
+ type: "textarea",
3485
+ label: _vm.$t("banners:comment"),
3486
+ error: _vm.errors.comment,
1168
3487
  },
1169
3488
  model: {
1170
- value: _vm.values.buttonIsNewTab,
3489
+ value: _vm.values.comment,
1171
3490
  callback: function ($$v) {
1172
- _vm.$set(_vm.values, "buttonIsNewTab", $$v);
3491
+ _vm.$set(_vm.values, "comment", $$v);
1173
3492
  },
1174
- expression: "values.buttonIsNewTab",
3493
+ expression: "values.comment",
1175
3494
  },
1176
3495
  }),
1177
3496
  ],
@@ -1181,118 +3500,129 @@
1181
3500
  },
1182
3501
  proxy: true,
1183
3502
  },
3503
+ {
3504
+ key: "footer",
3505
+ fn: function () {
3506
+ return [
3507
+ _c("FormFooter", {
3508
+ attrs: {
3509
+ "back-href": _vm.bannerListUrl,
3510
+ "on-submit": _vm.submitForm,
3511
+ "is-submitting": _vm.isSubmitting,
3512
+ "is-creation": _vm.isCreation,
3513
+ "can-create-another": _vm.isCreation,
3514
+ },
3515
+ }),
3516
+ ]
3517
+ },
3518
+ proxy: true,
3519
+ },
1184
3520
  ]),
1185
3521
  })
1186
3522
  };
1187
- var __vue_staticRenderFns__$3 = [];
1188
- __vue_render__$3._withStripped = true;
3523
+ var __vue_staticRenderFns__$2 = [];
3524
+ __vue_render__$2._withStripped = true;
1189
3525
 
1190
3526
  /* style */
1191
- const __vue_inject_styles__$3 = function (inject) {
3527
+ const __vue_inject_styles__$2 = function (inject) {
1192
3528
  if (!inject) return
1193
- inject("data-v-2ed0e9d3_0", { source: ".bottom[data-v-2ed0e9d3] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.save-button[data-v-2ed0e9d3] {\n min-width: 100px;\n}\n.alias-field-inner[data-v-2ed0e9d3] {\n display: flex;\n align-items: center;\n}\n.alias-field-inner span[data-v-2ed0e9d3] {\n font-size: 0.9em;\n margin-right: 10px;\n}\n\n/*# sourceMappingURL=BannerItemForm.vue.map */", map: {"version":3,"sources":["D:\\Work\\tager-admin-banners\\src\\views\\BannerItemForm.vue","BannerItemForm.vue"],"names":[],"mappings":"AAmNA;EACA,aAAA;EACA,8BAAA;EACA,mBAAA;AClNA;ADqNA;EACA,gBAAA;AClNA;ADqNA;EACA,aAAA;EACA,mBAAA;AClNA;ADoNA;EACA,gBAAA;EACA,kBAAA;AClNA;;AAEA,6CAA6C","file":"BannerItemForm.vue","sourcesContent":["<template>\n <page\n :title=\"isCreation ? 'Create Banner Item' : 'Update Banner Item'\"\n :is-content-loading=\"isContentLoading\"\n :footer=\"{ onSubmit: submitForm, backHref: bannerItemListUrl }\"\n >\n <template v-slot:content>\n <form novalidate @submit.prevent>\n <form-field\n v-model=\"values.title\"\n name=\"title\"\n label=\"Title\"\n :error=\"errors.title\"\n type=\"textarea\"\n />\n\n <form-field-rich-text-input\n v-model=\"values.text\"\n name=\"text\"\n label=\"Text\"\n :error=\"errors.text\"\n />\n\n <form-field-file-input\n v-model=\"values.image\"\n label=\"Image\"\n name=\"image\"\n file-type=\"image\"\n />\n\n <form-field\n v-model=\"values.buttonLabel\"\n name=\"buttonLabel\"\n label=\"Button: Label\"\n :error=\"errors.buttonLabel\"\n />\n\n <form-field\n v-model=\"values.buttonLink\"\n name=\"buttonLink\"\n label=\"Button: Link\"\n :error=\"errors.buttonLink\"\n />\n\n <form-field-checkbox\n v-model=\"values.buttonIsNewTab\"\n name=\"buttonIsNewTab\"\n label=\"Button: Is new tab?\"\n :error=\"errors.buttonIsNewTab\"\n />\n </form>\n </template>\n </page>\n</template>\n\n<script lang=\"ts\">\nimport Vue from 'vue';\nimport {\n convertRequestErrorToMap,\n FileType,\n Nullable,\n} from '@tager/admin-services';\n\nimport {\n BannerItemCreatePayload,\n createBannerItem,\n getBannerAreaByAlias,\n getBannerItemById,\n updateBannerItem,\n} from '../services/requests';\nimport { BannerArea, BannerItem } from '../typings/model';\nimport { getBannerItemListUrl } from '../constants/paths';\n\ntype FormValues = {\n title: string;\n text: string;\n buttonLink: string;\n buttonLabel: string;\n buttonIsNewTab: boolean;\n image: Nullable<FileType>;\n};\n\nconst INITIAL_VALUES: FormValues = {\n title: '',\n text: '',\n buttonLink: '',\n buttonLabel: '',\n buttonIsNewTab: false,\n image: null,\n};\n\nexport default Vue.extend({\n name: 'BannerItemForm',\n data(): {\n values: FormValues;\n errors: Record<string, string>;\n isContentLoading: boolean;\n bannerArea: Nullable<BannerArea>;\n } {\n return {\n values: { ...INITIAL_VALUES },\n errors: {},\n isContentLoading: false,\n bannerArea: null,\n };\n },\n computed: {\n itemId(): string {\n return this.$route.params.itemId;\n },\n areaAlias(): string {\n return this.$route.params.areaAlias;\n },\n isCreation(): boolean {\n return this.itemId === 'create';\n },\n bannerItemListUrl(): string {\n return getBannerItemListUrl({\n areaAlias: this.bannerArea?.alias ?? 'unknown',\n });\n },\n },\n watch: {\n itemId() {\n this.updateValues();\n },\n areaAlias() {\n this.updateValues();\n },\n },\n mounted(): void {\n this.updateValues();\n },\n methods: {\n updateValues(): void {\n this.isContentLoading = true;\n\n Promise.all([\n getBannerAreaByAlias(this.areaAlias)\n .then((response) => {\n this.bannerArea = response.data;\n })\n .catch(console.error),\n this.isCreation\n ? new Promise((resolve) => {\n this.values = { ...INITIAL_VALUES };\n resolve();\n })\n : getBannerItemById(this.itemId)\n .then((response) => {\n this.values = this.convertReviewToInitialValues(response.data);\n })\n .catch(console.error),\n ]).finally(() => {\n this.isContentLoading = false;\n });\n },\n convertReviewToInitialValues(bannerItem: BannerItem): FormValues {\n return {\n title: bannerItem.title,\n text: bannerItem.text,\n buttonLink: bannerItem.buttonLink ?? '',\n buttonLabel: bannerItem.buttonLabel,\n buttonIsNewTab: bannerItem.buttonIsNewTab,\n image: bannerItem.image,\n };\n },\n submitForm() {\n const creationBody: BannerItemCreatePayload = {\n title: this.values.title,\n text: this.values.text,\n buttonLink: this.values.buttonLink.trim() || null,\n buttonLabel: this.values.buttonLabel,\n buttonIsNewTab: this.values.buttonIsNewTab,\n image: this.values.image?.id ?? null,\n };\n\n const requestPromise = this.isCreation\n ? createBannerItem(this.bannerArea?.id ?? 'unknown', creationBody)\n : updateBannerItem(this.itemId, creationBody);\n\n requestPromise\n .then(() => {\n this.errors = {};\n this.$router.push(this.bannerItemListUrl);\n\n this.$toast({\n variant: 'success',\n title: 'Success',\n body: `Banner item has been successfully ${\n this.isCreation ? 'created' : 'updated'\n }`,\n });\n })\n .catch((error) => {\n console.error(error);\n this.errors = convertRequestErrorToMap(error);\n this.$toast({\n variant: 'danger',\n title: 'Error',\n body: `Banner item ${\n this.isCreation ? 'creation' : 'update'\n } has been failed`,\n });\n });\n },\n },\n});\n</script>\n\n<style scoped lang=\"scss\">\n.bottom {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.save-button {\n min-width: 100px;\n}\n\n.alias-field-inner {\n display: flex;\n align-items: center;\n\n span {\n font-size: 0.9em;\n margin-right: 10px;\n }\n}\n</style>\n",".bottom {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.save-button {\n min-width: 100px;\n}\n\n.alias-field-inner {\n display: flex;\n align-items: center;\n}\n.alias-field-inner span {\n font-size: 0.9em;\n margin-right: 10px;\n}\n\n/*# sourceMappingURL=BannerItemForm.vue.map */"]}, media: undefined });
3529
+ inject("data-v-60ad1218_0", { source: ".date {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n\n/*# sourceMappingURL=BannerForm.vue.map */", map: {"version":3,"sources":["/home/runner/work/tager-admin-banners/tager-admin-banners/src/views/Banners/BannerForm/BannerForm.vue","BannerForm.vue"],"names":[],"mappings":"AAsOA;EACA,aAAA;EACA,qCAAA;EACA,gBAAA;ACrOA;;AAEA,yCAAyC","file":"BannerForm.vue","sourcesContent":["<template>\n <page\n :title=\"\n isCreation ? $t('banners:createBanner') : $t('banners:updateBanner')\n \"\n :is-content-loading=\"isContentLoading\"\n >\n <template v-slot:content>\n <form novalidate @submit.prevent=\"submitForm\">\n <form-field-select\n v-model=\"values.bannerZone\"\n name=\"bannerZone\"\n :label=\"$t('banners:zone')\"\n :options=\"zonesOptionList\"\n :error=\"errors.bannerZone\"\n />\n\n <form-field-file-input\n v-model=\"values.image\"\n name=\"image\"\n file-type=\"image\"\n :label=\"$t('banners:image')\"\n :error=\"errors.file\"\n />\n\n <form-field\n v-model=\"values.link\"\n name=\"link\"\n :label=\"$t('banners:link')\"\n :error=\"errors.name\"\n />\n\n <form-field-checkbox\n v-model=\"values.openNewTab\"\n name=\"openNewTab\"\n :label=\"$t('banners:openNewTab')\"\n :error=\"errors.openNewTab\"\n />\n\n <input-label>{{ $t('banners:period') }}</input-label>\n\n <div class=\"date\">\n <form-field\n v-model=\"values.dateStart\"\n :label=\"$t('banners:from')\"\n name=\"dateStart\"\n type=\"date\"\n :max=\"values.dateEnd\"\n />\n\n <form-field\n v-model=\"values.dateEnd\"\n :label=\"$t('banners:to')\"\n name=\"dateEnd\"\n type=\"date\"\n :min=\"values.dateStart\"\n />\n </div>\n\n <form-field-checkbox\n v-model=\"values.disabled\"\n name=\"disabled\"\n :label=\"$t('banners:disabled')\"\n :error=\"errors.disabled\"\n />\n\n <form-field\n v-model=\"values.comment\"\n name=\"comment\"\n type=\"textarea\"\n :label=\"$t('banners:comment')\"\n :error=\"errors.comment\"\n />\n </form>\n </template>\n\n <template v-slot:footer>\n <FormFooter\n :back-href=\"bannerListUrl\"\n :on-submit=\"submitForm\"\n :is-submitting=\"isSubmitting\"\n :is-creation=\"isCreation\"\n :can-create-another=\"isCreation\"\n />\n </template>\n </page>\n</template>\n\n<script lang=\"ts\">\nimport {\n computed,\n defineComponent,\n ref,\n SetupContext,\n watch,\n} from '@vue/composition-api';\n\nimport { FormFooter, OptionType, TagerFormSubmitEvent } from '@tager/admin-ui';\nimport { convertRequestErrorToMap } from '@tager/admin-services';\n\nimport { useFetchZones } from '../../../hooks';\nimport { BannerFormValues } from '../../../typings/banners';\nimport { useFetchBanner } from '../../../hooks/useFetchBanner';\nimport {\n getBannersBannerFormUrl,\n getBannersBannerListUrl,\n} from '../../../constants/paths';\nimport { createBanner, updateBanner } from '../../../services/requests';\n\nimport {\n convertBannerFormValuesToPayload,\n convertBannerToFormValues,\n} from './BannerForm.helpers';\n\nexport default defineComponent({\n name: 'BannerForm',\n components: { FormFooter },\n setup(props, context: SetupContext) {\n const bannerId = computed<string>(\n () => context.root.$route.params.bannerId\n );\n const isCreation = computed<boolean>(() => bannerId.value === 'create');\n\n /** Zones **/\n\n const { data: zones, loading: isZonesLoading } = useFetchZones({ context });\n\n const zonesOptionList = computed<OptionType[]>(() =>\n zones.value.map<OptionType>((zone) => ({\n value: zone.id,\n label: zone.name,\n }))\n );\n\n /** Banner **/\n\n const { data: banner, loading: isBannerLoading } = useFetchBanner({\n context,\n bannerId,\n isCreation,\n });\n\n /** Form State **/\n\n const isSubmitting = ref<boolean>(false);\n const values = ref<BannerFormValues>(\n convertBannerToFormValues(banner.value, zonesOptionList.value)\n );\n const errors = ref<Record<string, string>>({});\n\n watch([banner, zones], () => {\n values.value = convertBannerToFormValues(\n banner.value,\n zonesOptionList.value\n );\n });\n\n const submitForm = (event: TagerFormSubmitEvent) => {\n isSubmitting.value = true;\n\n const body = convertBannerFormValuesToPayload(values.value);\n\n const requestPromise = isCreation.value\n ? createBanner(body)\n : updateBanner(bannerId.value, body);\n\n requestPromise\n .then(({ data }) => {\n errors.value = {};\n\n if (event.type === 'create') {\n context.root.$router.push(\n getBannersBannerFormUrl({ bannerId: String(data.id) })\n );\n }\n\n if (event.type === 'create_exit' || event.type === 'save_exit') {\n context.root.$router.push(getBannersBannerListUrl());\n }\n\n if (event.type === 'create_create-another') {\n values.value = convertBannerToFormValues(\n null,\n zonesOptionList.value\n );\n }\n\n context.root.$toast({\n variant: 'success',\n title: context.root.$t('banners:success'),\n body: isCreation.value\n ? context.root.$t('banners:bannerWasSuccessfullyCreated')\n : context.root.$t('banners:bannerWasSuccessfullyUpdated'),\n });\n })\n .catch((error) => {\n console.error(error);\n errors.value = convertRequestErrorToMap(error);\n context.root.$toast({\n variant: 'danger',\n title: context.root.$t('banners:error'),\n body: isCreation.value\n ? context.root.$t('banners:bannerCreationWasFailed')\n : context.root.$t('banners:bannerUpdateWasFailed'),\n });\n })\n .finally(() => {\n isSubmitting.value = false;\n });\n };\n\n const isContentLoading = computed<boolean>(\n () => isBannerLoading.value || isZonesLoading.value\n );\n\n return {\n isCreation,\n isContentLoading,\n isSubmitting,\n values,\n errors,\n submitForm,\n bannerListUrl: getBannersBannerListUrl(),\n zonesOptionList,\n };\n },\n});\n</script>\n\n<style lang=\"scss\">\n.date {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n</style>\n",".date {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n\n/*# sourceMappingURL=BannerForm.vue.map */"]}, media: undefined });
1194
3530
 
1195
3531
  };
1196
3532
  /* scoped */
1197
- const __vue_scope_id__$3 = "data-v-2ed0e9d3";
3533
+ const __vue_scope_id__$2 = undefined;
1198
3534
  /* module identifier */
1199
- const __vue_module_identifier__$3 = undefined;
3535
+ const __vue_module_identifier__$2 = undefined;
1200
3536
  /* functional template */
1201
- const __vue_is_functional_template__$3 = false;
3537
+ const __vue_is_functional_template__$2 = false;
1202
3538
  /* style inject SSR */
1203
3539
 
1204
3540
  /* style inject shadow dom */
1205
3541
 
1206
3542
 
1207
3543
 
1208
- const __vue_component__$3 = /*#__PURE__*/normalizeComponent(
1209
- { render: __vue_render__$3, staticRenderFns: __vue_staticRenderFns__$3 },
1210
- __vue_inject_styles__$3,
1211
- __vue_script__$3,
1212
- __vue_scope_id__$3,
1213
- __vue_is_functional_template__$3,
1214
- __vue_module_identifier__$3,
3544
+ const __vue_component__$2 = /*#__PURE__*/normalizeComponent(
3545
+ { render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 },
3546
+ __vue_inject_styles__$2,
3547
+ __vue_script__$2,
3548
+ __vue_scope_id__$2,
3549
+ __vue_is_functional_template__$2,
3550
+ __vue_module_identifier__$2,
1215
3551
  false,
1216
3552
  createInjector,
1217
3553
  undefined,
1218
3554
  undefined
1219
3555
  );
1220
3556
 
1221
- const HOME_BREADCRUMB = { path: '/', label: 'Home' };
1222
- const BANNER_AREA_LIST_ROUTE = {
1223
- path: BANNER_ROUTE_PATHS.AREA_LIST,
3557
+ const BANNERS_ZONE_LIST_ROUTE = {
3558
+ path: BANNERS_ROUTE_PATHS.ZONE_LIST,
1224
3559
  component: __vue_component__,
1225
- name: 'Banner Area List',
3560
+ name: 'Zones',
1226
3561
  meta: {
1227
- getBreadcrumbs: (route) => [
1228
- HOME_BREADCRUMB,
1229
- { path: route.path, label: route.name },
3562
+ getBreadcrumbs: (route, t) => [
3563
+ { url: '/', text: t('banners:home') },
3564
+ { url: BANNERS_ROUTE_PATHS.ZONE_LIST, text: t('banners:zones') },
1230
3565
  ],
1231
3566
  },
1232
3567
  };
1233
- const BANNER_AREA_FORM_ROUTE = {
1234
- path: BANNER_ROUTE_PATHS.AREA_FORM,
3568
+ const BANNERS_BANNER_LIST_ROUTE = {
3569
+ path: BANNERS_ROUTE_PATHS.BANNER_LIST,
1235
3570
  component: __vue_component__$1,
1236
- name: 'Banner Area Form',
3571
+ name: 'Banners',
1237
3572
  meta: {
1238
- getBreadcrumbs: (route) => [
1239
- HOME_BREADCRUMB,
1240
- {
1241
- path: BANNER_ROUTE_PATHS.AREA_LIST,
1242
- label: BANNER_AREA_LIST_ROUTE.name,
1243
- },
1244
- { path: route.path, label: route.name },
3573
+ getBreadcrumbs: (route, t) => [
3574
+ { url: '/', text: t('banners:home') },
3575
+ { url: BANNERS_ROUTE_PATHS.BANNER_LIST, text: t('banners:banners') },
1245
3576
  ],
1246
3577
  },
1247
3578
  };
1248
- const BANNER_ITEM_LIST_ROUTE = {
1249
- path: BANNER_ROUTE_PATHS.ITEM_LIST,
3579
+ const BANNERS_BANNER_FORM_ROUTE = {
3580
+ path: BANNERS_ROUTE_PATHS.BANNER_FORM,
1250
3581
  component: __vue_component__$2,
1251
- name: 'Banner Item List',
3582
+ name: 'Banner Form',
1252
3583
  meta: {
1253
- getBreadcrumbs: (route) => [
1254
- HOME_BREADCRUMB,
1255
- { path: route.path, label: route.name },
3584
+ getBreadcrumbs: (route, t) => [
3585
+ { url: '/', text: t('banners:home') },
3586
+ { url: BANNERS_ROUTE_PATHS.BANNER_LIST, text: t('banners:banners') },
3587
+ { url: route.path, text: t('banners:bannerForm') },
1256
3588
  ],
1257
3589
  },
1258
- };
1259
- const BANNER_ITEM_FORM_ROUTE = {
1260
- path: BANNER_ROUTE_PATHS.ITEM_FORM,
1261
- component: __vue_component__$3,
1262
- name: 'Banner Item Form',
1263
- meta: {
1264
- getBreadcrumbs: (route) => [
1265
- HOME_BREADCRUMB,
3590
+ };
3591
+
3592
+ function getBannersMenuItem(params) {
3593
+ return {
3594
+ id: 'banners',
3595
+ text: params.t('banners:banners'),
3596
+ icon: 'viewList',
3597
+ children: [
3598
+ { text: params.t('banners:zones'), url: getBannersZoneListUrl() },
3599
+ { text: params.t('banners:banners'), url: getBannersBannerListUrl() },
1266
3600
  {
1267
- path: getBannerItemListUrl({ areaAlias: route.params.areaAlias }),
1268
- label: BANNER_ITEM_LIST_ROUTE.name,
3601
+ text: params.t('banners:createBanner'),
3602
+ url: getBannersBannerFormUrl({ bannerId: 'create' }),
1269
3603
  },
1270
- { path: route.path, label: route.name },
1271
3604
  ],
1272
- },
1273
- };
3605
+ };
3606
+ }
1274
3607
 
1275
- const BANNER_MENU_ITEM = {
1276
- id: 'banner',
1277
- name: 'Banners',
1278
- path: '',
1279
- icon: 'viewList',
1280
- children: [
1281
- { name: 'Banner areas', path: '/banners' },
1282
- { name: 'Create banner area', path: '/banners/create' },
1283
- ],
1284
- };
3608
+ adminServices.i18n.addTranslations('en', 'blog', EN);
3609
+ adminServices.i18n.addTranslations('ru', 'blog', RU);
1285
3610
 
1286
- exports.BANNER_AREA_FORM_ROUTE = BANNER_AREA_FORM_ROUTE;
1287
- exports.BANNER_AREA_LIST_ROUTE = BANNER_AREA_LIST_ROUTE;
1288
- exports.BANNER_ITEM_FORM_ROUTE = BANNER_ITEM_FORM_ROUTE;
1289
- exports.BANNER_ITEM_LIST_ROUTE = BANNER_ITEM_LIST_ROUTE;
1290
- exports.BANNER_MENU_ITEM = BANNER_MENU_ITEM;
1291
- exports.BANNER_ROUTE_PATHS = BANNER_ROUTE_PATHS;
1292
- exports.getBannerAreaFormUrl = getBannerAreaFormUrl;
1293
- exports.getBannerAreaListUrl = getBannerAreaListUrl;
1294
- exports.getBannerItemFormUrl = getBannerItemFormUrl;
1295
- exports.getBannerItemListUrl = getBannerItemListUrl;
3611
+ exports.BANNERS_BANNER_FORM_ROUTE = BANNERS_BANNER_FORM_ROUTE;
3612
+ exports.BANNERS_BANNER_LIST_ROUTE = BANNERS_BANNER_LIST_ROUTE;
3613
+ exports.BANNERS_ROUTE_PATHS = BANNERS_ROUTE_PATHS;
3614
+ exports.BANNERS_ZONE_LIST_ROUTE = BANNERS_ZONE_LIST_ROUTE;
3615
+ exports.createBanner = createBanner;
3616
+ exports.deleteBanner = deleteBanner;
3617
+ exports.getBanner = getBanner;
3618
+ exports.getBannerCount = getBannerCount;
3619
+ exports.getBanners = getBanners;
3620
+ exports.getBannersBannerFormUrl = getBannersBannerFormUrl;
3621
+ exports.getBannersBannerListUrl = getBannersBannerListUrl;
3622
+ exports.getBannersMenuItem = getBannersMenuItem;
3623
+ exports.getBannersZoneListUrl = getBannersZoneListUrl;
3624
+ exports.getZones = getZones;
3625
+ exports.updateBanner = updateBanner;
1296
3626
 
1297
3627
  Object.defineProperty(exports, '__esModule', { value: true });
1298
3628