done postCategory page

parent ffcef7a9
......@@ -78,4 +78,6 @@ export enum API_PATHS {
updatePost = 'post/update',
addCategoryPost = 'postCategory/add',
deleteCategoryPost = 'postCategory/delete',
detailCategoryPost = 'postCategory/detail',
updateCategoryPost = 'postCategory/update',
}
import { defineComponent } from 'vue';
import { i18n } from 'src/boot/i18n';
import { defineComponent, PropType, Ref, ref, watch } from 'vue';
import UploadImage from 'components/upload-image/index.vue';
import {
PostType,
LanguageType,
FileUploadType,
PostCategoryDetailType,
} from 'src/assets/type';
import ListPostDialog from 'components/post-category/list-post-dialog/index.vue';
import { api, BaseResponseBody } from 'src/boot/axios';
import { AxiosResponse } from 'axios';
import { config } from 'src/assets/configurations';
export default defineComponent({
// name: 'ComponentName'
components: { UploadImage, ListPostDialog },
props: {
isOpenUpdateDialog: { type: Boolean, required: true },
languages: { type: Array as PropType<LanguageType[]>, required: true },
detailData: {
type: Object as PropType<PostCategoryDetailType>,
required: true,
},
},
setup(props, context) {
type FromDataType = {
name: string;
title: string;
status: number;
language: LanguageType;
};
watch(
() => props.isOpenUpdateDialog,
(value) => {
if (value) {
id.value = props.detailData.id;
imageAPI.value = config.API_IMAGE_ENDPOINT + props.detailData.image;
imageNotChange.value = props.detailData.image;
status.value = props.detailData.status;
langs.value = props.detailData.langs;
userTableRowsPost.value = props.detailData.posts;
}
console.log(langs.value, 'langs');
}
);
const id: Ref<number | null> = ref(null);
const name: Ref<string | null> = ref(null);
const title: Ref<string | null> = ref(null);
const image: Ref<string | null> = ref(null);
const imageAPI: Ref<string | null> = ref(null);
const imageNotChange: Ref<string | null> = ref(null);
const status: Ref<number> = ref(1);
const nameRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('post.validateMessages.requireName'),
];
const file: Ref<File | string> = ref('');
const urlFileLocal: Ref<string> = ref('');
const keywordSearch: Ref<string | null> = ref(null);
const userTableColumnsPost = [
{
name: 'stt',
field: 'stt',
required: true,
label: i18n.global.t('postCategory.tableColumnsPost.stt'),
align: 'center',
sortable: false,
},
{
name: 'name',
field: 'name',
required: true,
label: i18n.global.t('postCategory.tableColumnsPost.name'),
align: 'center',
headerStyle: 'text-align: center !important;',
sortable: false,
},
{
name: 'createBy',
field: 'createBy',
required: true,
label: i18n.global.t('postCategory.tableColumnsPost.createBy'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'updateTime',
field: 'updateTime',
required: true,
label: i18n.global.t('postCategory.tableColumnsPost.updateTime'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'status',
field: 'status',
required: true,
label: i18n.global.t('postCategory.tableColumnsPost.status'),
align: 'center',
sortable: false,
},
{
name: 'action',
field: 'action',
required: true,
label: i18n.global.t('postCategory.tableColumnsPost.action'),
align: 'center',
sortable: false,
},
];
const userTableRowsPost: Ref<PostType[]> = ref([]);
const isOpenListPost: Ref<boolean> = ref(false);
const langs: Ref<FromDataType[]> = ref([]);
const tabName: Ref<string> = ref('vi');
const tabTitle: Ref<string> = ref('vi');
const uploadImage = (value: FileList) => {
urlFileLocal.value = URL.createObjectURL(value[0]);
file.value = value[0];
image.value = urlFileLocal.value;
console.log(value, 'FileList');
};
const imageUploaded: Ref<string | null> = ref(null);
const deletePostSelected = (postIdx: number) => {
userTableRowsPost.value.splice(postIdx, 1);
};
const callApiUploadAvatar = async (file: File) => {
try {
const bodyFormData = new FormData();
bodyFormData.append('file', file);
const response = (await api({
headers: { 'Content-Type': 'multipart/form-data' },
url: config.API_IMAGE_ENDPOINT,
method: 'POST',
data: bodyFormData,
})) as AxiosResponse<BaseResponseBody<FileUploadType>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
imageUploaded.value = response.data.data.fileName;
}
} catch (error) {}
};
const confirmUpdatePostCategory = async () => {
await callApiUploadAvatar(file.value as File);
context.emit('updatePostCategory', {
id: id.value,
image: image.value ? imageUploaded.value : imageNotChange.value,
status: status.value,
posts: userTableRowsPost.value,
langs: langs.value,
});
};
return {
name,
title,
image,
status,
nameRules,
file,
urlFileLocal,
isOpenListPost,
uploadImage,
userTableColumnsPost,
userTableRowsPost,
keywordSearch,
deletePostSelected,
langs,
tabName,
tabTitle,
confirmUpdatePostCategory,
imageAPI,
};
},
emits: [
'update:isOpenUpdateDialog',
'click:closeBtnDialog',
'SetImage',
'deleteImage',
'updatePostCategory',
],
});
<template>
<div>My component</div>
</template>
<q-dialog
persistent
:model-value="isOpenUpdateDialog"
@update:model-value="$emit('update:isOpenUpdateDialog', $event)"
>
<q-card class="full-width" style="max-width: 60rem" bordered>
<q-form greedy @submit.prevent="confirmUpdatePostCategory">
<q-card-section class="q-pa-none">
<q-item>
<q-item-section>
<q-item-label class="text-h6 q-py-md text-weight-regular">
{{ $t('postCategory.title.updatePost') }}
</q-item-label>
</q-item-section>
</q-item>
</q-card-section>
<q-separator />
<q-card-section
class="overflow-auto"
style="max-height: calc(100vh - 14rem)"
>
<q-tabs
v-model="tabName"
dense
class="text-grey"
active-color="primary"
indicator-color="primary"
align="left"
narrow-indicator
>
<q-tab
v-for="(lang, idxLang) in langs"
:key="`${lang.language.id}-${idxLang}`"
:name="lang.language.code"
:label="lang.language.name"
no-caps
/>
</q-tabs>
<q-separator />
<q-tab-panels v-model="tabName" animated>
<q-tab-panel
v-for="(info, index) in langs"
:key="`${info.language.id}-${index}`"
:name="info.language.code"
>
<q-input
v-model="info.name"
:label="`${
tabName === 'vi'
? $t('postCategory.labelInput.namePost')
: $t('postCategory.labelInput.nameEnglish')
}`"
type="text"
class="q-my-sm"
outlined
:rules="tabName === 'vi' ? nameRules : ''"
hide-bottom-space
></q-input>
</q-tab-panel>
</q-tab-panels>
<q-tabs
v-model="tabTitle"
dense
class="text-grey"
active-color="primary"
indicator-color="primary"
align="left"
narrow-indicator
>
<q-tab
v-for="(lang, idxLang) in langs"
:key="`${lang.language.id}-${idxLang}`"
:name="lang.language.code"
:label="lang.language.name"
no-caps
/>
</q-tabs>
<q-separator />
<q-tab-panels v-model="tabTitle" animated>
<q-tab-panel
v-for="(info, index) in langs"
:key="`${info.language.id}-${index}`"
:name="info.language.code"
>
<q-input
v-model="info.title"
:label="`${
tabTitle === 'vi'
? $t('postCategory.labelInput.description')
: $t('postCategory.labelInput.shortDescription')
}`"
type="text"
class="q-my-sm"
outlined
></q-input>
</q-tab-panel>
</q-tab-panels>
<div class="row">
<div class="col-6">
<q-card v-if="imageAPI || image" flat style="max-height: 200px">
<div align="center">
<q-img
:src="!image ? imageAPI : image"
style="max-height: 200px; aspect-ratio: 16/9"
>
</q-img>
</div>
</q-card>
<q-card v-else flat style="max-height: 200px" class="q-mt-md">
<div align="center">
<q-img
src="~/assets/default.jpeg"
style="max-height: 200px; aspect-ratio: 16/9"
>
</q-img>
</div>
</q-card>
<UploadImage
class="q-mt-xs"
:isBtn="true"
@selectedFile="uploadImage"
></UploadImage>
</div>
</div>
<div class="q-mt-md">
<span class="text-body1 text-weight-regular">{{
$t('customerRank.dialogLabel.fieldLabels.status')
}}</span
><q-toggle
v-model="status"
:true-value="1"
:false-value="2"
size="50px"
></q-toggle>
</div>
<div class="row q-col-gutter-sm flex-center q-mt-sm">
<div
class="
col-auto
text-h6 text-weight-regular
flex flex-center
q-mr-md
"
>
{{ $t('postCategory.title.listPostsSelected') }}
<q-separator vertical spaced />
</div>
<q-space></q-space>
<!-- <div class="col-2">
<q-input
v-model="keywordSearch"
dense
outlined
:label="$t('postCategory.tableColumnsPost.name')"
clearable
></q-input>
</div>
<div class="col-auto">
<q-btn
color="primary"
no-caps
:label="$t('crudActions.search')"
style="width: 100px"
>
</q-btn>
</div> -->
<div class="col-auto">
<q-btn
color="primary"
no-caps
:label="$t('crudActions.add')"
style="width: 100px"
@click="isOpenListPost = true"
>
</q-btn>
</div>
<div class="col-12 q-mt-sm">
<q-table
:rows="userTableRowsPost"
:columns="userTableColumnsPost"
:no-data-label="$t('emptyData')"
row-key="name"
separator="cell"
hide-pagination
>
<template v-slot:body-cell-stt="item">
<q-td style="padding: 0; height: 100%">
<div align="center">
{{ item.rowIndex + 1 }}
</div>
</q-td>
</template>
<template v-slot:body-cell-status="rowData">
<q-td>
<div align="center">
<q-chip
:color="rowData.value === 1 ? 'positive' : 'orange'"
text-color="white"
size="sm"
>
{{
rowData.value === 1
? $t('customer.statusLabel.active')
: $t('customer.statusLabel.inactive')
}}
</q-chip>
</div>
</q-td>
</template>
<template v-slot:body-cell-action="post">
<q-td style="padding: 0; height: 100%">
<div align="center">
<q-btn
flat
round
color="primary"
icon="mdi-delete-outline"
@click="deletePostSelected(post.rowIndex)"
>
<q-tooltip :offset="[20, 10]">{{
$t('customer.toolTipMessage.deleteCustomer')
}}</q-tooltip>
</q-btn>
</div>
</q-td>
</template>
</q-table>
</div>
</div>
</q-card-section>
<q-card-actions align="right">
<div>
<q-btn
color="grey"
no-caps
style="width: 90px"
class="q-mr-sm"
:label="$t('post.crudActions.cancel')"
@click="$emit('click:closeBtnDialog')"
/>
<q-btn
type="submit"
color="primary"
no-caps
style="width: 90px"
:label="$t('post.crudActions.save')"
/>
</div>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
<ListPostDialog
v-model:is-open-list-post="isOpenListPost"
:post-selected="userTableRowsPost"
@click:closeBtnDialog="isOpenListPost = false"
@submit-data="(userTableRowsPost = $event), (isOpenListPost = false)"
></ListPostDialog>
</template>
<script lang="ts" src="./UpdatePostCategory.ts"></script>
......@@ -693,7 +693,7 @@ export default {
title: {
postCategory: 'Danh sách danh mục bài viết',
addPost: 'Thêm mới danh mục bài viết',
editPost: 'Cập nhật danh mục bài viết',
updatePost: 'Cập nhật danh mục bài viết',
listPosts: 'Danh sách bài viết',
listPostsSelected: 'Danh sách bài viết đã chọn',
addPostDialog: 'Thêm bài viết',
......@@ -725,6 +725,7 @@ export default {
actionMessages: {
addPostCategoryAccess: 'Thêm danh mục bài viết thành công',
deletePostCategoryAccess: 'Xoá danh mục bài viết thành công',
updatePostCategoryAccess: 'Cập nhật danh mục bài viết thành công',
},
confirmActionsTitle: {
confirmDeletePostCategory:
......
......@@ -9,11 +9,13 @@ import {
PostCategoryDetailType,
} from 'src/assets/type';
import AddCategoryPostDialog from 'components/post-category/add-post-category/index.vue';
import UpdateCategoryPostDialog from 'components/post-category/update-post-category/index.vue';
import { Dialog, Notify } from 'quasar';
// import { Dialog, Notify } from 'quasar';
export default defineComponent({
components: {
AddCategoryPostDialog,
UpdateCategoryPostDialog,
},
setup() {
const configImg = config;
......@@ -73,7 +75,9 @@ export default defineComponent({
];
const userTableRowsCategoryPost: Ref<CategoryPostType[]> = ref([]);
const isOpenAddDialog: Ref<boolean> = ref(false);
const isOpenUpdateDialog: Ref<boolean> = ref(false);
const languages: Ref<LanguageType[]> = ref([]);
const detailPostCategory: Ref<PostCategoryDetailType | null> = ref(null);
const getListCategoryPost = async () => {
try {
const response = (await api({
......@@ -84,11 +88,30 @@ export default defineComponent({
},
})) as AxiosResponse<BaseResponseBody<CategoryPostType[]>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
console.log(response, 'response');
userTableRowsCategoryPost.value = response.data.data;
keywordSearch.value = null;
}
} catch (error) {}
};
// const getList = () => {
// return new Promise((resolve, reject) => {
// void api({
// url: API_PATHS.getListCategoryPost,
// method: 'GET',
// params: {
// name: keywordSearch.value,
// },
// }),
// (
// err: any,
// result: AxiosResponse<BaseResponseBody<CategoryPostType[]>>
// ) => {
// if (err) return reject(err);
// resolve(result);
// };
// });
// };
const getLanguages = async () => {
try {
const response = (await api({
......@@ -160,6 +183,51 @@ export default defineComponent({
} catch (error) {}
});
};
const openUpdateDialog = async (id: number) => {
await getDetailCategoryPost(id);
isOpenUpdateDialog.value = true;
};
const getDetailCategoryPost = async (id: number) => {
try {
const response = (await api({
url: API_PATHS.detailCategoryPost,
method: 'GET',
params: {
id: id,
},
})) as AxiosResponse<BaseResponseBody<PostCategoryDetailType>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
console.log(response.data.data, 'detail PostCategory');
detailPostCategory.value = response.data.data;
}
} catch (error) {}
};
const updatePostCategory = async (formData: PostCategoryDetailType) => {
try {
const response = (await api({
url: API_PATHS.updateCategoryPost,
method: 'POST',
data: {
id: formData.id,
image: formData.image,
status: formData.status,
posts: formData.posts,
langs: formData.langs,
},
})) as AxiosResponse<BaseResponseBody<unknown>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
isOpenUpdateDialog.value = false;
Notify.create({
type: 'positive',
message: i18n.global.t(
'postCategory.actionMessages.updatePostCategoryAccess'
),
});
void getListCategoryPost();
}
} catch (error) {}
};
onMounted(() => {
void getListCategoryPost();
......@@ -171,11 +239,15 @@ export default defineComponent({
userTableColumnsCategoryPost,
userTableRowsCategoryPost,
isOpenAddDialog,
isOpenUpdateDialog,
getListCategoryPost,
getLanguages,
languages,
addPostCategory,
confirmDelete,
openUpdateDialog,
detailPostCategory,
updatePostCategory,
};
},
});
......@@ -85,7 +85,13 @@
<template v-slot:body-cell-action="item">
<q-td style="padding: 0; height: 100%">
<div align="center">
<q-btn flat round color="primary" icon="mdi-account-edit-outline">
<q-btn
flat
round
color="primary"
icon="mdi-account-edit-outline"
@click="openUpdateDialog(item.row.id)"
>
<q-tooltip :offset="[20, 10]">{{
$t('customer.toolTipMessage.updateCustomerInfo')
}}</q-tooltip>
......@@ -112,6 +118,13 @@
@click:closeBtnDialog="isOpenAddDialog = false"
@addPostCategory="addPostCategory($event)"
/>
<UpdateCategoryPostDialog
v-model:is-open-update-dialog="isOpenUpdateDialog"
:languages="languages"
:detail-data="detailPostCategory"
@click:closeBtnDialog="isOpenUpdateDialog = false"
@updatePostCategory="updatePostCategory($event)"
/>
</div>
</template>
<script lang="ts" src="./CategoryPost.ts"></script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment