import html, { getProp } from "html"; import AppForm from "../form/index.js"; import { get, post } from "../../request/index.js"; import { ref, reactive } from "vue"; import { useRoute } from "vue-router"; import { useI18n } from "vue-i18n"; import SvgIcon from "../../components/icon/index.js"; import { schemaToModel } from "../../utils/index.js"; import qs from "../../lib/qs/shim.js"; import AppFormInput from "../form/form-input.js"; import VueOfficeExcel from "@vue-office/excel"; import { camelCase, capitalize } from "lodash"; export default { components: { AppForm, SvgIcon, AppFormInput, VueOfficeExcel }, template: html` {{$t('selectAll')}} {{$t('selectInverse')}} `, props: ["modelValue"], emits: ["command"], async setup(props, context) { const tableRef = ref(null); const columns = ref([]); const filterDrawer = ref(false); const tableLoading = ref(false); const selectedRows = ref([]); const dialogVisible = ref(false); const route = useRoute(); const { t } = useI18n(); const baseUrl = `${route.meta.path}`.substring(1); const indexUrl = `${baseUrl}/index`; const vm = (await get(indexUrl)).data; const schema = vm.schema; const data = reactive(vm.model ?? schemaToModel(schema)); const sortColumns = ref(new Map()); const getSortModel = (model) => { const orderBy = model.orderBy .split(",") .map((o) => o.trim()) .filter((o) => o) .map((o) => ({ prop: camelCase(o.split(" ")[0]), order: (o.split(" ").filter((o) => o)[1] ?? "asc") + "ending", })) .forEach((o) => sortColumns.value.set(o.prop, o.order)); return orderBy; }; const sortModel = reactive(getSortModel(data)); const getClass = ({ row, column }) => { if (column.property) { column.order = sortColumns.value.get(column.property); } }; const sortChange = ({ column, prop, order }) => { if (order === null) { sortColumns.value.delete(prop); } else { sortColumns.value.set(prop, order); } data.orderBy = Array.from(sortColumns.value) .map((o) => capitalize(o[0]) + (o[1] === "ascending" ? "" : ` DESC`)) .join(","); load(indexUrl); }; const getColumns = (schema) => { Object.keys(schema.properties).forEach((propertyName) => { const property = schema.properties[propertyName]; if (property.type !== "object" && property.type !== "array" && !property.hidden) { columns.value.push({ name: propertyName, title: property.title, checked: true }); } }); }; const showColumn = (item, prop) => { return ( item.type !== "object" && item.type !== "array" && !item.hidden && columns.value.findIndex((o) => o.name === prop && o.checked) >= 0 ); }; getColumns(schema.properties.query); const queryFromSchema = schema.properties.query; const tableSchema = schema.properties.items; const editFormRef = ref(null); const editFormloading = ref(false); const editFormMode = ref(null); const editFormTitle = ref(""); const editFormSchema = reactive({}); const editFormModel = reactive({}); const exportModel = reactive({ includeAll: false, includeDeleted: false, }); const handleSelectionChange = (rows) => (selectedRows.value = rows); const load = async (url) => { tableLoading.value = true; try { const postData = JSON.parse(JSON.stringify(data)); delete postData["Id"]; delete postData["items"]; Object.assign(data, (await post(url, postData)).data); } catch (error) { console.log(error); } finally { tableLoading.value = false; } }; const onPageIndexChange = () => load(indexUrl); const onPageSizeChange = () => load(indexUrl); const click = async (item, rows) => { editFormMode.value = item.path; context.emit("command", item, rows); if (item.path === "index") { //list await load(indexUrl); } else if (item.path === "details") { //details const detailsUrl = `${baseUrl}/${item.path}?${qs.stringify({ id: rows[0].id })}`; Object.assign(editFormSchema, schema.properties.items.items); Object.assign(editFormModel, (await post(detailsUrl)).data); editFormTitle.value = `${t("details")}${schema.title}`; dialogVisible.value = true; } else if (item.path === "create") { //create const url = `${baseUrl}/${item.path}`; const vm = (await get(url)).data; Object.assign(editFormSchema, vm.schema); Object.assign(editFormModel, vm.model); editFormTitle.value = `${t("create")}${schema.title}`; dialogVisible.value = true; } else if (item.path === "update") { //update const url = `${baseUrl}/${item.path}`; const vm = (await get(url, { id: rows[0].id })).data; Object.assign(editFormSchema, vm.schema); Object.assign(editFormModel, vm.model); editFormTitle.value = `${t("update")}${schema.title}`; dialogVisible.value = true; } else if (item.path === "delete") { //delete if (!rows.length) { return; } const url = `${baseUrl}/${item.path}`; await post( url, rows.map((o) => o.id) ); await load(indexUrl); } else if (item.path === "export") { //export const url = `${baseUrl}/${item.path}`; const exportUrl = `${url}?${qs.stringify(exportModel)}`; await load(exportUrl); } else if (item.path === "import") { //import const url = `${baseUrl}/${item.path}`; editFormTitle.value = `${t("import")}${schema.title}`; dialogVisible.value = true; } }; const submit = async () => { if (editFormMode.value === "create" || editFormMode.value === "update") { try { const valid = await editFormRef.value.validate(); if (valid) { editFormloading.value = true; const url = `${baseUrl}/${editFormMode.value}`; const result = await post(url, editFormModel); if (result.errors) { model.errors = result.errors; //?? } else { await load(indexUrl); editFormMode.value = null; dialogVisible.value = false; } } } catch (error) { console.error(error); } finally { editFormloading.value = false; } } else if (editFormMode.value === "details") { load(indexUrl); editFormMode.value = null; dialogVisible.value = false; } }; await load(indexUrl); return { route, tableRef, tableLoading, columns, showColumn, filterDrawer, dialogVisible, selectedRows, schema, queryFromSchema, tableSchema, data, sortModel, getClass, sortChange, getProp, editFormRef, editFormMode, editFormTitle, editFormSchema, editFormModel, exportModel, onPageSizeChange, onPageIndexChange, handleSelectionChange, load, click, submit, }; }, };