@tager/admin-blog 0.3.38 → 0.3.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -37,7 +37,6 @@
37
37
  actions: 'Actions',
38
38
  updatePost: 'Update post',
39
39
  title: 'Title',
40
- status: 'Status',
41
40
  link: 'Link',
42
41
  excerpt: 'Excerpt',
43
42
  body: 'Body',
@@ -79,9 +78,16 @@
79
78
  },
80
79
  parentCategory: 'Parent category',
81
80
  noParent: 'No parent',
81
+ status: 'Status',
82
82
  statusPublished: 'Published',
83
83
  statusDraft: 'Draft',
84
- statusArchived: 'Archived'
84
+ statusArchived: 'Archived',
85
+ scheduleArchive: 'Schedule archive',
86
+ schedulePublish: 'Schedule publish',
87
+ archiveAt: 'Archive at',
88
+ publishAt: 'Publish at',
89
+ archiveAtLabel: 'Archive at',
90
+ publishAtLabel: 'Publish at',
85
91
  };
86
92
 
87
93
  const RU = {
@@ -118,7 +124,6 @@
118
124
  updatePost: 'Обновить пост',
119
125
  title: 'Заголовок',
120
126
  link: 'Ссылка',
121
- status: 'Статус',
122
127
  excerpt: 'Краткое описание',
123
128
  defaultCategory: 'Категория по-умолчанию',
124
129
  body: 'Содержание',
@@ -159,9 +164,16 @@
159
164
  },
160
165
  parentCategory: 'Родительская категория',
161
166
  noParent: 'Нет родительской',
167
+ status: 'Статус',
162
168
  statusPublished: 'Опубликован',
163
169
  statusDraft: 'Черновик',
164
- statusArchived: 'Снят с публикации'
170
+ statusArchived: 'В архиве',
171
+ scheduleArchive: 'Запланировать перенос в архив',
172
+ schedulePublish: 'Запланировать публикацию',
173
+ archiveAt: 'Перенести в архив в',
174
+ publishAt: 'Опубликовать в',
175
+ archiveAtLabel: 'Перенос в архив',
176
+ publishAtLabel: 'Публикация',
165
177
  };
166
178
 
167
179
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -2671,6 +2683,123 @@
2671
2683
  });
2672
2684
  }
2673
2685
 
2686
+ function generateNumberArray(length) {
2687
+ return Array.from({ length }, (_, index) => index);
2688
+ }
2689
+ function getNameWithDepth(name, depth) {
2690
+ return (generateNumberArray(depth)
2691
+ .map(() => '—')
2692
+ .join(' ') +
2693
+ ' ' +
2694
+ name);
2695
+ }
2696
+
2697
+ const getStatusOptions = (t) => [
2698
+ { label: t('blog:statusPublished'), value: 'PUBLISHED' },
2699
+ { label: t('blog:statusDraft'), value: 'DRAFT' },
2700
+ { label: t('blog:statusArchived'), value: 'ARCHIVED' }
2701
+ ];
2702
+ function convertPostToFormValues(post, languageOptionList, postOptionList, additionalFieldList, statusOptions) {
2703
+ var _a, _b, _c;
2704
+ if (!post) {
2705
+ return {
2706
+ title: '',
2707
+ excerpt: '',
2708
+ body: '',
2709
+ datetime: '',
2710
+ coverImage: null,
2711
+ image: null,
2712
+ imageMobile: null,
2713
+ pageTitle: '',
2714
+ pageDescription: '',
2715
+ openGraphImage: null,
2716
+ urlAlias: '',
2717
+ categories: [],
2718
+ language: null,
2719
+ relatedPosts: [],
2720
+ tags: '',
2721
+ additionalFields: additionalFieldList.map((fieldConfig) => adminDynamicField.universalFieldUtils.createFormField(fieldConfig, null)),
2722
+ status: statusOptions[0],
2723
+ statusDateEnabled: false,
2724
+ statusDate: null
2725
+ };
2726
+ }
2727
+ const currentLangOption = languageOptionList.find((option) => option.value === post.language);
2728
+ const selectedPostOptionList = postOptionList.filter((option) => post.relatedPosts.some((relatedPost) => relatedPost.id === option.value));
2729
+ const foundStatus = (_a = statusOptions.find(({ value }) => value === post.status)) !== null && _a !== void 0 ? _a : statusOptions[0];
2730
+ return {
2731
+ title: post.title,
2732
+ excerpt: post.excerpt,
2733
+ body: post.body,
2734
+ datetime: post.datetime ? post.datetime.substr(0, 10) : '',
2735
+ coverImage: post.coverImage
2736
+ ? { id: adminServices.createId(), file: post.coverImage }
2737
+ : null,
2738
+ image: post.image ? { id: adminServices.createId(), file: post.image } : null,
2739
+ imageMobile: post.imageMobile
2740
+ ? { id: adminServices.createId(), file: post.imageMobile }
2741
+ : null,
2742
+ pageTitle: (_b = post.pageTitle) !== null && _b !== void 0 ? _b : '',
2743
+ pageDescription: (_c = post.pageDescription) !== null && _c !== void 0 ? _c : '',
2744
+ openGraphImage: post.openGraphImage
2745
+ ? { id: adminServices.createId(), file: post.openGraphImage }
2746
+ : null,
2747
+ urlAlias: post.urlAlias,
2748
+ categories: post.categories.map((category) => ({
2749
+ value: category.id,
2750
+ label: category.name
2751
+ })),
2752
+ language: currentLangOption !== null && currentLangOption !== void 0 ? currentLangOption : null,
2753
+ relatedPosts: selectedPostOptionList,
2754
+ tags: post.tags.join(','),
2755
+ additionalFields: additionalFieldList.map((fieldConfig) => {
2756
+ const postAdditionalField = post.additionalFields.find(({ name }) => name === fieldConfig.name);
2757
+ return adminDynamicField.universalFieldUtils.createFormField(fieldConfig, postAdditionalField === null || postAdditionalField === void 0 ? void 0 : postAdditionalField.value);
2758
+ }),
2759
+ status: foundStatus,
2760
+ statusDateEnabled: post.status === 'PUBLISHED' ? !!post.archiveAt : (post.status === 'DRAFT' ? !!post.publishAt : false),
2761
+ statusDate: post.status === 'PUBLISHED' && post.archiveAt ? post.archiveAt.substr(0, 10) : (post.status === 'DRAFT' && post.publishAt ? post.publishAt.substr(0, 10) : null)
2762
+ };
2763
+ }
2764
+ function convertFormValuesToCreationPayload(values) {
2765
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
2766
+ return {
2767
+ title: values.title,
2768
+ excerpt: values.excerpt,
2769
+ urlAlias: values.urlAlias,
2770
+ body: values.body,
2771
+ datetime: values.datetime,
2772
+ coverImage: (_b = (_a = values.coverImage) === null || _a === void 0 ? void 0 : _a.file.id) !== null && _b !== void 0 ? _b : null,
2773
+ image: (_d = (_c = values.image) === null || _c === void 0 ? void 0 : _c.file.id) !== null && _d !== void 0 ? _d : null,
2774
+ imageMobile: (_f = (_e = values.imageMobile) === null || _e === void 0 ? void 0 : _e.file.id) !== null && _f !== void 0 ? _f : null,
2775
+ pageTitle: values.pageTitle,
2776
+ pageDescription: values.pageDescription,
2777
+ openGraphImage: (_h = (_g = values.openGraphImage) === null || _g === void 0 ? void 0 : _g.file.id) !== null && _h !== void 0 ? _h : null,
2778
+ categories: values.categories.map((option) => option.value),
2779
+ language: (_k = (_j = values.language) === null || _j === void 0 ? void 0 : _j.value) !== null && _k !== void 0 ? _k : null,
2780
+ relatedPosts: values.relatedPosts.map((relatedPostOption) => relatedPostOption.value),
2781
+ tags: values.tags.split(',').filter((tag) => tag.trim().length > 0),
2782
+ additionalFields: values.additionalFields.map((field) => ({
2783
+ name: field.config.name,
2784
+ value: adminDynamicField.universalFieldUtils.getOutgoingValue(field)
2785
+ })),
2786
+ status: values.status.value,
2787
+ archiveAt: values.status.value === 'PUBLISHED' && values.statusDateEnabled && values.statusDate ? values.statusDate : null,
2788
+ publishAt: values.status.value === 'DRAFT' && values.statusDateEnabled && values.statusDate ? values.statusDate : null
2789
+ };
2790
+ }
2791
+ function convertFormValuesToUpdatePayload(values) {
2792
+ return Object.assign(Object.assign({}, convertFormValuesToCreationPayload(values)), { urlAlias: values.urlAlias });
2793
+ }
2794
+ function convertCategoryListToOptions(categoryList, languageId) {
2795
+ return categoryList
2796
+ .filter(({ language }) => (languageId ? language === languageId : true))
2797
+ .map(({ id, name, depth }) => ({
2798
+ value: id,
2799
+ label: getNameWithDepth(name, depth)
2800
+ }));
2801
+ }
2802
+
2674
2803
  function convertPostList(postList, selectedCategory, languages) {
2675
2804
  return postList
2676
2805
  .filter((post) => selectedCategory
@@ -2701,7 +2830,7 @@
2701
2830
  name: 'ID',
2702
2831
  field: 'id',
2703
2832
  style: { width: '50px', textAlign: 'center' },
2704
- headStyle: { width: '50px', textAlign: 'center' }
2833
+ headStyle: { width: '50px', textAlign: 'center' },
2705
2834
  },
2706
2835
  {
2707
2836
  id: 2,
@@ -2709,78 +2838,71 @@
2709
2838
  field: 'status',
2710
2839
  style: { width: '120px' },
2711
2840
  headStyle: { width: '120px' },
2712
- format: ({ row }) => {
2713
- return getStatuses(t)[row.status];
2714
- }
2715
2841
  },
2716
2842
  {
2717
- id: 2,
2843
+ id: 3,
2718
2844
  name: t('blog:name'),
2719
2845
  field: 'name',
2720
2846
  type: 'name',
2721
2847
  format: ({ row }) => ({
2722
2848
  adminLink: {
2723
2849
  text: row.title,
2724
- url: getBlogPostFormUrl({ postId: row.id })
2850
+ url: getBlogPostFormUrl({ postId: row.id }),
2725
2851
  },
2726
2852
  websiteLink: {
2727
2853
  text: row.url,
2728
2854
  url: [
2729
2855
  process.env.VUE_APP_WEBSITE_URL || window.location.origin,
2730
- row.url
2731
- ].join('')
2732
- }
2733
- })
2856
+ row.url,
2857
+ ].join(''),
2858
+ },
2859
+ }),
2734
2860
  },
2735
2861
  {
2736
- id: 3,
2862
+ id: 4,
2737
2863
  name: t('blog:image'),
2738
2864
  field: 'image',
2739
2865
  type: 'image',
2740
2866
  style: { width: '250px' },
2741
- headStyle: { width: '250px' }
2867
+ headStyle: { width: '250px' },
2742
2868
  },
2743
2869
  isLangSpecific
2744
- ? { id: 4, name: t('blog:language'), field: 'language' }
2870
+ ? { id: 5, name: t('blog:language'), field: 'language' }
2745
2871
  : null,
2746
- { id: 5, name: t('blog:date'), field: 'datetime', type: 'datetime', options: { ignoreStartOfDayTime: true } },
2747
2872
  {
2748
2873
  id: 6,
2874
+ name: t('blog:date'),
2875
+ field: 'datetime',
2876
+ type: 'datetime',
2877
+ options: { ignoreStartOfDayTime: true },
2878
+ },
2879
+ {
2880
+ id: 7,
2749
2881
  name: t('blog:categories'),
2750
2882
  field: 'categories',
2751
- format: ({ row }) => row.categories.map((category) => category.name).join(', ')
2883
+ format: ({ row }) => row.categories.map((category) => category.name).join(', '),
2752
2884
  },
2753
2885
  {
2754
- id: 7,
2886
+ id: 8,
2755
2887
  name: t('blog:actions'),
2756
2888
  field: 'actions',
2757
2889
  style: { whiteSpace: 'nowrap', width: '120px' },
2758
- headStyle: { whiteSpace: 'nowrap', width: '120px' }
2759
- }
2890
+ headStyle: { whiteSpace: 'nowrap', width: '120px' },
2891
+ },
2760
2892
  ];
2761
2893
  return COLUMN_DEFS.filter(adminServices.notEmpty);
2762
2894
  }
2763
2895
 
2764
- function generateNumberArray(length) {
2765
- return Array.from({ length }, (_, index) => index);
2766
- }
2767
- function getNameWithDepth(name, depth) {
2768
- return (generateNumberArray(depth)
2769
- .map(() => '—')
2770
- .join(' ') +
2771
- ' ' +
2772
- name);
2773
- }
2774
-
2775
2896
  var FilterTypes;
2776
2897
  (function (FilterTypes) {
2777
2898
  FilterTypes["CATEGORY"] = "category";
2778
2899
  FilterTypes["LANGUAGE"] = "language";
2779
2900
  FilterTypes["FROM_DATE"] = "from-date";
2780
2901
  FilterTypes["TO_DATE"] = "to-date";
2902
+ FilterTypes["STATUS"] = "status";
2781
2903
  })(FilterTypes || (FilterTypes = {}));
2782
2904
  const dateFormat = (date) => date.split('-').reverse().join('.');
2783
- function useAdvancedSearch({ context, categoryList, languageList, }) {
2905
+ function useAdvancedSearch({ context, categoryList, languageList, statusOptionList, }) {
2784
2906
  /** Category **/
2785
2907
  const categoryOptionList = compositionApi.computed(() => categoryList.value.map(({ id, name, depth }) => ({
2786
2908
  value: String(id),
@@ -2838,11 +2960,21 @@
2838
2960
  title: context.root.$t('blog:dateOfPublication'),
2839
2961
  };
2840
2962
  });
2963
+ /** Status **/
2964
+ const initialStatusFilter = compositionApi.computed(() => {
2965
+ const queryValue = adminUi.getFilterParamAsStringArray(context.root.$route.query, FilterTypes.STATUS);
2966
+ return statusOptionList.value.filter(({ value }) => queryValue.some((selected) => selected === value));
2967
+ });
2968
+ const statusFilter = compositionApi.ref(initialStatusFilter.value);
2969
+ compositionApi.watch(initialStatusFilter, () => {
2970
+ statusFilter.value = initialStatusFilter.value;
2971
+ });
2841
2972
  /** Params **/
2842
2973
  const filterParams = compositionApi.computed(() => {
2843
2974
  const filters = {
2844
2975
  [FilterTypes.CATEGORY]: categoryFilter.value.map(({ value }) => value),
2845
2976
  [FilterTypes.LANGUAGE]: languageFilter.value.map(({ value }) => value),
2977
+ [FilterTypes.STATUS]: statusFilter.value.map(({ value }) => value),
2846
2978
  };
2847
2979
  if (fromDateFilter.value) {
2848
2980
  filters[FilterTypes.FROM_DATE] = fromDateFilter.value;
@@ -2864,6 +2996,9 @@
2864
2996
  fromDateFilter.value = '';
2865
2997
  toDateFilter.value = '';
2866
2998
  }
2999
+ if (event.name === FilterTypes.STATUS) {
3000
+ statusFilter.value = statusFilter.value.filter(({ value }) => value !== event.value);
3001
+ }
2867
3002
  }
2868
3003
  /** Tags **/
2869
3004
  const tags = compositionApi.computed(() => [
@@ -2880,6 +3015,12 @@
2880
3015
  title: context.root.$t('blog:language'),
2881
3016
  })),
2882
3017
  date.value,
3018
+ ...statusFilter.value.map(({ value, label }) => ({
3019
+ value,
3020
+ label,
3021
+ name: FilterTypes.STATUS,
3022
+ title: context.root.$t('blog:status'),
3023
+ })),
2883
3024
  ].filter(adminServices.isNotNullish));
2884
3025
  /** Helpers **/
2885
3026
  const selectedCategoryOptionList = compositionApi.computed(() => {
@@ -2899,6 +3040,7 @@
2899
3040
  languageOptionList,
2900
3041
  fromDateFilter,
2901
3042
  toDateFilter,
3043
+ statusFilter,
2902
3044
  tagRemovalHandler,
2903
3045
  tags: tags,
2904
3046
  filterParams,
@@ -2914,11 +3056,12 @@
2914
3056
  return Array.isArray(context.root.$route.query.category)
2915
3057
  ? (_a = context.root.$route.query.category[0]) !== null && _a !== void 0 ? _a : '' : context.root.$route.query.category;
2916
3058
  });
3059
+ const statusOptionList = compositionApi.computed(() => getStatusOptions(t));
2917
3060
  /** Fetch module config **/
2918
- const { data: moduleConfig, loading: isModuleConfigLoading, } = useFetchModuleConfig({ context });
3061
+ const { data: moduleConfig, loading: isModuleConfigLoading } = useFetchModuleConfig({ context });
2919
3062
  const languageList = compositionApi.computed(() => { var _a, _b; return (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.languages) !== null && _b !== void 0 ? _b : []; });
2920
3063
  /** Fetch category list **/
2921
- const { data: categoryList, loading: isCategoryListLoading, } = useFetchCategories({ context });
3064
+ const { data: categoryList, loading: isCategoryListLoading } = useFetchCategories({ context });
2922
3065
  const selectedCategory = compositionApi.computed(() => {
2923
3066
  var _a;
2924
3067
  return categoryId.value
@@ -2930,19 +3073,20 @@
2930
3073
  : context.root.$t('blog:posts');
2931
3074
  });
2932
3075
  /** Advanced search **/
2933
- const { categoryFilter, categoryOptionList, languageFilter, languageOptionList, fromDateFilter, toDateFilter, filterParams, tags, tagRemovalHandler, } = useAdvancedSearch({
3076
+ const { categoryFilter, categoryOptionList, languageFilter, languageOptionList, fromDateFilter, toDateFilter, filterParams, tags, tagRemovalHandler, statusFilter } = useAdvancedSearch({
2934
3077
  context,
2935
3078
  categoryList,
2936
3079
  languageList,
3080
+ statusOptionList
2937
3081
  });
2938
3082
  const isLangSpecific = compositionApi.computed(() => languageOptionList.value.length > 1);
2939
3083
  /** Fetch Post list **/
2940
- const { fetchEntityList: fetchPostList, isLoading: isPostLoading, rowData: postList, errorMessage, searchQuery, handleChange, pageNumber, pageCount, pageSize, } = adminUi.useDataTable({
3084
+ const { fetchEntityList: fetchPostList, isLoading: isPostLoading, rowData: postList, errorMessage, searchQuery, handleChange, pageNumber, pageCount, pageSize } = adminUi.useDataTable({
2941
3085
  fetchEntityList: (params) => getPosts(Object.assign({ query: params.searchQuery, pageNumber: params.pageNumber, pageSize: params.pageSize }, filterParams.value)),
2942
3086
  initialValue: [],
2943
3087
  context,
2944
3088
  resourceName: 'Blog post list',
2945
- pageSize: 100,
3089
+ pageSize: 100
2946
3090
  });
2947
3091
  compositionApi.watch(filterParams, () => {
2948
3092
  if (isModuleConfigLoading.value || isCategoryListLoading.value) {
@@ -2965,7 +3109,7 @@
2965
3109
  deleteResource: deleteBlogPost,
2966
3110
  resourceName: 'Post',
2967
3111
  onSuccess: fetchPostList,
2968
- context,
3112
+ context
2969
3113
  });
2970
3114
  const { isCloning, handleResourceClone } = adminServices.useResourceClone({
2971
3115
  cloneResource: clonePost,
@@ -2973,13 +3117,15 @@
2973
3117
  successMessage: t('blog:cloneSuccess'),
2974
3118
  failureMessage: t('blog:cloneFailure'),
2975
3119
  onSuccessRedirectTo: (data) => `/blog/posts/${data.id}`,
2976
- context,
3120
+ context
2977
3121
  });
2978
3122
  function isBusy(postId) {
2979
3123
  return isDeleting(postId) || isCloning(postId) || isRowDataLoading.value;
2980
3124
  }
2981
3125
  const columnDefs = compositionApi.computed(() => getPostTableColumnDefs(moduleConfig.value, context.root.$t));
2982
3126
  return {
3127
+ t,
3128
+ formatDateTime: adminUi.formatDateTime,
2983
3129
  columnDefs,
2984
3130
  rowData: displayedPostList,
2985
3131
  handleResourceDelete,
@@ -3002,13 +3148,16 @@
3002
3148
  languageOptionList,
3003
3149
  fromDateFilter,
3004
3150
  toDateFilter,
3151
+ statusFilter,
3152
+ statusOptionList,
3005
3153
  tags,
3006
3154
  tagRemovalHandler,
3155
+ getStatuses,
3007
3156
  // Clone
3008
3157
  handleResourceClone,
3009
- isBusy,
3158
+ isBusy
3010
3159
  };
3011
- },
3160
+ }
3012
3161
  });
3013
3162
 
3014
3163
  function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
@@ -3278,6 +3427,23 @@
3278
3427
  1
3279
3428
  ),
3280
3429
  ]),
