@tager/admin-blog 0.3.38 → 0.3.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +426 -186
- package/dist/index.umd.js +424 -184
- package/dist/locales/en.d.ts +7 -1
- package/dist/services/requests.d.ts +2 -0
- package/dist/typings/model.d.ts +3 -0
- package/dist/views/Categories/CategoryForm/CategoryForm.vue.d.ts +2 -0
- package/dist/views/Posts/PostForm/PostForm.helpers.d.ts +6 -1
- package/dist/views/Posts/PostForm/PostForm.vue.d.ts +18 -2
- package/dist/views/Posts/PostList/PostList.vue.d.ts +20 -9
- package/dist/views/Posts/PostList/hooks/useAdvancedSearch.d.ts +3 -1
- package/package.json +3 -3
- package/src/locales/en.ts +9 -2
- package/src/locales/ru.ts +9 -2
- package/src/services/requests.ts +2 -0
- package/src/typings/model.ts +3 -0
- package/src/views/Categories/CategoryForm/CategoryForm.helpers.ts +3 -1
- package/src/views/Categories/CategoryForm/CategoryForm.vue +7 -0
- package/src/views/Posts/PostForm/PostForm.helpers.ts +34 -10
- package/src/views/Posts/PostForm/PostForm.vue +192 -131
- package/src/views/Posts/PostList/PostList.helpers.ts +24 -21
- package/src/views/Posts/PostList/PostList.vue +117 -67
- package/src/views/Posts/PostList/hooks/useAdvancedSearch.ts +35 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Category,
|
|
8
8
|
ModuleConfig,
|
|
9
9
|
Language,
|
|
10
|
-
PostShort
|
|
10
|
+
PostShort,
|
|
11
11
|
} from '../../../typings/model';
|
|
12
12
|
import { getBlogPostFormUrl } from '../../../constants/paths';
|
|
13
13
|
|
|
@@ -28,7 +28,7 @@ export function convertPostList(
|
|
|
28
28
|
|
|
29
29
|
return {
|
|
30
30
|
...post,
|
|
31
|
-
language: foundLanguage ? foundLanguage.name : post.language
|
|
31
|
+
language: foundLanguage ? foundLanguage.name : post.language,
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -41,7 +41,7 @@ export function getStatuses(t: TFunction): Record<string, string> {
|
|
|
41
41
|
PUBLISHED: t('blog:statusPublished'),
|
|
42
42
|
DRAFT: t('blog:statusDraft'),
|
|
43
43
|
ARCHIVED: t('blog:statusArchived'),
|
|
44
|
-
}
|
|
44
|
+
};
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function getPostTableColumnDefs(
|
|
@@ -58,7 +58,7 @@ export function getPostTableColumnDefs(
|
|
|
58
58
|
name: 'ID',
|
|
59
59
|
field: 'id',
|
|
60
60
|
style: { width: '50px', textAlign: 'center' },
|
|
61
|
-
headStyle: { width: '50px', textAlign: 'center' }
|
|
61
|
+
headStyle: { width: '50px', textAlign: 'center' },
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
id: 2,
|
|
@@ -66,55 +66,58 @@ export function getPostTableColumnDefs(
|
|
|
66
66
|
field: 'status',
|
|
67
67
|
style: { width: '120px' },
|
|
68
68
|
headStyle: { width: '120px' },
|
|
69
|
-
format: ({ row }) => {
|
|
70
|
-
return getStatuses(t)[row.status];
|
|
71
|
-
}
|
|
72
69
|
},
|
|
73
70
|
{
|
|
74
|
-
id:
|
|
71
|
+
id: 3,
|
|
75
72
|
name: t('blog:name'),
|
|
76
73
|
field: 'name',
|
|
77
74
|
type: 'name',
|
|
78
75
|
format: ({ row }) => ({
|
|
79
76
|
adminLink: {
|
|
80
77
|
text: row.title,
|
|
81
|
-
url: getBlogPostFormUrl({ postId: row.id })
|
|
78
|
+
url: getBlogPostFormUrl({ postId: row.id }),
|
|
82
79
|
},
|
|
83
80
|
websiteLink: {
|
|
84
81
|
text: row.url,
|
|
85
82
|
url: [
|
|
86
83
|
process.env.VUE_APP_WEBSITE_URL || window.location.origin,
|
|
87
|
-
row.url
|
|
88
|
-
].join('')
|
|
89
|
-
}
|
|
90
|
-
})
|
|
84
|
+
row.url,
|
|
85
|
+
].join(''),
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
91
88
|
},
|
|
92
89
|
{
|
|
93
|
-
id:
|
|
90
|
+
id: 4,
|
|
94
91
|
name: t('blog:image'),
|
|
95
92
|
field: 'image',
|
|
96
93
|
type: 'image',
|
|
97
94
|
style: { width: '250px' },
|
|
98
|
-
headStyle: { width: '250px' }
|
|
95
|
+
headStyle: { width: '250px' },
|
|
99
96
|
},
|
|
100
97
|
isLangSpecific
|
|
101
|
-
? { id:
|
|
98
|
+
? { id: 5, name: t('blog:language'), field: 'language' }
|
|
102
99
|
: null,
|
|
103
|
-
{ id: 5, name: t('blog:date'), field: 'datetime', type: 'datetime', options: { ignoreStartOfDayTime: true } },
|
|
104
100
|
{
|
|
105
101
|
id: 6,
|
|
102
|
+
name: t('blog:date'),
|
|
103
|
+
field: 'datetime',
|
|
104
|
+
type: 'datetime',
|
|
105
|
+
options: { ignoreStartOfDayTime: true },
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: 7,
|
|
106
109
|
name: t('blog:categories'),
|
|
107
110
|
field: 'categories',
|
|
108
111
|
format: ({ row }) =>
|
|
109
|
-
row.categories.map((category) => category.name).join(', ')
|
|
112
|
+
row.categories.map((category) => category.name).join(', '),
|
|
110
113
|
},
|
|
111
114
|
{
|
|
112
|
-
id:
|
|
115
|
+
id: 8,
|
|
113
116
|
name: t('blog:actions'),
|
|
114
117
|
field: 'actions',
|
|
115
118
|
style: { whiteSpace: 'nowrap', width: '120px' },
|
|
116
|
-
headStyle: { whiteSpace: 'nowrap', width: '120px' }
|
|
117
|
-
}
|
|
119
|
+
headStyle: { whiteSpace: 'nowrap', width: '120px' },
|
|
120
|
+
},
|
|
118
121
|
];
|
|
119
122
|
|
|
120
123
|
return COLUMN_DEFS.filter(notEmpty);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<page
|
|
3
|
-
:title=
|
|
3
|
+
:title='pageTitle'
|
|
4
4
|
:header-buttons="[
|
|
5
5
|
{
|
|
6
6
|
text: $t('blog:newPost'),
|
|
@@ -10,95 +10,116 @@
|
|
|
10
10
|
>
|
|
11
11
|
<template v-slot:content>
|
|
12
12
|
<data-table
|
|
13
|
-
:column-defs=
|
|
14
|
-
:row-data=
|
|
15
|
-
:loading=
|
|
16
|
-
:error-message=
|
|
17
|
-
:search-query=
|
|
18
|
-
:pagination=
|
|
13
|
+
:column-defs='columnDefs'
|
|
14
|
+
:row-data='rowData'
|
|
15
|
+
:loading='isRowDataLoading'
|
|
16
|
+
:error-message='errorMessage'
|
|
17
|
+
:search-query='searchQuery'
|
|
18
|
+
:pagination='{
|
|
19
19
|
pageNumber,
|
|
20
20
|
pageCount,
|
|
21
21
|
pageSize,
|
|
22
22
|
disabled: isRowDataLoading,
|
|
23
|
-
}
|
|
24
|
-
data-table=
|
|
25
|
-
@change=
|
|
23
|
+
}'
|
|
24
|
+
data-table='blog-post'
|
|
25
|
+
@change='handleChange'
|
|
26
26
|
>
|
|
27
27
|
<template v-slot:filters>
|
|
28
|
-
<advanced-search :tags=
|
|
29
|
-
<div class=
|
|
28
|
+
<advanced-search :tags='tags' @click:tag='tagRemovalHandler'>
|
|
29
|
+
<div class='filters'>
|
|
30
30
|
<form-field-multi-select
|
|
31
|
-
v-model=
|
|
32
|
-
:options=
|
|
33
|
-
name=
|
|
34
|
-
:searchable=
|
|
31
|
+
v-model='categoryFilter'
|
|
32
|
+
:options='categoryOptionList'
|
|
33
|
+
name='categoryFilter'
|
|
34
|
+
:searchable='true'
|
|
35
35
|
:label="$t('blog:category')"
|
|
36
|
-
class=
|
|
36
|
+
class='filter'
|
|
37
37
|
/>
|
|
38
38
|
|
|
39
39
|
<form-field-multi-select
|
|
40
|
-
v-if=
|
|
41
|
-
v-model=
|
|
42
|
-
:options=
|
|
43
|
-
name=
|
|
44
|
-
:searchable=
|
|
40
|
+
v-if='isLangSpecific'
|
|
41
|
+
v-model='languageFilter'
|
|
42
|
+
:options='languageOptionList'
|
|
43
|
+
name='languageFilter'
|
|
44
|
+
:searchable='true'
|
|
45
45
|
:label="$t('blog:language')"
|
|
46
|
-
class=
|
|
46
|
+
class='filter'
|
|
47
47
|
/>
|
|
48
48
|
|
|
49
|
-
<div class=
|
|
50
|
-
<div class=
|
|
49
|
+
<div class='filter'>
|
|
50
|
+
<div class='date-label'>
|
|
51
51
|
{{ $t('blog:dateOfPublication') }}
|
|
52
52
|
</div>
|
|
53
53
|
|
|
54
|
-
<div class=
|
|
54
|
+
<div class='date-content'>
|
|
55
55
|
<form-field
|
|
56
|
-
v-model=
|
|
56
|
+
v-model='fromDateFilter'
|
|
57
57
|
:label="$t('blog:From')"
|
|
58
|
-
name=
|
|
59
|
-
type=
|
|
60
|
-
:max=
|
|
58
|
+
name='fromDateFilter'
|
|
59
|
+
type='date'
|
|
60
|
+
:max='toDateFilter'
|
|
61
61
|
/>
|
|
62
62
|
|
|
63
63
|
<form-field
|
|
64
|
-
v-model=
|
|
64
|
+
v-model='toDateFilter'
|
|
65
65
|
:label="$t('blog:To')"
|
|
66
|
-
name=
|
|
67
|
-
type=
|
|
68
|
-
:min=
|
|
66
|
+
name='toDateFilter'
|
|
67
|
+
type='date'
|
|
68
|
+
:min='fromDateFilter'
|
|
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>
|
|
75
84
|
|
|
76
|
-
<template v-slot:cell(
|
|
85
|
+
<template v-slot:cell(status)='{ row }'>
|
|
86
|
+
<div class='status'>
|
|
87
|
+
<span>{{ getStatuses(t)[row.status] }}</span>
|
|
88
|
+
<span v-if='row.status === "PUBLISHED" && row.archiveAt'>
|
|
89
|
+
{{ t('blog:publishAtLabel') }}: <i>{{ formatDateTime(new Date(row.archiveAt), true) }}</i>
|
|
90
|
+
</span>
|
|
91
|
+
<span v-if='row.status === "DRAFT" && row.publishAt'>
|
|
92
|
+
{{ t('blog:publishAtLabel') }}: <i>{{ formatDateTime(new Date(row.publishAt), true) }}</i>
|
|
93
|
+
</span>
|
|
94
|
+
</div>
|
|
95
|
+
</template>
|
|
96
|
+
|
|
97
|
+
<template v-slot:cell(actions)='{ row }'>
|
|
77
98
|
<base-button
|
|
78
|
-
variant=
|
|
99
|
+
variant='icon'
|
|
79
100
|
:title="$t('blog:edit')"
|
|
80
|
-
:disabled=
|
|
81
|
-
:href=
|
|
101
|
+
:disabled='isBusy(row.id)'
|
|
102
|
+
:href='getBlogPostFormUrl({ postId: row.id })'
|
|
82
103
|
>
|
|
83
|
-
<svg-icon name=
|
|
104
|
+
<svg-icon name='edit' />
|
|
84
105
|
</base-button>
|
|
85
106
|
|
|
86
107
|
<base-button
|
|
87
|
-
variant=
|
|
108
|
+
variant='icon'
|
|
88
109
|
:title="$t('blog:clone')"
|
|
89
|
-
:disabled=
|
|
90
|
-
@click=
|
|
110
|
+
:disabled='isBusy(row.id)'
|
|
111
|
+
@click='handleResourceClone(row.id)'
|
|
91
112
|
>
|
|
92
|
-
<svg-icon name=
|
|
113
|
+
<svg-icon name='contentCopy' />
|
|
93
114
|
</base-button>
|
|
94
115
|
|
|
95
116
|
<base-button
|
|
96
|
-
variant=
|
|
117
|
+
variant='icon'
|
|
97
118
|
:title="$t('blog:remove')"
|
|
98
|
-
:disabled=
|
|
99
|
-
@click=
|
|
119
|
+
:disabled='isBusy(row.id)'
|
|
120
|
+
@click='handleResourceDelete(row.id)'
|
|
100
121
|
>
|
|
101
|
-
<svg-icon name=
|
|
122
|
+
<svg-icon name='delete' />
|
|
102
123
|
</base-button>
|
|
103
124
|
</template>
|
|
104
125
|
</data-table>
|
|
@@ -106,37 +127,40 @@
|
|
|
106
127
|
</page>
|
|
107
128
|
</template>
|
|
108
129
|
|
|
109
|
-
<script lang=
|
|
130
|
+
<script lang='ts'>
|
|
110
131
|
import { computed, defineComponent, watch } from '@vue/composition-api';
|
|
111
132
|
import isEqual from 'lodash.isequal';
|
|
112
133
|
import pick from 'lodash.pick';
|
|
113
134
|
|
|
114
135
|
import {
|
|
115
136
|
ColumnDefinition,
|
|
137
|
+
OptionType,
|
|
116
138
|
useDataTable,
|
|
117
139
|
useTranslation,
|
|
140
|
+
formatDateTime
|
|
118
141
|
} from '@tager/admin-ui';
|
|
119
142
|
import {
|
|
120
143
|
Nullable,
|
|
121
144
|
useResourceClone,
|
|
122
|
-
useResourceDelete
|
|
145
|
+
useResourceDelete
|
|
123
146
|
} from '@tager/admin-services';
|
|
124
147
|
|
|
125
148
|
import { useFetchModuleConfig, useFetchCategories } from '../../../hooks';
|
|
126
149
|
import {
|
|
127
150
|
clonePost,
|
|
128
151
|
deleteBlogPost,
|
|
129
|
-
getPosts
|
|
152
|
+
getPosts
|
|
130
153
|
} from '../../../services/requests';
|
|
131
154
|
import { getBlogPostFormUrl } from '../../../constants/paths';
|
|
132
155
|
import {
|
|
133
156
|
Category,
|
|
134
157
|
Language,
|
|
135
158
|
PostFull,
|
|
136
|
-
PostShort
|
|
159
|
+
PostShort
|
|
137
160
|
} from '../../../typings/model';
|
|
161
|
+
import { getStatusOptions } from '../PostForm/PostForm.helpers';
|
|
138
162
|
|
|
139
|
-
import { convertPostList, getPostTableColumnDefs } from './PostList.helpers';
|
|
163
|
+
import { convertPostList, getPostTableColumnDefs, getStatuses } from './PostList.helpers';
|
|
140
164
|
import { useAdvancedSearch } from './hooks';
|
|
141
165
|
|
|
142
166
|
export default defineComponent({
|
|
@@ -150,11 +174,13 @@ export default defineComponent({
|
|
|
150
174
|
: context.root.$route.query.category;
|
|
151
175
|
});
|
|
152
176
|
|
|
177
|
+
const statusOptionList = computed<OptionType[]>(() => getStatusOptions(t));
|
|
178
|
+
|
|
153
179
|
/** Fetch module config **/
|
|
154
180
|
|
|
155
181
|
const {
|
|
156
182
|
data: moduleConfig,
|
|
157
|
-
loading: isModuleConfigLoading
|
|
183
|
+
loading: isModuleConfigLoading
|
|
158
184
|
} = useFetchModuleConfig({ context });
|
|
159
185
|
|
|
160
186
|
const languageList = computed<Language[]>(
|
|
@@ -165,22 +191,22 @@ export default defineComponent({
|
|
|
165
191
|
|
|
166
192
|
const {
|
|
167
193
|
data: categoryList,
|
|
168
|
-
loading: isCategoryListLoading
|
|
194
|
+
loading: isCategoryListLoading
|
|
169
195
|
} = useFetchCategories({ context });
|
|
170
196
|
|
|
171
197
|
const selectedCategory = computed<Nullable<Category>>(() =>
|
|
172
198
|
categoryId.value
|
|
173
199
|
? categoryList.value.find(
|
|
174
|
-
|
|
175
|
-
|
|
200
|
+
({ id }) => String(id) === String(categoryId.value)
|
|
201
|
+
) ?? null
|
|
176
202
|
: null
|
|
177
203
|
);
|
|
178
204
|
|
|
179
205
|
const pageTitle = computed<string>(() => {
|
|
180
206
|
return selectedCategory.value
|
|
181
207
|
? `${context.root.$t('blog:postsByCategory')} "${
|
|
182
|
-
|
|
183
|
-
|
|
208
|
+
selectedCategory.value.name
|
|
209
|
+
}"`
|
|
184
210
|
: context.root.$t('blog:posts');
|
|
185
211
|
});
|
|
186
212
|
|
|
@@ -196,10 +222,12 @@ export default defineComponent({
|
|
|
196
222
|
filterParams,
|
|
197
223
|
tags,
|
|
198
224
|
tagRemovalHandler,
|
|
225
|
+
statusFilter
|
|
199
226
|
} = useAdvancedSearch({
|
|
200
227
|
context,
|
|
201
228
|
categoryList,
|
|
202
229
|
languageList,
|
|
230
|
+
statusOptionList
|
|
203
231
|
});
|
|
204
232
|
|
|
205
233
|
const isLangSpecific = computed<boolean>(
|
|
@@ -217,19 +245,19 @@ export default defineComponent({
|
|
|
217
245
|
handleChange,
|
|
218
246
|
pageNumber,
|
|
219
247
|
pageCount,
|
|
220
|
-
pageSize
|
|
248
|
+
pageSize
|
|
221
249
|
} = useDataTable<PostShort>({
|
|
222
250
|
fetchEntityList: (params) =>
|
|
223
251
|
getPosts({
|
|
224
252
|
query: params.searchQuery,
|
|
225
253
|
pageNumber: params.pageNumber,
|
|
226
254
|
pageSize: params.pageSize,
|
|
227
|
-
...filterParams.value
|
|
255
|
+
...filterParams.value
|
|
228
256
|
}),
|
|
229
257
|
initialValue: [],
|
|
230
258
|
context,
|
|
231
259
|
resourceName: 'Blog post list',
|
|
232
|
-
pageSize: 100
|
|
260
|
+
pageSize: 100
|
|
233
261
|
});
|
|
234
262
|
|
|
235
263
|
watch(filterParams, () => {
|
|
@@ -239,7 +267,7 @@ export default defineComponent({
|
|
|
239
267
|
|
|
240
268
|
const newQuery = {
|
|
241
269
|
...pick(context.root.$route.query, ['query', 'pageNumber']),
|
|
242
|
-
...filterParams.value
|
|
270
|
+
...filterParams.value
|
|
243
271
|
};
|
|
244
272
|
|
|
245
273
|
if (!isEqual(context.root.$route.query, newQuery)) {
|
|
@@ -267,7 +295,7 @@ export default defineComponent({
|
|
|
267
295
|
deleteResource: deleteBlogPost,
|
|
268
296
|
resourceName: 'Post',
|
|
269
297
|
onSuccess: fetchPostList,
|
|
270
|
-
context
|
|
298
|
+
context
|
|
271
299
|
});
|
|
272
300
|
|
|
273
301
|
const { isCloning, handleResourceClone } = useResourceClone({
|
|
@@ -276,7 +304,7 @@ export default defineComponent({
|
|
|
276
304
|
successMessage: t('blog:cloneSuccess'),
|
|
277
305
|
failureMessage: t('blog:cloneFailure'),
|
|
278
306
|
onSuccessRedirectTo: (data: PostFull) => `/blog/posts/${data.id}`,
|
|
279
|
-
context
|
|
307
|
+
context
|
|
280
308
|
});
|
|
281
309
|
|
|
282
310
|
function isBusy(postId: number): boolean {
|
|
@@ -288,6 +316,8 @@ export default defineComponent({
|
|
|
288
316
|
);
|
|
289
317
|
|
|
290
318
|
return {
|
|
319
|
+
t,
|
|
320
|
+
formatDateTime,
|
|
291
321
|
columnDefs,
|
|
292
322
|
rowData: displayedPostList,
|
|
293
323
|
handleResourceDelete,
|
|
@@ -311,18 +341,21 @@ export default defineComponent({
|
|
|
311
341
|
languageOptionList,
|
|
312
342
|
fromDateFilter,
|
|
313
343
|
toDateFilter,
|
|
344
|
+
statusFilter,
|
|
345
|
+
statusOptionList,
|
|
314
346
|
tags,
|
|
315
347
|
tagRemovalHandler,
|
|
348
|
+
getStatuses,
|
|
316
349
|
|
|
317
350
|
// Clone
|
|
318
351
|
handleResourceClone,
|
|
319
|
-
isBusy
|
|
352
|
+
isBusy
|
|
320
353
|
};
|
|
321
|
-
}
|
|
354
|
+
}
|
|
322
355
|
});
|
|
323
356
|
</script>
|
|
324
357
|
|
|
325
|
-
<style scoped lang=
|
|
358
|
+
<style scoped lang='scss'>
|
|
326
359
|
.filters {
|
|
327
360
|
display: flex;
|
|
328
361
|
margin: 0 -10px;
|
|
@@ -347,4 +380,21 @@ export default defineComponent({
|
|
|
347
380
|
grid-template-columns: repeat(2, 1fr);
|
|
348
381
|
column-gap: 10px;
|
|
349
382
|
}
|
|
383
|
+
|
|
384
|
+
.status {
|
|
385
|
+
span:first-child {
|
|
386
|
+
display: block;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
span:nth-child(2) {
|
|
390
|
+
display: block;
|
|
391
|
+
margin-top: 5px;
|
|
392
|
+
font-size: 0.8rem;
|
|
393
|
+
|
|
394
|
+
i {
|
|
395
|
+
display: block;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
;
|
|
399
|
+
}
|
|
350
400
|
</style>
|
|
@@ -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,
|