@tager/admin-blog 0.3.39 → 0.3.43
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 +255 -88
- package/dist/index.umd.js +254 -87
- package/dist/locales/en.d.ts +6 -0
- 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 +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 +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 +15 -7
- package/src/views/Posts/PostForm/PostForm.vue +178 -138
- package/src/views/Posts/PostList/PostList.helpers.ts +8 -9
- package/src/views/Posts/PostList/PostList.vue +107 -74
|
@@ -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,104 +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
72
|
|
|
73
73
|
<form-field-multi-select
|
|
74
|
-
v-model=
|
|
75
|
-
:options=
|
|
76
|
-
name=
|
|
77
|
-
:searchable=
|
|
74
|
+
v-model='statusFilter'
|
|
75
|
+
:options='statusOptionList'
|
|
76
|
+
name='statusFilter'
|
|
77
|
+
:searchable='true'
|
|
78
78
|
:label="$t('blog:status')"
|
|
79
|
-
class=
|
|
79
|
+
class='filter'
|
|
80
80
|
/>
|
|
81
81
|
</div>
|
|
82
82
|
</advanced-search>
|
|
83
83
|
</template>
|
|
84
84
|
|
|
85
|
-
<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:archiveAtLabel') }}: <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 }'>
|
|
86
98
|
<base-button
|
|
87
|
-
variant=
|
|
99
|
+
variant='icon'
|
|
88
100
|
:title="$t('blog:edit')"
|
|
89
|
-
:disabled=
|
|
90
|
-
:href=
|
|
101
|
+
:disabled='isBusy(row.id)'
|
|
102
|
+
:href='getBlogPostFormUrl({ postId: row.id })'
|
|
91
103
|
>
|
|
92
|
-
<svg-icon name=
|
|
104
|
+
<svg-icon name='edit' />
|
|
93
105
|
</base-button>
|
|
94
106
|
|
|
95
107
|
<base-button
|
|
96
|
-
variant=
|
|
108
|
+
variant='icon'
|
|
97
109
|
:title="$t('blog:clone')"
|
|
98
|
-
:disabled=
|
|
99
|
-
@click=
|
|
110
|
+
:disabled='isBusy(row.id)'
|
|
111
|
+
@click='handleResourceClone(row.id)'
|
|
100
112
|
>
|
|
101
|
-
<svg-icon name=
|
|
113
|
+
<svg-icon name='contentCopy' />
|
|
102
114
|
</base-button>
|
|
103
115
|
|
|
104
116
|
<base-button
|
|
105
|
-
variant=
|
|
117
|
+
variant='icon'
|
|
106
118
|
:title="$t('blog:remove')"
|
|
107
|
-
:disabled=
|
|
108
|
-
@click=
|
|
119
|
+
:disabled='isBusy(row.id)'
|
|
120
|
+
@click='handleResourceDelete(row.id)'
|
|
109
121
|
>
|
|
110
|
-
<svg-icon name=
|
|
122
|
+
<svg-icon name='delete' />
|
|
111
123
|
</base-button>
|
|
112
124
|
</template>
|
|
113
125
|
</data-table>
|
|
@@ -115,7 +127,7 @@
|
|
|
115
127
|
</page>
|
|
116
128
|
</template>
|
|
117
129
|
|
|
118
|
-
<script lang=
|
|
130
|
+
<script lang='ts'>
|
|
119
131
|
import { computed, defineComponent, watch } from '@vue/composition-api';
|
|
120
132
|
import isEqual from 'lodash.isequal';
|
|
121
133
|
import pick from 'lodash.pick';
|
|
@@ -125,29 +137,30 @@ import {
|
|
|
125
137
|
OptionType,
|
|
126
138
|
useDataTable,
|
|
127
139
|
useTranslation,
|
|
140
|
+
formatDateTime
|
|
128
141
|
} from '@tager/admin-ui';
|
|
129
142
|
import {
|
|
130
143
|
Nullable,
|
|
131
144
|
useResourceClone,
|
|
132
|
-
useResourceDelete
|
|
145
|
+
useResourceDelete
|
|
133
146
|
} from '@tager/admin-services';
|
|
134
147
|
|
|
135
148
|
import { useFetchModuleConfig, useFetchCategories } from '../../../hooks';
|
|
136
149
|
import {
|
|
137
150
|
clonePost,
|
|
138
151
|
deleteBlogPost,
|
|
139
|
-
getPosts
|
|
152
|
+
getPosts
|
|
140
153
|
} from '../../../services/requests';
|
|
141
154
|
import { getBlogPostFormUrl } from '../../../constants/paths';
|
|
142
155
|
import {
|
|
143
156
|
Category,
|
|
144
157
|
Language,
|
|
145
158
|
PostFull,
|
|
146
|
-
PostShort
|
|
159
|
+
PostShort
|
|
147
160
|
} from '../../../typings/model';
|
|
148
161
|
import { getStatusOptions } from '../PostForm/PostForm.helpers';
|
|
149
162
|
|
|
150
|
-
import { convertPostList, getPostTableColumnDefs } from './PostList.helpers';
|
|
163
|
+
import { convertPostList, getPostTableColumnDefs, getStatuses } from './PostList.helpers';
|
|
151
164
|
import { useAdvancedSearch } from './hooks';
|
|
152
165
|
|
|
153
166
|
export default defineComponent({
|
|
@@ -167,7 +180,7 @@ export default defineComponent({
|
|
|
167
180
|
|
|
168
181
|
const {
|
|
169
182
|
data: moduleConfig,
|
|
170
|
-
loading: isModuleConfigLoading
|
|
183
|
+
loading: isModuleConfigLoading
|
|
171
184
|
} = useFetchModuleConfig({ context });
|
|
172
185
|
|
|
173
186
|
const languageList = computed<Language[]>(
|
|
@@ -178,22 +191,22 @@ export default defineComponent({
|
|
|
178
191
|
|
|
179
192
|
const {
|
|
180
193
|
data: categoryList,
|
|
181
|
-
loading: isCategoryListLoading
|
|
194
|
+
loading: isCategoryListLoading
|
|
182
195
|
} = useFetchCategories({ context });
|
|
183
196
|
|
|
184
197
|
const selectedCategory = computed<Nullable<Category>>(() =>
|
|
185
198
|
categoryId.value
|
|
186
199
|
? categoryList.value.find(
|
|
187
|
-
|
|
188
|
-
|
|
200
|
+
({ id }) => String(id) === String(categoryId.value)
|
|
201
|
+
) ?? null
|
|
189
202
|
: null
|
|
190
203
|
);
|
|
191
204
|
|
|
192
205
|
const pageTitle = computed<string>(() => {
|
|
193
206
|
return selectedCategory.value
|
|
194
207
|
? `${context.root.$t('blog:postsByCategory')} "${
|
|
195
|
-
|
|
196
|
-
|
|
208
|
+
selectedCategory.value.name
|
|
209
|
+
}"`
|
|
197
210
|
: context.root.$t('blog:posts');
|
|
198
211
|
});
|
|
199
212
|
|
|
@@ -209,12 +222,12 @@ export default defineComponent({
|
|
|
209
222
|
filterParams,
|
|
210
223
|
tags,
|
|
211
224
|
tagRemovalHandler,
|
|
212
|
-
statusFilter
|
|
225
|
+
statusFilter
|
|
213
226
|
} = useAdvancedSearch({
|
|
214
227
|
context,
|
|
215
228
|
categoryList,
|
|
216
229
|
languageList,
|
|
217
|
-
statusOptionList
|
|
230
|
+
statusOptionList
|
|
218
231
|
});
|
|
219
232
|
|
|
220
233
|
const isLangSpecific = computed<boolean>(
|
|
@@ -232,19 +245,19 @@ export default defineComponent({
|
|
|
232
245
|
handleChange,
|
|
233
246
|
pageNumber,
|
|
234
247
|
pageCount,
|
|
235
|
-
pageSize
|
|
248
|
+
pageSize
|
|
236
249
|
} = useDataTable<PostShort>({
|
|
237
250
|
fetchEntityList: (params) =>
|
|
238
251
|
getPosts({
|
|
239
252
|
query: params.searchQuery,
|
|
240
253
|
pageNumber: params.pageNumber,
|
|
241
254
|
pageSize: params.pageSize,
|
|
242
|
-
...filterParams.value
|
|
255
|
+
...filterParams.value
|
|
243
256
|
}),
|
|
244
257
|
initialValue: [],
|
|
245
258
|
context,
|
|
246
259
|
resourceName: 'Blog post list',
|
|
247
|
-
pageSize: 100
|
|
260
|
+
pageSize: 100
|
|
248
261
|
});
|
|
249
262
|
|
|
250
263
|
watch(filterParams, () => {
|
|
@@ -254,7 +267,7 @@ export default defineComponent({
|
|
|
254
267
|
|
|
255
268
|
const newQuery = {
|
|
256
269
|
...pick(context.root.$route.query, ['query', 'pageNumber']),
|
|
257
|
-
...filterParams.value
|
|
270
|
+
...filterParams.value
|
|
258
271
|
};
|
|
259
272
|
|
|
260
273
|
if (!isEqual(context.root.$route.query, newQuery)) {
|
|
@@ -282,7 +295,7 @@ export default defineComponent({
|
|
|
282
295
|
deleteResource: deleteBlogPost,
|
|
283
296
|
resourceName: 'Post',
|
|
284
297
|
onSuccess: fetchPostList,
|
|
285
|
-
context
|
|
298
|
+
context
|
|
286
299
|
});
|
|
287
300
|
|
|
288
301
|
const { isCloning, handleResourceClone } = useResourceClone({
|
|
@@ -291,7 +304,7 @@ export default defineComponent({
|
|
|
291
304
|
successMessage: t('blog:cloneSuccess'),
|
|
292
305
|
failureMessage: t('blog:cloneFailure'),
|
|
293
306
|
onSuccessRedirectTo: (data: PostFull) => `/blog/posts/${data.id}`,
|
|
294
|
-
context
|
|
307
|
+
context
|
|
295
308
|
});
|
|
296
309
|
|
|
297
310
|
function isBusy(postId: number): boolean {
|
|
@@ -303,6 +316,8 @@ export default defineComponent({
|
|
|
303
316
|
);
|
|
304
317
|
|
|
305
318
|
return {
|
|
319
|
+
t,
|
|
320
|
+
formatDateTime,
|
|
306
321
|
columnDefs,
|
|
307
322
|
rowData: displayedPostList,
|
|
308
323
|
handleResourceDelete,
|
|
@@ -330,16 +345,17 @@ export default defineComponent({
|
|
|
330
345
|
statusOptionList,
|
|
331
346
|
tags,
|
|
332
347
|
tagRemovalHandler,
|
|
348
|
+
getStatuses,
|
|
333
349
|
|
|
334
350
|
// Clone
|
|
335
351
|
handleResourceClone,
|
|
336
|
-
isBusy
|
|
352
|
+
isBusy
|
|
337
353
|
};
|
|
338
|
-
}
|
|
354
|
+
}
|
|
339
355
|
});
|
|
340
356
|
</script>
|
|
341
357
|
|
|
342
|
-
<style scoped lang=
|
|
358
|
+
<style scoped lang='scss'>
|
|
343
359
|
.filters {
|
|
344
360
|
display: flex;
|
|
345
361
|
margin: 0 -10px;
|
|
@@ -364,4 +380,21 @@ export default defineComponent({
|
|
|
364
380
|
grid-template-columns: repeat(2, 1fr);
|
|
365
381
|
column-gap: 10px;
|
|
366
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
|
+
}
|
|
367
400
|
</style>
|