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 useUserStore from 'src/stores/user';
|
||||||
import useOptionStore from 'src/stores/options';
|
import useOptionStore from 'src/stores/options';
|
||||||
|
import { useWorkflowTemplate } from 'src/stores/workflow-template';
|
||||||
import { baseUrl } from 'stores/utils';
|
import { baseUrl } from 'stores/utils';
|
||||||
import { getRole } from 'src/services/keycloak';
|
import { getRole } from 'src/services/keycloak';
|
||||||
import {
|
import {
|
||||||
WorkflowUserInTable,
|
WorkflowUserInTable,
|
||||||
WorkflowTemplatePayload,
|
WorkflowTemplatePayload,
|
||||||
WorkFlowPayloadStep,
|
WorkFlowPayloadStep,
|
||||||
|
Group,
|
||||||
} from 'src/stores/workflow-template/types';
|
} from 'src/stores/workflow-template/types';
|
||||||
import { User } from 'src/stores/user/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 NoData from '../NoData.vue';
|
||||||
import SelectBranch from '../shared/select/SelectBranch.vue';
|
import SelectBranch from '../shared/select/SelectBranch.vue';
|
||||||
import AddButton from '../button/AddButton.vue';
|
import AddButton from '../button/AddButton.vue';
|
||||||
|
import { QField } from 'quasar';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|
@ -29,6 +32,7 @@ defineProps<{
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const optionStore = useOptionStore();
|
const optionStore = useOptionStore();
|
||||||
|
const workflowStore = useWorkflowTemplate();
|
||||||
|
|
||||||
const userInTable = defineModel<WorkflowUserInTable[]>('userInTable', {
|
const userInTable = defineModel<WorkflowUserInTable[]>('userInTable', {
|
||||||
default: [],
|
default: [],
|
||||||
|
|
@ -51,7 +55,9 @@ let objectOptions = [
|
||||||
const options = ref(objectOptions);
|
const options = ref(objectOptions);
|
||||||
const role = ref<string[]>([]);
|
const role = ref<string[]>([]);
|
||||||
const userList = ref<User[]>([]);
|
const userList = ref<User[]>([]);
|
||||||
|
const groupList = ref<Group[]>([]);
|
||||||
const responsiblePersonSearch = ref('');
|
const responsiblePersonSearch = ref('');
|
||||||
|
const responsibleMenu = ref(false);
|
||||||
|
|
||||||
async function getUserList(opts?: { query: string }) {
|
async function getUserList(opts?: { query: string }) {
|
||||||
const resUser = await userStore.fetchList({
|
const resUser = await userStore.fetchList({
|
||||||
|
|
@ -60,10 +66,10 @@ async function getUserList(opts?: { query: string }) {
|
||||||
if (resUser) userList.value = resUser.result;
|
if (resUser) userList.value = resUser.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// async function getUserById(responsiblePersonId: string) {
|
async function getGroupList() {
|
||||||
// const resUser = await userStore.fetchById(responsiblePersonId);
|
const resGroup = await workflowStore.getGroupList();
|
||||||
// if (resUser) userInTable.value.push(resUser);
|
if (resGroup) groupList.value = resGroup;
|
||||||
// }
|
}
|
||||||
|
|
||||||
function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
|
function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
|
||||||
const currStep = flowData.value.step[stepIndex];
|
const currStep = flowData.value.step[stepIndex];
|
||||||
|
|
@ -78,6 +84,7 @@ function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
|
||||||
userInTable.value[stepIndex] = {
|
userInTable.value[stepIndex] = {
|
||||||
name: flowData.value.step[stepIndex].name,
|
name: flowData.value.step[stepIndex].name,
|
||||||
responsiblePerson: [],
|
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(
|
function selectItem(
|
||||||
val: Record<string, unknown>,
|
val: Record<string, unknown>,
|
||||||
responsibleInstitution?: string[],
|
responsibleInstitution?: string[],
|
||||||
|
|
@ -142,6 +176,7 @@ watch(
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
role.value = getRole() || [];
|
role.value = getRole() || [];
|
||||||
await getUserList();
|
await getUserList();
|
||||||
|
await getGroupList();
|
||||||
await userStore.fetchHqOption();
|
await userStore.fetchHqOption();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -467,33 +502,29 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- RESPONSIBLE-PERSON -->
|
<!-- RESPONSIBLE-PERSON -->
|
||||||
<q-select
|
<q-field
|
||||||
v-if="step.responsiblePersonId"
|
v-if="step.responsiblePersonId"
|
||||||
behavior="menu"
|
|
||||||
:for="`select-responsible-person-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
|
:for="`select-responsible-person-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
|
||||||
:bg-color="readonly ? 'transparent' : ''"
|
:bg-color="readonly ? 'transparent' : ''"
|
||||||
:readonly
|
:readonly
|
||||||
outlined
|
outlined
|
||||||
dense
|
:stack-label="
|
||||||
v-model="step.responsiblePersonId"
|
userInTable[index]?.responsiblePerson.length > 0 ||
|
||||||
multiple
|
userInTable[index]?.responsibleGroup.length > 0
|
||||||
:options="[1, 2, 3]"
|
"
|
||||||
hide-bottom-space
|
|
||||||
option-label="label"
|
|
||||||
option-value="value"
|
|
||||||
emit-value
|
|
||||||
:label="$t('flow.responsiblePerson')"
|
:label="$t('flow.responsiblePerson')"
|
||||||
|
dense
|
||||||
class="col-md-6 col-12"
|
class="col-md-6 col-12"
|
||||||
:hide-dropdown-icon="readonly"
|
:class="{ 'cursor-pointer': !readonly }"
|
||||||
>
|
>
|
||||||
<template v-slot:selected-item="scope">
|
<template #control>
|
||||||
<div class="column full-width">
|
<q-item
|
||||||
<div
|
dense
|
||||||
class="row items-center no-wrap"
|
class="items-center full-width no-padding"
|
||||||
v-for="person in userInTable[
|
v-for="person in userInTable[
|
||||||
index
|
index
|
||||||
]?.responsiblePerson.filter(
|
]?.responsiblePerson.filter((p) =>
|
||||||
(p) => p.id === scope.opt,
|
step.responsiblePersonId.includes(p.id),
|
||||||
)"
|
)"
|
||||||
:key="person.id"
|
:key="person.id"
|
||||||
>
|
>
|
||||||
|
|
@ -547,12 +578,52 @@ onMounted(async () => {
|
||||||
{{ person.code }}
|
{{ person.code }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</q-item>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-slot:option></template>
|
<div
|
||||||
<q-menu v-if="!readonly" :offset="[0, 4]">
|
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-list>
|
||||||
<q-item>
|
<q-item>
|
||||||
<q-input
|
<q-input
|
||||||
|
|
@ -581,6 +652,7 @@ onMounted(async () => {
|
||||||
{{ $t('general.noData') }}
|
{{ $t('general.noData') }}
|
||||||
</q-item>
|
</q-item>
|
||||||
<q-item
|
<q-item
|
||||||
|
v-else
|
||||||
v-for="(person, i) in userList"
|
v-for="(person, i) in userList"
|
||||||
dense
|
dense
|
||||||
:key="i"
|
:key="i"
|
||||||
|
|
@ -655,6 +727,7 @@ onMounted(async () => {
|
||||||
{{ $t('personnel.MESSENGER') }}
|
{{ $t('personnel.MESSENGER') }}
|
||||||
</span>
|
</span>
|
||||||
<q-item
|
<q-item
|
||||||
|
dense
|
||||||
clickable
|
clickable
|
||||||
@click="step.messengerByArea = !step.messengerByArea"
|
@click="step.messengerByArea = !step.messengerByArea"
|
||||||
class="column"
|
class="column"
|
||||||
|
|
@ -670,9 +743,49 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-item>
|
</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-list>
|
||||||
</q-menu>
|
</q-menu>
|
||||||
</q-select>
|
</q-field>
|
||||||
|
|
||||||
<!-- RESPONSIBLE-AGENCIES, RESPONSIBLE-INSTITUTION -->
|
<!-- RESPONSIBLE-AGENCIES, RESPONSIBLE-INSTITUTION -->
|
||||||
<q-select
|
<q-select
|
||||||
|
|
@ -815,4 +928,11 @@ onMounted(async () => {
|
||||||
:deep(.q-dialog.fullscreen.no-pointer-events.q-dialog--modal) {
|
:deep(.q-dialog.fullscreen.no-pointer-events.q-dialog--modal) {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transition-rotate {
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
.rotated {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ async function addStep() {
|
||||||
flowData.value.step.push({
|
flowData.value.step.push({
|
||||||
responsibleInstitution: [],
|
responsibleInstitution: [],
|
||||||
responsiblePersonId: [],
|
responsiblePersonId: [],
|
||||||
|
responsibleGroup: [],
|
||||||
value: [],
|
value: [],
|
||||||
detail: '',
|
detail: '',
|
||||||
name: '',
|
name: '',
|
||||||
|
|
@ -166,6 +167,7 @@ function triggerPropertiesDialog(step: WorkFlowPayloadStep) {
|
||||||
id="flow-form-dialog"
|
id="flow-form-dialog"
|
||||||
>
|
>
|
||||||
<FormFlow
|
<FormFlow
|
||||||
|
v-model:user-in-table="userInTable"
|
||||||
v-model:flow-data="flowData"
|
v-model:flow-data="flowData"
|
||||||
v-model:register-branch-id="registerBranchId"
|
v-model:register-branch-id="registerBranchId"
|
||||||
@trigger-properties="triggerPropertiesDialog"
|
@trigger-properties="triggerPropertiesDialog"
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ const columns = [
|
||||||
function triggerDialog(type: 'add' | 'edit' | 'view') {
|
function triggerDialog(type: 'add' | 'edit' | 'view') {
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
registeredBranchId.value = '';
|
registeredBranchId.value = '';
|
||||||
|
userInTable.value = [];
|
||||||
formDataWorkflow.value = {
|
formDataWorkflow.value = {
|
||||||
status: 'CREATED',
|
status: 'CREATED',
|
||||||
name: '',
|
name: '',
|
||||||
|
|
@ -207,7 +208,7 @@ async function submit() {
|
||||||
...formDataWorkflow.value,
|
...formDataWorkflow.value,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await workflowStore.creatWorkflowTemplate({
|
await workflowStore.createWorkflowTemplate({
|
||||||
registeredBranchId: registeredBranchId.value,
|
registeredBranchId: registeredBranchId.value,
|
||||||
...formDataWorkflow.value,
|
...formDataWorkflow.value,
|
||||||
});
|
});
|
||||||
|
|
@ -223,7 +224,11 @@ function assignFormData(workflowData: WorkflowTemplate) {
|
||||||
status: workflowData.status,
|
status: workflowData.status,
|
||||||
name: workflowData.name,
|
name: workflowData.name,
|
||||||
step: workflowData.step.map((s, i) => {
|
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) => {
|
s.responsiblePerson.forEach((p) => {
|
||||||
userInTable.value[i].responsiblePerson.push({
|
userInTable.value[i].responsiblePerson.push({
|
||||||
id: p.user.id,
|
id: p.user.id,
|
||||||
|
|
@ -237,12 +242,16 @@ function assignFormData(workflowData: WorkflowTemplate) {
|
||||||
code: p.user.code,
|
code: p.user.code,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
s.responsibleGroup.forEach((g) => {
|
||||||
|
userInTable.value[i].responsibleGroup.push(g);
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
id: s.id,
|
id: s.id,
|
||||||
name: s.name,
|
name: s.name,
|
||||||
detail: s.detail,
|
detail: s.detail,
|
||||||
messengerByArea: s.messengerByArea || false,
|
messengerByArea: s.messengerByArea || false,
|
||||||
value: s.value.length > 0 ? JSON.parse(JSON.stringify(s.value)) : [],
|
value: s.value.length > 0 ? JSON.parse(JSON.stringify(s.value)) : [],
|
||||||
|
responsibleGroup: s.responsibleGroup.map((g) => g),
|
||||||
responsiblePersonId: s.responsiblePerson.map((p) => p.userId),
|
responsiblePersonId: s.responsiblePerson.map((p) => p.userId),
|
||||||
responsibleInstitution: JSON.parse(
|
responsibleInstitution: JSON.parse(
|
||||||
JSON.stringify(s.responsibleInstitution),
|
JSON.stringify(s.responsibleInstitution),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { ref } from 'vue';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { api } from 'src/boot/axios';
|
import { api } from 'src/boot/axios';
|
||||||
import { PaginationResult } from 'src/types';
|
import { PaginationResult } from 'src/types';
|
||||||
import { WorkflowTemplate, WorkflowTemplatePayload, Group } from './types';
|
import { Group, WorkflowTemplate, WorkflowTemplatePayload } from './types';
|
||||||
import { Status } from '../types';
|
import { Status } from '../types';
|
||||||
|
|
||||||
export const useWorkflowTemplate = defineStore('workflow-store', () => {
|
export const useWorkflowTemplate = defineStore('workflow-store', () => {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export type WorkflowTemplatePayload = {
|
||||||
|
|
||||||
export type WorkflowUserInTable = {
|
export type WorkflowUserInTable = {
|
||||||
name: string;
|
name: string;
|
||||||
responsibleGroup: Group[];
|
responsibleGroup: string[];
|
||||||
responsiblePerson: {
|
responsiblePerson: {
|
||||||
id: string;
|
id: string;
|
||||||
selectedImage?: string;
|
selectedImage?: string;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue