feat(05): quotation product form
This commit is contained in:
parent
368e8ec588
commit
57b5392bfe
3 changed files with 423 additions and 11 deletions
393
src/pages/05_quotation/ProductServiceForm.vue
Normal file
393
src/pages/05_quotation/ProductServiceForm.vue
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
<script lang="ts" setup>
|
||||
import DialogForm from 'src/components/DialogForm.vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import TreeView from 'src/components/shared/TreeView.vue';
|
||||
|
||||
type Node = {
|
||||
[key: string]: any;
|
||||
opened?: boolean;
|
||||
checked?: boolean;
|
||||
bg?: string;
|
||||
fg?: string;
|
||||
icon?: string;
|
||||
children?: Node[];
|
||||
};
|
||||
|
||||
const model = defineModel<boolean>();
|
||||
const inputSearch = defineModel<string>('inputSearch');
|
||||
|
||||
const splitterModel = ref(20);
|
||||
const subSplitterModel = ref(100);
|
||||
const currentTab = ref('1');
|
||||
const currentSelectedType = ref<'group' | 'type' | 'work' | 'product' | ''>('');
|
||||
const currentSelectedNode = ref<Node[]>([]);
|
||||
|
||||
const nodes = ref([
|
||||
{
|
||||
title: 'กลุ่มสินค้าและบริการที่ 1',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'group',
|
||||
children: [
|
||||
{
|
||||
title:
|
||||
'บริการค่าบริการและค่าดำเนินงานยื่นแบบคำร้องขอนำเข้า MOU (Demand)',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'type',
|
||||
children: [
|
||||
{
|
||||
title: 'งาน 1',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'work',
|
||||
children: [
|
||||
{
|
||||
title: 'สินค้า 1',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'product',
|
||||
},
|
||||
{
|
||||
title: 'สินค้า 2',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'product',
|
||||
},
|
||||
{
|
||||
title: 'สินค้า 3',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'product',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
title: 'กลุ่มสินค้าและบริการที่ 2',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'group',
|
||||
children: [
|
||||
{
|
||||
title:
|
||||
'บริการค่าบริการและค่าดำเนินงานยื่นแบบคำร้องขอนำเข้า MOU (Demand)',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'type',
|
||||
children: [
|
||||
{
|
||||
title: 'งาน 1',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'work',
|
||||
children: [
|
||||
{
|
||||
title: 'สินค้า 1',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'product',
|
||||
},
|
||||
{
|
||||
title: 'สินค้า 2',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'product',
|
||||
},
|
||||
{
|
||||
title: 'สินค้า 3',
|
||||
subtitle: 'TG01000000001',
|
||||
selected: false,
|
||||
type: 'product',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
function triggerInfo() {
|
||||
if (subSplitterModel.value === 100) {
|
||||
subSplitterModel.value = 60;
|
||||
} else {
|
||||
subSplitterModel.value = 100;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSelected(node: Node) {
|
||||
if (currentSelectedNode.value.includes(node)) {
|
||||
currentSelectedNode.value = [];
|
||||
} else {
|
||||
currentSelectedNode.value = [];
|
||||
currentSelectedNode.value.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => currentSelectedNode.value,
|
||||
(v) => {
|
||||
if (v.length > 0) {
|
||||
currentSelectedType.value = v[0].type;
|
||||
} else {
|
||||
currentSelectedType.value = '';
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<DialogForm
|
||||
v-model:modal="model"
|
||||
:title="$t('general.list', { msg: $t('productService.title') })"
|
||||
:submit-label="$t('general.select', { msg: $t('productService.title') })"
|
||||
submit-icon="mdi-check"
|
||||
>
|
||||
<q-splitter
|
||||
v-model="splitterModel"
|
||||
:limits="[0, 30]"
|
||||
class="col"
|
||||
before-class="overflow-hidden"
|
||||
after-class="overflow-hidden"
|
||||
>
|
||||
<!-- SEC: tree component -->
|
||||
<template v-slot:before>
|
||||
<section class="column full-height">
|
||||
<header
|
||||
class="row no-wrap full-width bordered-b surface-3 items-center q-px-md q-py-sm"
|
||||
:style="`min-height: ${$q.screen.gt.sm ? '57px' : '100.8px'}`"
|
||||
>
|
||||
<span class="col ellipsis-2-lines">
|
||||
{{ $t('productService.group.title') }}
|
||||
</span>
|
||||
</header>
|
||||
<body class="surface-1 col">
|
||||
<!-- TODO: tree component -->
|
||||
waiting for tree
|
||||
</body>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<template v-slot:after>
|
||||
<section class="column full-height no-wrap">
|
||||
<header
|
||||
class="row items-center q-py-sm q-px-md justify-between full-width surface-3 bordered-b"
|
||||
>
|
||||
<q-input
|
||||
for="input-search"
|
||||
outlined
|
||||
dense
|
||||
:label="$t('general.search')"
|
||||
class="q-mr-md col-12 col-md-4"
|
||||
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
|
||||
v-model="inputSearch"
|
||||
debounce="200"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="mdi-magnify" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<div>
|
||||
<q-btn
|
||||
padding="4px"
|
||||
color="info"
|
||||
flat
|
||||
rounded
|
||||
icon="mdi-information-outline"
|
||||
@click="triggerInfo"
|
||||
/>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<body class="col">
|
||||
<q-splitter
|
||||
disable
|
||||
v-model="subSplitterModel"
|
||||
:limits="[0, 100]"
|
||||
before-class="overflow-hidden"
|
||||
after-class="overflow-hidden"
|
||||
style="height: 100%"
|
||||
>
|
||||
<!-- SEC: tree view body -->
|
||||
<template v-slot:before>
|
||||
<section class="full-height column">
|
||||
<span
|
||||
v-if="false"
|
||||
class="col column items-center justify-center app-text-muted"
|
||||
>
|
||||
<q-avatar color="input-border" class="q-mb-md">
|
||||
<q-icon name="mdi-shopping" />
|
||||
</q-avatar>
|
||||
{{
|
||||
$t('general.select', {
|
||||
msg: $t('general.list', {
|
||||
msg: $t('productService.title'),
|
||||
}),
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
<body>
|
||||
<TreeView
|
||||
class="full-width q-pt-sm"
|
||||
v-model:nodes="nodes"
|
||||
expandable
|
||||
selectable
|
||||
:selected-node="currentSelectedNode"
|
||||
@select="toggleSelected"
|
||||
:decoration="[
|
||||
{
|
||||
level: 0,
|
||||
icon: 'mdi-folder-outline',
|
||||
bg: 'hsla(var(--pink-6-hsl)/0.1)',
|
||||
fg: 'var(--pink-6)',
|
||||
},
|
||||
{
|
||||
level: 1,
|
||||
icon: 'mdi-server-outline',
|
||||
bg: 'hsla(var(--orange-5-hsl)/0.1)',
|
||||
fg: 'var(--orange-5)',
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
icon: 'mdi-briefcase-outline',
|
||||
bg: 'hsla(var(--violet-11-hsl)/0.1)',
|
||||
fg: 'var(--violet-11)',
|
||||
},
|
||||
{
|
||||
level: 3,
|
||||
icon: 'mdi-shopping-outline',
|
||||
bg: 'hsla(var(--teal-10-hsl)/0.1)',
|
||||
fg: 'var(--teal-10)',
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</body>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<!-- SEC: info -->
|
||||
<template v-slot:after>
|
||||
<section class="column no-wrap surface-1 full-height">
|
||||
<span
|
||||
v-if="currentSelectedType === ''"
|
||||
class="col column items-center justify-center app-text-muted"
|
||||
>
|
||||
<q-img
|
||||
:ratio="1"
|
||||
width="20vw"
|
||||
src="/images/finding.png"
|
||||
></q-img>
|
||||
{{
|
||||
$t('general.select', {
|
||||
msg: $t('general.list', {
|
||||
msg: $t('general.for', {
|
||||
msg: $t('general.viewDetail'),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
<body v-else class="col column no-wrap">
|
||||
<q-tabs
|
||||
inline-label
|
||||
mobile-arrows
|
||||
dense
|
||||
v-model="currentTab"
|
||||
align="left"
|
||||
class="full-width bordered-b"
|
||||
active-color="info"
|
||||
>
|
||||
<q-tab name="1" @click="currentTab = '1'">
|
||||
<div
|
||||
class="row text-capitalize"
|
||||
:class="
|
||||
currentTab === 'detail'
|
||||
? 'text-bold'
|
||||
: 'app-text-muted'
|
||||
"
|
||||
>
|
||||
{{ $t('general.detail') }}
|
||||
</div>
|
||||
</q-tab>
|
||||
<q-tab name="2" @click="currentTab = '2'">
|
||||
<div
|
||||
class="row text-capitalize"
|
||||
:class="
|
||||
currentTab === 'remark'
|
||||
? 'text-bold'
|
||||
: 'app-text-muted'
|
||||
"
|
||||
>
|
||||
{{
|
||||
currentSelectedType !== 'work'
|
||||
? $t('general.remark')
|
||||
: $t('productService.service.properties')
|
||||
}}
|
||||
</div>
|
||||
</q-tab>
|
||||
</q-tabs>
|
||||
|
||||
<div class="q-pa-md column">
|
||||
<span v-if="currentTab === '1'">
|
||||
<span class="app-text-muted">
|
||||
{{
|
||||
$t('general.detail', {
|
||||
msg:
|
||||
currentSelectedType === 'group'
|
||||
? $t('productService.group.title')
|
||||
: currentSelectedType === 'type'
|
||||
? $t('productService.type.title')
|
||||
: currentSelectedType === 'work'
|
||||
? $t('productService.service.title2')
|
||||
: $t('productService.product.title'),
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
<aside class="surface-3 q-pa-md">-</aside>
|
||||
</span>
|
||||
|
||||
<span v-if="currentTab === '2'">
|
||||
<span class="app-text-muted">
|
||||
{{
|
||||
currentSelectedType !== 'work'
|
||||
? $t('general.remark', {
|
||||
msg:
|
||||
currentSelectedType === 'group'
|
||||
? $t('productService.group.title')
|
||||
: currentSelectedType === 'type'
|
||||
? $t('productService.type.title')
|
||||
: $t('productService.product.title'),
|
||||
})
|
||||
: `${$t('productService.service.properties')}${$t('productService.service.title2')}`
|
||||
}}
|
||||
</span>
|
||||
<aside
|
||||
v-if="currentSelectedType !== 'work'"
|
||||
class="surface-3 q-pa-md"
|
||||
>
|
||||
-
|
||||
</aside>
|
||||
<aside v-else class="q-pt-md row q-gutter-sm">
|
||||
<div class="bordered q-py-xs q-px-sm rounded">
|
||||
บันทึกบริการ_Name
|
||||
</div>
|
||||
</aside>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</section>
|
||||
</template>
|
||||
</q-splitter>
|
||||
</body>
|
||||
</section>
|
||||
</template>
|
||||
</q-splitter>
|
||||
</DialogForm>
|
||||
</div>
|
||||
</template>
|
||||
Loading…
Add table
Add a link
Reference in a new issue