@tager/admin-banners 0.2.1 → 0.3.3

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