@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.
@@ -1,168 +1,191 @@
1
1
  <template>
2
2
  <page
3
3
  :title="isCreation ? $t('blog:createPost') : $t('blog:updatePost')"
4
- :is-content-loading="isContentLoading"
5
- :header-buttons="headerButtonList"
6
- :footer="{
4
+ :is-content-loading='isContentLoading'
5
+ :header-buttons='headerButtonList'
6
+ :footer='{
7
7
  backHref: postListUrl,
8
8
  onSubmit: submitForm,
9
9
  isSubmitting: isSubmitting,
10
- }"
10
+ }'
11
11
  >
12
12
  <template v-slot:content>
13
- <form novalidate @submit.prevent="submitForm">
13
+ <form novalidate @submit.prevent='submitForm'>
14
14
  <tab-list
15
- :tab-list="tabList"
16
- :selected-tab-id="selectedTabId"
17
- @tab:update="selectedTabId = $event.tabId"
15
+ :tab-list='tabList'
16
+ :selected-tab-id='selectedTabId'
17
+ @tab:update='selectedTabId = $event.tabId'
18
18
  />
19
19
 
20
20
  <template v-if="selectedTabId === 'common'">
21
- <form-field-select
22
- v-model="values.status"
23
- name="status"
24
- :error="errors.status"
25
- :label="$t('blog:status')"
26
- :no-options-message="$t('blog:noTemplates')"
27
- :options="statusOptions"
28
- />
29
21
 
30
22
  <form-field-select
31
- v-if="isCreation && isLangSpecific"
32
- v-model="values.language"
33
- name="language"
23
+ v-if='isCreation && isLangSpecific'
24
+ v-model='values.language'
25
+ name='language'
34
26
  :label="$t('blog:language')"
35
- :options="languageOptionList"
36
- :error="errors.language"
27
+ :options='languageOptionList'
28
+ :error='errors.language'
37
29
  />
38
30
 
39
31
  <form-field
40
- v-model="values.title"
41
- name="title"
32
+ v-model='values.title'
33
+ name='title'
42
34
  :label="$t('blog:title')"
43
- :error="errors.title"
44
- @input="handleTitleChange"
35
+ :error='errors.title'
36
+ @input='handleTitleChange'
45
37
  />
46
38
 
47
39
  <form-field-url-alias-input
48
- id="urlAlias"
49
- v-model="values.urlAlias"
50
- name="urlAlias"
40
+ id='urlAlias'
41
+ v-model='values.urlAlias'
42
+ name='urlAlias'
51
43
  :label="$t('blog:link')"
52
- :url-template="urlAliasTemplate"
53
- :error="errors.urlAlias"
54
- @change="handleAliasChange"
44
+ :url-template='urlAliasTemplate'
45
+ :error='errors.urlAlias'
46
+ @change='handleAliasChange'
47
+ />
48
+
49
+ <div class='status'>
50
+ <div class='status-value'>
51
+ <form-field-select
52
+ v-model='values.status'
53
+ name='status'
54
+ :error='errors.status'
55
+ :label="$t('blog:status')"
56
+ :no-options-message="$t('blog:noTemplates')"
57
+ :options='statusOptions'
58
+ />
59
+ </div>
60
+ <div class='status-checkbox' v-if='values.status.value === "PUBLISHED" || values.status.value === "DRAFT"'>
61
+ <form-field-checkbox
62
+ v-model='values.statusDateEnabled'
63
+ name='statusDateEnabled'
64
+ :label="$t(values.status.value === 'PUBLISHED' ? 'blog:scheduleArchive' : 'blog:schedulePublish')"
65
+ :error='errors.status'
66
+ />
67
+ </div>
68
+ <div class='status-date'
69
+ v-if='values.statusDateEnabled && (values.status.value === "PUBLISHED" || values.status.value === "DRAFT")'>
70
+ <form-field
71
+ v-model='values.statusDate'
72
+ name='statusDate'
73
+ type='date'
74
+ :label="$t(values.status.value === 'PUBLISHED' ? 'blog:archiveAt' : 'blog:publishAt')"
75
+ :error='errors.statusDate'
76
+ />
77
+ </div>
78
+ </div>
79
+
80
+ <form-field
81
+ v-model='values.datetime'
82
+ name='datetime'
83
+ :label="$t('blog:date')"
84
+ type='date'
85
+ :error='errors.datetime'
55
86
  />
56
87
 
57
88
  <form-field
58
- v-model="values.excerpt"
59
- name="excerpt"
89
+ v-model='values.excerpt'
90
+ name='excerpt'
60
91
  :label="$t('blog:excerpt')"
61
- type="textarea"
62
- :error="errors.excerpt"
92
+ type='textarea'
93
+ :error='errors.excerpt'
63
94
  />
64
95
 
65
96
  <form-field-rich-text-input
66
- v-model="values.body"
67
- name="body"
97
+ v-model='values.body'
98
+ name='body'
68
99
  :label="$t('blog:body')"
69
- :error="errors.body"
70
- :get-upload-adapter-options="getUploadAdapterOptions"
100
+ :error='errors.body'
101
+ :get-upload-adapter-options='getUploadAdapterOptions'
71
102
  />
72
103
 
73
104
  <ShortCodeConstructor
74
- :short-code-config-list="
105
+ :short-code-config-list='
75
106
  moduleConfig ? moduleConfig.shortcodes : []
76
- "
77
- />
78
-
79
- <form-field
80
- v-model="values.datetime"
81
- name="datetime"
82
- :label="$t('blog:date')"
83
- type="date"
84
- :error="errors.datetime"
107
+ '
85
108
  />
86
109
  </template>
87
110
 
88
111
  <template v-if="selectedTabId === 'images'">
89
112
  <form-field-file-input
90
- v-model="values.coverImage"
113
+ v-model='values.coverImage'
91
114
  :label="$t('blog:coverImage')"
92
- name="coverImage"
93
- file-type="image"
94
- :scenario="moduleConfig ? moduleConfig.fileScenarios.cover : null"
115
+ name='coverImage'
116
+ file-type='image'
117
+ :scenario='moduleConfig ? moduleConfig.fileScenarios.cover : null'
95
118
  />
96
119
 
97
120
  <form-field-file-input
98
- v-model="values.image"
99
- name="image"
121
+ v-model='values.image'
122
+ name='image'
100
123
  :label="$t('blog:innerImage')"
101
- file-type="image"
102
- :scenario="moduleConfig ? moduleConfig.fileScenarios.image : null"
124
+ file-type='image'
125
+ :scenario='moduleConfig ? moduleConfig.fileScenarios.image : null'
103
126
  />
104
127
 
105
128
  <form-field-file-input
106
- v-model="values.imageMobile"
107
- name="imageMobile"
129
+ v-model='values.imageMobile'
130
+ name='imageMobile'
108
131
  :label="$t('blog:innerImageMobile')"
109
- file-type="image"
110
- :scenario="
132
+ file-type='image'
133
+ :scenario='
111
134
  moduleConfig ? moduleConfig.fileScenarios.imageMobile : null
112
- "
135
+ '
113
136
  />
114
137
  </template>
115
138
 
116
139
  <template v-if="selectedTabId === 'relations'">
117
140
  <form-field
118
- v-model="values.tags"
119
- name="tags"
141
+ v-model='values.tags'
142
+ name='tags'
120
143
  :label="$t('blog:tags')"
121
- :error="errors.tags"
144
+ :error='errors.tags'
122
145
  />
123
146
 
124
147
  <form-field-multi-select
125
- :selected-options="values.categories"
126
- name="categories"
148
+ :selected-options='values.categories'
149
+ name='categories'
127
150
  :label="$t('blog:categories')"
128
- :options="categoryOptionList"
129
- :error="errors.categories"
130
- @change="handleCategoriesChange"
151
+ :options='categoryOptionList'
152
+ :error='errors.categories'
153
+ @change='handleCategoriesChange'
131
154
  />
132
155
 
133
156
  <form-field-multi-select
134
- v-model="values.relatedPosts"
135
- name="relatedPosts"
157
+ v-model='values.relatedPosts'
158
+ name='relatedPosts'
136
159
  :label="$t('blog:relatedPosts')"
137
- :options="postOptionList"
138
- :error="errors.relatedPosts"
139
- :searchable="true"
160
+ :options='postOptionList'
161
+ :error='errors.relatedPosts'
162
+ :searchable='true'
140
163
  />
141
164
  </template>
142
165
 
143
166
  <template v-if="selectedTabId === 'additional'">
144
167
  <DynamicField
145
- v-for="field of values.additionalFields"
146
- :key="field.name"
147
- :field="field"
168
+ v-for='field of values.additionalFields'
169
+ :key='field.name'
170
+ :field='field'
148
171
  />
149
172
  </template>
150
173
 
151
174
  <template v-if="selectedTabId === 'seo'">
152
175
  <seo-field-group
153
- :title="values.pageTitle"
154
- :title-error-message="errors.pageTitle"
176
+ :title='values.pageTitle'
177
+ :title-error-message='errors.pageTitle'
155
178
  :title-label="$t('blog:pageTitle')"
156
- :description="values.pageDescription"
157
- :description-error-message="errors.pageDescription"
179
+ :description='values.pageDescription'
180
+ :description-error-message='errors.pageDescription'
158
181
  :description-label="$t('blog:pageDescription')"
159
- :image="values.openGraphImage"
160
- :image-error-message="errors.openGraphImage"
182
+ :image='values.openGraphImage'
183
+ :image-error-message='errors.openGraphImage'
161
184
  :image-label="$t('blog:openGraphImage')"
162
- :image-scenario="
185
+ :image-scenario='
163
186
  moduleConfig ? moduleConfig.fileScenarios.openGraph : null
164
- "
165
- @change="handleSeoFieldGroupChange"
187
+ '
188
+ @change='handleSeoFieldGroupChange'
166
189
  />
167
190
  </template>
168
191
  </form>
@@ -170,23 +193,23 @@
170
193
 
171
194
  <template v-slot:footer>
172
195
  <FormFooter
173
- :back-href="postListUrl"
174
- :on-submit="submitForm"
175
- :is-submitting="isSubmitting"
176
- :is-creation="isCreation"
177
- :can-create-another="isCreation"
196
+ :back-href='postListUrl'
197
+ :on-submit='submitForm'
198
+ :is-submitting='isSubmitting'
199
+ :is-creation='isCreation'
200
+ :can-create-another='isCreation'
178
201
  />
179
202
  </template>
180
203
  </page>
181
204
  </template>
182
205
 
183
- <script lang="ts">
206
+ <script lang='ts'>
184
207
  import {
185
208
  computed,
186
209
  defineComponent,
187
210
  onMounted,
188
211
  ref,
189
- watch,
212
+ watch
190
213
  } from '@vue/composition-api';
191
214
 
192
215
  import {
@@ -194,7 +217,7 @@ import {
194
217
  isNotNullish,
195
218
  Nullable,
196
219
  useResource,
197
- urlTranslit,
220
+ urlTranslit
198
221
  } from '@tager/admin-services';
199
222
  import {
200
223
  createTabErrorFinder,
@@ -203,24 +226,24 @@ import {
203
226
  ShortCodeConstructor,
204
227
  SeoChangeEvent,
205
228
  FormFooter,
206
- TagerFormSubmitEvent,
229
+ TagerFormSubmitEvent
207
230
  } from '@tager/admin-ui';
208
231
  import { DynamicField } from '@tager/admin-dynamic-field';
209
232
 
210
233
  import {
211
234
  getBlogPostFormUrl,
212
- getBlogPostListUrl,
235
+ getBlogPostListUrl
213
236
  } from '../../../constants/paths';
214
237
  import {
215
238
  createBlogPost,
216
239
  getPost,
217
- updateBlogPost,
240
+ updateBlogPost
218
241
  } from '../../../services/requests';
219
242
  import { Language, PostFull } from '../../../typings/model';
220
243
  import {
221
244
  useFetchModuleConfig,
222
245
  useFetchCategories,
223
- useFetchPosts,
246
+ useFetchPosts
224
247
  } from '../../../hooks';
225
248
 
226
249
  import {
@@ -229,7 +252,7 @@ import {
229
252
  convertFormValuesToUpdatePayload,
230
253
  convertPostToFormValues,
231
254
  FormValues,
232
- getStatusOptions,
255
+ getStatusOptions
233
256
  } from './PostForm.helpers';
234
257
 
235
258
  export default defineComponent({
@@ -249,7 +272,7 @@ export default defineComponent({
249
272
 
250
273
  const {
251
274
  data: moduleConfig,
252
- loading: isModuleConfigLoading,
275
+ loading: isModuleConfigLoading
253
276
  } = useFetchModuleConfig({ context });
254
277
 
255
278
  const languageList = computed<Language[]>(
@@ -259,7 +282,7 @@ export default defineComponent({
259
282
  const languageOptionList = computed<OptionType[]>(() =>
260
283
  languageList.value.map(({ id, name }) => ({
261
284
  value: id,
262
- label: name,
285
+ label: name
263
286
  }))
264
287
  );
265
288
 
@@ -269,18 +292,16 @@ export default defineComponent({
269
292
 
270
293
  const {
271
294
  data: categoryList,
272
- loading: isCategoryListLoading,
295
+ loading: isCategoryListLoading
273
296
  } = useFetchCategories({ context });
274
297
 
275
298
  /** Fetch Post */
276
299
 
277
- const [fetchPost, { data: post, loading: isPostLoading }] = useResource<
278
- Nullable<PostFull>
279
- >({
300
+ const [fetchPost, { data: post, loading: isPostLoading }] = useResource<Nullable<PostFull>>({
280
301
  fetchResource: () => getPost(postId.value),
281
302
  initialValue: null,
282
303
  context,
283
- resourceName: 'Post',
304
+ resourceName: 'Post'
284
305
  });
285
306
 
286
307
  onMounted(() => {
@@ -297,7 +318,7 @@ export default defineComponent({
297
318
 
298
319
  /** Fetch post list */
299
320
  const { data: postList, loading: isPostListLoading } = useFetchPosts({
300
- context,
321
+ context
301
322
  });
302
323
 
303
324
  const postOptionList = computed<OptionType<number>[]>(() =>
@@ -305,7 +326,7 @@ export default defineComponent({
305
326
  .filter((relatedPost) => relatedPost.id !== post.value?.id)
306
327
  .map((post) => ({
307
328
  value: post.id,
308
- label: post.title,
329
+ label: post.title
309
330
  }))
310
331
  );
311
332
 
@@ -375,7 +396,7 @@ export default defineComponent({
375
396
  title: context.root.$t('blog:success'),
376
397
  body: isCreation.value
377
398
  ? context.root.$t('blog:blogPostWasSuccessfullyCreated')
378
- : context.root.$t('blog:blogPostWasSuccessfullyUpdated'),
399
+ : context.root.$t('blog:blogPostWasSuccessfullyUpdated')
379
400
  });
380
401
  })
381
402
  .catch((error) => {
@@ -386,7 +407,7 @@ export default defineComponent({
386
407
  title: context.root.$t('blog:error'),
387
408
  body: isCreation.value
388
409
  ? context.root.$t('blog:blogPostCreationWasFailed')
389
- : context.root.$t('blog:blogPostUpdateWasFailed'),
410
+ : context.root.$t('blog:blogPostUpdateWasFailed')
390
411
  });
391
412
  })
392
413
  .finally(() => {
@@ -459,25 +480,25 @@ export default defineComponent({
459
480
  'urlAlias',
460
481
  'excerpt',
461
482
  'body',
462
- 'date',
463
- ]),
483
+ 'date'
484
+ ])
464
485
  },
465
486
  {
466
487
  id: 'images',
467
488
  label: context.root.$t('blog:images'),
468
- hasErrors: hasErrors(['coverImage', 'image']),
489
+ hasErrors: hasErrors(['coverImage', 'image'])
469
490
  },
470
491
  {
471
492
  id: 'relations',
472
493
  label: context.root.$t('blog:relations'),
473
- hasErrors: hasErrors(['categories', 'relatedPosts', 'tags']),
494
+ hasErrors: hasErrors(['categories', 'relatedPosts', 'tags'])
474
495
  },
475
496
  values.value.additionalFields.length > 0
476
497
  ? {
477
- id: 'additional',
478
- label: context.root.$t('blog:additionalFields'),
479
- hasErrors: hasErrors([]),
480
- }
498
+ id: 'additional',
499
+ label: context.root.$t('blog:additionalFields'),
500
+ hasErrors: hasErrors([])
501
+ }
481
502
  : null,
482
503
  {
483
504
  id: 'seo',
@@ -485,33 +506,31 @@ export default defineComponent({
485
506
  hasErrors: hasErrors([
486
507
  'pageTitle',
487
508
  'pageDescription',
488
- 'openGraphImage',
489
- ]),
490
- },
509
+ 'openGraphImage'
510
+ ])
511
+ }
491
512
  ].filter(isNotNullish);
492
513
  });
493
514
 
494
515
  const selectedTabId = ref<string>(tabList.value[0].id);
495
516
 
496
- const headerButtonList = computed<
497
- { text: string; href: string; target?: string }[]
498
- >(() =>
517
+ const headerButtonList = computed<{ text: string; href: string; target?: string }[]>(() =>
499
518
  [
500
519
  post.value
501
520
  ? {
502
- text: context.root.$t('blog:viewPost'),
503
- href: process.env.VUE_APP_WEBSITE_URL + post.value.url,
504
- target: '_blank',
505
- }
506
- : null,
521
+ text: context.root.$t('blog:viewPost'),
522
+ href: process.env.VUE_APP_WEBSITE_URL + post.value.url,
523
+ target: '_blank'
524
+ }
525
+ : null
507
526
  ].filter(isNotNullish)
508
527
  );
509
528
 
510
529
  function handleSeoFieldGroupChange({
511
- title,
512
- description,
513
- image,
514
- }: SeoChangeEvent) {
530
+ title,
531
+ description,
532
+ image
533
+ }: SeoChangeEvent) {
515
534
  values.value.pageTitle = title;
516
535
  values.value.pageDescription = description;
517
536
  values.value.openGraphImage = image;
@@ -560,7 +579,7 @@ export default defineComponent({
560
579
 
561
580
  const newSelectedOption: OptionType<number> = {
562
581
  value: foundSelectedCategory.id,
563
- label: foundSelectedCategory.name,
582
+ label: foundSelectedCategory.name
564
583
  };
565
584
 
566
585
  if (
@@ -607,8 +626,29 @@ export default defineComponent({
607
626
  urlAliasTemplate,
608
627
  handleCategoriesChange,
609
628
 
610
- statusOptions,
629
+ statusOptions
611
630
  };
612
- },
631
+ }
613
632
  });
614
633
  </script>
634
+
635
+ <style scoped lang='scss'>
636
+ .status {
637
+ display: flex;
638
+ align-items: flex-end;
639
+ }
640
+
641
+ .status-value {
642
+ flex-basis: 50%;
643
+ }
644
+
645
+ .status-checkbox {
646
+ margin-left: 20px;
647
+ padding-bottom: 8px;
648
+ }
649
+
650
+ .status-date {
651
+ margin-left: 20px;
652
+ flex: 1 1 1px;
653
+ }
654
+ </style>
@@ -66,10 +66,9 @@ export function getPostTableColumnDefs(
66
66
  field: 'status',
67
67
  style: { width: '120px' },
68
68
  headStyle: { width: '120px' },
69
- format: ({ row }) => getStatuses(t)[row.status],
70
69
  },
71
70
  {
72
- id: 2,
71
+ id: 3,
73
72
  name: t('blog:name'),
74
73
  field: 'name',
75
74
  type: 'name',
@@ -88,7 +87,7 @@ export function getPostTableColumnDefs(
88
87
  }),
89
88
  },
90
89
  {
91
- id: 3,
90
+ id: 4,
92
91
  name: t('blog:image'),
93
92
  field: 'image',
94
93
  type: 'image',
@@ -96,24 +95,24 @@ export function getPostTableColumnDefs(
96
95
  headStyle: { width: '250px' },
97
96
  },
98
97
  isLangSpecific
99
- ? { id: 4, name: t('blog:language'), field: 'language' }
98
+ ? { id: 5, name: t('blog:language'), field: 'language' }
100
99
  : null,
101
100
  {
102
- id: 5,
101
+ id: 6,
103
102
  name: t('blog:date'),
104
103
  field: 'datetime',
105
104
  type: 'datetime',
106
105
  options: { ignoreStartOfDayTime: true },
107
106
  },
108
107
  {
109
- id: 6,
108
+ id: 7,
110
109
  name: t('blog:categories'),
111
110
  field: 'categories',
112
111
  format: ({ row }) =>
113
112
  row.categories.map((category) => category.name).join(', '),
114
113
  },
115
114
  {
116
- id: 7,
115
+ id: 8,
117
116
  name: t('blog:actions'),
118
117
  field: 'actions',
119
118
  style: { whiteSpace: 'nowrap', width: '120px' },