refactor: workflow dialog & mock data
This commit is contained in:
parent
9e1881cba0
commit
3ddca35589
2 changed files with 322 additions and 16 deletions
250
src/components/04_flow-management/FormFlow.vue
Normal file
250
src/components/04_flow-management/FormFlow.vue
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { QTableProps } from 'quasar';
|
||||
import { moveItemUp, moveItemDown, deleteItem } from 'src/stores/utils';
|
||||
|
||||
import ToggleButton from 'src/components/button/ToggleButton.vue';
|
||||
import { DeleteButton } from '../button';
|
||||
|
||||
type WorkFlow = {
|
||||
name: string;
|
||||
step: FlowStep[];
|
||||
};
|
||||
|
||||
type FlowStep = {
|
||||
responsiblePersonId: string[];
|
||||
value: string[];
|
||||
name: string;
|
||||
};
|
||||
|
||||
const flowData = defineModel<WorkFlow>('flowData', {
|
||||
required: true,
|
||||
default: {
|
||||
name: '',
|
||||
step: [],
|
||||
},
|
||||
});
|
||||
|
||||
const responsiblePersonSearch = ref('');
|
||||
const columns = [
|
||||
{
|
||||
name: 'detail',
|
||||
align: 'center',
|
||||
label: 'general.detail',
|
||||
field: 'detail',
|
||||
},
|
||||
{
|
||||
name: 'responsiblePerson',
|
||||
align: 'center',
|
||||
label: 'flow.responsiblePerson',
|
||||
field: 'responsiblePerson',
|
||||
},
|
||||
{
|
||||
name: 'action',
|
||||
align: 'right',
|
||||
label: '',
|
||||
field: 'action',
|
||||
},
|
||||
] satisfies QTableProps['columns'];
|
||||
|
||||
defineEmits<{
|
||||
(e: 'moveUp'): void;
|
||||
(e: 'moveDown'): void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row col-12">
|
||||
<section
|
||||
class="col-12 q-pb-sm text-weight-bold text-body1 row items-center"
|
||||
>
|
||||
<q-icon
|
||||
flat
|
||||
size="xs"
|
||||
class="q-pa-sm rounded q-mr-xs"
|
||||
color="info"
|
||||
name="mdi-office-building-outline"
|
||||
style="background-color: var(--surface-3)"
|
||||
/>
|
||||
{{ $t(`general.name`, { msg: $t('flow.title') }) }}
|
||||
<span class="row items-center q-ml-auto text-weight-regular">
|
||||
{{ $t('status.title') }}
|
||||
<ToggleButton class="q-ml-md" />
|
||||
</span>
|
||||
</section>
|
||||
|
||||
<section id="form-flow-template" class="col-12 row">
|
||||
<q-input
|
||||
outlined
|
||||
dense
|
||||
class="col"
|
||||
v-model="flowData.name"
|
||||
:label="$t(`general.name`, { msg: $t('flow.step') })"
|
||||
></q-input>
|
||||
</section>
|
||||
|
||||
<section
|
||||
id="form-flow-step"
|
||||
class="col-12 q-pb-sm q-pt-lg text-weight-bold text-body1 row items-center"
|
||||
>
|
||||
<q-icon
|
||||
flat
|
||||
size="xs"
|
||||
class="q-pa-sm rounded q-mr-xs"
|
||||
color="info"
|
||||
name="mdi-office-building-outline"
|
||||
style="background-color: var(--surface-3)"
|
||||
/>
|
||||
{{ $t(`flow.processStep`) }}
|
||||
</section>
|
||||
|
||||
<section class="col-12">
|
||||
<q-table
|
||||
flat
|
||||
bordered
|
||||
hide-pagination
|
||||
class="full-width"
|
||||
:columns
|
||||
:rows="flowData.step"
|
||||
:no-data-label="$t('general.noDataTable')"
|
||||
:pagination="{
|
||||
rowsPerPage: 0,
|
||||
}"
|
||||
>
|
||||
<template #header="{ cols }">
|
||||
<q-tr style="background-color: hsla(var(--info-bg) / 0.07)">
|
||||
<q-th v-for="v in cols" :key="v">
|
||||
{{ v.label && $t(v.label, { msg: $t('flow.step') }) }}
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
<template #body="props">
|
||||
<q-tr>
|
||||
<q-td style="width: 60%">
|
||||
<section class="row items-center">
|
||||
<q-btn
|
||||
id="btn-up"
|
||||
for="btn-up"
|
||||
icon="mdi-arrow-up"
|
||||
size="sm"
|
||||
dense
|
||||
flat
|
||||
round
|
||||
:disable="props.rowIndex === 0"
|
||||
style="color: hsl(var(--text-mute-2))"
|
||||
@click.stop="moveItemUp(flowData.step, props.rowIndex)"
|
||||
/>
|
||||
<q-btn
|
||||
id="btn-down"
|
||||
for="btn-down"
|
||||
icon="mdi-arrow-down"
|
||||
size="sm"
|
||||
dense
|
||||
flat
|
||||
round
|
||||
class="q-mx-sm"
|
||||
:disable="props.rowIndex === flowData.step.length - 1"
|
||||
style="color: hsl(var(--text-mute-2))"
|
||||
@click.stop="moveItemDown(flowData.step, props.rowIndex)"
|
||||
/>
|
||||
|
||||
<q-avatar
|
||||
size="md"
|
||||
class="q-mx-lg"
|
||||
style="background-color: var(--surface-tab)"
|
||||
>
|
||||
{{ props.rowIndex + 1 }}
|
||||
</q-avatar>
|
||||
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
:id="`input-flow-step-name-${props.rowIndex}`"
|
||||
:for="`input-flow-step-name-${props.rowIndex}`"
|
||||
class="col"
|
||||
:placeholder="$t('general.no', { msg: $t('flow.step') })"
|
||||
v-model="props.row.name"
|
||||
></q-input>
|
||||
</section>
|
||||
</q-td>
|
||||
|
||||
<q-td>
|
||||
<q-field @click.stop dense outlined>
|
||||
<span class="app-text-muted">
|
||||
{{ $t('general.no', { msg: $t('flow.responsiblePerson') }) }}
|
||||
</span>
|
||||
<q-menu style="width: 18rem" :offset="[0, 4]">
|
||||
<q-list>
|
||||
<q-item>
|
||||
<q-input
|
||||
for="input-search"
|
||||
outlined
|
||||
dense
|
||||
:label="$t('general.search')"
|
||||
class="col responsible-search"
|
||||
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
|
||||
v-model="responsiblePersonSearch"
|
||||
debounce="200"
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="mdi-magnify" />
|
||||
</template>
|
||||
</q-input>
|
||||
</q-item>
|
||||
<span class="text-caption app-text-muted-2 q-px-md">
|
||||
ผู้คน
|
||||
</span>
|
||||
|
||||
<q-item clickable class="column">
|
||||
<div class="row items-center">
|
||||
<q-checkbox :model-value="false" size="xs"></q-checkbox>
|
||||
<q-avatar class="q-ml-sm" size="md">
|
||||
<q-img :src="`/images/employee-avatar.png`" />
|
||||
</q-avatar>
|
||||
<div class="column q-pl-md">
|
||||
<span>นาย กอไก่ ขอไข่</span>
|
||||
<span class="text-caption app-text-muted">10002</span>
|
||||
</div>
|
||||
</div>
|
||||
</q-item>
|
||||
|
||||
<span class="text-caption app-text-muted-2 q-px-md">
|
||||
กลุ่ม
|
||||
</span>
|
||||
<q-item clickable class="column">
|
||||
<div class="row items-center">
|
||||
<q-checkbox :model-value="false" size="xs"></q-checkbox>
|
||||
<q-avatar class="q-ml-sm" size="md">
|
||||
<q-img :src="`/images/employee-avatar.png`" />
|
||||
</q-avatar>
|
||||
<div class="column q-pl-md">
|
||||
<span>กลุ่มคาโมมายด์</span>
|
||||
</div>
|
||||
</div>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-field>
|
||||
</q-td>
|
||||
|
||||
<q-td style="width: 10%">
|
||||
<DeleteButton
|
||||
icon-only
|
||||
class="q-ml-auto"
|
||||
@click="deleteItem(flowData.step, props.rowIndex)"
|
||||
/>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.responsible-search .q-field__control) {
|
||||
height: 36px;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,8 +1,56 @@
|
|||
<script lang="ts" setup>
|
||||
import DialogForm from 'src/components/DialogForm.vue';
|
||||
import SideMenu from 'src/components/SideMenu.vue';
|
||||
import FormFlow from 'src/components/04_flow-management/FormFlow.vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
type WorkFlow = {
|
||||
name: string;
|
||||
step: FlowStep[];
|
||||
};
|
||||
|
||||
type FlowStep = {
|
||||
responsiblePersonId: string[];
|
||||
value: string[];
|
||||
name: string;
|
||||
};
|
||||
|
||||
const model = defineModel<boolean>({ required: true, default: false });
|
||||
const flowData = defineModel<WorkFlow>('flowStep', {
|
||||
required: true,
|
||||
default: {
|
||||
name: '',
|
||||
step: [],
|
||||
},
|
||||
});
|
||||
|
||||
const mockFlowData = ref<WorkFlow>({
|
||||
name: '',
|
||||
step: [],
|
||||
});
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
readonly?: boolean;
|
||||
}>(),
|
||||
{ readonly: false },
|
||||
);
|
||||
|
||||
function addStep() {
|
||||
mockFlowData.value.step.push({
|
||||
responsiblePersonId: [''],
|
||||
value: [''],
|
||||
name: '',
|
||||
});
|
||||
|
||||
const scrollTarget = document.getElementById(
|
||||
`input-flow-step-name-${mockFlowData.value.step.length - 1}`,
|
||||
);
|
||||
console.log(`input-flow-step-name-${mockFlowData.value.step.length - 1}`);
|
||||
console.log(scrollTarget);
|
||||
if (scrollTarget)
|
||||
scrollTarget.scrollIntoView({ behavior: 'instant', inline: 'center' });
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<DialogForm :title="$t('flow.title')" v-model:modal="model">
|
||||
|
|
@ -23,7 +71,12 @@ const model = defineModel<boolean>({ required: true, default: false });
|
|||
:menu="[
|
||||
{
|
||||
name: $t('general.name', { msg: $t('flow.template') }),
|
||||
anchor: 'form-group',
|
||||
anchor: 'form-flow-template',
|
||||
},
|
||||
{
|
||||
name: $t('flow.processStep'),
|
||||
anchor: 'form-flow-step',
|
||||
useBtn: true,
|
||||
},
|
||||
]"
|
||||
background="transparent"
|
||||
|
|
@ -31,8 +84,23 @@ const model = defineModel<boolean>({ required: true, default: false });
|
|||
background: 'hsla(var(--blue-6-hsl) / .2)',
|
||||
foreground: 'var(--blue-6)',
|
||||
}"
|
||||
scroll-element="#group-form"
|
||||
/>
|
||||
scroll-element="#flow-form"
|
||||
>
|
||||
<template v-slot:btn-form-flow-step>
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
icon="mdi-plus"
|
||||
size="sm"
|
||||
rounded
|
||||
id="btn-add-step"
|
||||
padding="0px 0px"
|
||||
style="color: var(--stone-9)"
|
||||
@click.stop="addStep"
|
||||
:disabled="readonly"
|
||||
/>
|
||||
</template>
|
||||
</SideMenu>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -45,19 +113,7 @@ const model = defineModel<boolean>({ required: true, default: false });
|
|||
}"
|
||||
style="height: 100%; max-height: 100%; overflow-y: auto"
|
||||
>
|
||||
<div class="row col-12">
|
||||
<div class="col-12 q-pb-sm text-weight-bold text-body1">
|
||||
<q-icon
|
||||
flat
|
||||
size="xs"
|
||||
class="q-pa-sm rounded q-mr-xs"
|
||||
color="info"
|
||||
name="mdi-office-building-outline"
|
||||
style="background-color: var(--surface-3)"
|
||||
/>
|
||||
{{ $t(`general.name`, { msg: $t('') }) }}
|
||||
</div>
|
||||
</div>
|
||||
<FormFlow id="#flow-form" v-model:flow-data="mockFlowData" />
|
||||
</section>
|
||||
</div>
|
||||
</DialogForm>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue