jws-frontend/src/pages/08_request-list/PropertiesExpansion.vue
net 2b1e3b12a4
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 6s
refacotr: add id
2025-11-07 16:24:10 +07:00

203 lines
5.3 KiB
Vue

<script setup lang="ts">
import { reactive, ref } from 'vue';
import PropertiesToInput from 'src/components/08_request-list/PropertiesToInput.vue';
import { UndoButton, SaveButton, EditButton } from 'src/components/button';
import {
PropDate,
PropNumber,
PropOptions,
PropString,
} from 'src/stores/product-service/types';
import { Attributes, RequestData } from 'src/stores/request-list/types';
import { getCustomerName, getEmployeeName } from 'src/stores/utils';
import useOptionStore from 'src/stores/options';
import { useRequestList } from 'src/stores/request-list';
import { useI18n } from 'vue-i18n';
const { locale } = useI18n();
const optionStore = useOptionStore();
const requestListStore = useRequestList();
const props = withDefaults(
defineProps<{
id: string;
readonly?: boolean;
propertiesToShow: (PropString | PropNumber | PropDate | PropOptions)[];
requestListData: RequestData;
prefix?: string;
}>(),
{
id: '',
properties: () => [],
},
);
const readonlyField = [
'quotationNo',
'contactPerson',
'telephone',
'employer',
'employee',
];
const formRemark = ref<string>('');
const formData = ref<{
[field: string]: string | number | null | undefined;
}>({});
const state = reactive({
isEdit: false,
});
const attributes = defineModel<Attributes>('attributes', {
default: {
remark: '',
properties: {},
},
});
function triggerUndo() {
assignToForm();
state.isEdit = false;
}
async function triggerSubmit() {
const res = await requestListStore.editRequestWork({
id: props.id,
attributes: {
...(attributes.value || {}),
properties: formData.value,
remark: formRemark.value,
},
});
if (res) {
if (!attributes.value) attributes.value = {};
attributes.value.remark = formRemark.value || '';
attributes.value.properties = JSON.parse(
JSON.stringify(formData.value || {}),
);
state.isEdit = false;
}
}
function triggerEdit() {
state.isEdit = true;
}
function assignToForm() {
const requestData = props.requestListData;
// console.log(requestData);
formRemark.value = attributes.value?.remark || '';
formData.value = JSON.parse(
JSON.stringify(attributes.value?.properties || {}),
);
formData.value['quotationNo'] = requestData.quotation.code;
formData.value['contactPerson'] = requestData.quotation.contactName;
formData.value['telephone'] = requestData.quotation.contactTel;
formData.value['employee'] = getEmployeeName(requestData.employee, {
locale: locale.value,
});
formData.value['employer'] = getCustomerName(
requestData.quotation.customerBranch,
{ locale: locale.value },
);
}
defineEmits<{
(e: 'save', v: { [field: string]: string | number | null | undefined }): void;
}>();
</script>
<template>
<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"
@before-show="assignToForm"
>
<template #header>
<span>
{{ $t('general.properties') }}
</span>
<nav class="q-ml-auto row" v-if="!readonly">
<UndoButton
v-if="state.isEdit"
:id="`btn-properties-${props.prefix || 'nome'}-info-basic-undo`"
icon-only
type="button"
@click.stop="triggerUndo"
/>
<SaveButton
v-if="state.isEdit"
id="btn-info-basic-save"
:id="`btn-properties-${props.prefix || 'nome'}-info-basic-save`"
icon-only
type="submit"
@click.stop="triggerSubmit"
/>
<EditButton
v-if="!state.isEdit"
:id="`btn-properties-${props.prefix || 'nome'}-info-basic-edit`"
icon-only
@click.stop="triggerEdit"
type="button"
/>
</nav>
</template>
<main class="q-px-md q-py-sm" :class="{ row: $q.screen.gt.sm }">
<section class="col-7" :class="{ 'q-pr-sm': $q.screen.gt.sm }">
<span
v-for="(prop, i) in propertiesToShow.filter(
(v) =>
v.fieldName !== 'documentCheck' &&
v.fieldName !== 'designForm' &&
v.fieldName !== 'duty' &&
v.fieldName !== 'messenger',
)"
:key="i"
class="row items-center q-pb-sm"
>
<article class="col-5">
{{ i + 1 }}
{{ optionStore.mapOption(prop.fieldName, 'propertiesField') }}
</article>
<PropertiesToInput
:readonly="!state.isEdit || readonlyField.includes(prop.fieldName)"
:prop="prop"
:placeholder="
optionStore.mapOption(prop.fieldName, 'propertiesField')
"
v-model="formData[prop.fieldName]"
/>
</span>
</section>
<section class="col-5">
<q-input
class="full-height"
:model-value="!state.isEdit ? formRemark || '-' : formRemark"
dense
:readonly="!state.isEdit"
outlined
type="textarea"
:label="$t('general.remark')"
stack-label
@update:model-value="(v) => (formRemark = v as string)"
/>
</section>
</main>
</q-expansion-item>
</template>
<style scoped>
:deep(.q-textarea .q-field__control) {
height: 100%;
}
</style>