feat: update responsibleGroup type to string array and initialize in workflow steps
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 7s
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 7s
This commit is contained in:
parent
28395b4f80
commit
56a63185a1
5 changed files with 215 additions and 84 deletions
|
|
@ -6,12 +6,14 @@ import { useI18n } from 'vue-i18n';
|
|||
|
||||
import useUserStore from 'src/stores/user';
|
||||
import useOptionStore from 'src/stores/options';
|
||||
import { useWorkflowTemplate } from 'src/stores/workflow-template';
|
||||
import { baseUrl } from 'stores/utils';
|
||||
import { getRole } from 'src/services/keycloak';
|
||||
import {
|
||||
WorkflowUserInTable,
|
||||
WorkflowTemplatePayload,
|
||||
WorkFlowPayloadStep,
|
||||
Group,
|
||||
} from 'src/stores/workflow-template/types';
|
||||
import { User } from 'src/stores/user/types';
|
||||
|
||||
|
|
@ -20,6 +22,7 @@ import ToggleButton from 'src/components/button/ToggleButton.vue';
|
|||
import NoData from '../NoData.vue';
|
||||
import SelectBranch from '../shared/select/SelectBranch.vue';
|
||||
import AddButton from '../button/AddButton.vue';
|
||||
import { QField } from 'quasar';
|
||||
|
||||
defineProps<{
|
||||
readonly?: boolean;
|
||||
|
|
@ -29,6 +32,7 @@ defineProps<{
|
|||
const { t } = useI18n();
|
||||
const userStore = useUserStore();
|
||||
const optionStore = useOptionStore();
|
||||
const workflowStore = useWorkflowTemplate();
|
||||
|
||||
const userInTable = defineModel<WorkflowUserInTable[]>('userInTable', {
|
||||
default: [],
|
||||
|
|
@ -51,7 +55,9 @@ let objectOptions = [
|
|||
const options = ref(objectOptions);
|
||||
const role = ref<string[]>([]);
|
||||
const userList = ref<User[]>([]);
|
||||
const groupList = ref<Group[]>([]);
|
||||
const responsiblePersonSearch = ref('');
|
||||
const responsibleMenu = ref(false);
|
||||
|
||||
async function getUserList(opts?: { query: string }) {
|
||||
const resUser = await userStore.fetchList({
|
||||
|
|
@ -60,10 +66,10 @@ async function getUserList(opts?: { query: string }) {
|
|||
if (resUser) userList.value = resUser.result;
|
||||
}
|
||||
|
||||
// async function getUserById(responsiblePersonId: string) {
|
||||
// const resUser = await userStore.fetchById(responsiblePersonId);
|
||||
// if (resUser) userInTable.value.push(resUser);
|
||||
// }
|
||||
async function getGroupList() {
|
||||
const resGroup = await workflowStore.getGroupList();
|
||||
if (resGroup) groupList.value = resGroup;
|
||||
}
|
||||
|
||||
function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
|
||||
const currStep = flowData.value.step[stepIndex];
|
||||
|
|
@ -78,6 +84,7 @@ function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
|
|||
userInTable.value[stepIndex] = {
|
||||
name: flowData.value.step[stepIndex].name,
|
||||
responsiblePerson: [],
|
||||
responsibleGroup: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -101,6 +108,33 @@ function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
|
|||
}
|
||||
}
|
||||
|
||||
function selectResponsibleGroup(stepIndex: number, responsibleGroup: string) {
|
||||
const currStep = flowData.value.step[stepIndex];
|
||||
const existGroupIndex = currStep.responsibleGroup?.findIndex(
|
||||
(p) => p === responsibleGroup,
|
||||
);
|
||||
|
||||
if (existGroupIndex === -1) {
|
||||
currStep.responsibleGroup?.push(responsibleGroup);
|
||||
|
||||
if (!userInTable.value[stepIndex]) {
|
||||
userInTable.value[stepIndex] = {
|
||||
name: flowData.value.step[stepIndex].name,
|
||||
responsiblePerson: [],
|
||||
responsibleGroup: [],
|
||||
};
|
||||
}
|
||||
|
||||
userInTable.value[stepIndex]?.responsibleGroup.push(responsibleGroup);
|
||||
} else {
|
||||
currStep.responsibleGroup?.splice(Number(existGroupIndex), 1);
|
||||
userInTable.value[stepIndex]?.responsibleGroup.splice(
|
||||
Number(existGroupIndex),
|
||||
1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function selectItem(
|
||||
val: Record<string, unknown>,
|
||||
responsibleInstitution?: string[],
|
||||
|
|
@ -142,6 +176,7 @@ watch(
|
|||
onMounted(async () => {
|
||||
role.value = getRole() || [];
|
||||
await getUserList();
|
||||
await getGroupList();
|
||||
await userStore.fetchHqOption();
|
||||
});
|
||||
</script>
|
||||
|
|
@ -467,92 +502,128 @@ onMounted(async () => {
|
|||
</div>
|
||||
|
||||
<!-- RESPONSIBLE-PERSON -->
|
||||
<q-select
|
||||
<q-field
|
||||
v-if="step.responsiblePersonId"
|
||||
behavior="menu"
|
||||
:for="`select-responsible-person-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
|
||||
:bg-color="readonly ? 'transparent' : ''"
|
||||
:readonly
|
||||
outlined
|
||||
dense
|
||||
v-model="step.responsiblePersonId"
|
||||
multiple
|
||||
:options="[1, 2, 3]"
|
||||
hide-bottom-space
|
||||
option-label="label"
|
||||
option-value="value"
|
||||
emit-value
|
||||
:stack-label="
|
||||
userInTable[index]?.responsiblePerson.length > 0 ||
|
||||
userInTable[index]?.responsibleGroup.length > 0
|
||||
"
|
||||
:label="$t('flow.responsiblePerson')"
|
||||
dense
|
||||
class="col-md-6 col-12"
|
||||
:hide-dropdown-icon="readonly"
|
||||
:class="{ 'cursor-pointer': !readonly }"
|
||||
>
|
||||
<template v-slot:selected-item="scope">
|
||||
<div class="column full-width">
|
||||
<div
|
||||
class="row items-center no-wrap"
|
||||
v-for="person in userInTable[
|
||||
index
|
||||
]?.responsiblePerson.filter(
|
||||
(p) => p.id === scope.opt,
|
||||
)"
|
||||
:key="person.id"
|
||||
>
|
||||
<q-avatar class="q-ml-sm" size="md">
|
||||
<q-img
|
||||
class="text-center"
|
||||
:ratio="1"
|
||||
:src="`${baseUrl}/user/${person.id}/profile-image/${person.selectedImage}`"
|
||||
>
|
||||
<template #error>
|
||||
<div
|
||||
class="no-padding full-width full-height flex items-center justify-center"
|
||||
:style="`${person.gender ? 'background: white' : 'background: linear-gradient(135deg,rgba(43, 137, 223, 1) 0%, rgba(230, 51, 81, 1) 100%);'}`"
|
||||
>
|
||||
<q-img
|
||||
v-if="person.gender"
|
||||
:src="
|
||||
person.gender === 'male'
|
||||
? '/no-img-man.png'
|
||||
: '/no-img-female.png'
|
||||
"
|
||||
/>
|
||||
<q-icon
|
||||
v-else
|
||||
size="sm"
|
||||
name="mdi-account-outline"
|
||||
style="color: white"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</q-img>
|
||||
</q-avatar>
|
||||
<div
|
||||
class="column q-pl-md"
|
||||
style="color: var(--foreground)"
|
||||
<template #control>
|
||||
<q-item
|
||||
dense
|
||||
class="items-center full-width no-padding"
|
||||
v-for="person in userInTable[
|
||||
index
|
||||
]?.responsiblePerson.filter((p) =>
|
||||
step.responsiblePersonId.includes(p.id),
|
||||
)"
|
||||
:key="person.id"
|
||||
>
|
||||
<q-avatar class="q-ml-sm" size="md">
|
||||
<q-img
|
||||
class="text-center"
|
||||
:ratio="1"
|
||||
:src="`${baseUrl}/user/${person.id}/profile-image/${person.selectedImage}`"
|
||||
>
|
||||
<span>
|
||||
{{
|
||||
`${optionStore.mapOption(person.namePrefix || '')} ${
|
||||
$i18n.locale === 'eng'
|
||||
? person.firstNameEN
|
||||
: person.firstName
|
||||
} ${
|
||||
$i18n.locale === 'eng'
|
||||
? person.lastNameEN
|
||||
: person.lastName
|
||||
}`
|
||||
}}
|
||||
</span>
|
||||
<span class="text-caption app-text-muted">
|
||||
{{ person.code }}
|
||||
</span>
|
||||
</div>
|
||||
<template #error>
|
||||
<div
|
||||
class="no-padding full-width full-height flex items-center justify-center"
|
||||
:style="`${person.gender ? 'background: white' : 'background: linear-gradient(135deg,rgba(43, 137, 223, 1) 0%, rgba(230, 51, 81, 1) 100%);'}`"
|
||||
>
|
||||
<q-img
|
||||
v-if="person.gender"
|
||||
:src="
|
||||
person.gender === 'male'
|
||||
? '/no-img-man.png'
|
||||
: '/no-img-female.png'
|
||||
"
|
||||
/>
|
||||
<q-icon
|
||||
v-else
|
||||
size="sm"
|
||||
name="mdi-account-outline"
|
||||
style="color: white"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</q-img>
|
||||
</q-avatar>
|
||||
<div
|
||||
class="column q-pl-md"
|
||||
style="color: var(--foreground)"
|
||||
>
|
||||
<span>
|
||||
{{
|
||||
`${optionStore.mapOption(person.namePrefix || '')} ${
|
||||
$i18n.locale === 'eng'
|
||||
? person.firstNameEN
|
||||
: person.firstName
|
||||
} ${
|
||||
$i18n.locale === 'eng'
|
||||
? person.lastNameEN
|
||||
: person.lastName
|
||||
}`
|
||||
}}
|
||||
</span>
|
||||
<span class="text-caption app-text-muted">
|
||||
{{ person.code }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</q-item>
|
||||
|
||||
<template v-slot:option></template>
|
||||
<q-menu v-if="!readonly" :offset="[0, 4]">
|
||||
<div
|
||||
v-if="step.responsibleGroup.length > 0"
|
||||
class="full-width app-text-muted text-weight-medium"
|
||||
style="font-size: 10px"
|
||||
>
|
||||
{{ $t('general.group') }}
|
||||
</div>
|
||||
<q-item
|
||||
class="items-center full-width no-padding"
|
||||
v-for="group in userInTable[
|
||||
index
|
||||
]?.responsibleGroup.filter((g) =>
|
||||
step.responsibleGroup.includes(g),
|
||||
)"
|
||||
:key="group"
|
||||
dense
|
||||
>
|
||||
<q-avatar class="q-ml-sm" size="md">
|
||||
<q-img
|
||||
class="text-center"
|
||||
:ratio="1"
|
||||
:src="`/img-group.png`"
|
||||
/>
|
||||
</q-avatar>
|
||||
<span class="q-pl-md">
|
||||
{{ group }}
|
||||
</span>
|
||||
</q-item>
|
||||
</template>
|
||||
<template #append>
|
||||
<q-icon
|
||||
name="mdi-menu-down"
|
||||
:class="{ rotated: responsibleMenu }"
|
||||
class="transition-rotate"
|
||||
/>
|
||||
</template>
|
||||
<q-menu
|
||||
v-if="!readonly"
|
||||
no-focus
|
||||
no-refocus
|
||||
:offset="[0, 4]"
|
||||
@before-show="() => (responsibleMenu = true)"
|
||||
@before-hide="() => (responsibleMenu = false)"
|
||||
>
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-input
|
||||
|
|
@ -581,6 +652,7 @@ onMounted(async () => {
|
|||
{{ $t('general.noData') }}
|
||||
</q-item>
|
||||
<q-item
|
||||
v-else
|
||||
v-for="(person, i) in userList"
|
||||
dense
|
||||
:key="i"
|
||||
|
|
@ -655,6 +727,7 @@ onMounted(async () => {
|
|||
{{ $t('personnel.MESSENGER') }}
|
||||
</span>
|
||||
<q-item
|
||||
dense
|
||||
clickable
|
||||
@click="step.messengerByArea = !step.messengerByArea"
|
||||
class="column"
|
||||
|
|
@ -670,9 +743,49 @@ onMounted(async () => {
|
|||
</div>
|
||||
</div>
|
||||
</q-item>
|
||||
|
||||
<span class="text-caption app-text-muted-2 q-px-md">
|
||||
{{ $t('general.group') }}
|
||||
</span>
|
||||
<q-item
|
||||
v-if="groupList.length === 0"
|
||||
class="app-text-muted q-px-lg"
|
||||
>
|
||||
{{ $t('general.noData') }}
|
||||
</q-item>
|
||||
<q-item
|
||||
v-else
|
||||
v-for="(group, i) in groupList"
|
||||
dense
|
||||
clickable
|
||||
@click="selectResponsibleGroup(index, group.name)"
|
||||
class="column"
|
||||
>
|
||||
<div class="row items-center">
|
||||
<q-checkbox
|
||||
size="xs"
|
||||
:model-value="
|
||||
step.responsibleGroup.includes(group.name)
|
||||
"
|
||||
@click.stop="
|
||||
selectResponsibleGroup(index, group.name)
|
||||
"
|
||||
/>
|
||||
<q-avatar class="q-ml-sm" size="md">
|
||||
<q-img
|
||||
class="text-center"
|
||||
:ratio="1"
|
||||
:src="`/img-group.png`"
|
||||
/>
|
||||
</q-avatar>
|
||||
<div class="column q-pl-md">
|
||||
<span>{{ group.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-select>
|
||||
</q-field>
|
||||
|
||||
<!-- RESPONSIBLE-AGENCIES, RESPONSIBLE-INSTITUTION -->
|
||||
<q-select
|
||||
|
|
@ -815,4 +928,11 @@ onMounted(async () => {
|
|||
:deep(.q-dialog.fullscreen.no-pointer-events.q-dialog--modal) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.transition-rotate {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
.rotated {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ async function addStep() {
|
|||
flowData.value.step.push({
|
||||
responsibleInstitution: [],
|
||||
responsiblePersonId: [],
|
||||
responsibleGroup: [],
|
||||
value: [],
|
||||
detail: '',
|
||||
name: '',
|
||||
|
|
@ -166,6 +167,7 @@ function triggerPropertiesDialog(step: WorkFlowPayloadStep) {
|
|||
id="flow-form-dialog"
|
||||
>
|
||||
<FormFlow
|
||||
v-model:user-in-table="userInTable"
|
||||
v-model:flow-data="flowData"
|
||||
v-model:register-branch-id="registerBranchId"
|
||||
@trigger-properties="triggerPropertiesDialog"
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ const columns = [
|
|||
function triggerDialog(type: 'add' | 'edit' | 'view') {
|
||||
if (type === 'add') {
|
||||
registeredBranchId.value = '';
|
||||
userInTable.value = [];
|
||||
formDataWorkflow.value = {
|
||||
status: 'CREATED',
|
||||
name: '',
|
||||
|
|
@ -207,7 +208,7 @@ async function submit() {
|
|||
...formDataWorkflow.value,
|
||||
});
|
||||
} else {
|
||||
await workflowStore.creatWorkflowTemplate({
|
||||
await workflowStore.createWorkflowTemplate({
|
||||
registeredBranchId: registeredBranchId.value,
|
||||
...formDataWorkflow.value,
|
||||
});
|
||||
|
|
@ -223,7 +224,11 @@ function assignFormData(workflowData: WorkflowTemplate) {
|
|||
status: workflowData.status,
|
||||
name: workflowData.name,
|
||||
step: workflowData.step.map((s, i) => {
|
||||
userInTable.value[i] = { name: s.name, responsiblePerson: [] };
|
||||
userInTable.value[i] = {
|
||||
name: s.name,
|
||||
responsiblePerson: [],
|
||||
responsibleGroup: [],
|
||||
};
|
||||
s.responsiblePerson.forEach((p) => {
|
||||
userInTable.value[i].responsiblePerson.push({
|
||||
id: p.user.id,
|
||||
|
|
@ -237,12 +242,16 @@ function assignFormData(workflowData: WorkflowTemplate) {
|
|||
code: p.user.code,
|
||||
});
|
||||
});
|
||||
s.responsibleGroup.forEach((g) => {
|
||||
userInTable.value[i].responsibleGroup.push(g);
|
||||
});
|
||||
return {
|
||||
id: s.id,
|
||||
name: s.name,
|
||||
detail: s.detail,
|
||||
messengerByArea: s.messengerByArea || false,
|
||||
value: s.value.length > 0 ? JSON.parse(JSON.stringify(s.value)) : [],
|
||||
responsibleGroup: s.responsibleGroup.map((g) => g),
|
||||
responsiblePersonId: s.responsiblePerson.map((p) => p.userId),
|
||||
responsibleInstitution: JSON.parse(
|
||||
JSON.stringify(s.responsibleInstitution),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { ref } from 'vue';
|
|||
import { defineStore } from 'pinia';
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PaginationResult } from 'src/types';
|
||||
import { WorkflowTemplate, WorkflowTemplatePayload, Group } from './types';
|
||||
import { Group, WorkflowTemplate, WorkflowTemplatePayload } from './types';
|
||||
import { Status } from '../types';
|
||||
|
||||
export const useWorkflowTemplate = defineStore('workflow-store', () => {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export type WorkflowTemplatePayload = {
|
|||
|
||||
export type WorkflowUserInTable = {
|
||||
name: string;
|
||||
responsibleGroup: Group[];
|
||||
responsibleGroup: string[];
|
||||
responsiblePerson: {
|
||||
id: string;
|
||||
selectedImage?: string;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue