jws-frontend/src/components/04_product-service/FormServiceWork.vue
2024-09-25 17:47:01 +07:00

166 lines
4.3 KiB
Vue

<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { moveItemUp, moveItemDown, deleteItem, dialog } from 'stores/utils';
import NoData from 'components/NoData.vue';
import WorkManagementComponent from './WorkManagementComponent.vue';
import AddButton from '../button/AddButton.vue';
import { ServiceCreate, WorkItems } from 'stores/product-service/types';
import TreeView from '../shared/TreeView.vue';
import { ref } from 'vue';
const { t } = useI18n();
const workItems = defineModel<WorkItems[]>('workItems', { default: [] });
const props = defineProps<{
service?: ServiceCreate;
dense?: boolean;
outlined?: boolean;
readonly?: boolean;
separator?: boolean;
treeView?: boolean;
priceDisplay?: {
price: boolean;
agentPrice: boolean;
serviceCharge: boolean;
};
}>();
defineEmits<{
(e: 'addProduct', index: number): void;
(e: 'manageWorkName'): void;
(e: 'workProperties', index: number): void;
}>();
const nodes = ref([
{
title: props.service?.name,
subtitle: props.service?.code,
selected: false,
children: workItems.value.map((v) => ({
title: v.name,
subtitle: ' ',
children: v.product.map((x) => ({
title: x.name,
subtitle: x.code,
})),
})),
},
]);
function addWork() {
workItems.value.push({
id: '',
name: '',
attributes: { additional: [], showTotalPrice: false },
product: [],
});
}
function confirmDelete(items: unknown[], index: number) {
dialog({
color: 'negative',
icon: 'mdi-alert',
title: t('dialog.title.confirmDelete'),
actionText: t('general.delete'),
message: t('dialog.message.confirmDelete'),
action: async () => {
deleteItem(items, index);
},
cancel: () => {},
});
}
</script>
<template>
<div class="column col-12 full-height no-wrap">
<div class="text-weight-bold text-body1 row items-center q-pb-md">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-sm"
color="info"
name="mdi-briefcase-outline"
style="background-color: var(--surface-3)"
/>
{{ $t(`productService.service.workInformation`) }}
<AddButton
v-if="!readonly"
id="btn-add-work"
icon-only
class="q-ml-sm"
@click="addWork"
/>
</div>
<div v-if="workItems.length > 0 && !treeView" class="q-gutter-y-md row">
<WorkManagementComponent
class="col-12"
v-for="(work, index) in workItems"
:key="work.id"
:index="index"
:length="workItems.length"
:workIndex="index"
:readonly="readonly"
:priceDisplay="priceDisplay"
v-model:work-name="workItems[index].name"
v-model:product-items="work.product"
v-model:attributes="work.attributes"
@add-product="$emit('addProduct', index)"
@move-work-up="moveItemUp(workItems, index)"
@move-work-down="moveItemDown(workItems, index)"
@delete-work="confirmDelete(workItems, index)"
@move-product-up="moveItemUp"
@move-product-down="moveItemDown"
@delete-product="confirmDelete"
@manage-work-name="$emit('manageWorkName')"
@work-properties="$emit('workProperties', index)"
></WorkManagementComponent>
<div class="col-12" style="height: 12px"></div>
</div>
<div
v-else-if="workItems.length > 0 && treeView"
class="row rounded bordered surface-2 col q-pa-md"
>
<TreeView
expandable
hideCheckBox
icon-size="2.5rem"
class="full-width"
v-model:nodes="nodes"
:decoration="[
{
level: 0,
icon: 'mdi-server-outline',
bg: 'hsla(var(--orange-5-hsl)/0.1)',
fg: 'var(--orange-5)',
},
{
level: 1,
icon: 'mdi-briefcase-outline',
bg: 'hsla(var(--violet-11-hsl)/0.1)',
fg: 'var(--violet-11)',
},
{
level: 2,
icon: 'mdi-shopping-outline',
bg: 'hsla(var(--teal-10-hsl)/0.1)',
fg: 'var(--teal-10)',
},
]"
/>
</div>
<div
v-else
class="col row rounded bordered surface-2 justify-center items-center"
>
<NoData />
</div>
</div>
</template>
<style scoped lang="scss"></style>