3430
+ _vm._v(" "),
3431
+ _c("form-field-multi-select", {
3432
+ staticClass: "filter",
3433
+ attrs: {
3434
+ options: _vm.statusOptionList,
3435
+ name: "statusFilter",
3436
+ searchable: true,
3437
+ label: _vm.$t("blog:status"),
3438
+ },
3439
+ model: {
3440
+ value: _vm.statusFilter,
3441
+ callback: function ($$v) {
3442
+ _vm.statusFilter = $$v;
3443
+ },
3444
+ expression: "statusFilter",
3445
+ },
3446
+ }),
3281
3447
  ],
3282
3448
  1
3283
3449
  ),
@@ -3287,6 +3453,59 @@
3287
3453
  },
3288
3454
  proxy: true,
3289
3455
  },
3456
+ {
3457
+ key: "cell(status)",
3458
+ fn: function (ref) {
3459
+ var row = ref.row;
3460
+ return [
3461
+ _c("div", { staticClass: "status" }, [
3462
+ _c("span", [
3463
+ _vm._v(_vm._s(_vm.getStatuses(_vm.t)[row.status])),
3464
+ ]),
3465
+ _vm._v(" "),
3466
+ row.status === "PUBLISHED" && row.archiveAt
3467
+ ? _c("span", [
3468
+ _vm._v(
3469
+ "\n " +
3470
+ _vm._s(_vm.t("blog:publishAtLabel")) +
3471
+ ": "
3472
+ ),
3473
+ _c("i", [
3474
+ _vm._v(
3475
+ _vm._s(
3476
+ _vm.formatDateTime(
3477
+ new Date(row.archiveAt),
3478
+ true
3479
+ )
3480
+ )
3481
+ ),
3482
+ ]),
3483
+ ])
3484
+ : _vm._e(),
3485
+ _vm._v(" "),
3486
+ row.status === "DRAFT" && row.publishAt
3487
+ ? _c("span", [
3488
+ _vm._v(
3489
+ "\n " +
3490
+ _vm._s(_vm.t("blog:publishAtLabel")) +
3491
+ ": "
3492
+ ),
3493
+ _c("i", [
3494
+ _vm._v(
3495
+ _vm._s(
3496
+ _vm.formatDateTime(
3497
+ new Date(row.publishAt),
3498
+ true
3499
+ )
3500
+ )
3501
+ ),
3502
+ ]),
3503
+ ])
3504
+ : _vm._e(),
3505
+ ]),
3506
+ ]
3507
+ },
3508
+ },
3290
3509
  {
3291
3510
  key: "cell(actions)",
3292
3511
  fn: function (ref) {
@@ -3359,11 +3578,11 @@
3359
3578
  /* style */
3360
3579
  const __vue_inject_styles__ = function (inject) {
3361
3580
  if (!inject) return
3362
- inject("data-v-6697ac14_0", { source: ".filters[data-v-6697ac14] {\n display: flex;\n margin: 0 -10px;\n}\n.filters[data-v-6697ac14]:not(:first-child) {\n margin-top: 10px;\n}\n.filters .filter[data-v-6697ac14] {\n padding: 10px 10px 0;\n width: 50%;\n margin: 0;\n}\n.date-label[data-v-6697ac14] {\n margin-bottom: 0.5rem;\n}\n.date-content[data-v-6697ac14] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n\n/*# sourceMappingURL=PostList.vue.map */", map: {"version":3,"sources":["/home/runner/work/tager-admin-blog/tager-admin-blog/src/views/Posts/PostList/PostList.vue","PostList.vue"],"names":[],"mappings":"AAqUA;EACA,aAAA;EACA,eAAA;ACpUA;ADsUA;EACA,gBAAA;ACpUA;ADuUA;EACA,oBAAA;EACA,UAAA;EACA,SAAA;ACrUA;ADyUA;EACA,qBAAA;ACtUA;ADyUA;EACA,aAAA;EACA,qCAAA;EACA,gBAAA;ACtUA;;AAEA,uCAAuC","file":"PostList.vue","sourcesContent":["<template>\n <page\n :title=\"pageTitle\"\n :header-buttons=\"[\n {\n text: $t('blog:newPost'),\n href: getBlogPostFormUrl({ postId: '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 :search-query=\"searchQuery\"\n :pagination=\"{\n pageNumber,\n pageCount,\n pageSize,\n disabled: isRowDataLoading,\n }\"\n data-table=\"blog-post\"\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=\"categoryFilter\"\n :options=\"categoryOptionList\"\n name=\"categoryFilter\"\n :searchable=\"true\"\n :label=\"$t('blog:category')\"\n class=\"filter\"\n />\n\n <form-field-multi-select\n v-if=\"isLangSpecific\"\n v-model=\"languageFilter\"\n :options=\"languageOptionList\"\n name=\"languageFilter\"\n :searchable=\"true\"\n :label=\"$t('blog:language')\"\n class=\"filter\"\n />\n\n <div class=\"filter\">\n <div class=\"date-label\">\n {{ $t('blog:dateOfPublication') }}\n </div>\n\n <div class=\"date-content\">\n <form-field\n v-model=\"fromDateFilter\"\n :label=\"$t('blog:From')\"\n name=\"fromDateFilter\"\n type=\"date\"\n :max=\"toDateFilter\"\n />\n\n <form-field\n v-model=\"toDateFilter\"\n :label=\"$t('blog:To')\"\n name=\"toDateFilter\"\n type=\"date\"\n :min=\"fromDateFilter\"\n />\n </div>\n </div>\n </div>\n </advanced-search>\n </template>\n\n <template v-slot:cell(actions)=\"{ row }\">\n <base-button\n variant=\"icon\"\n :title=\"$t('blog:edit')\"\n :disabled=\"isBusy(row.id)\"\n :href=\"getBlogPostFormUrl({ postId: row.id })\"\n >\n <svg-icon name=\"edit\" />\n </base-button>\n\n <base-button\n variant=\"icon\"\n :title=\"$t('blog:clone')\"\n :disabled=\"isBusy(row.id)\"\n @click=\"handleResourceClone(row.id)\"\n >\n <svg-icon name=\"contentCopy\" />\n </base-button>\n\n <base-button\n variant=\"icon\"\n :title=\"$t('blog: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 { computed, defineComponent, watch } 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 {\n Nullable,\n useResourceClone,\n useResourceDelete,\n} from '@tager/admin-services';\n\nimport { useFetchModuleConfig, useFetchCategories } from '../../../hooks';\nimport {\n clonePost,\n deleteBlogPost,\n getPosts,\n} from '../../../services/requests';\nimport { getBlogPostFormUrl } from '../../../constants/paths';\nimport {\n Category,\n Language,\n PostFull,\n PostShort,\n} from '../../../typings/model';\n\nimport { convertPostList, getPostTableColumnDefs } from './PostList.helpers';\nimport { useAdvancedSearch } from './hooks';\n\nexport default defineComponent({\n name: 'Posts',\n setup(props, context) {\n const { t } = useTranslation(context);\n\n const categoryId = computed<string>(() => {\n return Array.isArray(context.root.$route.query.category)\n ? context.root.$route.query.category[0] ?? ''\n : context.root.$route.query.category;\n });\n\n /** Fetch module config **/\n\n const {\n data: moduleConfig,\n loading: isModuleConfigLoading,\n } = useFetchModuleConfig({ context });\n\n const languageList = computed<Language[]>(\n () => moduleConfig.value?.languages ?? []\n );\n\n /** Fetch category list **/\n\n const {\n data: categoryList,\n loading: isCategoryListLoading,\n } = useFetchCategories({ context });\n\n const selectedCategory = computed<Nullable<Category>>(() =>\n categoryId.value\n ? categoryList.value.find(\n ({ id }) => String(id) === String(categoryId.value)\n ) ?? null\n : null\n );\n\n const pageTitle = computed<string>(() => {\n return selectedCategory.value\n ? `${context.root.$t('blog:postsByCategory')} \"${\n selectedCategory.value.name\n }\"`\n : context.root.$t('blog:posts');\n });\n\n /** Advanced search **/\n\n const {\n categoryFilter,\n categoryOptionList,\n languageFilter,\n languageOptionList,\n fromDateFilter,\n toDateFilter,\n filterParams,\n tags,\n tagRemovalHandler,\n } = useAdvancedSearch({\n context,\n categoryList,\n languageList,\n });\n\n const isLangSpecific = computed<boolean>(\n () => languageOptionList.value.length > 1\n );\n\n /** Fetch Post list **/\n\n const {\n fetchEntityList: fetchPostList,\n isLoading: isPostLoading,\n rowData: postList,\n errorMessage,\n searchQuery,\n handleChange,\n pageNumber,\n pageCount,\n pageSize,\n } = useDataTable<PostShort>({\n fetchEntityList: (params) =>\n getPosts({\n query: params.searchQuery,\n pageNumber: params.pageNumber,\n pageSize: params.pageSize,\n ...filterParams.value,\n }),\n initialValue: [],\n context,\n resourceName: 'Blog post list',\n pageSize: 100,\n });\n\n watch(filterParams, () => {\n if (isModuleConfigLoading.value || isCategoryListLoading.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 fetchPostList();\n }\n });\n\n const displayedPostList = computed<PostShort[]>(() =>\n convertPostList(\n postList.value,\n selectedCategory.value,\n moduleConfig.value?.languages ?? []\n )\n );\n\n const isRowDataLoading = computed<boolean>(\n () =>\n isCategoryListLoading.value ||\n isPostLoading.value ||\n isModuleConfigLoading.value\n );\n\n const { isDeleting, handleResourceDelete } = useResourceDelete({\n deleteResource: deleteBlogPost,\n resourceName: 'Post',\n onSuccess: fetchPostList,\n context,\n });\n\n const { isCloning, handleResourceClone } = useResourceClone({\n cloneResource: clonePost,\n confirmMessage: t('blog:cloneConfirm'),\n successMessage: t('blog:cloneSuccess'),\n failureMessage: t('blog:cloneFailure'),\n onSuccessRedirectTo: (data: PostFull) => `/blog/posts/${data.id}`,\n context,\n });\n\n function isBusy(postId: number): boolean {\n return isDeleting(postId) || isCloning(postId) || isRowDataLoading.value;\n }\n\n const columnDefs = computed<ColumnDefinition<PostShort>[]>(() =>\n getPostTableColumnDefs(moduleConfig.value, context.root.$t)\n );\n\n return {\n columnDefs,\n rowData: displayedPostList,\n handleResourceDelete,\n isDeleting,\n categoryList,\n isRowDataLoading,\n errorMessage,\n getBlogPostFormUrl,\n pageTitle,\n searchQuery,\n handleChange,\n pageNumber,\n pageCount,\n pageSize,\n\n // Advanced search\n categoryFilter,\n categoryOptionList,\n isLangSpecific,\n languageFilter,\n languageOptionList,\n fromDateFilter,\n toDateFilter,\n tags,\n tagRemovalHandler,\n\n // Clone\n handleResourceClone,\n isBusy,\n };\n },\n});\n</script>\n\n<style scoped 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\n.date-label {\n margin-bottom: 0.5rem;\n}\n\n.date-content {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\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.date-label {\n margin-bottom: 0.5rem;\n}\n\n.date-content {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n\n/*# sourceMappingURL=PostList.vue.map */"]}, media: undefined });
3581
+ inject("data-v-61f152be_0", { source: ".filters[data-v-61f152be] {\n display: flex;\n margin: 0 -10px;\n}\n.filters[data-v-61f152be]:not(:first-child) {\n margin-top: 10px;\n}\n.filters .filter[data-v-61f152be] {\n padding: 10px 10px 0;\n width: 50%;\n margin: 0;\n}\n.date-label[data-v-61f152be] {\n margin-bottom: 0.5rem;\n}\n.date-content[data-v-61f152be] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n.status span[data-v-61f152be]:first-child {\n display: block;\n}\n.status span[data-v-61f152be]:nth-child(2) {\n display: block;\n margin-top: 5px;\n font-size: 0.8rem;\n}\n.status span:nth-child(2) i[data-v-61f152be] {\n display: block;\n}\n\n/*# sourceMappingURL=PostList.vue.map */", map: {"version":3,"sources":["/home/runner/work/tager-admin-blog/tager-admin-blog/src/views/Posts/PostList/PostList.vue","PostList.vue"],"names":[],"mappings":"AAsWA;EACA,aAAA;EACA,eAAA;ACrWA;ADuWA;EACA,gBAAA;ACrWA;ADwWA;EACA,oBAAA;EACA,UAAA;EACA,SAAA;ACtWA;AD0WA;EACA,qBAAA;ACvWA;AD0WA;EACA,aAAA;EACA,qCAAA;EACA,gBAAA;ACvWA;AD2WA;EACA,cAAA;ACxWA;AD2WA;EACA,cAAA;EACA,eAAA;EACA,iBAAA;ACzWA;AD2WA;EACA,cAAA;ACzWA;;AAEA,uCAAuC","file":"PostList.vue","sourcesContent":["<template>\n <page\n :title='pageTitle'\n :header-buttons=\"[\n {\n text: $t('blog:newPost'),\n href: getBlogPostFormUrl({ postId: '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 :search-query='searchQuery'\n :pagination='{\n pageNumber,\n pageCount,\n pageSize,\n disabled: isRowDataLoading,\n }'\n data-table='blog-post'\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='categoryFilter'\n :options='categoryOptionList'\n name='categoryFilter'\n :searchable='true'\n :label=\"$t('blog:category')\"\n class='filter'\n />\n\n <form-field-multi-select\n v-if='isLangSpecific'\n v-model='languageFilter'\n :options='languageOptionList'\n name='languageFilter'\n :searchable='true'\n :label=\"$t('blog:language')\"\n class='filter'\n />\n\n <div class='filter'>\n <div class='date-label'>\n {{ $t('blog:dateOfPublication') }}\n </div>\n\n <div class='date-content'>\n <form-field\n v-model='fromDateFilter'\n :label=\"$t('blog:From')\"\n name='fromDateFilter'\n type='date'\n :max='toDateFilter'\n />\n\n <form-field\n v-model='toDateFilter'\n :label=\"$t('blog:To')\"\n name='toDateFilter'\n type='date'\n :min='fromDateFilter'\n />\n </div>\n </div>\n\n <form-field-multi-select\n v-model='statusFilter'\n :options='statusOptionList'\n name='statusFilter'\n :searchable='true'\n :label=\"$t('blog:status')\"\n class='filter'\n />\n </div>\n </advanced-search>\n </template>\n\n <template v-slot:cell(status)='{ row }'>\n <div class='status'>\n <span>{{ getStatuses(t)[row.status] }}</span>\n <span v-if='row.status === \"PUBLISHED\" && row.archiveAt'>\n {{ t('blog:publishAtLabel') }}: <i>{{ formatDateTime(new Date(row.archiveAt), true) }}</i>\n </span>\n <span v-if='row.status === \"DRAFT\" && row.publishAt'>\n {{ t('blog:publishAtLabel') }}: <i>{{ formatDateTime(new Date(row.publishAt), true) }}</i>\n </span>\n </div>\n </template>\n\n <template v-slot:cell(actions)='{ row }'>\n <base-button\n variant='icon'\n :title=\"$t('blog:edit')\"\n :disabled='isBusy(row.id)'\n :href='getBlogPostFormUrl({ postId: row.id })'\n >\n <svg-icon name='edit' />\n </base-button>\n\n <base-button\n variant='icon'\n :title=\"$t('blog:clone')\"\n :disabled='isBusy(row.id)'\n @click='handleResourceClone(row.id)'\n >\n <svg-icon name='contentCopy' />\n </base-button>\n\n <base-button\n variant='icon'\n :title=\"$t('blog: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 { computed, defineComponent, watch } from '@vue/composition-api';\nimport isEqual from 'lodash.isequal';\nimport pick from 'lodash.pick';\n\nimport {\n ColumnDefinition,\n OptionType,\n useDataTable,\n useTranslation,\n formatDateTime\n} from '@tager/admin-ui';\nimport {\n Nullable,\n useResourceClone,\n useResourceDelete\n} from '@tager/admin-services';\n\nimport { useFetchModuleConfig, useFetchCategories } from '../../../hooks';\nimport {\n clonePost,\n deleteBlogPost,\n getPosts\n} from '../../../services/requests';\nimport { getBlogPostFormUrl } from '../../../constants/paths';\nimport {\n Category,\n Language,\n PostFull,\n PostShort\n} from '../../../typings/model';\nimport { getStatusOptions } from '../PostForm/PostForm.helpers';\n\nimport { convertPostList, getPostTableColumnDefs, getStatuses } from './PostList.helpers';\nimport { useAdvancedSearch } from './hooks';\n\nexport default defineComponent({\n name: 'Posts',\n setup(props, context) {\n const { t } = useTranslation(context);\n\n const categoryId = computed<string>(() => {\n return Array.isArray(context.root.$route.query.category)\n ? context.root.$route.query.category[0] ?? ''\n : context.root.$route.query.category;\n });\n\n const statusOptionList = computed<OptionType[]>(() => getStatusOptions(t));\n\n /** Fetch module config **/\n\n const {\n data: moduleConfig,\n loading: isModuleConfigLoading\n } = useFetchModuleConfig({ context });\n\n const languageList = computed<Language[]>(\n () => moduleConfig.value?.languages ?? []\n );\n\n /** Fetch category list **/\n\n const {\n data: categoryList,\n loading: isCategoryListLoading\n } = useFetchCategories({ context });\n\n const selectedCategory = computed<Nullable<Category>>(() =>\n categoryId.value\n ? categoryList.value.find(\n ({ id }) => String(id) === String(categoryId.value)\n ) ?? null\n : null\n );\n\n const pageTitle = computed<string>(() => {\n return selectedCategory.value\n ? `${context.root.$t('blog:postsByCategory')} \"${\n selectedCategory.value.name\n }\"`\n : context.root.$t('blog:posts');\n });\n\n /** Advanced search **/\n\n const {\n categoryFilter,\n categoryOptionList,\n languageFilter,\n languageOptionList,\n fromDateFilter,\n toDateFilter,\n filterParams,\n tags,\n tagRemovalHandler,\n statusFilter\n } = useAdvancedSearch({\n context,\n categoryList,\n languageList,\n statusOptionList\n });\n\n const isLangSpecific = computed<boolean>(\n () => languageOptionList.value.length > 1\n );\n\n /** Fetch Post list **/\n\n const {\n fetchEntityList: fetchPostList,\n isLoading: isPostLoading,\n rowData: postList,\n errorMessage,\n searchQuery,\n handleChange,\n pageNumber,\n pageCount,\n pageSize\n } = useDataTable<PostShort>({\n fetchEntityList: (params) =>\n getPosts({\n query: params.searchQuery,\n pageNumber: params.pageNumber,\n pageSize: params.pageSize,\n ...filterParams.value\n }),\n initialValue: [],\n context,\n resourceName: 'Blog post list',\n pageSize: 100\n });\n\n watch(filterParams, () => {\n if (isModuleConfigLoading.value || isCategoryListLoading.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 fetchPostList();\n }\n });\n\n const displayedPostList = computed<PostShort[]>(() =>\n convertPostList(\n postList.value,\n selectedCategory.value,\n moduleConfig.value?.languages ?? []\n )\n );\n\n const isRowDataLoading = computed<boolean>(\n () =>\n isCategoryListLoading.value ||\n isPostLoading.value ||\n isModuleConfigLoading.value\n );\n\n const { isDeleting, handleResourceDelete } = useResourceDelete({\n deleteResource: deleteBlogPost,\n resourceName: 'Post',\n onSuccess: fetchPostList,\n context\n });\n\n const { isCloning, handleResourceClone } = useResourceClone({\n cloneResource: clonePost,\n confirmMessage: t('blog:cloneConfirm'),\n successMessage: t('blog:cloneSuccess'),\n failureMessage: t('blog:cloneFailure'),\n onSuccessRedirectTo: (data: PostFull) => `/blog/posts/${data.id}`,\n context\n });\n\n function isBusy(postId: number): boolean {\n return isDeleting(postId) || isCloning(postId) || isRowDataLoading.value;\n }\n\n const columnDefs = computed<ColumnDefinition<PostShort>[]>(() =>\n getPostTableColumnDefs(moduleConfig.value, context.root.$t)\n );\n\n return {\n t,\n formatDateTime,\n columnDefs,\n rowData: displayedPostList,\n handleResourceDelete,\n isDeleting,\n categoryList,\n isRowDataLoading,\n errorMessage,\n getBlogPostFormUrl,\n pageTitle,\n searchQuery,\n handleChange,\n pageNumber,\n pageCount,\n pageSize,\n\n // Advanced search\n categoryFilter,\n categoryOptionList,\n isLangSpecific,\n languageFilter,\n languageOptionList,\n fromDateFilter,\n toDateFilter,\n statusFilter,\n statusOptionList,\n tags,\n tagRemovalHandler,\n getStatuses,\n\n // Clone\n handleResourceClone,\n isBusy\n };\n }\n});\n</script>\n\n<style scoped 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\n.date-label {\n margin-bottom: 0.5rem;\n}\n\n.date-content {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n\n.status {\n span:first-child {\n display: block;\n }\n\n span:nth-child(2) {\n display: block;\n margin-top: 5px;\n font-size: 0.8rem;\n\n i {\n display: block;\n }\n }\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.date-label {\n margin-bottom: 0.5rem;\n}\n\n.date-content {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n column-gap: 10px;\n}\n\n.status span:first-child {\n display: block;\n}\n.status span:nth-child(2) {\n display: block;\n margin-top: 5px;\n font-size: 0.8rem;\n}\n.status span:nth-child(2) i {\n display: block;\n}\n\n/*# sourceMappingURL=PostList.vue.map */"]}, media: undefined });
3363
3582
 
3364
3583
  };
3365
3584
  /* scoped */
3366
- const __vue_scope_id__ = "data-v-6697ac14";
3585
+ const __vue_scope_id__ = "data-v-61f152be";
3367
3586
  /* module identifier */
3368
3587
  const __vue_module_identifier__ = undefined;
3369
3588
  /* functional template */
@@ -3387,98 +3606,6 @@
3387
3606
  undefined
3388
3607
  );
3389
3608
 
3390
- function convertPostToFormValues(post, languageOptionList, postOptionList, additionalFieldList) {
3391
- var _a, _b;
3392
- if (!post) {
3393
- return {
3394
- title: '',
3395
- excerpt: '',
3396
- body: '',
3397
- datetime: '',
3398
- coverImage: null,
3399
- image: null,
3400
- imageMobile: null,
3401
- pageTitle: '',
3402
- pageDescription: '',
3403
- openGraphImage: null,
3404
- urlAlias: '',
3405
- categories: [],
3406
- language: null,
3407
- relatedPosts: [],
3408
- tags: '',
3409
- additionalFields: additionalFieldList.map((fieldConfig) => adminDynamicField.universalFieldUtils.createFormField(fieldConfig, null)),
3410
- };
3411
- }
3412
- const currentLangOption = languageOptionList.find((option) => option.value === post.language);
3413
- const selectedPostOptionList = postOptionList.filter((option) => post.relatedPosts.some((relatedPost) => relatedPost.id === option.value));
3414
- return {
3415
- title: post.title,
3416
- excerpt: post.excerpt,
3417
- body: post.body,
3418
- datetime: post.datetime ? post.datetime.substr(0, 10) : '',
3419
- coverImage: post.coverImage
3420
- ? { id: adminServices.createId(), file: post.coverImage }
3421
- : null,
3422
- image: post.image ? { id: adminServices.createId(), file: post.image } : null,
3423
- imageMobile: post.imageMobile
3424
- ? { id: adminServices.createId(), file: post.imageMobile }
3425
- : null,
3426
- pageTitle: (_a = post.pageTitle) !== null && _a !== void 0 ? _a : '',
3427
- pageDescription: (_b = post.pageDescription) !== null && _b !== void 0 ? _b : '',
3428
- openGraphImage: post.openGraphImage
3429
- ? { id: adminServices.createId(), file: post.openGraphImage }
3430
- : null,
3431
- urlAlias: post.urlAlias,
3432
- categories: post.categories.map((category) => ({
3433
- value: category.id,
3434
- label: category.name,
3435
- })),
3436
- language: currentLangOption !== null && currentLangOption !== void 0 ? currentLangOption : null,
3437
- relatedPosts: selectedPostOptionList,
3438
- tags: post.tags.join(','),
3439
- additionalFields: additionalFieldList.map((fieldConfig, index) => {
3440
- const postAdditionalField = post.additionalFields.find((item) => item.name === fieldConfig.name);
3441
- return adminDynamicField.universalFieldUtils.createFormField(fieldConfig, postAdditionalField === null || postAdditionalField === void 0 ? void 0 : postAdditionalField.value);
3442
- }),
3443
- };
3444
- }
3445
- function convertFormValuesToCreationPayload(values) {
3446
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3447
- return {
3448
- title: values.title,
3449
- excerpt: values.excerpt,
3450
- urlAlias: values.urlAlias,
3451
- body: values.body,
3452
- datetime: values.datetime,
3453
- coverImage: (_b = (_a = values.coverImage) === null || _a === void 0 ? void 0 : _a.file.id) !== null && _b !== void 0 ? _b : null,
3454
- image: (_d = (_c = values.image) === null || _c === void 0 ? void 0 : _c.file.id) !== null && _d !== void 0 ? _d : null,
3455
- imageMobile: (_f = (_e = values.imageMobile) === null || _e === void 0 ? void 0 : _e.file.id) !== null && _f !== void 0 ? _f : null,
3456
- pageTitle: values.pageTitle,
3457
- pageDescription: values.pageDescription,
3458
- openGraphImage: (_h = (_g = values.openGraphImage) === null || _g === void 0 ? void 0 : _g.file.id) !== null && _h !== void 0 ? _h : null,
3459
- status: 'PUBLISHED',
3460
- categories: values.categories.map((option) => option.value),
3461
- language: (_k = (_j = values.language) === null || _j === void 0 ? void 0 : _j.value) !== null && _k !== void 0 ? _k : null,
3462
- relatedPosts: values.relatedPosts.map((relatedPostOption) => relatedPostOption.value),
3463
- tags: values.tags.split(',').filter((tag) => tag.trim().length > 0),
3464
- additionalFields: values.additionalFields.map((field) => ({
3465
- name: field.config.name,
3466
- value: adminDynamicField.universalFieldUtils.getOutgoingValue(field),
3467
- })),
3468
- };
3469
- }
3470
- function convertFormValuesToUpdatePayload(values) {
3471
- return Object.assign(Object.assign({}, convertFormValuesToCreationPayload(values)), { urlAlias: values.urlAlias });
3472
- }
3473
- function convertCategoryListToOptions(categoryList, languageId) {
3474
- return categoryList
3475
- .filter(({ language }) => (languageId ? language === languageId : true))
3476
- .map(({ id, name, depth }) => ({
3477
- value: id,
3478
- label: getNameWithDepth(name, depth),
3479
- }));
3480
- }
3481
-
3482
3609
  var script$1 = compositionApi.defineComponent({
3483
3610
  name: 'BlogPostForm',
3484
3611
  components: { DynamicField: adminDynamicField.DynamicField, ShortCodeConstructor: adminUi.ShortCodeConstructor, FormFooter: adminUi.FormFooter },
@@ -3487,22 +3614,23 @@
3487
3614
  const postId = compositionApi.computed(() => context.root.$route.params.postId);
3488
3615
  const isCreation = compositionApi.computed(() => postId.value === 'create');
3489
3616
  const urlAliasChanged = compositionApi.ref(false);
3617
+ const statusOptions = compositionApi.computed(() => getStatusOptions(context.root.$t));
3490
3618
  /** Fetch module config **/
3491
- const { data: moduleConfig, loading: isModuleConfigLoading, } = useFetchModuleConfig({ context });
3619
+ const { data: moduleConfig, loading: isModuleConfigLoading } = useFetchModuleConfig({ context });
3492
3620
  const languageList = compositionApi.computed(() => { var _a, _b; return (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.languages) !== null && _b !== void 0 ? _b : []; });
3493
3621
  const languageOptionList = compositionApi.computed(() => languageList.value.map(({ id, name }) => ({
3494
3622
  value: id,
3495
- label: name,
3623
+ label: name
3496
3624
  })));
3497
3625
  const isLangSpecific = compositionApi.computed(() => languageOptionList.value.length > 0);
3498
3626
  /** Fetch category list */
3499
- const { data: categoryList, loading: isCategoryListLoading, } = useFetchCategories({ context });
3627
+ const { data: categoryList, loading: isCategoryListLoading } = useFetchCategories({ context });
3500
3628
  /** Fetch Post */
3501
3629
  const [fetchPost, { data: post, loading: isPostLoading }] = adminServices.useResource({
3502
3630
  fetchResource: () => getPost(postId.value),
3503
3631
  initialValue: null,
3504
3632
  context,
3505
- resourceName: 'Post',
3633
+ resourceName: 'Post'
3506
3634
  });
3507
3635
  compositionApi.onMounted(() => {
3508
3636
  if (isCreation.value)
@@ -3516,21 +3644,21 @@
3516
3644
  });
3517
3645
  /** Fetch post list */
3518
3646
  const { data: postList, loading: isPostListLoading } = useFetchPosts({
3519
- context,
3647
+ context
3520
3648
  });
3521
3649
  const postOptionList = compositionApi.computed(() => postList.value
3522
3650
  .filter((relatedPost) => { var _a; return relatedPost.id !== ((_a = post.value) === null || _a === void 0 ? void 0 : _a.id); })
3523
3651
  .map((post) => ({
3524
3652
  value: post.id,
3525
- label: post.title,
3653
+ label: post.title
3526
3654
  })));
3527
3655
  /** Form State **/
3528
3656
  const isSubmitting = compositionApi.ref(false);
3529
- const values = compositionApi.ref(convertPostToFormValues(post.value, languageOptionList.value, postOptionList.value, (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : []));
3657
+ const values = compositionApi.ref(convertPostToFormValues(post.value, languageOptionList.value, postOptionList.value, (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : [], statusOptions.value));
3530
3658
  const errors = compositionApi.ref({});
3531
3659
  compositionApi.watch([post, languageOptionList, postOptionList, moduleConfig], () => {
3532
3660
  var _a, _b;
3533
- values.value = convertPostToFormValues(post.value, languageOptionList.value, postOptionList.value, (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : []);
3661
+ values.value = convertPostToFormValues(post.value, languageOptionList.value, postOptionList.value, (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : [], statusOptions.value);
3534
3662
  });
3535
3663
  function submitForm(event) {
3536
3664
  isSubmitting.value = true;
@@ -3555,14 +3683,14 @@
3555
3683
  }
3556
3684
  }
3557
3685
  if (event.type === 'create_create-another') {
3558
- values.value = convertPostToFormValues(null, languageOptionList.value, postOptionList.value, (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : []);
3686
+ values.value = convertPostToFormValues(null, languageOptionList.value, postOptionList.value, (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : [], statusOptions.value);
3559
3687
  }
3560
3688
  context.root.$toast({
3561
3689
  variant: 'success',
3562
3690
  title: context.root.$t('blog:success'),
3563
3691
  body: isCreation.value
3564
3692
  ? context.root.$t('blog:blogPostWasSuccessfullyCreated')
3565
- : context.root.$t('blog:blogPostWasSuccessfullyUpdated'),
3693
+ : context.root.$t('blog:blogPostWasSuccessfullyUpdated')
3566
3694
  });
3567
3695
  })
3568
3696
  .catch((error) => {
@@ -3573,7 +3701,7 @@
3573
3701
  title: context.root.$t('blog:error'),
3574
3702
  body: isCreation.value
3575
3703
  ? context.root.$t('blog:blogPostCreationWasFailed')
3576
- : context.root.$t('blog:blogPostUpdateWasFailed'),
3704
+ : context.root.$t('blog:blogPostUpdateWasFailed')
3577
3705
  });
3578
3706
  })
3579
3707
  .finally(() => {
@@ -3626,24 +3754,24 @@
3626
3754
  'urlAlias',
3627
3755
  'excerpt',
3628
3756
  'body',
3629
- 'date',
3630
- ]),
3757
+ 'date'
3758
+ ])
3631
3759
  },
3632
3760
  {
3633
3761
  id: 'images',
3634
3762
  label: context.root.$t('blog:images'),
3635
- hasErrors: hasErrors(['coverImage', 'image']),
3763
+ hasErrors: hasErrors(['coverImage', 'image'])
3636
3764
  },
3637
3765
  {
3638
3766
  id: 'relations',
3639
3767
  label: context.root.$t('blog:relations'),
3640
- hasErrors: hasErrors(['categories', 'relatedPosts', 'tags']),
3768
+ hasErrors: hasErrors(['categories', 'relatedPosts', 'tags'])
3641
3769
  },
3642
3770
  values.value.additionalFields.length > 0
3643
3771
  ? {
3644
3772
  id: 'additional',
3645
3773
  label: context.root.$t('blog:additionalFields'),
3646
- hasErrors: hasErrors([]),
3774
+ hasErrors: hasErrors([])
3647
3775
  }
3648
3776
  : null,
3649
3777
  {
@@ -3652,9 +3780,9 @@
3652
3780
  hasErrors: hasErrors([
3653
3781
  'pageTitle',
3654
3782
  'pageDescription',
3655
- 'openGraphImage',
3656
- ]),
3657
- },
3783
+ 'openGraphImage'
3784
+ ])
3785
+ }
3658
3786
  ].filter(adminServices.isNotNullish);
3659
3787
  });
3660
3788
  const selectedTabId = compositionApi.ref(tabList.value[0].id);
@@ -3663,17 +3791,17 @@
3663
3791
  ? {
3664
3792
  text: context.root.$t('blog:viewPost'),
3665
3793
  href: process.env.VUE_APP_WEBSITE_URL + post.value.url,
3666
- target: '_blank',
3794
+ target: '_blank'
3667
3795
  }
3668
- : null,
3796
+ : null
3669
3797
  ].filter(adminServices.isNotNullish));
3670
- function handleSeoFieldGroupChange({ title, description, image, }) {
3798
+ function handleSeoFieldGroupChange({ title, description, image }) {
3671
3799
  values.value.pageTitle = title;
3672
3800
  values.value.pageDescription = description;
3673
3801
  values.value.openGraphImage = image;
3674
3802
  }
3675
3803
  function handleTitleChange(value) {
3676
- if (urlAliasChanged.value === false) {
3804
+ if (isCreation.value && urlAliasChanged.value === false) {
3677
3805
  values.value.urlAlias = adminServices.urlTranslit(value);
3678
3806
  }
3679
3807
  }
@@ -3703,7 +3831,7 @@
3703
3831
  }
3704
3832
  const newSelectedOption = {
3705
3833
  value: foundSelectedCategory.id,
3706
- label: foundSelectedCategory.name,
3834
+ label: foundSelectedCategory.name
3707
3835
  };
3708
3836
  if (!newSelectedOptions.some(({ value }) => value === newSelectedOption.value)) {
3709
3837
  newSelectedOptions.push(newSelectedOption);
@@ -3740,8 +3868,9 @@
3740
3868
  handleAliasChange,
3741
3869
  urlAliasTemplate,
3742
3870
  handleCategoriesChange,
3871
+ statusOptions
3743
3872
  };
3744
- },
3873
+ }
3745
3874
  });
3746
3875
 
3747
3876
  /* script */
@@ -3848,6 +3977,114 @@
3848
3977
  },
3849
3978
  }),
3850
3979
  _vm._v(" "),
3980
+ _c("div", { staticClass: "status" }, [
3981
+ _c(
3982
+ "div",
3983
+ { staticClass: "status-value" },
3984
+ [
3985
+ _c("form-field-select", {
3986
+ attrs: {
3987
+ name: "status",
3988
+ error: _vm.errors.status,
3989
+ label: _vm.$t("blog:status"),
3990
+ "no-options-message": _vm.$t(
3991
+ "blog:noTemplates"
3992
+ ),
3993
+ options: _vm.statusOptions,
3994
+ },
3995
+ model: {
3996
+ value: _vm.values.status,
3997
+ callback: function ($$v) {
3998
+ _vm.$set(_vm.values, "status", $$v);
3999
+ },
4000
+ expression: "values.status",
4001
+ },
4002
+ }),
4003
+ ],
4004
+ 1
4005
+ ),
4006
+ _vm._v(" "),
4007
+ _vm.values.status.value === "PUBLISHED" ||
4008
+ _vm.values.status.value === "DRAFT"
4009
+ ? _c(
4010
+ "div",
4011
+ { staticClass: "status-checkbox" },
4012
+ [
4013
+ _c("form-field-checkbox", {
4014
+ attrs: {
4015
+ name: "statusDateEnabled",
4016
+ label: _vm.$t(
4017
+ _vm.values.status.value === "PUBLISHED"
4018
+ ? "blog:scheduleArchive"
4019
+ : "blog:schedulePublish"
4020
+ ),
4021
+ error: _vm.errors.status,
4022
+ },
4023
+ model: {
4024
+ value: _vm.values.statusDateEnabled,
4025
+ callback: function ($$v) {
4026
+ _vm.$set(
4027
+ _vm.values,
4028
+ "statusDateEnabled",
4029
+ $$v
4030
+ );
4031
+ },
4032
+ expression: "values.statusDateEnabled",
4033
+ },
4034
+ }),
4035
+ ],
4036
+ 1
4037
+ )
4038
+ : _vm._e(),
4039
+ _vm._v(" "),
4040
+ _vm.values.statusDateEnabled &&
4041
+ (_vm.values.status.value === "PUBLISHED" ||
4042
+ _vm.values.status.value === "DRAFT")
4043
+ ? _c(
4044
+ "div",
4045
+ { staticClass: "status-date" },
4046
+ [
4047
+ _c("form-field", {
4048
+ attrs: {
4049
+ name: "statusDate",
4050
+ type: "date",
4051
+ label: _vm.$t(
4052
+ _vm.values.status.value === "PUBLISHED"
4053
+ ? "blog:archiveAt"
4054
+ : "blog:publishAt"
4055
+ ),
4056
+ error: _vm.errors.statusDate,
4057
+ },
4058
+ model: {
4059
+ value: _vm.values.statusDate,
4060
+ callback: function ($$v) {
4061
+ _vm.$set(_vm.values, "statusDate", $$v);
4062
+ },
4063
+ expression: "values.statusDate",
4064
+ },
4065
+ }),
4066
+ ],
4067
+ 1
4068
+ )
4069
+ : _vm._e(),
4070
+ ]),
4071
+ _vm._v(" "),
4072
+ _c("form-field", {
4073
+ attrs: {
4074
+ name: "datetime",
4075
+ label: _vm.$t("blog:date"),
4076
+ type: "date",
4077
+ error: _vm.errors.datetime,
4078
+ },
4079
+ model: {
4080
+ value: _vm.values.datetime,
4081
+ callback: function ($$v) {
4082
+ _vm.$set(_vm.values, "datetime", $$v);
4083
+ },
4084
+ expression: "values.datetime",
4085
+ },
4086
+ }),
4087
+ _vm._v(" "),
3851
4088
  _c("form-field", {
3852
4089
  attrs: {
3853
4090
  name: "excerpt",
@@ -3888,22 +4125,6 @@
3888
4125
  : [],
3889
4126
  },
3890
4127
  }),
