@tager/admin-blog 0.3.36 → 0.3.40
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 +216 -118
- package/dist/index.umd.js +215 -117
- package/dist/locales/en.d.ts +4 -0
- package/dist/services/requests.d.ts +1 -1
- package/dist/typings/model.d.ts +2 -2
- package/dist/views/Posts/PostForm/PostForm.helpers.d.ts +5 -2
- package/dist/views/Posts/PostForm/PostForm.vue.d.ts +14 -2
- package/dist/views/Posts/PostList/PostList.helpers.d.ts +1 -0
- package/dist/views/Posts/PostList/PostList.vue.d.ts +13 -9
- package/dist/views/Posts/PostList/hooks/useAdvancedSearch.d.ts +3 -1
- package/package.json +1 -1
- package/src/locales/en.ts +5 -0
- package/src/locales/ru.ts +5 -0
- package/src/services/requests.ts +1 -1
- package/src/typings/model.ts +2 -2
- package/src/views/Posts/PostForm/PostForm.helpers.ts +24 -8
- package/src/views/Posts/PostForm/PostForm.vue +28 -7
- package/src/views/Posts/PostList/PostList.helpers.ts +23 -1
- package/src/views/Posts/PostList/PostList.vue +17 -0
- package/src/views/Posts/PostList/hooks/useAdvancedSearch.ts +35 -0
|
@@ -9,7 +9,7 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
9
9
|
title: string;
|
|
10
10
|
excerpt: string;
|
|
11
11
|
body: string;
|
|
12
|
-
|
|
12
|
+
datetime: string;
|
|
13
13
|
coverImage: {
|
|
14
14
|
id: string;
|
|
15
15
|
file: {
|
|
@@ -4657,6 +4657,11 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
4657
4657
|
};
|
|
4658
4658
|
value: null;
|
|
4659
4659
|
})[];
|
|
4660
|
+
status: {
|
|
4661
|
+
value: string;
|
|
4662
|
+
label: string;
|
|
4663
|
+
disabled?: boolean | undefined;
|
|
4664
|
+
};
|
|
4660
4665
|
}>;
|
|
4661
4666
|
errors: import("@vue/composition-api").Ref<{
|
|
4662
4667
|
[x: string]: string;
|
|
@@ -4684,6 +4689,7 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
4684
4689
|
handleAliasChange: () => void;
|
|
4685
4690
|
urlAliasTemplate: import("@vue/composition-api").ComputedRef<string>;
|
|
4686
4691
|
handleCategoriesChange: (selectedOptions: OptionType<number>[]) => void;
|
|
4692
|
+
statusOptions: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
4687
4693
|
}> & {
|
|
4688
4694
|
[key: string]: unknown;
|
|
4689
4695
|
}, {}, {}, unknown, {
|
|
@@ -4699,7 +4705,7 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
4699
4705
|
title: string;
|
|
4700
4706
|
excerpt: string;
|
|
4701
4707
|
body: string;
|
|
4702
|
-
|
|
4708
|
+
datetime: string;
|
|
4703
4709
|
coverImage: {
|
|
4704
4710
|
id: string;
|
|
4705
4711
|
file: {
|
|
@@ -9347,6 +9353,11 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
9347
9353
|
};
|
|
9348
9354
|
value: null;
|
|
9349
9355
|
})[];
|
|
9356
|
+
status: {
|
|
9357
|
+
value: string;
|
|
9358
|
+
label: string;
|
|
9359
|
+
disabled?: boolean | undefined;
|
|
9360
|
+
};
|
|
9350
9361
|
}>;
|
|
9351
9362
|
errors: import("@vue/composition-api").Ref<{
|
|
9352
9363
|
[x: string]: string;
|
|
@@ -9374,6 +9385,7 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
9374
9385
|
handleAliasChange: () => void;
|
|
9375
9386
|
urlAliasTemplate: import("@vue/composition-api").ComputedRef<string>;
|
|
9376
9387
|
handleCategoriesChange: (selectedOptions: OptionType<number>[]) => void;
|
|
9388
|
+
statusOptions: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
9377
9389
|
}>, {
|
|
9378
9390
|
[x: string]: any;
|
|
9379
9391
|
}, {}, {}, {
|
|
@@ -3,4 +3,5 @@ import { Nullable } from '@tager/admin-services';
|
|
|
3
3
|
import { ColumnDefinition } from '@tager/admin-ui';
|
|
4
4
|
import { Category, ModuleConfig, Language, PostShort } from '../../../typings/model';
|
|
5
5
|
export declare function convertPostList(postList: PostShort[], selectedCategory: Nullable<Category>, languages: Language[]): PostShort[];
|
|
6
|
+
export declare function getStatuses(t: TFunction): Record<string, string>;
|
|
6
7
|
export declare function getPostTableColumnDefs(moduleConfig: Nullable<ModuleConfig>, t: TFunction): ColumnDefinition<PostShort>[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnDefinition } from '@tager/admin-ui';
|
|
1
|
+
import { ColumnDefinition, OptionType } from '@tager/admin-ui';
|
|
2
2
|
import { getBlogPostFormUrl } from '../../../constants/paths';
|
|
3
3
|
import { Category, PostShort } from '../../../typings/model';
|
|
4
4
|
declare const _default: import("vue").ComponentOptions<import("vue").default, import("@vue/composition-api").ShallowUnwrapRef<{
|
|
@@ -16,13 +16,15 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
16
16
|
pageNumber: import("@vue/composition-api").Ref<number>;
|
|
17
17
|
pageCount: import("@vue/composition-api").ComputedRef<number>;
|
|
18
18
|
pageSize: import("@vue/composition-api").Ref<number>;
|
|
19
|
-
categoryFilter: import("@vue/composition-api").Ref<
|
|
20
|
-
categoryOptionList: import("@vue/composition-api").ComputedRef<
|
|
19
|
+
categoryFilter: import("@vue/composition-api").Ref<OptionType<string>[]>;
|
|
20
|
+
categoryOptionList: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
21
21
|
isLangSpecific: import("@vue/composition-api").ComputedRef<boolean>;
|
|
22
|
-
languageFilter: import("@vue/composition-api").Ref<
|
|
23
|
-
languageOptionList: import("@vue/composition-api").ComputedRef<
|
|
22
|
+
languageFilter: import("@vue/composition-api").Ref<OptionType<string>[]>;
|
|
23
|
+
languageOptionList: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
24
24
|
fromDateFilter: import("@vue/composition-api").Ref<string>;
|
|
25
25
|
toDateFilter: import("@vue/composition-api").Ref<string>;
|
|
26
|
+
statusFilter: import("@vue/composition-api").Ref<OptionType<string>[]>;
|
|
27
|
+
statusOptionList: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
26
28
|
tags: import("@vue/composition-api").ComputedRef<import("@tager/admin-ui").FilterTagType[]>;
|
|
27
29
|
tagRemovalHandler: (event: import("@tager/admin-ui").FilterTagType) => void;
|
|
28
30
|
handleResourceClone: (entityId: string | number) => void;
|
|
@@ -48,13 +50,15 @@ declare const _default: import("vue").ComponentOptions<import("vue").default, im
|
|
|
48
50
|
pageNumber: import("@vue/composition-api").Ref<number>;
|
|
49
51
|
pageCount: import("@vue/composition-api").ComputedRef<number>;
|
|
50
52
|
pageSize: import("@vue/composition-api").Ref<number>;
|
|
51
|
-
categoryFilter: import("@vue/composition-api").Ref<
|
|
52
|
-
categoryOptionList: import("@vue/composition-api").ComputedRef<
|
|
53
|
+
categoryFilter: import("@vue/composition-api").Ref<OptionType<string>[]>;
|
|
54
|
+
categoryOptionList: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
53
55
|
isLangSpecific: import("@vue/composition-api").ComputedRef<boolean>;
|
|
54
|
-
languageFilter: import("@vue/composition-api").Ref<
|
|
55
|
-
languageOptionList: import("@vue/composition-api").ComputedRef<
|
|
56
|
+
languageFilter: import("@vue/composition-api").Ref<OptionType<string>[]>;
|
|
57
|
+
languageOptionList: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
56
58
|
fromDateFilter: import("@vue/composition-api").Ref<string>;
|
|
57
59
|
toDateFilter: import("@vue/composition-api").Ref<string>;
|
|
60
|
+
statusFilter: import("@vue/composition-api").Ref<OptionType<string>[]>;
|
|
61
|
+
statusOptionList: import("@vue/composition-api").ComputedRef<OptionType<string>[]>;
|
|
58
62
|
tags: import("@vue/composition-api").ComputedRef<import("@tager/admin-ui").FilterTagType[]>;
|
|
59
63
|
tagRemovalHandler: (event: import("@tager/admin-ui").FilterTagType) => void;
|
|
60
64
|
handleResourceClone: (entityId: string | number) => void;
|
|
@@ -5,6 +5,7 @@ interface Params {
|
|
|
5
5
|
context: SetupContext;
|
|
6
6
|
categoryList: ComputedRef<Category[]>;
|
|
7
7
|
languageList: ComputedRef<Language[]>;
|
|
8
|
+
statusOptionList: ComputedRef<OptionType[]>;
|
|
8
9
|
}
|
|
9
10
|
interface State {
|
|
10
11
|
categoryFilter: Ref<OptionType[]>;
|
|
@@ -13,10 +14,11 @@ interface State {
|
|
|
13
14
|
languageOptionList: ComputedRef<OptionType[]>;
|
|
14
15
|
fromDateFilter: Ref<string>;
|
|
15
16
|
toDateFilter: Ref<string>;
|
|
17
|
+
statusFilter: Ref<OptionType[]>;
|
|
16
18
|
filterParams: ComputedRef<Record<string, string | string[]>>;
|
|
17
19
|
tags: ComputedRef<FilterTagType[]>;
|
|
18
20
|
tagRemovalHandler(event: FilterTagType): void;
|
|
19
21
|
}
|
|
20
22
|
export declare const dateFormat: (date: string) => string;
|
|
21
|
-
export declare function useAdvancedSearch({ context, categoryList, languageList, }: Params): State;
|
|
23
|
+
export declare function useAdvancedSearch({ context, categoryList, languageList, statusOptionList, }: Params): State;
|
|
22
24
|
export {};
|
package/package.json
CHANGED
package/src/locales/en.ts
CHANGED
package/src/locales/ru.ts
CHANGED
|
@@ -77,6 +77,11 @@ const RU: typeof EN = {
|
|
|
77
77
|
|
|
78
78
|
parentCategory: 'Родительская категория',
|
|
79
79
|
noParent: 'Нет родительской',
|
|
80
|
+
|
|
81
|
+
status: 'Статус',
|
|
82
|
+
statusPublished: 'Опубликован',
|
|
83
|
+
statusDraft: 'Черновик',
|
|
84
|
+
statusArchived: 'В архиве',
|
|
80
85
|
};
|
|
81
86
|
|
|
82
87
|
export default RU;
|
package/src/services/requests.ts
CHANGED
package/src/typings/model.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface PostShort {
|
|
|
40
40
|
readonly status: string;
|
|
41
41
|
readonly language: string;
|
|
42
42
|
readonly categories: Category[];
|
|
43
|
-
readonly
|
|
43
|
+
readonly datetime: string;
|
|
44
44
|
readonly image: Nullable<FileType>;
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -51,7 +51,7 @@ export interface PostFull extends SeoInfo {
|
|
|
51
51
|
readonly url: string;
|
|
52
52
|
readonly urlTemplate: string;
|
|
53
53
|
readonly urlAlias: string;
|
|
54
|
-
readonly
|
|
54
|
+
readonly datetime: string|null;
|
|
55
55
|
readonly status: string;
|
|
56
56
|
readonly excerpt: string;
|
|
57
57
|
readonly image: Nullable<FileType>;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { TFunction } from 'i18next';
|
|
2
|
+
|
|
1
3
|
import { createId, Nullable } from '@tager/admin-services';
|
|
2
4
|
import { OptionType, SingleFileInputValueType } from '@tager/admin-ui';
|
|
3
5
|
import {
|
|
@@ -13,11 +15,17 @@ import {
|
|
|
13
15
|
import { getNameWithDepth } from '../../../utils/common';
|
|
14
16
|
import { Category, PostFull } from '../../../typings/model';
|
|
15
17
|
|
|
18
|
+
export const getStatusOptions = (t: TFunction): OptionType[] => [
|
|
19
|
+
{ label: t('blog:statusPublished'), value: 'PUBLISHED' },
|
|
20
|
+
{ label: t('blog:statusDraft'), value: 'DRAFT' },
|
|
21
|
+
{ label: t('blog:statusArchived'), value: 'ARCHIVED' },
|
|
22
|
+
];
|
|
23
|
+
|
|
16
24
|
export interface FormValues {
|
|
17
25
|
title: string;
|
|
18
26
|
excerpt: string;
|
|
19
27
|
body: string;
|
|
20
|
-
|
|
28
|
+
datetime: string;
|
|
21
29
|
coverImage: Nullable<SingleFileInputValueType>;
|
|
22
30
|
image: Nullable<SingleFileInputValueType>;
|
|
23
31
|
imageMobile: Nullable<SingleFileInputValueType>;
|
|
@@ -30,20 +38,22 @@ export interface FormValues {
|
|
|
30
38
|
relatedPosts: OptionType<number>[];
|
|
31
39
|
tags: string;
|
|
32
40
|
additionalFields: FieldUnion[];
|
|
41
|
+
status: OptionType;
|
|
33
42
|
}
|
|
34
43
|
|
|
35
44
|
export function convertPostToFormValues(
|
|
36
45
|
post: Nullable<PostFull>,
|
|
37
46
|
languageOptionList: OptionType[],
|
|
38
47
|
postOptionList: OptionType<number>[],
|
|
39
|
-
additionalFieldList: FieldConfigUnion[]
|
|
48
|
+
additionalFieldList: FieldConfigUnion[],
|
|
49
|
+
statusOptions: OptionType[]
|
|
40
50
|
): FormValues {
|
|
41
51
|
if (!post) {
|
|
42
52
|
return {
|
|
43
53
|
title: '',
|
|
44
54
|
excerpt: '',
|
|
45
55
|
body: '',
|
|
46
|
-
|
|
56
|
+
datetime: '',
|
|
47
57
|
coverImage: null,
|
|
48
58
|
image: null,
|
|
49
59
|
imageMobile: null,
|
|
@@ -58,6 +68,7 @@ export function convertPostToFormValues(
|
|
|
58
68
|
additionalFields: additionalFieldList.map((fieldConfig) =>
|
|
59
69
|
universalFieldUtils.createFormField(fieldConfig, null)
|
|
60
70
|
),
|
|
71
|
+
status: statusOptions[0],
|
|
61
72
|
};
|
|
62
73
|
}
|
|
63
74
|
|
|
@@ -69,11 +80,15 @@ export function convertPostToFormValues(
|
|
|
69
80
|
post.relatedPosts.some((relatedPost) => relatedPost.id === option.value)
|
|
70
81
|
);
|
|
71
82
|
|
|
83
|
+
const foundStatus =
|
|
84
|
+
statusOptions.find(({ value }) => value === post.status) ??
|
|
85
|
+
statusOptions[0];
|
|
86
|
+
|
|
72
87
|
return {
|
|
73
88
|
title: post.title,
|
|
74
89
|
excerpt: post.excerpt,
|
|
75
90
|
body: post.body,
|
|
76
|
-
|
|
91
|
+
datetime: post.datetime ? post.datetime.substr(0, 10) : '',
|
|
77
92
|
coverImage: post.coverImage
|
|
78
93
|
? { id: createId(), file: post.coverImage }
|
|
79
94
|
: null,
|
|
@@ -94,15 +109,16 @@ export function convertPostToFormValues(
|
|
|
94
109
|
language: currentLangOption ?? null,
|
|
95
110
|
relatedPosts: selectedPostOptionList,
|
|
96
111
|
tags: post.tags.join(','),
|
|
97
|
-
additionalFields: additionalFieldList.map((fieldConfig
|
|
112
|
+
additionalFields: additionalFieldList.map((fieldConfig) => {
|
|
98
113
|
const postAdditionalField = post.additionalFields.find(
|
|
99
|
-
(
|
|
114
|
+
({ name }) => name === fieldConfig.name
|
|
100
115
|
);
|
|
101
116
|
return universalFieldUtils.createFormField(
|
|
102
117
|
fieldConfig,
|
|
103
118
|
postAdditionalField?.value
|
|
104
119
|
);
|
|
105
120
|
}),
|
|
121
|
+
status: foundStatus,
|
|
106
122
|
};
|
|
107
123
|
}
|
|
108
124
|
|
|
@@ -114,14 +130,13 @@ export function convertFormValuesToCreationPayload(
|
|
|
114
130
|
excerpt: values.excerpt,
|
|
115
131
|
urlAlias: values.urlAlias,
|
|
116
132
|
body: values.body,
|
|
117
|
-
|
|
133
|
+
datetime: values.datetime,
|
|
118
134
|
coverImage: values.coverImage?.file.id ?? null,
|
|
119
135
|
image: values.image?.file.id ?? null,
|
|
120
136
|
imageMobile: values.imageMobile?.file.id ?? null,
|
|
121
137
|
pageTitle: values.pageTitle,
|
|
122
138
|
pageDescription: values.pageDescription,
|
|
123
139
|
openGraphImage: values.openGraphImage?.file.id ?? null,
|
|
124
|
-
status: 'PUBLISHED',
|
|
125
140
|
categories: values.categories.map((option) => option.value),
|
|
126
141
|
language: values.language?.value ?? null,
|
|
127
142
|
relatedPosts: values.relatedPosts.map(
|
|
@@ -132,6 +147,7 @@ export function convertFormValuesToCreationPayload(
|
|
|
132
147
|
name: field.config.name,
|
|
133
148
|
value: universalFieldUtils.getOutgoingValue(field),
|
|
134
149
|
})),
|
|
150
|
+
status: values.status.value,
|
|
135
151
|
};
|
|
136
152
|
}
|
|
137
153
|
|
|
@@ -18,6 +18,15 @@
|
|
|
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
|
<form-field-select
|
|
22
31
|
v-if="isCreation && isLangSpecific"
|
|
23
32
|
v-model="values.language"
|
|
@@ -52,6 +61,7 @@
|
|
|
52
61
|
type="textarea"
|
|
53
62
|
:error="errors.excerpt"
|
|
54
63
|
/>
|
|
64
|
+
|
|
55
65
|
<form-field-rich-text-input
|
|
56
66
|
v-model="values.body"
|
|
57
67
|
name="body"
|
|
@@ -59,6 +69,7 @@
|
|
|
59
69
|
:error="errors.body"
|
|
60
70
|
:get-upload-adapter-options="getUploadAdapterOptions"
|
|
61
71
|
/>
|
|
72
|
+
|
|
62
73
|
<ShortCodeConstructor
|
|
63
74
|
:short-code-config-list="
|
|
64
75
|
moduleConfig ? moduleConfig.shortcodes : []
|
|
@@ -66,11 +77,11 @@
|
|
|
66
77
|
/>
|
|
67
78
|
|
|
68
79
|
<form-field
|
|
69
|
-
v-model="values.
|
|
70
|
-
name="
|
|
80
|
+
v-model="values.datetime"
|
|
81
|
+
name="datetime"
|
|
71
82
|
:label="$t('blog:date')"
|
|
72
83
|
type="date"
|
|
73
|
-
:error="errors.
|
|
84
|
+
:error="errors.datetime"
|
|
74
85
|
/>
|
|
75
86
|
</template>
|
|
76
87
|
|
|
@@ -218,6 +229,7 @@ import {
|
|
|
218
229
|
convertFormValuesToUpdatePayload,
|
|
219
230
|
convertPostToFormValues,
|
|
220
231
|
FormValues,
|
|
232
|
+
getStatusOptions,
|
|
221
233
|
} from './PostForm.helpers';
|
|
222
234
|
|
|
223
235
|
export default defineComponent({
|
|
@@ -229,6 +241,10 @@ export default defineComponent({
|
|
|
229
241
|
|
|
230
242
|
const urlAliasChanged = ref<boolean>(false);
|
|
231
243
|
|
|
244
|
+
const statusOptions = computed<OptionType[]>(() =>
|
|
245
|
+
getStatusOptions(context.root.$t)
|
|
246
|
+
);
|
|
247
|
+
|
|
232
248
|
/** Fetch module config **/
|
|
233
249
|
|
|
234
250
|
const {
|
|
@@ -300,7 +316,8 @@ export default defineComponent({
|
|
|
300
316
|
post.value,
|
|
301
317
|
languageOptionList.value,
|
|
302
318
|
postOptionList.value,
|
|
303
|
-
moduleConfig.value?.fields ?? []
|
|
319
|
+
moduleConfig.value?.fields ?? [],
|
|
320
|
+
statusOptions.value
|
|
304
321
|
)
|
|
305
322
|
);
|
|
306
323
|
const errors = ref<Record<string, string>>({});
|
|
@@ -310,7 +327,8 @@ export default defineComponent({
|
|
|
310
327
|
post.value,
|
|
311
328
|
languageOptionList.value,
|
|
312
329
|
postOptionList.value,
|
|
313
|
-
moduleConfig.value?.fields ?? []
|
|
330
|
+
moduleConfig.value?.fields ?? [],
|
|
331
|
+
statusOptions.value
|
|
314
332
|
);
|
|
315
333
|
});
|
|
316
334
|
|
|
@@ -347,7 +365,8 @@ export default defineComponent({
|
|
|
347
365
|
null,
|
|
348
366
|
languageOptionList.value,
|
|
349
367
|
postOptionList.value,
|
|
350
|
-
moduleConfig.value?.fields ?? []
|
|
368
|
+
moduleConfig.value?.fields ?? [],
|
|
369
|
+
statusOptions.value
|
|
351
370
|
);
|
|
352
371
|
}
|
|
353
372
|
|
|
@@ -499,7 +518,7 @@ export default defineComponent({
|
|
|
499
518
|
}
|
|
500
519
|
|
|
501
520
|
function handleTitleChange(value: string) {
|
|
502
|
-
if (urlAliasChanged.value === false) {
|
|
521
|
+
if (isCreation.value && urlAliasChanged.value === false) {
|
|
503
522
|
values.value.urlAlias = urlTranslit(value);
|
|
504
523
|
}
|
|
505
524
|
}
|
|
@@ -587,6 +606,8 @@ export default defineComponent({
|
|
|
587
606
|
handleAliasChange,
|
|
588
607
|
urlAliasTemplate,
|
|
589
608
|
handleCategoriesChange,
|
|
609
|
+
|
|
610
|
+
statusOptions,
|
|
590
611
|
};
|
|
591
612
|
},
|
|
592
613
|
});
|
|
@@ -36,6 +36,14 @@ export function convertPostList(
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
export function getStatuses(t: TFunction): Record<string, string> {
|
|
40
|
+
return {
|
|
41
|
+
PUBLISHED: t('blog:statusPublished'),
|
|
42
|
+
DRAFT: t('blog:statusDraft'),
|
|
43
|
+
ARCHIVED: t('blog:statusArchived'),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
39
47
|
export function getPostTableColumnDefs(
|
|
40
48
|
moduleConfig: Nullable<ModuleConfig>,
|
|
41
49
|
t: TFunction
|
|
@@ -52,6 +60,14 @@ export function getPostTableColumnDefs(
|
|
|
52
60
|
style: { width: '50px', textAlign: 'center' },
|
|
53
61
|
headStyle: { width: '50px', textAlign: 'center' },
|
|
54
62
|
},
|
|
63
|
+
{
|
|
64
|
+
id: 2,
|
|
65
|
+
name: t('blog:status'),
|
|
66
|
+
field: 'status',
|
|
67
|
+
style: { width: '120px' },
|
|
68
|
+
headStyle: { width: '120px' },
|
|
69
|
+
format: ({ row }) => getStatuses(t)[row.status],
|
|
70
|
+
},
|
|
55
71
|
{
|
|
56
72
|
id: 2,
|
|
57
73
|
name: t('blog:name'),
|
|
@@ -82,7 +98,13 @@ export function getPostTableColumnDefs(
|
|
|
82
98
|
isLangSpecific
|
|
83
99
|
? { id: 4, name: t('blog:language'), field: 'language' }
|
|
84
100
|
: null,
|
|
85
|
-
{
|
|
101
|
+
{
|
|
102
|
+
id: 5,
|
|
103
|
+
name: t('blog:date'),
|
|
104
|
+
field: 'datetime',
|
|
105
|
+
type: 'datetime',
|
|
106
|
+
options: { ignoreStartOfDayTime: true },
|
|
107
|
+
},
|
|
86
108
|
{
|
|
87
109
|
id: 6,
|
|
88
110
|
name: t('blog:categories'),
|
|
@@ -69,6 +69,15 @@
|
|
|
69
69
|
/>
|
|
70
70
|
</div>
|
|
71
71
|
</div>
|
|
72
|
+
|
|
73
|
+
<form-field-multi-select
|
|
74
|
+
v-model="statusFilter"
|
|
75
|
+
:options="statusOptionList"
|
|
76
|
+
name="statusFilter"
|
|
77
|
+
:searchable="true"
|
|
78
|
+
:label="$t('blog:status')"
|
|
79
|
+
class="filter"
|
|
80
|
+
/>
|
|
72
81
|
</div>
|
|
73
82
|
</advanced-search>
|
|
74
83
|
</template>
|
|
@@ -113,6 +122,7 @@ import pick from 'lodash.pick';
|
|
|
113
122
|
|
|
114
123
|
import {
|
|
115
124
|
ColumnDefinition,
|
|
125
|
+
OptionType,
|
|
116
126
|
useDataTable,
|
|
117
127
|
useTranslation,
|
|
118
128
|
} from '@tager/admin-ui';
|
|
@@ -135,6 +145,7 @@ import {
|
|
|
135
145
|
PostFull,
|
|
136
146
|
PostShort,
|
|
137
147
|
} from '../../../typings/model';
|
|
148
|
+
import { getStatusOptions } from '../PostForm/PostForm.helpers';
|
|
138
149
|
|
|
139
150
|
import { convertPostList, getPostTableColumnDefs } from './PostList.helpers';
|
|
140
151
|
import { useAdvancedSearch } from './hooks';
|
|
@@ -150,6 +161,8 @@ export default defineComponent({
|
|
|
150
161
|
: context.root.$route.query.category;
|
|
151
162
|
});
|
|
152
163
|
|
|
164
|
+
const statusOptionList = computed<OptionType[]>(() => getStatusOptions(t));
|
|
165
|
+
|
|
153
166
|
/** Fetch module config **/
|
|
154
167
|
|
|
155
168
|
const {
|
|
@@ -196,10 +209,12 @@ export default defineComponent({
|
|
|
196
209
|
filterParams,
|
|
197
210
|
tags,
|
|
198
211
|
tagRemovalHandler,
|
|
212
|
+
statusFilter,
|
|
199
213
|
} = useAdvancedSearch({
|
|
200
214
|
context,
|
|
201
215
|
categoryList,
|
|
202
216
|
languageList,
|
|
217
|
+
statusOptionList,
|
|
203
218
|
});
|
|
204
219
|
|
|
205
220
|
const isLangSpecific = computed<boolean>(
|
|
@@ -311,6 +326,8 @@ export default defineComponent({
|
|
|
311
326
|
languageOptionList,
|
|
312
327
|
fromDateFilter,
|
|
313
328
|
toDateFilter,
|
|
329
|
+
statusFilter,
|
|
330
|
+
statusOptionList,
|
|
314
331
|
tags,
|
|
315
332
|
tagRemovalHandler,
|
|
316
333
|
|
|
@@ -23,6 +23,7 @@ interface Params {
|
|
|
23
23
|
context: SetupContext;
|
|
24
24
|
categoryList: ComputedRef<Category[]>;
|
|
25
25
|
languageList: ComputedRef<Language[]>;
|
|
26
|
+
statusOptionList: ComputedRef<OptionType[]>;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
interface State {
|
|
@@ -32,6 +33,7 @@ interface State {
|
|
|
32
33
|
languageOptionList: ComputedRef<OptionType[]>;
|
|
33
34
|
fromDateFilter: Ref<string>;
|
|
34
35
|
toDateFilter: Ref<string>;
|
|
36
|
+
statusFilter: Ref<OptionType[]>;
|
|
35
37
|
filterParams: ComputedRef<Record<string, string | string[]>>;
|
|
36
38
|
tags: ComputedRef<FilterTagType[]>;
|
|
37
39
|
tagRemovalHandler(event: FilterTagType): void;
|
|
@@ -42,6 +44,7 @@ enum FilterTypes {
|
|
|
42
44
|
LANGUAGE = 'language',
|
|
43
45
|
FROM_DATE = 'from-date',
|
|
44
46
|
TO_DATE = 'to-date',
|
|
47
|
+
STATUS = 'status',
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
export const dateFormat = (date: string) => date.split('-').reverse().join('.');
|
|
@@ -50,6 +53,7 @@ export function useAdvancedSearch({
|
|
|
50
53
|
context,
|
|
51
54
|
categoryList,
|
|
52
55
|
languageList,
|
|
56
|
+
statusOptionList,
|
|
53
57
|
}: Params): State {
|
|
54
58
|
/** Category **/
|
|
55
59
|
|
|
@@ -161,12 +165,31 @@ export function useAdvancedSearch({
|
|
|
161
165
|
};
|
|
162
166
|
});
|
|
163
167
|
|
|
168
|
+
/** Status **/
|
|
169
|
+
|
|
170
|
+
const initialStatusFilter = computed<OptionType[]>(() => {
|
|
171
|
+
const queryValue = getFilterParamAsStringArray(
|
|
172
|
+
context.root.$route.query,
|
|
173
|
+
FilterTypes.STATUS
|
|
174
|
+
);
|
|
175
|
+
return statusOptionList.value.filter(({ value }) =>
|
|
176
|
+
queryValue.some((selected) => selected === value)
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const statusFilter = ref<OptionType[]>(initialStatusFilter.value);
|
|
181
|
+
|
|
182
|
+
watch(initialStatusFilter, () => {
|
|
183
|
+
statusFilter.value = initialStatusFilter.value;
|
|
184
|
+
});
|
|
185
|
+
|
|
164
186
|
/** Params **/
|
|
165
187
|
|
|
166
188
|
const filterParams = computed(() => {
|
|
167
189
|
const filters: Record<string, string | string[]> = {
|
|
168
190
|
[FilterTypes.CATEGORY]: categoryFilter.value.map(({ value }) => value),
|
|
169
191
|
[FilterTypes.LANGUAGE]: languageFilter.value.map(({ value }) => value),
|
|
192
|
+
[FilterTypes.STATUS]: statusFilter.value.map(({ value }) => value),
|
|
170
193
|
};
|
|
171
194
|
|
|
172
195
|
if (fromDateFilter.value) {
|
|
@@ -197,6 +220,11 @@ export function useAdvancedSearch({
|
|
|
197
220
|
fromDateFilter.value = '';
|
|
198
221
|
toDateFilter.value = '';
|
|
199
222
|
}
|
|
223
|
+
if (event.name === FilterTypes.STATUS) {
|
|
224
|
+
statusFilter.value = statusFilter.value.filter(
|
|
225
|
+
({ value }) => value !== event.value
|
|
226
|
+
);
|
|
227
|
+
}
|
|
200
228
|
}
|
|
201
229
|
|
|
202
230
|
/** Tags **/
|
|
@@ -216,6 +244,12 @@ export function useAdvancedSearch({
|
|
|
216
244
|
title: context.root.$t('blog:language'),
|
|
217
245
|
})),
|
|
218
246
|
date.value,
|
|
247
|
+
...statusFilter.value.map(({ value, label }) => ({
|
|
248
|
+
value,
|
|
249
|
+
label,
|
|
250
|
+
name: FilterTypes.STATUS,
|
|
251
|
+
title: context.root.$t('blog:status'),
|
|
252
|
+
})),
|
|
219
253
|
].filter(isNotNullish)
|
|
220
254
|
);
|
|
221
255
|
|
|
@@ -243,6 +277,7 @@ export function useAdvancedSearch({
|
|
|
243
277
|
languageOptionList,
|
|
244
278
|
fromDateFilter,
|
|
245
279
|
toDateFilter,
|
|
280
|
+
statusFilter,
|
|
246
281
|
tagRemovalHandler,
|
|
247
282
|
tags: tags,
|
|
248
283
|
filterParams,
|