Merge branch 'develop' of https://github.com/Frappet/bma-ehr-frontend into develop
This commit is contained in:
commit
b2c8dd6eed
7 changed files with 373 additions and 3 deletions
|
|
@ -21,4 +21,5 @@ export default {
|
||||||
orgPosType: `${orgPos}/type`,
|
orgPosType: `${orgPos}/type`,
|
||||||
orgPosLevel: `${orgPos}/level`,
|
orgPosLevel: `${orgPos}/level`,
|
||||||
orgPosMaster: `${orgPos}/master`,
|
orgPosMaster: `${orgPos}/master`,
|
||||||
|
organizationShortName: `${organization}/sort`,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
127
src/modules/02_organizationalNew/components/DialogSortAgency.vue
Normal file
127
src/modules/02_organizationalNew/components/DialogSortAgency.vue
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, watch } from "vue";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
|
||||||
|
import DialogHeader from "@/components/DialogHeader.vue";
|
||||||
|
|
||||||
|
import type {
|
||||||
|
FormDataNewStructure,
|
||||||
|
FormNewStructureRef,
|
||||||
|
DataOption,
|
||||||
|
HistoryType,
|
||||||
|
} from "@/modules/02_organizationalNew/interface/index/Main";
|
||||||
|
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
|
||||||
|
|
||||||
|
const $q = useQuasar();
|
||||||
|
const store = useOrganizational();
|
||||||
|
const { dialogConfirm, showLoader, success, hideLoader, messageError } =
|
||||||
|
useCounterMixin();
|
||||||
|
|
||||||
|
const modal = defineModel<boolean>("sortAgency", { required: true });
|
||||||
|
const modalSort = defineModel<Array<any>>("data", { required: true });
|
||||||
|
const rows = ref<any>([]);
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
required: true,
|
||||||
|
label: "ชื่อ",
|
||||||
|
align: "left",
|
||||||
|
field: "name",
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
function onDrop(from: any, to: any) {
|
||||||
|
onDropRow(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDropRow(from: any, to: any) {
|
||||||
|
rows.value.splice(to, 0, rows.value.splice(from, 1)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
dialogConfirm($q, () => {
|
||||||
|
const data = rows.value;
|
||||||
|
const dataId = data.map((item: any) => item.orgTreeId);
|
||||||
|
http
|
||||||
|
.put(config.API.organizationShortName, {
|
||||||
|
id: data[0].orgLevel === 0 ? data[0].orgRevisionId : data[0].orgRootId,
|
||||||
|
type: data[0].orgLevel,
|
||||||
|
sortId: dataId,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
modal.value = false;
|
||||||
|
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => modal.value,
|
||||||
|
() => {
|
||||||
|
if (modal.value == true) {
|
||||||
|
rows.value = [];
|
||||||
|
const dataStandant = modalSort.value;
|
||||||
|
const mappedData = dataStandant.map((item: any) => ({
|
||||||
|
name: `${item.orgTreeName} (${item.orgTreeShortName})`,
|
||||||
|
orgRootId: item.orgRootId,
|
||||||
|
orgTreeId: item.orgTreeId,
|
||||||
|
orgLevel: item.orgLevel,
|
||||||
|
orgTreeName: item.orgTreeName,
|
||||||
|
orgTreeShortName: item.orgTreeShortName,
|
||||||
|
orgRevisionId: item.orgRevisionId,
|
||||||
|
}));
|
||||||
|
rows.value = mappedData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<template>
|
||||||
|
<q-dialog v-model="modal" persistent>
|
||||||
|
<q-card style="min-width: 50vw">
|
||||||
|
<!-- <form @submit.prevent="validateForm"> -->
|
||||||
|
<DialogHeader
|
||||||
|
:tittle="`จัดลำดับการแสดงผล`"
|
||||||
|
:close="() => (modal = false)"
|
||||||
|
/>
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-card-section>
|
||||||
|
<q-table
|
||||||
|
v-draggable-table="{
|
||||||
|
options: {
|
||||||
|
mode: 'row',
|
||||||
|
onlyBody: true,
|
||||||
|
dragHandler: 'th,td',
|
||||||
|
},
|
||||||
|
onDrop,
|
||||||
|
}"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:rows-per-page-options="[100]"
|
||||||
|
row-key="orgTreeId"
|
||||||
|
hide-bottom
|
||||||
|
hide-pagination
|
||||||
|
hide-header
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal">
|
||||||
|
<q-btn type="submit" :label="`บันทึก`" color="public" @click="save" />
|
||||||
|
</q-card-actions>
|
||||||
|
<!-- </form> -->
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
@ -4,8 +4,6 @@ import { useQuasar } from "quasar";
|
||||||
import http from "@/plugins/http";
|
import http from "@/plugins/http";
|
||||||
import config from "@/app.config";
|
import config from "@/app.config";
|
||||||
|
|
||||||
import type { HistoryType } from "@/modules/02_organizationalNew/interface/index/Main";
|
|
||||||
|
|
||||||
import DialogHeader from "@/components/DialogHeader.vue";
|
import DialogHeader from "@/components/DialogHeader.vue";
|
||||||
|
|
||||||
import { useCounterMixin } from "@/stores/mixin";
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import type { OrgTree } from "@/modules/02_organizationalNew/interface/response/
|
||||||
/** importComponents*/
|
/** importComponents*/
|
||||||
import DialogAgency from "@/modules/02_organizationalNew/components/DialogFormAgency.vue";
|
import DialogAgency from "@/modules/02_organizationalNew/components/DialogFormAgency.vue";
|
||||||
import DialogStructureDetail from "@/modules/02_organizationalNew/components/StructureDetail.vue";
|
import DialogStructureDetail from "@/modules/02_organizationalNew/components/StructureDetail.vue";
|
||||||
|
import DialogSortAgency from "@/modules/02_organizationalNew/components/DialogSortAgency.vue";
|
||||||
|
|
||||||
/** importStore*/
|
/** importStore*/
|
||||||
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
|
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
|
||||||
|
|
@ -86,7 +87,9 @@ const nodeTEST = defineModel<OrgTree[]>("nodeTree", { default: [] });
|
||||||
const nodeId = defineModel<string>("nodeId", { require: true });
|
const nodeId = defineModel<string>("nodeId", { require: true });
|
||||||
const isLoad = defineModel<boolean>("isLoad", { require: true });
|
const isLoad = defineModel<boolean>("isLoad", { require: true });
|
||||||
const filter = ref<string>("");
|
const filter = ref<string>("");
|
||||||
|
const level = ref<number>(0);
|
||||||
const nodes = ref<Array<OrgTree>>([]);
|
const nodes = ref<Array<OrgTree>>([]);
|
||||||
|
const dataSort = ref<Array<any>>([]);
|
||||||
const lazy = ref(nodes);
|
const lazy = ref(nodes);
|
||||||
const expanded = ref<Array<any>>([]);
|
const expanded = ref<Array<any>>([]);
|
||||||
const notFound = ref<string>("ไม่พบข้อมูลที่ค้นหา");
|
const notFound = ref<string>("ไม่พบข้อมูลที่ค้นหา");
|
||||||
|
|
@ -176,6 +179,7 @@ function deleteNode(treeNode: any, organizationId: any): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const modalSortAgency = ref<boolean>(false);
|
||||||
const dialogAgency = ref<boolean>(false);
|
const dialogAgency = ref<boolean>(false);
|
||||||
const actionType = ref<string>("");
|
const actionType = ref<string>("");
|
||||||
const dataNode = ref<any>();
|
const dataNode = ref<any>();
|
||||||
|
|
@ -225,6 +229,42 @@ async function onClickDel(type: number, id: string) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onClickSort(id: string) {
|
||||||
|
modalSortAgency.value = true;
|
||||||
|
if (id) {
|
||||||
|
breakLoop.value = false;
|
||||||
|
|
||||||
|
const orgId = id;
|
||||||
|
|
||||||
|
for (let index = 0; index < nodes.value.length; index++) {
|
||||||
|
const data = nodes.value[index];
|
||||||
|
searchAndReplace(data, orgId);
|
||||||
|
if (breakLoop.value) break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const dataList = nodes.value;
|
||||||
|
const dataMap = dataList.map((item: any) => ({
|
||||||
|
orgTreeId: item.orgTreeId,
|
||||||
|
orgLevel: item.orgLevel,
|
||||||
|
orgTreeName: item.orgTreeName,
|
||||||
|
orgTreeShortName: item.orgTreeShortName,
|
||||||
|
orgRevisionId: item.orgRevisionId,
|
||||||
|
}));
|
||||||
|
|
||||||
|
dataSort.value = dataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchAndReplace(data: any, id: string) {
|
||||||
|
if (data.orgTreeId === id) {
|
||||||
|
dataSort.value = data.children;
|
||||||
|
breakLoop.value = true;
|
||||||
|
} else if (data.children) {
|
||||||
|
for (const child of data.children) {
|
||||||
|
searchAndReplace(child, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
watch(
|
watch(
|
||||||
() => nodeTEST.value,
|
() => nodeTEST.value,
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -341,6 +381,8 @@ onMounted(async () => {});
|
||||||
? onClickDetail(prop.node.orgTreeId, prop.node.orgLevel)
|
? onClickDetail(prop.node.orgTreeId, prop.node.orgLevel)
|
||||||
: item.type === 'DEL'
|
: item.type === 'DEL'
|
||||||
? onClickDel(prop.node.orgLevel, prop.node.orgTreeId)
|
? onClickDel(prop.node.orgLevel, prop.node.orgTreeId)
|
||||||
|
: item.type === 'SORT'
|
||||||
|
? onClickSort(prop.node.orgRootId)
|
||||||
: null
|
: null
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
|
@ -464,6 +506,11 @@ onMounted(async () => {});
|
||||||
v-model:treeId="treeId"
|
v-model:treeId="treeId"
|
||||||
v-model:orgLevel="orgLevel"
|
v-model:orgLevel="orgLevel"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<DialogSortAgency
|
||||||
|
v-model:sort-agency="modalSortAgency"
|
||||||
|
v-model:data="dataSort"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const mainPage = () => import("@/modules/02_organizationalNew/views/main.vue");
|
const mainPage = () => import("@/modules/02_organizationalNew/views/main.vue");
|
||||||
|
const testPage = () => import("@/modules/02_organizationalNew/views/ExampleSearchTree.vue");
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
|
|
@ -11,4 +12,15 @@ export default [
|
||||||
Role: "organization",
|
Role: "organization",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/organization-new/test",
|
||||||
|
name: "organizationalNewTest",
|
||||||
|
component: testPage,
|
||||||
|
meta: {
|
||||||
|
Auth: true,
|
||||||
|
Key: [7],
|
||||||
|
Role: "organization",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
165
src/modules/02_organizationalNew/views/ExampleSearchTree.vue
Normal file
165
src/modules/02_organizationalNew/views/ExampleSearchTree.vue
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
|
||||||
|
import type { ListMenu } from "@/modules/02_organizationalNew/interface/index/Main";
|
||||||
|
import type { OrgTree } from "@/modules/02_organizationalNew/interface/response/organizational";
|
||||||
|
|
||||||
|
/** importStore*/
|
||||||
|
import { useOrganizational } from "@/modules/02_organizationalNew/store/organizational";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
|
||||||
|
const store = useOrganizational();
|
||||||
|
const { dialogRemove, showLoader, hideLoader, messageError, success } =
|
||||||
|
useCounterMixin();
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
const filter = ref<string>("");
|
||||||
|
const nodes = ref<Array<any>>([]);
|
||||||
|
const lazy = ref(nodes);
|
||||||
|
const expanded = ref<Array<any>>([]);
|
||||||
|
const notFound = ref<string>("ไม่พบข้อมูลที่ค้นหา");
|
||||||
|
const noData = ref<string>("ไม่มีข้อมูล");
|
||||||
|
const selected = ref("");
|
||||||
|
|
||||||
|
const idVal = ref("");
|
||||||
|
async function fetchDataTree(id: string) {
|
||||||
|
showLoader();
|
||||||
|
await http
|
||||||
|
.get(config.API.orgByid(id.toString()))
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
nodes.value = data;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
messageError($q, err);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hideLoader();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const breakLoop = ref<boolean>(false);
|
||||||
|
const dataObject = ref([]);
|
||||||
|
async function onSort(orgRootId: string) {
|
||||||
|
if (orgRootId) {
|
||||||
|
idVal.value = 'children => '+orgRootId;
|
||||||
|
breakLoop.value = false;
|
||||||
|
|
||||||
|
const targetNodeId = orgRootId;
|
||||||
|
|
||||||
|
for (let index = 0; index < nodes.value.length; index++) {
|
||||||
|
const element = nodes.value[index];
|
||||||
|
searchAndReplace(element, targetNodeId);
|
||||||
|
if (breakLoop.value) break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idVal.value = 'root';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchAndReplace(treeNode: any, organizationId: string) {
|
||||||
|
if (treeNode.orgTreeId === organizationId) {
|
||||||
|
dataObject.value = treeNode.children;
|
||||||
|
breakLoop.value = true;
|
||||||
|
} else if (treeNode.children) {
|
||||||
|
for (const child of treeNode.children) {
|
||||||
|
searchAndReplace(child, organizationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const listAdd = ref<ListMenu[]>([
|
||||||
|
{
|
||||||
|
label: "จัดลำดับ",
|
||||||
|
icon: "filter_list",
|
||||||
|
type: "SORT",
|
||||||
|
color: "green-7",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchDataTree("a449eac0-93a5-4ccc-8fbc-2974ca8ee61b");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="col-12 q-py-md q-px-lg">
|
||||||
|
<q-tree
|
||||||
|
class="q-pa-md q-gutter-sm"
|
||||||
|
dense
|
||||||
|
default-expand-all
|
||||||
|
selected-color="primary"
|
||||||
|
:nodes="lazy"
|
||||||
|
node-key="orgTreeId"
|
||||||
|
label-key="orgTreeName"
|
||||||
|
:filter="filter"
|
||||||
|
:no-results-label="notFound"
|
||||||
|
:no-nodes-label="noData"
|
||||||
|
v-model:expanded="expanded"
|
||||||
|
v-model:selected="selected"
|
||||||
|
>
|
||||||
|
<template v-slot:default-header="prop">
|
||||||
|
<!-- {{ prop.node.orgTreeName }} -->
|
||||||
|
|
||||||
|
<div class="row items-center q-px-xs q-pt-xs q-gutter-sm">
|
||||||
|
<!--แสดงชื่อแผนก พิมพ์ตัวหนา คลิกแล้วกาง/หุบ Tree-->
|
||||||
|
<div>
|
||||||
|
<div class="text-weight-medium">
|
||||||
|
{{ prop.node.orgTreeName }}
|
||||||
|
</div>
|
||||||
|
<div class="text-weight-light">
|
||||||
|
{{ prop.node.orgCode == null ? null : prop.node.orgCode }}
|
||||||
|
{{
|
||||||
|
prop.node.orgTreeShortName == null
|
||||||
|
? null
|
||||||
|
: prop.node.orgTreeShortName
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
icon="mdi-dots-vertical"
|
||||||
|
class="q-pa-none q-ml-xs"
|
||||||
|
color="grey-13"
|
||||||
|
>
|
||||||
|
<q-menu>
|
||||||
|
<q-list
|
||||||
|
dense
|
||||||
|
v-for="(item, index) in prop.node.orgLevel === 4
|
||||||
|
? listAdd.slice(1, 6)
|
||||||
|
: listAdd"
|
||||||
|
:key="index"
|
||||||
|
style="min-width: 100px"
|
||||||
|
>
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
v-close-popup
|
||||||
|
@click="onSort(prop.node.orgRootId)"
|
||||||
|
>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon :color="item.color" :name="item.icon" />
|
||||||
|
</q-item-section>
|
||||||
|
<div>
|
||||||
|
<q-item-section> {{ item.label }}หน่วยงาน </q-item-section>
|
||||||
|
</div>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-menu>
|
||||||
|
</q-btn>
|
||||||
|
</template>
|
||||||
|
</q-tree>
|
||||||
|
|
||||||
|
<h5>orgRootId = {{ idVal }}</h5>
|
||||||
|
<div>
|
||||||
|
{{ dataObject }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -17,6 +17,7 @@ import type {
|
||||||
import type { QTableProps } from "quasar";
|
import type { QTableProps } from "quasar";
|
||||||
import PopupPersonal from "@/components/Dialogs/PopupPersonal.vue";
|
import PopupPersonal from "@/components/Dialogs/PopupPersonal.vue";
|
||||||
|
|
||||||
|
const avatar = ref<string>('')
|
||||||
const modalPersonal = ref<boolean>(false);
|
const modalPersonal = ref<boolean>(false);
|
||||||
const personId = ref<string>("");
|
const personId = ref<string>("");
|
||||||
/** Use */
|
/** Use */
|
||||||
|
|
@ -179,6 +180,7 @@ const fetchData = async (id: string) => {
|
||||||
location.value = data.location ?? "";
|
location.value = data.location ?? "";
|
||||||
status.value = data.status ?? "";
|
status.value = data.status ?? "";
|
||||||
remarkHorizontal.value = data.remarkHorizontal ?? "-";
|
remarkHorizontal.value = data.remarkHorizontal ?? "-";
|
||||||
|
getAvatar(data.profileId)
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
messageError($q, e);
|
messageError($q, e);
|
||||||
|
|
@ -187,6 +189,23 @@ const fetchData = async (id: string) => {
|
||||||
hideLoader();
|
hideLoader();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getAvatar(id:string){
|
||||||
|
if(id){
|
||||||
|
http
|
||||||
|
.get(config.API.profileAvaId(id))
|
||||||
|
.then((res)=>{
|
||||||
|
console.log(res)
|
||||||
|
const dataList = res.data.result
|
||||||
|
avatar.value = dataList.avatar
|
||||||
|
}).catch((e)=>{
|
||||||
|
|
||||||
|
}).finally(()=>{
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// const downloadFile = (response: any, filename: string) => {
|
// const downloadFile = (response: any, filename: string) => {
|
||||||
// const link = document.createElement("a");
|
// const link = document.createElement("a");
|
||||||
// var fileName = filename;
|
// var fileName = filename;
|
||||||
|
|
@ -435,7 +454,8 @@ function updatemodalPersonal(modal: boolean) {
|
||||||
<div class="row col-12 q-pa-md">
|
<div class="row col-12 q-pa-md">
|
||||||
<div class="col-12 row bg-white q-col-gutter-md">
|
<div class="col-12 row bg-white q-col-gutter-md">
|
||||||
<div class="col-xs-3 col-sm-2 col-md-1 row">
|
<div class="col-xs-3 col-sm-2 col-md-1 row">
|
||||||
<q-img src="@/assets/avatar_user.jpg" />
|
<q-img :src="avatar" v-if="avatar !== '' && avatar !== null" />
|
||||||
|
<q-img src="@/assets/avatar_user.jpg" v-else />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-6 col-sm-3 row items-center">
|
<div class="col-xs-6 col-sm-3 row items-center">
|
||||||
<div class="col-12 q-pl-md">
|
<div class="col-12 q-pl-md">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue