@tager/admin-blog 0.3.41 → 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.esm.js +234 -84
- package/dist/index.umd.js +233 -83
- package/dist/locales/en.d.ts +6 -0
- package/dist/services/requests.d.ts +2 -0
- package/dist/typings/model.d.ts +2 -0
- package/dist/views/Posts/PostForm/PostForm.helpers.d.ts +2 -0
- package/dist/views/Posts/PostForm/PostForm.vue.d.ts +6 -2
- package/dist/views/Posts/PostList/PostList.vue.d.ts +8 -1
- package/package.json +3 -3
- package/src/locales/en.ts +7 -0
- package/src/locales/ru.ts +7 -0
- package/src/services/requests.ts +2 -0
- package/src/typings/model.ts +2 -0
- package/src/views/Posts/PostForm/PostForm.helpers.ts +15 -7
- package/src/views/Posts/PostForm/PostForm.vue +177 -137
- package/src/views/Posts/PostList/PostList.helpers.ts +6 -7
- package/src/views/Posts/PostList/PostList.vue +107 -74
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { request, useResource, createId, notEmpty, isNotNullish, useResourceDelete, useResourceClone, convertRequestErrorToMap, urlTranslit, getWebsiteOrigin, i18n } from '@tager/admin-services';
|
|
2
2
|
import { onMounted, watch, computed, ref, defineComponent } from '@vue/composition-api';
|
|
3
|
-
import { getFilterParamAsStringArray, getFilterParamAsString, getFilterParams, useTranslation, useDataTable, ShortCodeConstructor, FormFooter, createTabErrorFinder } from '@tager/admin-ui';
|
|
3
|
+
import { getFilterParamAsStringArray, getFilterParamAsString, getFilterParams, useTranslation, useDataTable, formatDateTime, ShortCodeConstructor, FormFooter, createTabErrorFinder } from '@tager/admin-ui';
|
|
4
4
|
import { compile } from 'path-to-regexp';
|
|
5
5
|
import { universalFieldUtils, DynamicField } from '@tager/admin-dynamic-field';
|
|
6
6
|
|
|
@@ -82,6 +82,12 @@ const EN = {
|
|
|
82
82
|
statusPublished: 'Published',
|
|
83
83
|
statusDraft: 'Draft',
|
|
84
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 = {
|
|
@@ -162,6 +168,12 @@ const RU = {
|
|
|
162
168
|
statusPublished: 'Опубликован',
|
|
163
169
|
statusDraft: 'Черновик',
|
|
164
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 : {};
|
|
@@ -2685,7 +2697,7 @@ function getNameWithDepth(name, depth) {
|
|
|
2685
2697
|
const getStatusOptions = (t) => [
|
|
2686
2698
|
{ label: t('blog:statusPublished'), value: 'PUBLISHED' },
|
|
2687
2699
|
{ label: t('blog:statusDraft'), value: 'DRAFT' },
|
|
2688
|
-
{ label: t('blog:statusArchived'), value: 'ARCHIVED' }
|
|
2700
|
+
{ label: t('blog:statusArchived'), value: 'ARCHIVED' }
|
|
2689
2701
|
];
|
|
2690
2702
|
function convertPostToFormValues(post, languageOptionList, postOptionList, additionalFieldList, statusOptions) {
|
|
2691
2703
|
var _a, _b, _c;
|
|
@@ -2708,6 +2720,8 @@ function convertPostToFormValues(post, languageOptionList, postOptionList, addit
|
|
|
2708
2720
|
tags: '',
|
|
2709
2721
|
additionalFields: additionalFieldList.map((fieldConfig) => universalFieldUtils.createFormField(fieldConfig, null)),
|
|
2710
2722
|
status: statusOptions[0],
|
|
2723
|
+
statusDateEnabled: false,
|
|
2724
|
+
statusDate: null
|
|
2711
2725
|
};
|
|
2712
2726
|
}
|
|
2713
2727
|
const currentLangOption = languageOptionList.find((option) => option.value === post.language);
|
|
@@ -2733,7 +2747,7 @@ function convertPostToFormValues(post, languageOptionList, postOptionList, addit
|
|
|
2733
2747
|
urlAlias: post.urlAlias,
|
|
2734
2748
|
categories: post.categories.map((category) => ({
|
|
2735
2749
|
value: category.id,
|
|
2736
|
-
label: category.name
|
|
2750
|
+
label: category.name
|
|
2737
2751
|
})),
|
|
2738
2752
|
language: currentLangOption !== null && currentLangOption !== void 0 ? currentLangOption : null,
|
|
2739
2753
|
relatedPosts: selectedPostOptionList,
|
|
@@ -2743,6 +2757,8 @@ function convertPostToFormValues(post, languageOptionList, postOptionList, addit
|
|
|
2743
2757
|
return universalFieldUtils.createFormField(fieldConfig, postAdditionalField === null || postAdditionalField === void 0 ? void 0 : postAdditionalField.value);
|
|
2744
2758
|
}),
|
|
2745
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)
|
|
2746
2762
|
};
|
|
2747
2763
|
}
|
|
2748
2764
|
function convertFormValuesToCreationPayload(values) {
|
|
@@ -2765,9 +2781,11 @@ function convertFormValuesToCreationPayload(values) {
|
|
|
2765
2781
|
tags: values.tags.split(',').filter((tag) => tag.trim().length > 0),
|
|
2766
2782
|
additionalFields: values.additionalFields.map((field) => ({
|
|
2767
2783
|
name: field.config.name,
|
|
2768
|
-
value: universalFieldUtils.getOutgoingValue(field)
|
|
2784
|
+
value: universalFieldUtils.getOutgoingValue(field)
|
|
2769
2785
|
})),
|
|
2770
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
|
|
2771
2789
|
};
|
|
2772
2790
|
}
|
|
2773
2791
|
function convertFormValuesToUpdatePayload(values) {
|
|
@@ -2778,7 +2796,7 @@ function convertCategoryListToOptions(categoryList, languageId) {
|
|
|
2778
2796
|
.filter(({ language }) => (languageId ? language === languageId : true))
|
|
2779
2797
|
.map(({ id, name, depth }) => ({
|
|
2780
2798
|
value: id,
|
|
2781
|
-
label: getNameWithDepth(name, depth)
|
|
2799
|
+
label: getNameWithDepth(name, depth)
|
|
2782
2800
|
}));
|
|
2783
2801
|
}
|
|
2784
2802
|
|
|
@@ -2820,10 +2838,9 @@ function getPostTableColumnDefs(moduleConfig, t) {
|
|
|
2820
2838
|
field: 'status',
|
|
2821
2839
|
style: { width: '120px' },
|
|
2822
2840
|
headStyle: { width: '120px' },
|
|
2823
|
-
format: ({ row }) => getStatuses(t)[row.status],
|
|
2824
2841
|
},
|
|
2825
2842
|
{
|
|
2826
|
-
id:
|
|
2843
|
+
id: 3,
|
|
2827
2844
|
name: t('blog:name'),
|
|
2828
2845
|
field: 'name',
|
|
2829
2846
|
type: 'name',
|
|
@@ -2842,7 +2859,7 @@ function getPostTableColumnDefs(moduleConfig, t) {
|
|
|
2842
2859
|
}),
|
|
2843
2860
|
},
|
|
2844
2861
|
{
|
|
2845
|
-
id:
|
|
2862
|
+
id: 4,
|
|
2846
2863
|
name: t('blog:image'),
|
|
2847
2864
|
field: 'image',
|
|
2848
2865
|
type: 'image',
|
|
@@ -2850,23 +2867,23 @@ function getPostTableColumnDefs(moduleConfig, t) {
|
|
|
2850
2867
|
headStyle: { width: '250px' },
|
|
2851
2868
|
},
|
|
2852
2869
|
isLangSpecific
|
|
2853
|
-
? { id:
|
|
2870
|
+
? { id: 5, name: t('blog:language'), field: 'language' }
|
|
2854
2871
|
: null,
|
|
2855
2872
|
{
|
|
2856
|
-
id:
|
|
2873
|
+
id: 6,
|
|
2857
2874
|
name: t('blog:date'),
|
|
2858
2875
|
field: 'datetime',
|
|
2859
2876
|
type: 'datetime',
|
|
2860
2877
|
options: { ignoreStartOfDayTime: true },
|
|
2861
2878
|
},
|
|
2862
2879
|
{
|
|
2863
|
-
id:
|
|
2880
|
+
id: 7,
|
|
2864
2881
|
name: t('blog:categories'),
|
|
2865
2882
|
field: 'categories',
|
|
2866
2883
|
format: ({ row }) => row.categories.map((category) => category.name).join(', '),
|
|
2867
2884
|
},
|
|
2868
2885
|
{
|
|
2869
|
-
id:
|
|
2886
|
+
id: 8,
|
|
2870
2887
|
name: t('blog:actions'),
|
|
2871
2888
|
field: 'actions',
|
|
2872
2889
|
style: { whiteSpace: 'nowrap', width: '120px' },
|
|
@@ -3041,10 +3058,10 @@ var script = defineComponent({
|
|
|
3041
3058
|
});
|
|
3042
3059
|
const statusOptionList = computed(() => getStatusOptions(t));
|
|
3043
3060
|
/** Fetch module config **/
|
|
3044
|
-
const { data: moduleConfig, loading: isModuleConfigLoading
|
|
3061
|
+
const { data: moduleConfig, loading: isModuleConfigLoading } = useFetchModuleConfig({ context });
|
|
3045
3062
|
const languageList = computed(() => { var _a, _b; return (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.languages) !== null && _b !== void 0 ? _b : []; });
|
|
3046
3063
|
/** Fetch category list **/
|
|
3047
|
-
const { data: categoryList, loading: isCategoryListLoading
|
|
3064
|
+
const { data: categoryList, loading: isCategoryListLoading } = useFetchCategories({ context });
|
|
3048
3065
|
const selectedCategory = computed(() => {
|
|
3049
3066
|
var _a;
|
|
3050
3067
|
return categoryId.value
|
|
@@ -3056,20 +3073,20 @@ var script = defineComponent({
|
|
|
3056
3073
|
: context.root.$t('blog:posts');
|
|
3057
3074
|
});
|
|
3058
3075
|
/** Advanced search **/
|
|
3059
|
-
const { categoryFilter, categoryOptionList, languageFilter, languageOptionList, fromDateFilter, toDateFilter, filterParams, tags, tagRemovalHandler, statusFilter
|
|
3076
|
+
const { categoryFilter, categoryOptionList, languageFilter, languageOptionList, fromDateFilter, toDateFilter, filterParams, tags, tagRemovalHandler, statusFilter } = useAdvancedSearch({
|
|
3060
3077
|
context,
|
|
3061
3078
|
categoryList,
|
|
3062
3079
|
languageList,
|
|
3063
|
-
statusOptionList
|
|
3080
|
+
statusOptionList
|
|
3064
3081
|
});
|
|
3065
3082
|
const isLangSpecific = computed(() => languageOptionList.value.length > 1);
|
|
3066
3083
|
/** Fetch Post list **/
|
|
3067
|
-
const { fetchEntityList: fetchPostList, isLoading: isPostLoading, rowData: postList, errorMessage, searchQuery, handleChange, pageNumber, pageCount, pageSize
|
|
3084
|
+
const { fetchEntityList: fetchPostList, isLoading: isPostLoading, rowData: postList, errorMessage, searchQuery, handleChange, pageNumber, pageCount, pageSize } = useDataTable({
|
|
3068
3085
|
fetchEntityList: (params) => getPosts(Object.assign({ query: params.searchQuery, pageNumber: params.pageNumber, pageSize: params.pageSize }, filterParams.value)),
|
|
3069
3086
|
initialValue: [],
|
|
3070
3087
|
context,
|
|
3071
3088
|
resourceName: 'Blog post list',
|
|
3072
|
-
pageSize: 100
|
|
3089
|
+
pageSize: 100
|
|
3073
3090
|
});
|
|
3074
3091
|
watch(filterParams, () => {
|
|
3075
3092
|
if (isModuleConfigLoading.value || isCategoryListLoading.value) {
|
|
@@ -3092,7 +3109,7 @@ var script = defineComponent({
|
|
|
3092
3109
|
deleteResource: deleteBlogPost,
|
|
3093
3110
|
resourceName: 'Post',
|
|
3094
3111
|
onSuccess: fetchPostList,
|
|
3095
|
-
context
|
|
3112
|
+
context
|
|
3096
3113
|
});
|
|
3097
3114
|
const { isCloning, handleResourceClone } = useResourceClone({
|
|
3098
3115
|
cloneResource: clonePost,
|
|
@@ -3100,13 +3117,15 @@ var script = defineComponent({
|
|
|
3100
3117
|
successMessage: t('blog:cloneSuccess'),
|
|
3101
3118
|
failureMessage: t('blog:cloneFailure'),
|
|
3102
3119
|
onSuccessRedirectTo: (data) => `/blog/posts/${data.id}`,
|
|
3103
|
-
context
|
|
3120
|
+
context
|
|
3104
3121
|
});
|
|
3105
3122
|
function isBusy(postId) {
|
|
3106
3123
|
return isDeleting(postId) || isCloning(postId) || isRowDataLoading.value;
|
|
3107
3124
|
}
|
|
3108
3125
|
const columnDefs = computed(() => getPostTableColumnDefs(moduleConfig.value, context.root.$t));
|
|
3109
3126
|
return {
|
|
3127
|
+
t,
|
|
3128
|
+
formatDateTime,
|
|
3110
3129
|
columnDefs,
|
|
3111
3130
|
rowData: displayedPostList,
|
|
3112
3131
|
handleResourceDelete,
|
|
@@ -3133,11 +3152,12 @@ var script = defineComponent({
|
|
|
3133
3152
|
statusOptionList,
|
|
3134
3153
|
tags,
|
|
3135
3154
|
tagRemovalHandler,
|
|
3155
|
+
getStatuses,
|
|
3136
3156
|
// Clone
|
|
3137
3157
|
handleResourceClone,
|
|
3138
|
-
isBusy
|
|
3158
|
+
isBusy
|
|
3139
3159
|
};
|
|
3140
|
-
}
|
|
3160
|
+
}
|
|
3141
3161
|
});
|
|
3142
3162
|
|
|
3143
3163
|
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
|
|
@@ -3433,6 +3453,59 @@ var __vue_render__ = function () {
|
|
|
3433
3453
|
},
|
|
3434
3454
|
proxy: true,
|
|
3435
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
|
+
},
|
|
3436
3509
|
{
|
|
3437
3510
|
key: "cell(actions)",
|
|
3438
3511
|
fn: function (ref) {
|
|
@@ -3505,11 +3578,11 @@ __vue_render__._withStripped = true;
|
|
|
3505
3578
|
/* style */
|
|
3506
3579
|
const __vue_inject_styles__ = function (inject) {
|
|
3507
3580
|
if (!inject) return
|
|
3508
|
-
inject("data-v-075b6310_0", { source: ".filters[data-v-075b6310] {\n display: flex;\n margin: 0 -10px;\n}\n.filters[data-v-075b6310]:not(:first-child) {\n margin-top: 10px;\n}\n.filters .filter[data-v-075b6310] {\n padding: 10px 10px 0;\n width: 50%;\n margin: 0;\n}\n.date-label[data-v-075b6310] {\n margin-bottom: 0.5rem;\n}\n.date-content[data-v-075b6310] {\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":"AAsVA;EACA,aAAA;EACA,eAAA;ACrVA;ADuVA;EACA,gBAAA;ACrVA;ADwVA;EACA,oBAAA;EACA,UAAA;EACA,SAAA;ACtVA;AD0VA;EACA,qBAAA;ACvVA;AD0VA;EACA,aAAA;EACA,qCAAA;EACA,gBAAA;ACvVA;;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(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} 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 } 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 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\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 });
|
|
3509
3582
|
|
|
3510
3583
|
};
|
|
3511
3584
|
/* scoped */
|
|
3512
|
-
const __vue_scope_id__ = "data-v-
|
|
3585
|
+
const __vue_scope_id__ = "data-v-61f152be";
|
|
3513
3586
|
/* module identifier */
|
|
3514
3587
|
const __vue_module_identifier__ = undefined;
|
|
3515
3588
|
/* functional template */
|
|
@@ -3543,21 +3616,21 @@ var script$1 = defineComponent({
|
|
|
3543
3616
|
const urlAliasChanged = ref(false);
|
|
3544
3617
|
const statusOptions = computed(() => getStatusOptions(context.root.$t));
|
|
3545
3618
|
/** Fetch module config **/
|
|
3546
|
-
const { data: moduleConfig, loading: isModuleConfigLoading
|
|
3619
|
+
const { data: moduleConfig, loading: isModuleConfigLoading } = useFetchModuleConfig({ context });
|
|
3547
3620
|
const languageList = computed(() => { var _a, _b; return (_b = (_a = moduleConfig.value) === null || _a === void 0 ? void 0 : _a.languages) !== null && _b !== void 0 ? _b : []; });
|
|
3548
3621
|
const languageOptionList = computed(() => languageList.value.map(({ id, name }) => ({
|
|
3549
3622
|
value: id,
|
|
3550
|
-
label: name
|
|
3623
|
+
label: name
|
|
3551
3624
|
})));
|
|
3552
3625
|
const isLangSpecific = computed(() => languageOptionList.value.length > 0);
|
|
3553
3626
|
/** Fetch category list */
|
|
3554
|
-
const { data: categoryList, loading: isCategoryListLoading
|
|
3627
|
+
const { data: categoryList, loading: isCategoryListLoading } = useFetchCategories({ context });
|
|
3555
3628
|
/** Fetch Post */
|
|
3556
3629
|
const [fetchPost, { data: post, loading: isPostLoading }] = useResource({
|
|
3557
3630
|
fetchResource: () => getPost(postId.value),
|
|
3558
3631
|
initialValue: null,
|
|
3559
3632
|
context,
|
|
3560
|
-
resourceName: 'Post'
|
|
3633
|
+
resourceName: 'Post'
|
|
3561
3634
|
});
|
|
3562
3635
|
onMounted(() => {
|
|
3563
3636
|
if (isCreation.value)
|
|
@@ -3571,13 +3644,13 @@ var script$1 = defineComponent({
|
|
|
3571
3644
|
});
|
|
3572
3645
|
/** Fetch post list */
|
|
3573
3646
|
const { data: postList, loading: isPostListLoading } = useFetchPosts({
|
|
3574
|
-
context
|
|
3647
|
+
context
|
|
3575
3648
|
});
|
|
3576
3649
|
const postOptionList = computed(() => postList.value
|
|
3577
3650
|
.filter((relatedPost) => { var _a; return relatedPost.id !== ((_a = post.value) === null || _a === void 0 ? void 0 : _a.id); })
|
|
3578
3651
|
.map((post) => ({
|
|
3579
3652
|
value: post.id,
|
|
3580
|
-
label: post.title
|
|
3653
|
+
label: post.title
|
|
3581
3654
|
})));
|
|
3582
3655
|
/** Form State **/
|
|
3583
3656
|
const isSubmitting = ref(false);
|
|
@@ -3617,7 +3690,7 @@ var script$1 = defineComponent({
|
|
|
3617
3690
|
title: context.root.$t('blog:success'),
|
|
3618
3691
|
body: isCreation.value
|
|
3619
3692
|
? context.root.$t('blog:blogPostWasSuccessfullyCreated')
|
|
3620
|
-
: context.root.$t('blog:blogPostWasSuccessfullyUpdated')
|
|
3693
|
+
: context.root.$t('blog:blogPostWasSuccessfullyUpdated')
|
|
3621
3694
|
});
|
|
3622
3695
|
})
|
|
3623
3696
|
.catch((error) => {
|
|
@@ -3628,7 +3701,7 @@ var script$1 = defineComponent({
|
|
|
3628
3701
|
title: context.root.$t('blog:error'),
|
|
3629
3702
|
body: isCreation.value
|
|
3630
3703
|
? context.root.$t('blog:blogPostCreationWasFailed')
|
|
3631
|
-
: context.root.$t('blog:blogPostUpdateWasFailed')
|
|
3704
|
+
: context.root.$t('blog:blogPostUpdateWasFailed')
|
|
3632
3705
|
});
|
|
3633
3706
|
})
|
|
3634
3707
|
.finally(() => {
|
|
@@ -3681,24 +3754,24 @@ var script$1 = defineComponent({
|
|
|
3681
3754
|
'urlAlias',
|
|
3682
3755
|
'excerpt',
|
|
3683
3756
|
'body',
|
|
3684
|
-
'date'
|
|
3685
|
-
])
|
|
3757
|
+
'date'
|
|
3758
|
+
])
|
|
3686
3759
|
},
|
|
3687
3760
|
{
|
|
3688
3761
|
id: 'images',
|
|
3689
3762
|
label: context.root.$t('blog:images'),
|
|
3690
|
-
hasErrors: hasErrors(['coverImage', 'image'])
|
|
3763
|
+
hasErrors: hasErrors(['coverImage', 'image'])
|
|
3691
3764
|
},
|
|
3692
3765
|
{
|
|
3693
3766
|
id: 'relations',
|
|
3694
3767
|
label: context.root.$t('blog:relations'),
|
|
3695
|
-
hasErrors: hasErrors(['categories', 'relatedPosts', 'tags'])
|
|
3768
|
+
hasErrors: hasErrors(['categories', 'relatedPosts', 'tags'])
|
|
3696
3769
|
},
|
|
3697
3770
|
values.value.additionalFields.length > 0
|
|
3698
3771
|
? {
|
|
3699
3772
|
id: 'additional',
|
|
3700
3773
|
label: context.root.$t('blog:additionalFields'),
|
|
3701
|
-
hasErrors: hasErrors([])
|
|
3774
|
+
hasErrors: hasErrors([])
|
|
3702
3775
|
}
|
|
3703
3776
|
: null,
|
|
3704
3777
|
{
|
|
@@ -3707,9 +3780,9 @@ var script$1 = defineComponent({
|
|
|
3707
3780
|
hasErrors: hasErrors([
|
|
3708
3781
|
'pageTitle',
|
|
3709
3782
|
'pageDescription',
|
|
3710
|
-
'openGraphImage'
|
|
3711
|
-
])
|
|
3712
|
-
}
|
|
3783
|
+
'openGraphImage'
|
|
3784
|
+
])
|
|
3785
|
+
}
|
|
3713
3786
|
].filter(isNotNullish);
|
|
3714
3787
|
});
|
|
3715
3788
|
const selectedTabId = ref(tabList.value[0].id);
|
|
@@ -3718,11 +3791,11 @@ var script$1 = defineComponent({
|
|
|
3718
3791
|
? {
|
|
3719
3792
|
text: context.root.$t('blog:viewPost'),
|
|
3720
3793
|
href: process.env.VUE_APP_WEBSITE_URL + post.value.url,
|
|
3721
|
-
target: '_blank'
|
|
3794
|
+
target: '_blank'
|
|
3722
3795
|
}
|
|
3723
|
-
: null
|
|
3796
|
+
: null
|
|
3724
3797
|
].filter(isNotNullish));
|
|
3725
|
-
function handleSeoFieldGroupChange({ title, description, image
|
|
3798
|
+
function handleSeoFieldGroupChange({ title, description, image }) {
|
|
3726
3799
|
values.value.pageTitle = title;
|
|
3727
3800
|
values.value.pageDescription = description;
|
|
3728
3801
|
values.value.openGraphImage = image;
|
|
@@ -3758,7 +3831,7 @@ var script$1 = defineComponent({
|
|
|
3758
3831
|
}
|
|
3759
3832
|
const newSelectedOption = {
|
|
3760
3833
|
value: foundSelectedCategory.id,
|
|
3761
|
-
label: foundSelectedCategory.name
|
|
3834
|
+
label: foundSelectedCategory.name
|
|
3762
3835
|
};
|
|
3763
3836
|
if (!newSelectedOptions.some(({ value }) => value === newSelectedOption.value)) {
|
|
3764
3837
|
newSelectedOptions.push(newSelectedOption);
|
|
@@ -3795,9 +3868,9 @@ var script$1 = defineComponent({
|
|
|
3795
3868
|
handleAliasChange,
|
|
3796
3869
|
urlAliasTemplate,
|
|
3797
3870
|
handleCategoriesChange,
|
|
3798
|
-
statusOptions
|
|
3871
|
+
statusOptions
|
|
3799
3872
|
};
|
|
3800
|
-
}
|
|
3873
|
+
}
|
|
3801
3874
|
});
|
|
3802
3875
|
|
|
3803
3876
|
/* script */
|
|
@@ -3852,23 +3925,6 @@ var __vue_render__$1 = function () {
|
|
|
3852
3925
|
_vm._v(" "),
|
|
3853
3926
|
_vm.selectedTabId === "common"
|
|
3854
3927
|
? [
|
|
3855
|
-
_c("form-field-select", {
|
|
3856
|
-
attrs: {
|
|
3857
|
-
name: "status",
|
|
3858
|
-
error: _vm.errors.status,
|
|
3859
|
-
label: _vm.$t("blog:status"),
|
|
3860
|
-
"no-options-message": _vm.$t("blog:noTemplates"),
|
|
3861
|
-
options: _vm.statusOptions,
|
|
3862
|
-
},
|
|
3863
|
-
model: {
|
|
3864
|
-
value: _vm.values.status,
|
|
3865
|
-
callback: function ($$v) {
|
|
3866
|
-
_vm.$set(_vm.values, "status", $$v);
|
|
3867
|
-
},
|
|
3868
|
-
expression: "values.status",
|
|
3869
|
-
},
|
|
3870
|
-
}),
|
|
3871
|
-
_vm._v(" "),
|
|
3872
3928
|
_vm.isCreation && _vm.isLangSpecific
|
|
3873
3929
|
? _c("form-field-select", {
|
|
3874
3930
|
attrs: {
|
|
@@ -3921,6 +3977,114 @@ var __vue_render__$1 = function () {
|
|
|
3921
3977
|
},
|
|
3922
3978
|
}),
|
|
3923
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(" "),
|
|
3924
4088
|
_c("form-field", {
|
|
3925
4089
|
attrs: {
|
|
3926
4090
|
name: "excerpt",
|
|
@@ -3961,22 +4125,6 @@ var __vue_render__$1 = function () {
|
|
|
3961
4125
|
: [],
|
|
3962
4126
|
},
|
|
3963
4127
|
}),
|
|
3964
|
-
_vm._v(" "),
|
|
3965
|
-
_c("form-field", {
|
|
3966
|
-
attrs: {
|
|
3967
|
-
name: "datetime",
|
|
3968
|
-
label: _vm.$t("blog:date"),
|
|
3969
|
-
type: "date",
|
|
3970
|
-
error: _vm.errors.datetime,
|
|
3971
|
-
},
|
|
3972
|
-
model: {
|
|
3973
|
-
value: _vm.values.datetime,
|
|
3974
|
-
callback: function ($$v) {
|
|
3975
|
-
_vm.$set(_vm.values, "datetime", $$v);
|
|
3976
|
-
},
|
|
3977
|
-
expression: "values.datetime",
|
|
3978
|
-
},
|
|
3979
|
-
}),
|
|
3980
4128
|
]
|
|
3981
4129
|
: _vm._e(),
|
|
3982
4130
|
_vm._v(" "),
|
|
@@ -4147,15 +4295,17 @@ var __vue_staticRenderFns__$1 = [];
|
|
|
4147
4295
|
__vue_render__$1._withStripped = true;
|
|
4148
4296
|
|
|
4149
4297
|
/* style */
|
|
4150
|
-
const __vue_inject_styles__$1 =
|
|
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
|
+
};
|
|
4151
4303
|
/* scoped */
|
|
4152
|
-
const __vue_scope_id__$1 =
|
|
4304
|
+
const __vue_scope_id__$1 = "data-v-50f3750d";
|
|
4153
4305
|
/* module identifier */
|
|
4154
4306
|
const __vue_module_identifier__$1 = undefined;
|
|
4155
4307
|
/* functional template */
|
|
4156
4308
|
const __vue_is_functional_template__$1 = false;
|
|
4157
|
-
/* style inject */
|
|
4158
|
-
|
|
4159
4309
|
/* style inject SSR */
|
|
4160
4310
|
|
|
4161
4311
|
/* style inject shadow dom */
|
|
@@ -4170,7 +4320,7 @@ __vue_render__$1._withStripped = true;
|
|
|
4170
4320
|
__vue_is_functional_template__$1,
|
|
4171
4321
|
__vue_module_identifier__$1,
|
|
4172
4322
|
false,
|
|
4173
|
-
|
|
4323
|
+
createInjector,
|
|
4174
4324
|
undefined,
|
|
4175
4325
|
undefined
|
|
4176
4326
|
);
|