203 lines
5.3 KiB
Vue
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>
|