jws-frontend/src/pages/08_request-list/RequestAction.vue
Thanaphon Frappet e2abeca79a
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 7s
fix: v-mode open missing
2025-03-12 15:46:46 +07:00

229 lines
5.5 KiB
Vue

<script setup lang="ts">
import { reactive, ref } from 'vue';
import { RequestWork } from 'src/stores/request-list';
import { DialogContainer, DialogHeader } from 'src/components/dialog';
import {
BackButton,
CancelButton,
MainButton,
SaveButton,
} from 'src/components/button';
import TableProductAndService from 'src/components/shared/table/TableProductAndService.vue';
import { Product } from 'src/stores/product-service/types';
import FormResponsibleUser from './FormResponsibleUser.vue';
import FormGroupHead from './FormGroupHead.vue';
defineProps<{
work: RequestWork[];
responsibleDistrictId: string;
}>();
defineEmits<{
(
e: 'submit',
data: {
form: { responsibleUserLocal: boolean; responsibleUserId: string };
selected: { _work: RequestWork }[];
},
): void;
}>();
enum Step {
Product = 1,
Configure = 2,
}
const open = defineModel<boolean>({ default: false });
const step = ref<Step>(Step.Product);
const selected = ref<{ _work: RequestWork }[]>([]);
const form = reactive({
responsibleUserLocal: false,
responsibleUserId: '',
});
function reset() {
step.value = Step.Product;
selected.value = [];
}
function prev() {
step.value = Step.Product;
}
</script>
<template>
<DialogContainer v-model="open" :onOpen="reset">
<template #header>
<DialogHeader :title="$t('requestList.action.title')" />
</template>
<div class="surface-0 q-pa-md">
<div class="stepper-wrapper">
<div class="stepper">
<template
v-for="(label, i) in [
$t('menu.product'),
$t('requestList.action.configure'),
]"
:key="i"
>
<span class="step" :class="{ ['step__active']: step > i }">
<span class="step-outer"><span class="step-inner" /></span>
<span class="step-label">{{ label }}</span>
</span>
<span
class="step-connector"
:class="{ ['step-connector__active']: step > i + 1 }"
/>
</template>
</div>
</div>
</div>
<div class="surface-1 q-pa-md col">
<TableProductAndService
v-if="step === Step.Product"
type="product"
v-model:selected="selected"
:disabled-product-fields="[
'#priceInformation',
'productProcessingTime',
]"
:rows="
(work?.map((v) => ({
...v.productService.product,
type: 'product',
_work: v,
})) || []) as unknown as Product[]
"
/>
<template v-if="step === Step.Configure">
<q-expansion-item
dense
class="overflow-hidden bordered full-width"
switch-toggle-side
style="border-radius: var(--radius-2)"
expand-icon="mdi-chevron-down-circle"
header-class="surface-1 q-py-sm text-medium text-body1"
default-opened
>
<template #header>
<span>
{{ $t('requestList.employeeMessenger') }}
</span>
</template>
<FormGroupHead>
{{
$t('general.select', { msg: $t('requestList.employeeMessenger') })
}}
</FormGroupHead>
<FormResponsibleUser
:district-id="responsibleDistrictId"
v-model:responsible-user-id="form.responsibleUserId"
v-model:responsible-user-local="form.responsibleUserLocal"
/>
</q-expansion-item>
</template>
</div>
<template #footer>
<div class="q-gutter-x-xs q-ml-auto">
<CancelButton
v-if="step === Step.Product"
id="btn-cancel"
outlined
@click="
reset();
open = false;
"
/>
<BackButton
v-if="step === Step.Configure"
id="btn-back"
outlined
@click="prev"
/>
<MainButton
icon="mdi-check"
color="207 96% 32%"
solid
id="btn-next"
v-if="step === Step.Product"
@click="step = Step.Configure"
>
{{ $t('general.next') }}
</MainButton>
<SaveButton
v-if="step === Step.Configure"
id="btn-save"
solid
@click="$emit('submit', { form, selected })"
/>
</div>
</template>
</DialogContainer>
</template>
<style lang="scss" scoped>
.stepper {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1.5rem;
margin-inline: 25%;
& > .step {
--__color: var(--gray-5);
display: flex;
flex-direction: column;
align-items: center;
position: relative;
gap: 0.25rem;
&.step__active {
--__color: var(--brand-1);
}
& > .step-label {
position: absolute;
font-weight: 600;
color: var(--__color);
white-space: nowrap;
top: 2rem;
}
& > .step-outer {
display: inline-flex;
border: 2px solid var(--__color);
border-radius: 50%;
width: 1.5rem;
height: 1.5rem;
align-items: center;
justify-content: center;
& > .step-inner {
display: inline-block;
border-radius: 50%;
background-color: var(--__color);
width: 0.7rem;
height: 0.7rem;
}
}
}
& > .step-connector {
display: block;
border-bottom: 2px solid var(--gray-5);
flex-grow: 1;
&.step-connector__active {
border-color: var(--brand-1);
}
&:last-child {
display: none;
}
}
}
</style>