@tager/admin-blog 0.3.43 → 1.0.0
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/constants/paths.d.ts +6 -14
- package/dist/constants/routes.d.ts +5 -5
- package/dist/dev/App.vue.d.ts +5 -0
- package/dist/dev/config.d.ts +2 -0
- package/dist/dev/env.d.ts +1 -0
- package/dist/dev/main.d.ts +3 -0
- package/dist/hooks/index.d.ts +4 -4
- package/dist/hooks/useFetchCategories.d.ts +3 -6
- package/dist/hooks/useFetchCategory.d.ts +7 -8
- package/dist/hooks/useFetchModuleConfig.d.ts +3 -6
- package/dist/hooks/useFetchPosts.d.ts +3 -6
- package/dist/index.mjs +2363 -0
- package/dist/locales/apply.d.ts +1 -0
- package/dist/locales/en.d.ts +87 -86
- package/dist/locales/ru.d.ts +3 -3
- package/dist/main.d.ts +3 -4
- package/dist/services/requests.d.ts +59 -59
- package/dist/style.css +1 -0
- package/dist/typings/common.d.ts +1 -1
- package/dist/typings/model.d.ts +106 -106
- package/dist/utils/common.d.ts +2 -2
- package/dist/utils/paths.d.ts +8 -0
- package/dist/views/Categories/CategoryForm/CategoryForm.helpers.d.ts +7 -7
- package/dist/views/Categories/CategoryForm/CategoryForm.vue.d.ts +53 -116
- package/dist/views/Categories/CategoryForm/index.d.ts +1 -1
- package/dist/views/Categories/CategoryList/CategoryList.helpers.d.ts +7 -7
- package/dist/views/Categories/CategoryList/CategoryList.vue.d.ts +26 -57
- package/dist/views/Categories/CategoryList/hooks/index.d.ts +1 -1
- package/dist/views/Categories/CategoryList/hooks/useAdvancedSearch.d.ts +19 -16
- package/dist/views/Categories/CategoryList/index.d.ts +1 -1
- package/dist/views/Posts/PostForm/PostForm.helpers.d.ts +32 -32
- package/dist/views/Posts/PostForm/PostForm.vue.d.ts +2768 -9398
- package/dist/views/Posts/PostForm/components/TabList/TabList.types.d.ts +5 -5
- package/dist/views/Posts/PostForm/components/TabList/TabList.vue.d.ts +23 -0
- package/dist/views/Posts/PostForm/components/TabList/index.d.ts +2 -2
- package/dist/views/Posts/PostForm/index.d.ts +1 -1
- package/dist/views/Posts/PostList/PostList.helpers.d.ts +7 -7
- package/dist/views/Posts/PostList/PostList.vue.d.ts +38 -78
- package/dist/views/Posts/PostList/hooks/index.d.ts +1 -1
- package/dist/views/Posts/PostList/hooks/useAdvancedSearch.d.ts +27 -24
- package/dist/views/Posts/PostList/index.d.ts +1 -1
- package/package.json +51 -49
- package/src/constants/paths.ts +0 -22
- package/src/constants/routes.ts +9 -9
- package/src/dev/App.vue +56 -0
- package/src/dev/config.ts +23 -0
- package/src/dev/env.ts +17 -0
- package/src/dev/main.ts +49 -0
- package/src/hooks/useFetchCategories.ts +2 -7
- package/src/hooks/useFetchCategory.ts +3 -6
- package/src/hooks/useFetchModuleConfig.ts +2 -7
- package/src/hooks/useFetchPosts.ts +2 -5
- package/src/locales/apply.ts +9 -0
- package/src/locales/en.ts +3 -3
- package/src/locales/ru.ts +4 -2
- package/src/main.ts +3 -8
- package/src/utils/paths.ts +23 -0
- package/src/views/Categories/CategoryForm/CategoryForm.vue +81 -61
- package/src/views/Categories/CategoryList/CategoryList.helpers.ts +1 -1
- package/src/views/Categories/CategoryList/CategoryList.vue +86 -58
- package/src/views/Categories/CategoryList/hooks/useAdvancedSearch.ts +9 -12
- package/src/views/Posts/PostForm/PostForm.vue +262 -223
- package/src/views/Posts/PostForm/components/TabList/TabList.vue +2 -2
- package/src/views/Posts/PostList/PostList.helpers.ts +1 -1
- package/src/views/Posts/PostList/PostList.vue +168 -168
- package/src/views/Posts/PostList/hooks/useAdvancedSearch.ts +22 -30
- package/CHANGELOG.md +0 -13
- package/dist/constants/menu.d.ts +0 -5
- package/dist/dev.d.ts +0 -1
- package/dist/index.esm.js +0 -5294
- package/dist/index.umd.js +0 -5321
- package/dist/router/index.d.ts +0 -4
- package/src/constants/menu.ts +0 -31
- package/src/dev.ts +0 -34
- package/src/router/index.ts +0 -40
- package/src/typings/sfc.d.ts +0 -12
- package/src/typings/shims-tsx.d.ts +0 -13
- package/src/typings/shims-vue.d.ts +0 -11
- package/src/typings/translate.d.ts +0 -10
- package/src/views/App.vue +0 -22
- package/src/views/Home.vue +0 -31
|
@@ -1,223 +1,246 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
:title="
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
:
|
|
2
|
+
<Page
|
|
3
|
+
:title="
|
|
4
|
+
isCreation ? $i18n.t('blog:createPost') : $i18n.t('blog:updatePost')
|
|
5
|
+
"
|
|
6
|
+
:is-content-loading="isContentLoading"
|
|
7
|
+
:header-buttons="headerButtonList"
|
|
8
|
+
:footer="{
|
|
7
9
|
backHref: postListUrl,
|
|
8
10
|
onSubmit: submitForm,
|
|
9
11
|
isSubmitting: isSubmitting,
|
|
10
|
-
}
|
|
12
|
+
}"
|
|
11
13
|
>
|
|
12
|
-
<template
|
|
13
|
-
<form novalidate @submit.prevent=
|
|
14
|
-
<
|
|
15
|
-
:tab-list=
|
|
16
|
-
:selected-tab-id=
|
|
17
|
-
@tab:update=
|
|
14
|
+
<template #content>
|
|
15
|
+
<form novalidate @submit.prevent="submitForm">
|
|
16
|
+
<TabList
|
|
17
|
+
:tab-list="tabList"
|
|
18
|
+
:selected-tab-id="selectedTabId"
|
|
19
|
+
@tab:update="selectedTabId = $event.tabId"
|
|
18
20
|
/>
|
|
19
21
|
|
|
20
22
|
<template v-if="selectedTabId === 'common'">
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
v-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
:
|
|
27
|
-
:
|
|
28
|
-
:error='errors.language'
|
|
23
|
+
<FormFieldSelect
|
|
24
|
+
v-if="isCreation && isLangSpecific"
|
|
25
|
+
v-model:value="values.language"
|
|
26
|
+
name="language"
|
|
27
|
+
:label="$i18n.t('blog:language')"
|
|
28
|
+
:options="languageOptionList"
|
|
29
|
+
:error="errors.language"
|
|
29
30
|
/>
|
|
30
31
|
|
|
31
|
-
<
|
|
32
|
-
v-model=
|
|
33
|
-
name=
|
|
34
|
-
:label="$t('blog:title')"
|
|
35
|
-
:error=
|
|
36
|
-
@input=
|
|
32
|
+
<FormField
|
|
33
|
+
v-model:value="values.title"
|
|
34
|
+
name="title"
|
|
35
|
+
:label="$i18n.t('blog:title')"
|
|
36
|
+
:error="errors.title"
|
|
37
|
+
@input="handleTitleChange"
|
|
37
38
|
/>
|
|
38
39
|
|
|
39
|
-
<
|
|
40
|
-
id=
|
|
41
|
-
v-model=
|
|
42
|
-
name=
|
|
43
|
-
:label="$t('blog:link')"
|
|
44
|
-
:url-template=
|
|
45
|
-
:error=
|
|
46
|
-
@change=
|
|
40
|
+
<FormFieldUrlAliasInput
|
|
41
|
+
id="urlAlias"
|
|
42
|
+
v-model:value="values.urlAlias"
|
|
43
|
+
name="urlAlias"
|
|
44
|
+
:label="$i18n.t('blog:link')"
|
|
45
|
+
:url-template="urlAliasTemplate"
|
|
46
|
+
:error="errors.urlAlias"
|
|
47
|
+
@change="handleAliasChange"
|
|
47
48
|
/>
|
|
48
49
|
|
|
49
|
-
<div class=
|
|
50
|
-
<div class=
|
|
51
|
-
<
|
|
52
|
-
v-model=
|
|
53
|
-
name=
|
|
54
|
-
:error=
|
|
55
|
-
:label="$t('blog:status')"
|
|
56
|
-
:no-options-message="$t('blog:noTemplates')"
|
|
57
|
-
:options=
|
|
50
|
+
<div class="status">
|
|
51
|
+
<div class="status-value">
|
|
52
|
+
<FormFieldSelect
|
|
53
|
+
v-model:value="values.status"
|
|
54
|
+
name="status"
|
|
55
|
+
:error="errors.status"
|
|
56
|
+
:label="$i18n.t('blog:status')"
|
|
57
|
+
:no-options-message="$i18n.t('blog:noTemplates')"
|
|
58
|
+
:options="statusOptions"
|
|
58
59
|
/>
|
|
59
60
|
</div>
|
|
60
|
-
<div
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
<div
|
|
62
|
+
v-if="
|
|
63
|
+
values.status.value === 'PUBLISHED' ||
|
|
64
|
+
values.status.value === 'DRAFT'
|
|
65
|
+
"
|
|
66
|
+
class="status-checkbox"
|
|
67
|
+
>
|
|
68
|
+
<FormFieldCheckbox
|
|
69
|
+
v-model:checked="values.statusDateEnabled"
|
|
70
|
+
name="statusDateEnabled"
|
|
71
|
+
:label="
|
|
72
|
+
$i18n.t(
|
|
73
|
+
values.status.value === 'PUBLISHED'
|
|
74
|
+
? 'blog:scheduleArchive'
|
|
75
|
+
: 'blog:schedulePublish'
|
|
76
|
+
)
|
|
77
|
+
"
|
|
78
|
+
:error="errors.status"
|
|
66
79
|
/>
|
|
67
80
|
</div>
|
|
68
|
-
<div
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
<div
|
|
82
|
+
v-if="
|
|
83
|
+
values.statusDateEnabled &&
|
|
84
|
+
(values.status.value === 'PUBLISHED' ||
|
|
85
|
+
values.status.value === 'DRAFT')
|
|
86
|
+
"
|
|
87
|
+
class="status-date"
|
|
88
|
+
>
|
|
89
|
+
<FormField
|
|
90
|
+
v-model:value="values.statusDate"
|
|
91
|
+
name="statusDate"
|
|
92
|
+
type="date"
|
|
93
|
+
:label="
|
|
94
|
+
$i18n.t(
|
|
95
|
+
values.status.value === 'PUBLISHED'
|
|
96
|
+
? 'blog:archiveAt'
|
|
97
|
+
: 'blog:publishAt'
|
|
98
|
+
)
|
|
99
|
+
"
|
|
100
|
+
:error="errors.statusDate"
|
|
76
101
|
/>
|
|
77
102
|
</div>
|
|
78
103
|
</div>
|
|
79
104
|
|
|
80
|
-
<
|
|
81
|
-
v-model=
|
|
82
|
-
name=
|
|
83
|
-
:label="$t('blog:date')"
|
|
84
|
-
type=
|
|
85
|
-
:error=
|
|
105
|
+
<FormField
|
|
106
|
+
v-model:value="values.datetime"
|
|
107
|
+
name="datetime"
|
|
108
|
+
:label="$i18n.t('blog:date')"
|
|
109
|
+
type="date"
|
|
110
|
+
:error="errors.datetime"
|
|
86
111
|
/>
|
|
87
112
|
|
|
88
|
-
<
|
|
89
|
-
v-model=
|
|
90
|
-
name=
|
|
91
|
-
:label="$t('blog:excerpt')"
|
|
92
|
-
type=
|
|
93
|
-
:error=
|
|
113
|
+
<FormField
|
|
114
|
+
v-model:value="values.excerpt"
|
|
115
|
+
name="excerpt"
|
|
116
|
+
:label="$i18n.t('blog:excerpt')"
|
|
117
|
+
type="textarea"
|
|
118
|
+
:error="errors.excerpt"
|
|
94
119
|
/>
|
|
95
120
|
|
|
96
|
-
<
|
|
97
|
-
v-model=
|
|
98
|
-
name=
|
|
99
|
-
:label="$t('blog:body')"
|
|
100
|
-
:error=
|
|
101
|
-
:get-upload-adapter-options=
|
|
121
|
+
<FormFieldRichTextInput
|
|
122
|
+
v-model:value="values.body"
|
|
123
|
+
name="body"
|
|
124
|
+
:label="$i18n.t('blog:body')"
|
|
125
|
+
:error="errors.body"
|
|
126
|
+
:get-upload-adapter-options="getUploadAdapterOptions"
|
|
102
127
|
/>
|
|
103
128
|
|
|
104
129
|
<ShortCodeConstructor
|
|
105
|
-
:short-code-config-list=
|
|
130
|
+
:short-code-config-list="
|
|
106
131
|
moduleConfig ? moduleConfig.shortcodes : []
|
|
107
|
-
|
|
132
|
+
"
|
|
108
133
|
/>
|
|
109
134
|
</template>
|
|
110
135
|
|
|
111
136
|
<template v-if="selectedTabId === 'images'">
|
|
112
|
-
<
|
|
113
|
-
v-model=
|
|
114
|
-
:label="$t('blog:coverImage')"
|
|
115
|
-
name=
|
|
116
|
-
file-type=
|
|
117
|
-
:scenario=
|
|
137
|
+
<FormFieldFileInput
|
|
138
|
+
v-model:value="values.coverImage"
|
|
139
|
+
:label="$i18n.t('blog:coverImage')"
|
|
140
|
+
name="coverImage"
|
|
141
|
+
file-type="image"
|
|
142
|
+
:scenario="moduleConfig ? moduleConfig.fileScenarios.cover : null"
|
|
118
143
|
/>
|
|
119
144
|
|
|
120
|
-
<
|
|
121
|
-
v-model=
|
|
122
|
-
name=
|
|
123
|
-
:label="$t('blog:innerImage')"
|
|
124
|
-
file-type=
|
|
125
|
-
:scenario=
|
|
145
|
+
<FormFieldFileInput
|
|
146
|
+
v-model:value="values.image"
|
|
147
|
+
name="image"
|
|
148
|
+
:label="$i18n.t('blog:innerImage')"
|
|
149
|
+
file-type="image"
|
|
150
|
+
:scenario="moduleConfig ? moduleConfig.fileScenarios.image : null"
|
|
126
151
|
/>
|
|
127
152
|
|
|
128
|
-
<
|
|
129
|
-
v-model=
|
|
130
|
-
name=
|
|
131
|
-
:label="$t('blog:innerImageMobile')"
|
|
132
|
-
file-type=
|
|
133
|
-
:scenario=
|
|
153
|
+
<FormFieldFileInput
|
|
154
|
+
v-model:value="values.imageMobile"
|
|
155
|
+
name="imageMobile"
|
|
156
|
+
:label="$i18n.t('blog:innerImageMobile')"
|
|
157
|
+
file-type="image"
|
|
158
|
+
:scenario="
|
|
134
159
|
moduleConfig ? moduleConfig.fileScenarios.imageMobile : null
|
|
135
|
-
|
|
160
|
+
"
|
|
136
161
|
/>
|
|
137
162
|
</template>
|
|
138
163
|
|
|
139
164
|
<template v-if="selectedTabId === 'relations'">
|
|
140
|
-
<
|
|
141
|
-
v-model=
|
|
142
|
-
name=
|
|
143
|
-
:label="$t('blog:tags')"
|
|
144
|
-
:error=
|
|
165
|
+
<FormField
|
|
166
|
+
v-model:value="values.tags"
|
|
167
|
+
name="tags"
|
|
168
|
+
:label="$i18n.t('blog:tags')"
|
|
169
|
+
:error="errors.tags"
|
|
145
170
|
/>
|
|
146
171
|
|
|
147
|
-
<
|
|
148
|
-
:selected-options=
|
|
149
|
-
name=
|
|
150
|
-
:label="$t('blog:categories')"
|
|
151
|
-
:options=
|
|
152
|
-
:error=
|
|
153
|
-
@change=
|
|
172
|
+
<FormFieldMultiSelect
|
|
173
|
+
v-model:selected-options="values.categories"
|
|
174
|
+
name="categories"
|
|
175
|
+
:label="$i18n.t('blog:categories')"
|
|
176
|
+
:options="categoryOptionList"
|
|
177
|
+
:error="errors.categories"
|
|
178
|
+
@change="handleCategoriesChange"
|
|
154
179
|
/>
|
|
155
180
|
|
|
156
|
-
<
|
|
157
|
-
v-model=
|
|
158
|
-
name=
|
|
159
|
-
:label="$t('blog:relatedPosts')"
|
|
160
|
-
:options=
|
|
161
|
-
:error=
|
|
162
|
-
:searchable=
|
|
181
|
+
<FormFieldMultiSelect
|
|
182
|
+
v-model:selected-options="values.relatedPosts"
|
|
183
|
+
name="relatedPosts"
|
|
184
|
+
:label="$i18n.t('blog:relatedPosts')"
|
|
185
|
+
:options="postOptionList"
|
|
186
|
+
:error="errors.relatedPosts"
|
|
187
|
+
:searchable="true"
|
|
163
188
|
/>
|
|
164
189
|
</template>
|
|
165
190
|
|
|
166
191
|
<template v-if="selectedTabId === 'additional'">
|
|
167
192
|
<DynamicField
|
|
168
|
-
v-for=
|
|
169
|
-
:key=
|
|
170
|
-
:field=
|
|
193
|
+
v-for="field of values.additionalFields"
|
|
194
|
+
:key="field.name"
|
|
195
|
+
:field="field"
|
|
171
196
|
/>
|
|
172
197
|
</template>
|
|
173
198
|
|
|
174
199
|
<template v-if="selectedTabId === 'seo'">
|
|
175
|
-
<
|
|
176
|
-
:title=
|
|
177
|
-
:title-error-message=
|
|
178
|
-
:title-label="$t('blog:pageTitle')"
|
|
179
|
-
:description=
|
|
180
|
-
:description-error-message=
|
|
181
|
-
:description-label="$t('blog:pageDescription')"
|
|
182
|
-
:image=
|
|
183
|
-
:image-error-message=
|
|
184
|
-
:image-label="$t('blog:openGraphImage')"
|
|
185
|
-
:image-scenario=
|
|
200
|
+
<SeoFieldGroup
|
|
201
|
+
:title="values.pageTitle"
|
|
202
|
+
:title-error-message="errors.pageTitle"
|
|
203
|
+
:title-label="$i18n.t('blog:pageTitle')"
|
|
204
|
+
:description="values.pageDescription"
|
|
205
|
+
:description-error-message="errors.pageDescription"
|
|
206
|
+
:description-label="$i18n.t('blog:pageDescription')"
|
|
207
|
+
:image="values.openGraphImage"
|
|
208
|
+
:image-error-message="errors.openGraphImage"
|
|
209
|
+
:image-label="$i18n.t('blog:openGraphImage')"
|
|
210
|
+
:image-scenario="
|
|
186
211
|
moduleConfig ? moduleConfig.fileScenarios.openGraph : null
|
|
187
|
-
|
|
188
|
-
@change=
|
|
212
|
+
"
|
|
213
|
+
@change="handleSeoFieldGroupChange"
|
|
189
214
|
/>
|
|
190
215
|
</template>
|
|
191
216
|
</form>
|
|
192
217
|
</template>
|
|
193
218
|
|
|
194
|
-
<template
|
|
219
|
+
<template #footer>
|
|
195
220
|
<FormFooter
|
|
196
|
-
:back-href=
|
|
197
|
-
:
|
|
198
|
-
:is-
|
|
199
|
-
:
|
|
200
|
-
|
|
221
|
+
:back-href="postListUrl"
|
|
222
|
+
:is-submitting="isSubmitting"
|
|
223
|
+
:is-creation="isCreation"
|
|
224
|
+
:can-create-another="isCreation"
|
|
225
|
+
@submit="submitForm"
|
|
201
226
|
/>
|
|
202
227
|
</template>
|
|
203
|
-
</
|
|
228
|
+
</Page>
|
|
204
229
|
</template>
|
|
205
230
|
|
|
206
|
-
<script lang=
|
|
207
|
-
import {
|
|
208
|
-
|
|
209
|
-
defineComponent,
|
|
210
|
-
onMounted,
|
|
211
|
-
ref,
|
|
212
|
-
watch
|
|
213
|
-
} from '@vue/composition-api';
|
|
231
|
+
<script lang="ts">
|
|
232
|
+
import { computed, defineComponent, onMounted, ref, watch } from 'vue';
|
|
233
|
+
import { useRoute, useRouter } from 'vue-router';
|
|
214
234
|
|
|
215
235
|
import {
|
|
216
236
|
convertRequestErrorToMap,
|
|
217
237
|
isNotNullish,
|
|
218
238
|
Nullable,
|
|
219
239
|
useResource,
|
|
220
|
-
urlTranslit
|
|
240
|
+
urlTranslit,
|
|
241
|
+
useI18n,
|
|
242
|
+
useToast,
|
|
243
|
+
navigateBack,
|
|
221
244
|
} from '@tager/admin-services';
|
|
222
245
|
import {
|
|
223
246
|
createTabErrorFinder,
|
|
@@ -226,24 +249,30 @@ import {
|
|
|
226
249
|
ShortCodeConstructor,
|
|
227
250
|
SeoChangeEvent,
|
|
228
251
|
FormFooter,
|
|
229
|
-
TagerFormSubmitEvent
|
|
252
|
+
TagerFormSubmitEvent,
|
|
253
|
+
FormFieldSelect,
|
|
254
|
+
FormField,
|
|
255
|
+
FormFieldUrlAliasInput,
|
|
256
|
+
FormFieldCheckbox,
|
|
257
|
+
FormFieldRichTextInput,
|
|
258
|
+
FormFieldFileInput,
|
|
259
|
+
FormFieldMultiSelect,
|
|
260
|
+
SeoFieldGroup,
|
|
230
261
|
} from '@tager/admin-ui';
|
|
231
262
|
import { DynamicField } from '@tager/admin-dynamic-field';
|
|
263
|
+
import { Page } from '@tager/admin-layout';
|
|
232
264
|
|
|
233
|
-
import {
|
|
234
|
-
getBlogPostFormUrl,
|
|
235
|
-
getBlogPostListUrl
|
|
236
|
-
} from '../../../constants/paths';
|
|
265
|
+
import { getBlogPostFormUrl, getBlogPostListUrl } from '../../../utils/paths';
|
|
237
266
|
import {
|
|
238
267
|
createBlogPost,
|
|
239
268
|
getPost,
|
|
240
|
-
updateBlogPost
|
|
269
|
+
updateBlogPost,
|
|
241
270
|
} from '../../../services/requests';
|
|
242
271
|
import { Language, PostFull } from '../../../typings/model';
|
|
243
272
|
import {
|
|
244
273
|
useFetchModuleConfig,
|
|
245
274
|
useFetchCategories,
|
|
246
|
-
useFetchPosts
|
|
275
|
+
useFetchPosts,
|
|
247
276
|
} from '../../../hooks';
|
|
248
277
|
|
|
249
278
|
import {
|
|
@@ -252,28 +281,44 @@ import {
|
|
|
252
281
|
convertFormValuesToUpdatePayload,
|
|
253
282
|
convertPostToFormValues,
|
|
254
283
|
FormValues,
|
|
255
|
-
getStatusOptions
|
|
284
|
+
getStatusOptions,
|
|
256
285
|
} from './PostForm.helpers';
|
|
286
|
+
import TabList from './components/TabList/TabList.vue';
|
|
257
287
|
|
|
258
288
|
export default defineComponent({
|
|
259
289
|
name: 'BlogPostForm',
|
|
260
|
-
components: {
|
|
261
|
-
|
|
262
|
-
|
|
290
|
+
components: {
|
|
291
|
+
SeoFieldGroup,
|
|
292
|
+
FormFieldMultiSelect,
|
|
293
|
+
FormFieldFileInput,
|
|
294
|
+
FormFieldRichTextInput,
|
|
295
|
+
FormFieldCheckbox,
|
|
296
|
+
FormFieldUrlAliasInput,
|
|
297
|
+
FormField,
|
|
298
|
+
FormFieldSelect,
|
|
299
|
+
TabList,
|
|
300
|
+
Page,
|
|
301
|
+
DynamicField,
|
|
302
|
+
ShortCodeConstructor,
|
|
303
|
+
FormFooter,
|
|
304
|
+
},
|
|
305
|
+
setup() {
|
|
306
|
+
const route = useRoute();
|
|
307
|
+
const router = useRouter();
|
|
308
|
+
const toast = useToast();
|
|
309
|
+
const { t } = useI18n();
|
|
310
|
+
|
|
311
|
+
const postId = computed<string>(() => route.params.postId as string);
|
|
263
312
|
const isCreation = computed<boolean>(() => postId.value === 'create');
|
|
264
313
|
|
|
265
314
|
const urlAliasChanged = ref<boolean>(false);
|
|
266
315
|
|
|
267
|
-
const statusOptions = computed<OptionType[]>(() =>
|
|
268
|
-
getStatusOptions(context.root.$t)
|
|
269
|
-
);
|
|
316
|
+
const statusOptions = computed<OptionType[]>(() => getStatusOptions(t));
|
|
270
317
|
|
|
271
318
|
/** Fetch module config **/
|
|
272
319
|
|
|
273
|
-
const {
|
|
274
|
-
|
|
275
|
-
loading: isModuleConfigLoading
|
|
276
|
-
} = useFetchModuleConfig({ context });
|
|
320
|
+
const { data: moduleConfig, loading: isModuleConfigLoading } =
|
|
321
|
+
useFetchModuleConfig();
|
|
277
322
|
|
|
278
323
|
const languageList = computed<Language[]>(
|
|
279
324
|
() => moduleConfig.value?.languages ?? []
|
|
@@ -282,7 +327,7 @@ export default defineComponent({
|
|
|
282
327
|
const languageOptionList = computed<OptionType[]>(() =>
|
|
283
328
|
languageList.value.map(({ id, name }) => ({
|
|
284
329
|
value: id,
|
|
285
|
-
label: name
|
|
330
|
+
label: name,
|
|
286
331
|
}))
|
|
287
332
|
);
|
|
288
333
|
|
|
@@ -290,18 +335,18 @@ export default defineComponent({
|
|
|
290
335
|
|
|
291
336
|
/** Fetch category list */
|
|
292
337
|
|
|
293
|
-
const {
|
|
294
|
-
|
|
295
|
-
loading: isCategoryListLoading
|
|
296
|
-
} = useFetchCategories({ context });
|
|
338
|
+
const { data: categoryList, loading: isCategoryListLoading } =
|
|
339
|
+
useFetchCategories();
|
|
297
340
|
|
|
298
341
|
/** Fetch Post */
|
|
299
342
|
|
|
300
|
-
const [fetchPost, { data: post, loading: isPostLoading }] = useResource<
|
|
301
|
-
|
|
343
|
+
const [fetchPost, { data: post, loading: isPostLoading }] = useResource<
|
|
344
|
+
Nullable<PostFull>
|
|
345
|
+
>({
|
|
346
|
+
fetchResource: () =>
|
|
347
|
+
postId.value ? getPost(postId.value) : new Promise(() => null),
|
|
302
348
|
initialValue: null,
|
|
303
|
-
|
|
304
|
-
resourceName: 'Post'
|
|
349
|
+
resourceName: 'Post',
|
|
305
350
|
});
|
|
306
351
|
|
|
307
352
|
onMounted(() => {
|
|
@@ -317,16 +362,14 @@ export default defineComponent({
|
|
|
317
362
|
});
|
|
318
363
|
|
|
319
364
|
/** Fetch post list */
|
|
320
|
-
const { data: postList, loading: isPostListLoading } = useFetchPosts(
|
|
321
|
-
context
|
|
322
|
-
});
|
|
365
|
+
const { data: postList, loading: isPostListLoading } = useFetchPosts();
|
|
323
366
|
|
|
324
367
|
const postOptionList = computed<OptionType<number>[]>(() =>
|
|
325
368
|
postList.value
|
|
326
369
|
.filter((relatedPost) => relatedPost.id !== post.value?.id)
|
|
327
370
|
.map((post) => ({
|
|
328
371
|
value: post.id,
|
|
329
|
-
label: post.title
|
|
372
|
+
label: post.title,
|
|
330
373
|
}))
|
|
331
374
|
);
|
|
332
375
|
|
|
@@ -368,17 +411,11 @@ export default defineComponent({
|
|
|
368
411
|
errors.value = {};
|
|
369
412
|
|
|
370
413
|
if (event.type === 'create') {
|
|
371
|
-
|
|
372
|
-
getBlogPostFormUrl({ postId: String(data.id) })
|
|
373
|
-
);
|
|
414
|
+
router.push(getBlogPostFormUrl({ postId: String(data.id) }));
|
|
374
415
|
}
|
|
375
416
|
|
|
376
417
|
if (event.type === 'create_exit' || event.type === 'save_exit') {
|
|
377
|
-
|
|
378
|
-
context.root.$router.back();
|
|
379
|
-
} else {
|
|
380
|
-
context.root.$router.push(getBlogPostListUrl());
|
|
381
|
-
}
|
|
418
|
+
navigateBack(router, getBlogPostListUrl());
|
|
382
419
|
}
|
|
383
420
|
|
|
384
421
|
if (event.type === 'create_create-another') {
|
|
@@ -391,23 +428,23 @@ export default defineComponent({
|
|
|
391
428
|
);
|
|
392
429
|
}
|
|
393
430
|
|
|
394
|
-
|
|
431
|
+
toast.show({
|
|
395
432
|
variant: 'success',
|
|
396
|
-
title:
|
|
433
|
+
title: t('blog:success'),
|
|
397
434
|
body: isCreation.value
|
|
398
|
-
?
|
|
399
|
-
:
|
|
435
|
+
? t('blog:blogPostWasSuccessfullyCreated')
|
|
436
|
+
: t('blog:blogPostWasSuccessfullyUpdated'),
|
|
400
437
|
});
|
|
401
438
|
})
|
|
402
439
|
.catch((error) => {
|
|
403
440
|
console.error(error);
|
|
404
441
|
errors.value = convertRequestErrorToMap(error);
|
|
405
|
-
|
|
442
|
+
toast.show({
|
|
406
443
|
variant: 'danger',
|
|
407
|
-
title:
|
|
444
|
+
title: t('blog:error'),
|
|
408
445
|
body: isCreation.value
|
|
409
|
-
?
|
|
410
|
-
:
|
|
446
|
+
? t('blog:blogPostCreationWasFailed')
|
|
447
|
+
: t('blog:blogPostUpdateWasFailed'),
|
|
411
448
|
});
|
|
412
449
|
})
|
|
413
450
|
.finally(() => {
|
|
@@ -473,32 +510,32 @@ export default defineComponent({
|
|
|
473
510
|
return [
|
|
474
511
|
{
|
|
475
512
|
id: 'common',
|
|
476
|
-
label:
|
|
513
|
+
label: t('blog:common'),
|
|
477
514
|
hasErrors: hasErrors([
|
|
478
515
|
'title',
|
|
479
516
|
'language',
|
|
480
517
|
'urlAlias',
|
|
481
518
|
'excerpt',
|
|
482
519
|
'body',
|
|
483
|
-
'date'
|
|
484
|
-
])
|
|
520
|
+
'date',
|
|
521
|
+
]),
|
|
485
522
|
},
|
|
486
523
|
{
|
|
487
524
|
id: 'images',
|
|
488
|
-
label:
|
|
489
|
-
hasErrors: hasErrors(['coverImage', 'image'])
|
|
525
|
+
label: t('blog:images'),
|
|
526
|
+
hasErrors: hasErrors(['coverImage', 'image']),
|
|
490
527
|
},
|
|
491
528
|
{
|
|
492
529
|
id: 'relations',
|
|
493
|
-
label:
|
|
494
|
-
hasErrors: hasErrors(['categories', 'relatedPosts', 'tags'])
|
|
530
|
+
label: t('blog:relations'),
|
|
531
|
+
hasErrors: hasErrors(['categories', 'relatedPosts', 'tags']),
|
|
495
532
|
},
|
|
496
533
|
values.value.additionalFields.length > 0
|
|
497
534
|
? {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
535
|
+
id: 'additional',
|
|
536
|
+
label: t('blog:additionalFields'),
|
|
537
|
+
hasErrors: hasErrors([]),
|
|
538
|
+
}
|
|
502
539
|
: null,
|
|
503
540
|
{
|
|
504
541
|
id: 'seo',
|
|
@@ -506,31 +543,33 @@ export default defineComponent({
|
|
|
506
543
|
hasErrors: hasErrors([
|
|
507
544
|
'pageTitle',
|
|
508
545
|
'pageDescription',
|
|
509
|
-
'openGraphImage'
|
|
510
|
-
])
|
|
511
|
-
}
|
|
546
|
+
'openGraphImage',
|
|
547
|
+
]),
|
|
548
|
+
},
|
|
512
549
|
].filter(isNotNullish);
|
|
513
550
|
});
|
|
514
551
|
|
|
515
552
|
const selectedTabId = ref<string>(tabList.value[0].id);
|
|
516
553
|
|
|
517
|
-
const headerButtonList = computed<
|
|
554
|
+
const headerButtonList = computed<
|
|
555
|
+
{ text: string; href: string; target?: string }[]
|
|
556
|
+
>(() =>
|
|
518
557
|
[
|
|
519
558
|
post.value
|
|
520
559
|
? {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
: null
|
|
560
|
+
text: t('blog:viewPost'),
|
|
561
|
+
href: process.env.VUE_APP_WEBSITE_URL + post.value.url,
|
|
562
|
+
target: '_blank',
|
|
563
|
+
}
|
|
564
|
+
: null,
|
|
526
565
|
].filter(isNotNullish)
|
|
527
566
|
);
|
|
528
567
|
|
|
529
568
|
function handleSeoFieldGroupChange({
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
569
|
+
title,
|
|
570
|
+
description,
|
|
571
|
+
image,
|
|
572
|
+
}: SeoChangeEvent) {
|
|
534
573
|
values.value.pageTitle = title;
|
|
535
574
|
values.value.pageDescription = description;
|
|
536
575
|
values.value.openGraphImage = image;
|
|
@@ -579,7 +618,7 @@ export default defineComponent({
|
|
|
579
618
|
|
|
580
619
|
const newSelectedOption: OptionType<number> = {
|
|
581
620
|
value: foundSelectedCategory.id,
|
|
582
|
-
label: foundSelectedCategory.name
|
|
621
|
+
label: foundSelectedCategory.name,
|
|
583
622
|
};
|
|
584
623
|
|
|
585
624
|
if (
|
|
@@ -626,13 +665,13 @@ export default defineComponent({
|
|
|
626
665
|
urlAliasTemplate,
|
|
627
666
|
handleCategoriesChange,
|
|
628
667
|
|
|
629
|
-
statusOptions
|
|
668
|
+
statusOptions,
|
|
630
669
|
};
|
|
631
|
-
}
|
|
670
|
+
},
|
|
632
671
|
});
|
|
633
672
|
</script>
|
|
634
673
|
|
|
635
|
-
<style scoped lang=
|
|
674
|
+
<style scoped lang="scss">
|
|
636
675
|
.status {
|
|
637
676
|
display: flex;
|
|
638
677
|
align-items: flex-end;
|
|
@@ -651,4 +690,4 @@ export default defineComponent({
|
|
|
651
690
|
margin-left: 20px;
|
|
652
691
|
flex: 1 1 1px;
|
|
653
692
|
}
|
|
654
|
-
</style>
|
|
693
|
+
</style>
|