3891
- _vm._v(" "),
3892
- _c("form-field", {
3893
- attrs: {
3894
- name: "datetime",
3895
- label: _vm.$t("blog:date"),
3896
- type: "date",
3897
- error: _vm.errors.datetime,
3898
- },
3899
- model: {
3900
- value: _vm.values.datetime,
3901
- callback: function ($$v) {
3902
- _vm.$set(_vm.values, "datetime", $$v);
3903
- },
3904
- expression: "values.datetime",
3905
- },
3906
- }),
3907
4128
  ]
3908
4129
  : _vm._e(),
3909
4130
  _vm._v(" "),
@@ -4074,15 +4295,17 @@
4074
4295
  __vue_render__$1._withStripped = true;
4075
4296
 
4076
4297
  /* style */
4077
- const __vue_inject_styles__$1 = undefined;
4298
+ const __vue_inject_styles__$1 = function (inject) {
4299
+ if (!inject) return
4300
+ inject("data-v-50f3750d_0", { source: ".status[data-v-50f3750d] {\n display: flex;\n align-items: flex-end;\n}\n.status-value[data-v-50f3750d] {\n flex-basis: 50%;\n}\n.status-checkbox[data-v-50f3750d] {\n margin-left: 20px;\n padding-bottom: 8px;\n}\n.status-date[data-v-50f3750d] {\n margin-left: 20px;\n flex: 1 1 1px;\n}\n\n/*# sourceMappingURL=PostForm.vue.map */", map: {"version":3,"sources":["/home/runner/work/tager-admin-blog/tager-admin-blog/src/views/Posts/PostForm/PostForm.vue","PostForm.vue"],"names":[],"mappings":"AA2nBA;EACA,aAAA;EACA,qBAAA;AC1nBA;AD6nBA;EACA,eAAA;AC1nBA;AD6nBA;EACA,iBAAA;EACA,mBAAA;AC1nBA;AD6nBA;EACA,iBAAA;EACA,aAAA;AC1nBA;;AAEA,uCAAuC","file":"PostForm.vue","sourcesContent":["<template>\n <page\n :title=\"isCreation ? $t('blog:createPost') : $t('blog:updatePost')\"\n :is-content-loading='isContentLoading'\n :header-buttons='headerButtonList'\n :footer='{\n backHref: postListUrl,\n onSubmit: submitForm,\n isSubmitting: isSubmitting,\n }'\n >\n <template v-slot:content>\n <form novalidate @submit.prevent='submitForm'>\n <tab-list\n :tab-list='tabList'\n :selected-tab-id='selectedTabId'\n @tab:update='selectedTabId = $event.tabId'\n />\n\n <template v-if=\"selectedTabId === 'common'\">\n\n <form-field-select\n v-if='isCreation && isLangSpecific'\n v-model='values.language'\n name='language'\n :label=\"$t('blog:language')\"\n :options='languageOptionList'\n :error='errors.language'\n />\n\n <form-field\n v-model='values.title'\n name='title'\n :label=\"$t('blog:title')\"\n :error='errors.title'\n @input='handleTitleChange'\n />\n\n <form-field-url-alias-input\n id='urlAlias'\n v-model='values.urlAlias'\n name='urlAlias'\n :label=\"$t('blog:link')\"\n :url-template='urlAliasTemplate'\n :error='errors.urlAlias'\n @change='handleAliasChange'\n />\n\n <div class='status'>\n <div class='status-value'>\n <form-field-select\n v-model='values.status'\n name='status'\n :error='errors.status'\n :label=\"$t('blog:status')\"\n :no-options-message=\"$t('blog:noTemplates')\"\n :options='statusOptions'\n />\n </div>\n <div class='status-checkbox' v-if='values.status.value === \"PUBLISHED\" || values.status.value === \"DRAFT\"'>\n <form-field-checkbox\n v-model='values.statusDateEnabled'\n name='statusDateEnabled'\n :label=\"$t(values.status.value === 'PUBLISHED' ? 'blog:scheduleArchive' : 'blog:schedulePublish')\"\n :error='errors.status'\n />\n </div>\n <div class='status-date'\n v-if='values.statusDateEnabled && (values.status.value === \"PUBLISHED\" || values.status.value === \"DRAFT\")'>\n <form-field\n v-model='values.statusDate'\n name='statusDate'\n type='date'\n :label=\"$t(values.status.value === 'PUBLISHED' ? 'blog:archiveAt' : 'blog:publishAt')\"\n :error='errors.statusDate'\n />\n </div>\n </div>\n\n <form-field\n v-model='values.datetime'\n name='datetime'\n :label=\"$t('blog:date')\"\n type='date'\n :error='errors.datetime'\n />\n\n <form-field\n v-model='values.excerpt'\n name='excerpt'\n :label=\"$t('blog:excerpt')\"\n type='textarea'\n :error='errors.excerpt'\n />\n\n <form-field-rich-text-input\n v-model='values.body'\n name='body'\n :label=\"$t('blog:body')\"\n :error='errors.body'\n :get-upload-adapter-options='getUploadAdapterOptions'\n />\n\n <ShortCodeConstructor\n :short-code-config-list='\n moduleConfig ? moduleConfig.shortcodes : []\n '\n />\n </template>\n\n <template v-if=\"selectedTabId === 'images'\">\n <form-field-file-input\n v-model='values.coverImage'\n :label=\"$t('blog:coverImage')\"\n name='coverImage'\n file-type='image'\n :scenario='moduleConfig ? moduleConfig.fileScenarios.cover : null'\n />\n\n <form-field-file-input\n v-model='values.image'\n name='image'\n :label=\"$t('blog:innerImage')\"\n file-type='image'\n :scenario='moduleConfig ? moduleConfig.fileScenarios.image : null'\n />\n\n <form-field-file-input\n v-model='values.imageMobile'\n name='imageMobile'\n :label=\"$t('blog:innerImageMobile')\"\n file-type='image'\n :scenario='\n moduleConfig ? moduleConfig.fileScenarios.imageMobile : null\n '\n />\n </template>\n\n <template v-if=\"selectedTabId === 'relations'\">\n <form-field\n v-model='values.tags'\n name='tags'\n :label=\"$t('blog:tags')\"\n :error='errors.tags'\n />\n\n <form-field-multi-select\n :selected-options='values.categories'\n name='categories'\n :label=\"$t('blog:categories')\"\n :options='categoryOptionList'\n :error='errors.categories'\n @change='handleCategoriesChange'\n />\n\n <form-field-multi-select\n v-model='values.relatedPosts'\n name='relatedPosts'\n :label=\"$t('blog:relatedPosts')\"\n :options='postOptionList'\n :error='errors.relatedPosts'\n :searchable='true'\n />\n </template>\n\n <template v-if=\"selectedTabId === 'additional'\">\n <DynamicField\n v-for='field of values.additionalFields'\n :key='field.name'\n :field='field'\n />\n </template>\n\n <template v-if=\"selectedTabId === 'seo'\">\n <seo-field-group\n :title='values.pageTitle'\n :title-error-message='errors.pageTitle'\n :title-label=\"$t('blog:pageTitle')\"\n :description='values.pageDescription'\n :description-error-message='errors.pageDescription'\n :description-label=\"$t('blog:pageDescription')\"\n :image='values.openGraphImage'\n :image-error-message='errors.openGraphImage'\n :image-label=\"$t('blog:openGraphImage')\"\n :image-scenario='\n moduleConfig ? moduleConfig.fileScenarios.openGraph : null\n '\n @change='handleSeoFieldGroupChange'\n />\n </template>\n </form>\n </template>\n\n <template v-slot:footer>\n <FormFooter\n :back-href='postListUrl'\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 onMounted,\n ref,\n watch\n} from '@vue/composition-api';\n\nimport {\n convertRequestErrorToMap,\n isNotNullish,\n Nullable,\n useResource,\n urlTranslit\n} from '@tager/admin-services';\nimport {\n createTabErrorFinder,\n OptionType,\n TabType,\n ShortCodeConstructor,\n SeoChangeEvent,\n FormFooter,\n TagerFormSubmitEvent\n} from '@tager/admin-ui';\nimport { DynamicField } from '@tager/admin-dynamic-field';\n\nimport {\n getBlogPostFormUrl,\n getBlogPostListUrl\n} from '../../../constants/paths';\nimport {\n createBlogPost,\n getPost,\n updateBlogPost\n} from '../../../services/requests';\nimport { Language, PostFull } from '../../../typings/model';\nimport {\n useFetchModuleConfig,\n useFetchCategories,\n useFetchPosts\n} from '../../../hooks';\n\nimport {\n convertCategoryListToOptions,\n convertFormValuesToCreationPayload,\n convertFormValuesToUpdatePayload,\n convertPostToFormValues,\n FormValues,\n getStatusOptions\n} from './PostForm.helpers';\n\nexport default defineComponent({\n name: 'BlogPostForm',\n components: { DynamicField, ShortCodeConstructor, FormFooter },\n setup(props, context) {\n const postId = computed<string>(() => context.root.$route.params.postId);\n const isCreation = computed<boolean>(() => postId.value === 'create');\n\n const urlAliasChanged = ref<boolean>(false);\n\n const statusOptions = computed<OptionType[]>(() =>\n getStatusOptions(context.root.$t)\n );\n\n /** Fetch module config **/\n\n const {\n data: moduleConfig,\n loading: isModuleConfigLoading\n } = useFetchModuleConfig({ context });\n\n const languageList = computed<Language[]>(\n () => moduleConfig.value?.languages ?? []\n );\n\n const languageOptionList = computed<OptionType[]>(() =>\n languageList.value.map(({ id, name }) => ({\n value: id,\n label: name\n }))\n );\n\n const isLangSpecific = computed(() => languageOptionList.value.length > 0);\n\n /** Fetch category list */\n\n const {\n data: categoryList,\n loading: isCategoryListLoading\n } = useFetchCategories({ context });\n\n /** Fetch Post */\n\n const [fetchPost, { data: post, loading: isPostLoading }] = useResource<Nullable<PostFull>>({\n fetchResource: () => getPost(postId.value),\n initialValue: null,\n context,\n resourceName: 'Post'\n });\n\n onMounted(() => {\n if (isCreation.value) return;\n\n fetchPost();\n });\n\n watch(postId, () => {\n if (isCreation.value) return;\n\n fetchPost();\n });\n\n /** Fetch post list */\n const { data: postList, loading: isPostListLoading } = useFetchPosts({\n context\n });\n\n const postOptionList = computed<OptionType<number>[]>(() =>\n postList.value\n .filter((relatedPost) => relatedPost.id !== post.value?.id)\n .map((post) => ({\n value: post.id,\n label: post.title\n }))\n );\n\n /** Form State **/\n const isSubmitting = ref<boolean>(false);\n const values = ref<FormValues>(\n convertPostToFormValues(\n post.value,\n languageOptionList.value,\n postOptionList.value,\n moduleConfig.value?.fields ?? [],\n statusOptions.value\n )\n );\n const errors = ref<Record<string, string>>({});\n\n watch([post, languageOptionList, postOptionList, moduleConfig], () => {\n values.value = convertPostToFormValues(\n post.value,\n languageOptionList.value,\n postOptionList.value,\n moduleConfig.value?.fields ?? [],\n statusOptions.value\n );\n });\n\n function submitForm(event: TagerFormSubmitEvent) {\n isSubmitting.value = true;\n\n const creationBody = convertFormValuesToCreationPayload(values.value);\n const updateBody = convertFormValuesToUpdatePayload(values.value);\n\n const requestPromise = isCreation.value\n ? createBlogPost(creationBody)\n : updateBlogPost(postId.value, updateBody);\n\n requestPromise\n .then(({ data }) => {\n errors.value = {};\n\n if (event.type === 'create') {\n context.root.$router.push(\n getBlogPostFormUrl({ postId: String(data.id) })\n );\n }\n\n if (event.type === 'create_exit' || event.type === 'save_exit') {\n if (context.root.$previousRoute) {\n context.root.$router.back();\n } else {\n context.root.$router.push(getBlogPostListUrl());\n }\n }\n\n if (event.type === 'create_create-another') {\n values.value = convertPostToFormValues(\n null,\n languageOptionList.value,\n postOptionList.value,\n moduleConfig.value?.fields ?? [],\n statusOptions.value\n );\n }\n\n context.root.$toast({\n variant: 'success',\n title: context.root.$t('blog:success'),\n body: isCreation.value\n ? context.root.$t('blog:blogPostWasSuccessfullyCreated')\n : context.root.$t('blog:blogPostWasSuccessfullyUpdated')\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('blog:error'),\n body: isCreation.value\n ? context.root.$t('blog:blogPostCreationWasFailed')\n : context.root.$t('blog:blogPostUpdateWasFailed')\n });\n })\n .finally(() => {\n isSubmitting.value = false;\n });\n }\n\n /** Category Options */\n\n const categoryOptionList = computed<OptionType<number>[]>(() =>\n convertCategoryListToOptions(\n categoryList.value,\n values.value.language?.value ?? null\n )\n );\n\n watch([categoryOptionList, moduleConfig], () => {\n function isOptionExist(\n selectedCategoryOption: OptionType<number>\n ): boolean {\n return categoryOptionList.value.some(\n (option) => option.value === selectedCategoryOption.value\n );\n }\n\n if (isCreation.value) {\n if (moduleConfig?.value?.defaultCategories) {\n const defaultIds = moduleConfig.value.defaultCategories.map(\n (item: { id: number }) => item.id\n );\n values.value.categories = categoryOptionList.value.filter(\n (item: OptionType<number>) => {\n return defaultIds.indexOf(item.value) !== -1;\n }\n );\n }\n }\n\n values.value.categories = values.value.categories.filter(isOptionExist);\n });\n\n /** Misc */\n\n const isContentLoading = computed<boolean>(\n () =>\n isPostLoading.value ||\n isCategoryListLoading.value ||\n isPostListLoading.value ||\n isModuleConfigLoading.value\n );\n\n function getUploadAdapterOptions() {\n return { uploadScenario: moduleConfig.value?.fileScenarios.content };\n }\n\n const blogPagePath = computed<string>(() => {\n const origin = process.env.VUE_APP_WEBSITE_URL || window.location.origin;\n return origin + (post.value?.urlTemplate ?? '');\n });\n\n const tabList = computed<TabType[]>(() => {\n const hasErrors = createTabErrorFinder(errors.value);\n return [\n {\n id: 'common',\n label: context.root.$t('blog:common'),\n hasErrors: hasErrors([\n 'title',\n 'language',\n 'urlAlias',\n 'excerpt',\n 'body',\n 'date'\n ])\n },\n {\n id: 'images',\n label: context.root.$t('blog:images'),\n hasErrors: hasErrors(['coverImage', 'image'])\n },\n {\n id: 'relations',\n label: context.root.$t('blog:relations'),\n hasErrors: hasErrors(['categories', 'relatedPosts', 'tags'])\n },\n values.value.additionalFields.length > 0\n ? {\n id: 'additional',\n label: context.root.$t('blog:additionalFields'),\n hasErrors: hasErrors([])\n }\n : null,\n {\n id: 'seo',\n label: 'SEO',\n hasErrors: hasErrors([\n 'pageTitle',\n 'pageDescription',\n 'openGraphImage'\n ])\n }\n ].filter(isNotNullish);\n });\n\n const selectedTabId = ref<string>(tabList.value[0].id);\n\n const headerButtonList = computed<{ text: string; href: string; target?: string }[]>(() =>\n [\n post.value\n ? {\n text: context.root.$t('blog:viewPost'),\n href: process.env.VUE_APP_WEBSITE_URL + post.value.url,\n target: '_blank'\n }\n : null\n ].filter(isNotNullish)\n );\n\n function handleSeoFieldGroupChange({\n title,\n description,\n image\n }: SeoChangeEvent) {\n values.value.pageTitle = title;\n values.value.pageDescription = description;\n values.value.openGraphImage = image;\n }\n\n function handleTitleChange(value: string) {\n if (isCreation.value && urlAliasChanged.value === false) {\n values.value.urlAlias = urlTranslit(value);\n }\n }\n\n function handleAliasChange() {\n urlAliasChanged.value = true;\n }\n\n const urlAliasTemplate = computed<string>(() => {\n if (!moduleConfig.value || !moduleConfig.value.urlPostTemplate) {\n return '';\n }\n\n let result = moduleConfig.value.urlPostTemplate;\n\n if (values.value.language) {\n result = result.replace('{language}', values.value.language.value);\n }\n\n if (postId.value !== 'create') {\n result = result.replace('{id}', postId.value);\n }\n\n return result;\n });\n\n const handleCategoriesChange = (selectedOptions: OptionType<number>[]) => {\n const newSelectedOptions: OptionType<number>[] = [];\n\n selectedOptions.forEach((selectedOption) => {\n const findTreeSelectedCategory = (categoryId: Nullable<number>) => {\n const foundSelectedCategory = categoryList.value.find(\n ({ id }) => id === categoryId\n );\n\n if (!foundSelectedCategory) {\n return;\n }\n\n const newSelectedOption: OptionType<number> = {\n value: foundSelectedCategory.id,\n label: foundSelectedCategory.name\n };\n\n if (\n !newSelectedOptions.some(\n ({ value }) => value === newSelectedOption.value\n )\n ) {\n newSelectedOptions.push(newSelectedOption);\n }\n\n if (foundSelectedCategory.parent) {\n findTreeSelectedCategory(foundSelectedCategory.parent.id);\n }\n };\n\n findTreeSelectedCategory(selectedOption.value);\n });\n\n values.value.categories = newSelectedOptions;\n };\n\n return {\n isCreation,\n postId,\n pagePath: blogPagePath,\n categoryOptionList,\n values,\n errors,\n isContentLoading,\n postListUrl: getBlogPostListUrl(),\n submitForm,\n isLangSpecific,\n languageOptionList,\n isSubmitting,\n moduleConfig,\n postOptionList,\n getUploadAdapterOptions,\n tabList,\n selectedTabId,\n headerButtonList,\n handleSeoFieldGroupChange,\n handleTitleChange,\n handleAliasChange,\n urlAliasTemplate,\n handleCategoriesChange,\n\n statusOptions\n };\n }\n});\n</script>\n\n<style scoped lang='scss'>\n.status {\n display: flex;\n align-items: flex-end;\n}\n\n.status-value {\n flex-basis: 50%;\n}\n\n.status-checkbox {\n margin-left: 20px;\n padding-bottom: 8px;\n}\n\n.status-date {\n margin-left: 20px;\n flex: 1 1 1px;\n}\n</style>",".status {\n display: flex;\n align-items: flex-end;\n}\n\n.status-value {\n flex-basis: 50%;\n}\n\n.status-checkbox {\n margin-left: 20px;\n padding-bottom: 8px;\n}\n\n.status-date {\n margin-left: 20px;\n flex: 1 1 1px;\n}\n\n/*# sourceMappingURL=PostForm.vue.map */"]}, media: undefined });
4301
+
4302
+ };
4078
4303
  /* scoped */
4079
- const __vue_scope_id__$1 = undefined;
4304
+ const __vue_scope_id__$1 = "data-v-50f3750d";
4080
4305
  /* module identifier */
4081
4306
  const __vue_module_identifier__$1 = undefined;
4082
4307
  /* functional template */
4083
4308
  const __vue_is_functional_template__$1 = false;
4084
- /* style inject */
4085
-
4086
4309
  /* style inject SSR */
4087
4310
 
4088
4311
  /* style inject shadow dom */
@@ -4097,7 +4320,7 @@
4097
4320
  __vue_is_functional_template__$1,
4098
4321
  __vue_module_identifier__$1,
4099
4322
  false,
4100
- undefined,
4323
+ createInjector,
4101
4324
  undefined,
4102
4325
  undefined
4103
4326
  );
@@ -4530,6 +4753,7 @@
4530
4753
  name: '',
4531
4754
  parent: { value: null, label: t('blog:noParent') },
4532
4755
  urlAlias: '',
4756
+ isDefault: false,
4533
4757
  pageTitle: '',
4534
4758
  pageDescription: '',
4535
4759
  pageKeywords: '',
@@ -4540,6 +4764,7 @@
4540
4764
  }
4541
4765
  return {
4542
4766
  language: currentLangOption !== null && currentLangOption !== void 0 ? currentLangOption : null,
4767
+ isDefault: category.isDefault,
4543
4768
  name: category.name,
4544
4769
  parent: category.parent
4545
4770
  ? { value: category.parent.id, label: category.parent.name }
@@ -4562,7 +4787,7 @@
4562
4787
  name: values.name,
4563
4788
  parent: values.parent.value,
4564
4789
  urlAlias: values.urlAlias,
4565
- isDefault: false,
4790
+ isDefault: values.isDefault,
4566
4791
  pageTitle: values.pageTitle,
4567
4792
  pageDescription: values.pageDescription,
4568
4793
  openGraphImage: (_d = (_c = values.openGraphImage) === null || _c === void 0 ? void 0 : _c.file.id) !== null && _d !== void 0 ? _d : null,
@@ -4847,6 +5072,21 @@
4847
5072
  })
4848
5073
  : _vm._e(),
4849
5074
  _vm._v(" "),
5075
+ _c("form-field-checkbox", {
5076
+ attrs: {
5077
+ name: "isDefault",
5078
+ label: _vm.$t("blog:defaultCategory"),
5079
+ error: _vm.errors.isDefault,
5080
+ },
5081
+ model: {
5082
+ value: _vm.values.isDefault,
5083
+ callback: function ($$v) {
5084
+ _vm.$set(_vm.values, "isDefault", $$v);
5085
+ },
5086
+ expression: "values.isDefault",
5087
+ },
5088
+ }),
5089
+ _vm._v(" "),
4850
5090
  _c("form-field", {
4851
5091
  attrs: {
4852
5092
  name: "name",