Merge branch 'ui-new' into develop
This commit is contained in:
commit
b9d54d5e01
53 changed files with 6634 additions and 2322 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import { boot } from 'quasar/wrappers';
|
import { boot } from 'quasar/wrappers';
|
||||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||||
import '@vuepic/vue-datepicker/dist/main.css'
|
import '@vuepic/vue-datepicker/dist/main.css';
|
||||||
import GlobalDialog from 'components/GlobalDialog.vue';
|
import GlobalDialog from 'components/GlobalDialog.vue';
|
||||||
import GlobalLoading from 'components/GlobalLoading.vue';
|
import GlobalLoading from 'components/GlobalLoading.vue';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,21 @@
|
||||||
defineProps<{
|
defineProps<{
|
||||||
inactive?: boolean;
|
inactive?: boolean;
|
||||||
color?: 'none' | 'hq' | 'br';
|
color?: 'none' | 'hq' | 'br';
|
||||||
data: Record<string, unknown>;
|
data: {
|
||||||
|
branchLabelCode: string;
|
||||||
|
branchLabelName: string;
|
||||||
|
branchLabelTel: string;
|
||||||
|
branchLabelAddress: string;
|
||||||
|
branchLabelType: string;
|
||||||
|
};
|
||||||
metadata?: unknown;
|
metadata?: unknown;
|
||||||
badgeField?: string[];
|
badgeField?: string[];
|
||||||
fieldSelected?: string[];
|
fieldSelected?: (
|
||||||
|
| 'branchLabelName'
|
||||||
|
| 'branchLabelAddress'
|
||||||
|
| 'branchLabelTel'
|
||||||
|
| 'branchLabelType'
|
||||||
|
)[];
|
||||||
footer?: boolean;
|
footer?: boolean;
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -21,112 +32,124 @@ defineProps<{
|
||||||
'branch-card__hq': color === 'hq',
|
'branch-card__hq': color === 'hq',
|
||||||
'branch-card__br': color === 'br',
|
'branch-card__br': color === 'br',
|
||||||
}"
|
}"
|
||||||
|
@click="$emit('open')"
|
||||||
>
|
>
|
||||||
|
<div class="branch-card__header">
|
||||||
|
<div class="branch-card__wrapper">
|
||||||
|
<div class="branch-card__icon">
|
||||||
|
<q-icon
|
||||||
|
size="md"
|
||||||
|
style="scale: 0.8"
|
||||||
|
name="mdi-office-building-outline"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="branch-card__name">
|
||||||
|
<b>{{ data.branchLabelName }}</b>
|
||||||
|
<small class="branch-card__code">{{ data.branchLabelCode }}</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="branch-card__action">
|
||||||
|
<q-btn icon="mdi-dots-vertical" size="sm" dense round flat @click.stop>
|
||||||
|
<slot name="action" />
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="branch-card__row"
|
style="
|
||||||
:class="{
|
display: block;
|
||||||
'branch-card__header': i === 0,
|
width: 100%;
|
||||||
'branch-card__footer': footer && i === Object.keys(data).length - 1,
|
height: 1px;
|
||||||
}"
|
background: hsla(0 0% 0% / 0.1);
|
||||||
v-for="([k, v], i) in Object.entries(data).filter(
|
margin-bottom: var(--size-2);
|
||||||
([key], idx) =>
|
"
|
||||||
idx === 0 || (fieldSelected ? fieldSelected.includes(key) : true),
|
/>
|
||||||
)"
|
<div
|
||||||
:key="k"
|
v-for="key in fieldSelected?.sort() || [
|
||||||
|
'branchLabelAddress',
|
||||||
|
'branchLabelTel',
|
||||||
|
'branchLabelType',
|
||||||
|
]"
|
||||||
|
class="branch-card__data"
|
||||||
>
|
>
|
||||||
<div class="branch-card__label">
|
<div>{{ $t(key) }}</div>
|
||||||
<span>{{ $t(k) }}</span>
|
<div>{{ data[key as keyof typeof data] }}</div>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="branch-card__value"
|
|
||||||
:class="{ 'branch-card__badge': badgeField?.includes(k) }"
|
|
||||||
style="justify-content: space-between"
|
|
||||||
>
|
|
||||||
<span>{{ v }}</span>
|
|
||||||
<q-btn
|
|
||||||
:id="`${v}-view-detail`"
|
|
||||||
@click.stop="$emit('view-detail', metadata ?? data)"
|
|
||||||
:label="$t('viewDetail')"
|
|
||||||
rounded
|
|
||||||
outline
|
|
||||||
dense
|
|
||||||
style="text-wrap: nowrap; max-width: 80%"
|
|
||||||
no-caps
|
|
||||||
class="branch-card__view-detail q-px-md text-caption"
|
|
||||||
v-if="i === 0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.branch-card {
|
.branch-card {
|
||||||
--_branch-card-row-fg: 0 0% 100%;
|
--_branch-card-fg: 0 0% 100%;
|
||||||
--_branch-card-row-bg: var(--blue-5-hsl);
|
--_branch-card-bg: var(--blue-5-hsl);
|
||||||
--_branch-badge-fg: var(--green-8-hsl);
|
--_branch-status-color: var(--green-6-hsl);
|
||||||
--_branch-badge-bg: var(--green-6-hsl);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: var(--shadow-2);
|
padding: var(--size-3);
|
||||||
|
|
||||||
& > .branch-card__row {
|
& .branch-card__header {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: var(--size-2);
|
||||||
|
|
||||||
|
& .branch-card__icon {
|
||||||
|
background-color: hsla(var(--_branch-card-bg) / 0.15);
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: var(--size-1);
|
||||||
|
position: relative;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
aspect-ratio: 1;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
block-size: 0.5rem;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
right: -0.25rem;
|
||||||
|
top: calc(50% - 0.25rem);
|
||||||
|
bottom: calc(50% - 0.25rem);
|
||||||
|
background-color: hsla(var(--_branch-status-color) / 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
& :deep(.q-icon) {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
color: hsla(var(--_branch-card-bg) / 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .branch-card__name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
padding-inline: var(--size-2);
|
||||||
|
|
||||||
|
& .branch-card__code {
|
||||||
|
color: hsla(var(--text-mute) / 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .branch-card__action {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& .branch-card__data {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
|
||||||
padding-inline: var(--size-4);
|
|
||||||
padding-block: var(--size-2);
|
padding-block: var(--size-2);
|
||||||
|
|
||||||
&:last-child {
|
& > :first-child {
|
||||||
flex-grow: 1;
|
color: hsla(var(--text-mute) / 1);
|
||||||
}
|
width: 0%;
|
||||||
|
min-width: 40%;
|
||||||
&:nth-child(2n + 1) {
|
|
||||||
background-color: hsla(var(--_branch-card-row-bg) / 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.branch-card__header,
|
|
||||||
&.branch-card__footer {
|
|
||||||
color: hsl(var(--_branch-card-row-fg));
|
|
||||||
background-color: hsl(var(--_branch-card-row-bg));
|
|
||||||
|
|
||||||
&:deep(*) {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.branch-card__header > * {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .branch-card__label {
|
|
||||||
min-width: 120px;
|
|
||||||
width: 30%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.branch-card__header) .branch-card__label {
|
|
||||||
color: hsl(var(--stone-6-hsl));
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .branch-card__value {
|
|
||||||
width: 70%;
|
|
||||||
|
|
||||||
&.branch-card__badge > span {
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 999rem;
|
|
||||||
padding-inline: var(--size-2);
|
|
||||||
color: hsl(var(--_branch-badge-fg));
|
|
||||||
background-color: hsla(var(--_branch-badge-bg) / 0.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__none {
|
&.branch-card__none {
|
||||||
--_branch-card-row-bg: var(--gray-3-hsl);
|
--_branch-card-bg: var(--gray-3-hsl);
|
||||||
|
|
||||||
&.branch-card__dark {
|
&.branch-card__dark {
|
||||||
--_branch-card-row-bg: var(--gray-9-hsl);
|
--_branch-card-bg: var(--gray-9-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.branch-card__dark) .branch-card__header {
|
&:not(.branch-card__dark) .branch-card__header {
|
||||||
|
|
@ -139,17 +162,22 @@ defineProps<{
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__hq {
|
&.branch-card__hq {
|
||||||
--_branch-card-row-bg: var(--pink-6-hsl);
|
--_branch-card-bg: var(--pink-6-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__br {
|
&.branch-card__br {
|
||||||
--_branch-card-row-bg: var(--violet-11-hsl);
|
--_branch-card-bg: var(--violet-11-hsl);
|
||||||
|
|
||||||
|
&.branch-card__dark {
|
||||||
|
--_branch-card-bg: var(--violet-10-hsl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__inactive {
|
&.branch-card__inactive {
|
||||||
--_branch-badge-fg: var(--red-4-hsl);
|
--_branch-status-color: var(--red-4-hsl);
|
||||||
--_branch-badge-bg: var(--red-4-hsl);
|
--_branch-badge-bg: var(--red-4-hsl);
|
||||||
filter: grayscale(40%);
|
filter: grayscale(1);
|
||||||
|
background-color: hsl(var(--gray-6-hsl) / 0.1);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,11 @@ const branchNo = defineModel<number>('branchNo');
|
||||||
class="col-6"
|
class="col-6"
|
||||||
:label="$t('taxNo')"
|
:label="$t('taxNo')"
|
||||||
v-model="taxNo"
|
v-model="taxNo"
|
||||||
|
:rules="[
|
||||||
|
(val) =>
|
||||||
|
(val && val.length === 13 && /[0-9]+/.test(val)) ||
|
||||||
|
$t('formDialogInputTaxNoValidate'),
|
||||||
|
]"
|
||||||
/>
|
/>
|
||||||
<q-input
|
<q-input
|
||||||
for="input-registerName"
|
for="input-registerName"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { getRole } from 'src/services/keycloak';
|
||||||
import { CustomerBranch } from 'src/stores/customer/types';
|
import { CustomerBranch } from 'src/stores/customer/types';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
|
@ -23,7 +24,7 @@ const customerBranch = defineModel<{
|
||||||
const employeeId = defineModel<string>('employeeId');
|
const employeeId = defineModel<string>('employeeId');
|
||||||
const nrcNo = defineModel<string>('nrcNo');
|
const nrcNo = defineModel<string>('nrcNo');
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
outlined?: boolean;
|
outlined?: boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|
@ -38,8 +39,6 @@ defineProps<{
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
(e: 'filterOwnerBranch', val: string, update: void): void;
|
(e: 'filterOwnerBranch', val: string, update: void): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
onMounted(async () => {});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -63,7 +62,16 @@ onMounted(async () => {});
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="registeredBranchId"
|
v-model="registeredBranchId"
|
||||||
:options="optionsBranch"
|
:options="optionsBranch"
|
||||||
:rules="[(val) => !!val]"
|
:rules="[
|
||||||
|
(val) => {
|
||||||
|
const roles = getRole() || [];
|
||||||
|
const isSpecialRole = ['admin', 'system', 'head_of_admin'].some(
|
||||||
|
(role) => roles.includes(role),
|
||||||
|
);
|
||||||
|
return isSpecialRole || !!val || 'กรุณากรอกข้อมูล';
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
clearable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
|
|
@ -89,6 +97,11 @@ onMounted(async () => {});
|
||||||
class="col-6"
|
class="col-6"
|
||||||
:label="$t('taxNo')"
|
:label="$t('taxNo')"
|
||||||
v-model="taxNo"
|
v-model="taxNo"
|
||||||
|
:rules="[
|
||||||
|
(val) =>
|
||||||
|
(val && val.length === 13 && /[0-9]+/.test(val)) ||
|
||||||
|
$t('formDialogInputTaxNoValidate'),
|
||||||
|
]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,27 @@
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import AppBox from 'components/app/AppBox.vue';
|
defineProps<{
|
||||||
|
inactive?: boolean;
|
||||||
import { CustomerBranch } from 'src/stores/customer/types';
|
color?: 'none' | 'pers' | 'corp';
|
||||||
|
data: {
|
||||||
withDefaults(
|
customerBranchFormTab: number;
|
||||||
defineProps<{
|
branchName: string;
|
||||||
inactive?: boolean;
|
address: string;
|
||||||
color?: 'none' | 'CORP' | 'PERS';
|
telephone: string;
|
||||||
|
businessTypePure: string;
|
||||||
metadata?: unknown;
|
totalEmployee: number;
|
||||||
badgeField?: string[];
|
};
|
||||||
fieldSelected?: string[];
|
metadata?: unknown;
|
||||||
footer?: boolean;
|
badgeField?: string[];
|
||||||
|
fieldSelected?: (
|
||||||
data: {
|
| 'customerBranchFormTab'
|
||||||
customerBranchFormTab: number;
|
| 'branchName'
|
||||||
branchName: string;
|
| 'address'
|
||||||
address: string;
|
| 'telephone'
|
||||||
telephone: string;
|
| 'businessTypePure'
|
||||||
businessTypePure: string;
|
| 'totalEmployee'
|
||||||
status: string;
|
)[];
|
||||||
totalEmployee: number;
|
footer?: boolean;
|
||||||
};
|
}>();
|
||||||
}>(),
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -34,114 +31,135 @@ withDefaults(
|
||||||
'branch-card__dark': $q.dark.isActive,
|
'branch-card__dark': $q.dark.isActive,
|
||||||
'branch-card__inactive': inactive,
|
'branch-card__inactive': inactive,
|
||||||
'branch-card__none':
|
'branch-card__none':
|
||||||
color !== 'CORP' && color !== 'PERS' && (!color || color === 'none'),
|
color !== 'pers' && color !== 'corp' && (!color || color === 'none'),
|
||||||
'branch-card__CORP': color === 'CORP',
|
'branch-card__pers': color === 'pers',
|
||||||
'branch-card__PERS': color === 'PERS',
|
'branch-card__corp': color === 'corp',
|
||||||
}"
|
}"
|
||||||
|
@click="$emit('open')"
|
||||||
>
|
>
|
||||||
<div
|
<div class="branch-card__header">
|
||||||
class="branch-card__row"
|
<div class="branch-card__icon">
|
||||||
:class="{
|
<q-icon
|
||||||
'branch-card__header': i === 0,
|
size="md"
|
||||||
'branch-card__footer': footer && i === Object.keys(data).length - 1,
|
style="scale: 0.8"
|
||||||
}"
|
name="mdi-office-building-outline"
|
||||||
v-for="([k, v], i) in Object.entries(data).filter(
|
|
||||||
([key], idx) =>
|
|
||||||
idx === 0 || (fieldSelected ? fieldSelected.includes(key) : true),
|
|
||||||
)"
|
|
||||||
:key="k"
|
|
||||||
>
|
|
||||||
<div class="branch-card__label">
|
|
||||||
<span>{{ $t(k) }}</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="branch-card__value"
|
|
||||||
:class="{ 'branch-card__badge': badgeField?.includes(k) }"
|
|
||||||
style="justify-content: space-between"
|
|
||||||
>
|
|
||||||
<span>{{ v }}</span>
|
|
||||||
<q-btn
|
|
||||||
@click.stop="$emit('view-detail', metadata ?? data)"
|
|
||||||
:label="$t('viewDetail')"
|
|
||||||
rounded
|
|
||||||
outline
|
|
||||||
dense
|
|
||||||
no-caps
|
|
||||||
class="branch-card__view-detail q-px-md text-caption"
|
|
||||||
v-if="i === 0"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="branch-card__name">
|
||||||
|
<b>{{ data.branchName }}</b>
|
||||||
|
<small class="branch-card__code">{{ data.branchName }}</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="branch-card__action">
|
||||||
|
<q-btn
|
||||||
|
icon="mdi-eye-outline"
|
||||||
|
size="sm"
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
flat
|
||||||
|
@click.stop="$emit('viewDetail')"
|
||||||
|
>
|
||||||
|
<slot name="action" />
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
background: hsla(0 0% 0% / 0.1);
|
||||||
|
margin-bottom: var(--size-2);
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-for="key in fieldSelected?.sort() || [
|
||||||
|
'customerBranchFormTab',
|
||||||
|
'branchName',
|
||||||
|
'address',
|
||||||
|
'telephone',
|
||||||
|
'businessTypePure',
|
||||||
|
'totalEmployee',
|
||||||
|
]"
|
||||||
|
class="branch-card__data"
|
||||||
|
>
|
||||||
|
<div>{{ $t(key) }}</div>
|
||||||
|
<div>{{ data[key as keyof typeof data] }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.branch-card {
|
.branch-card {
|
||||||
--_branch-card-row-fg: 0 0% 100%;
|
--_branch-card-fg: 0 0% 100%;
|
||||||
--_branch-card-row-bg: var(--blue-5-hsl);
|
--_branch-card-bg: var(--blue-5-hsl);
|
||||||
--_branch-badge-fg: var(--green-8-hsl);
|
--_branch-status-color: var(--green-6-hsl);
|
||||||
--_branch-badge-bg: var(--green-6-hsl);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: var(--shadow-2);
|
padding: var(--size-3);
|
||||||
|
|
||||||
& > .branch-card__row {
|
& .branch-card__header {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: var(--size-2);
|
||||||
|
|
||||||
|
& .branch-card__icon {
|
||||||
|
background-color: hsla(var(--_branch-card-bg) / 0.15);
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: var(--size-1);
|
||||||
|
position: relative;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
block-size: 0.5rem;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
right: -0.25rem;
|
||||||
|
top: calc(50% - 0.25rem);
|
||||||
|
bottom: calc(50% - 0.25rem);
|
||||||
|
background-color: hsla(var(--_branch-status-color) / 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
& :deep(.q-icon) {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
color: hsla(var(--_branch-card-bg) / 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .branch-card__name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
padding-inline: var(--size-2);
|
||||||
|
|
||||||
|
& .branch-card__code {
|
||||||
|
color: hsla(var(--text-mute) / 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .branch-card__action {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& .branch-card__data {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
|
||||||
padding-inline: var(--size-4);
|
|
||||||
padding-block: var(--size-2);
|
padding-block: var(--size-2);
|
||||||
|
|
||||||
&:last-child {
|
& > :first-child {
|
||||||
flex-grow: 1;
|
color: hsla(var(--text-mute) / 1);
|
||||||
}
|
width: 0%;
|
||||||
|
min-width: 40%;
|
||||||
&:nth-child(2n + 1) {
|
|
||||||
background-color: hsla(var(--_branch-card-row-bg) / 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.branch-card__header,
|
|
||||||
&.branch-card__footer {
|
|
||||||
color: hsl(var(--_branch-card-row-fg));
|
|
||||||
background-color: hsl(var(--_branch-card-row-bg));
|
|
||||||
|
|
||||||
&:deep(*) {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.branch-card__header > * {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .branch-card__label {
|
|
||||||
min-width: 120px;
|
|
||||||
width: 30%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.branch-card__header) .branch-card__label {
|
|
||||||
color: hsl(var(--stone-6-hsl));
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .branch-card__value {
|
|
||||||
width: 70%;
|
|
||||||
|
|
||||||
&.branch-card__badge > span {
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 999rem;
|
|
||||||
padding-inline: var(--size-2);
|
|
||||||
color: hsl(var(--_branch-badge-fg));
|
|
||||||
background-color: hsla(var(--_branch-badge-bg) / 0.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__none {
|
&.branch-card__none {
|
||||||
--_branch-card-row-bg: var(--gray-3-hsl);
|
--_branch-card-bg: var(--gray-3-hsl);
|
||||||
|
|
||||||
&.branch-card__dark {
|
&.branch-card__dark {
|
||||||
--_branch-card-row-bg: var(--gray-9-hsl);
|
--_branch-card-bg: var(--gray-9-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.branch-card__dark) .branch-card__header {
|
&:not(.branch-card__dark) .branch-card__header {
|
||||||
|
|
@ -153,18 +171,23 @@ withDefaults(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__CORP {
|
&.branch-card__pers {
|
||||||
--_branch-card-row-bg: var(--purple-11-hsl);
|
--_branch-card-bg: var(--pink-6-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__PERS {
|
&.branch-card__corp {
|
||||||
--_branch-card-row-bg: var(--teal-9-hsl);
|
--_branch-card-bg: var(--violet-11-hsl);
|
||||||
|
|
||||||
|
&.branch-card__dark {
|
||||||
|
--_branch-card-bg: var(--violet-10-hsl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.branch-card__inactive {
|
&.branch-card__inactive {
|
||||||
--_branch-badge-fg: var(--red-4-hsl);
|
--_branch-status-color: var(--red-4-hsl);
|
||||||
--_branch-badge-bg: var(--red-4-hsl);
|
--_branch-badge-bg: var(--red-4-hsl);
|
||||||
filter: grayscale(40%);
|
filter: grayscale(1);
|
||||||
|
background-color: hsl(var(--gray-6-hsl) / 0.1);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { ref, onMounted, watch } from 'vue';
|
||||||
|
|
||||||
import useCustomerStore from 'src/stores/customer';
|
import useCustomerStore from 'src/stores/customer';
|
||||||
import useFlowStore from 'src/stores/flow';
|
import useFlowStore from 'src/stores/flow';
|
||||||
|
import useOptionStore from 'src/stores/options';
|
||||||
|
|
||||||
import { Status } from 'src/stores/types';
|
import { Status } from 'src/stores/types';
|
||||||
import { CustomerBranch, CustomerType } from 'src/stores/customer/types';
|
import { CustomerBranch, CustomerType } from 'src/stores/customer/types';
|
||||||
|
|
@ -45,9 +46,9 @@ const prop = withDefaults(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
defineEmits<{
|
||||||
(e: 'back'): void;
|
(e: 'back'): void;
|
||||||
(e: 'viewDetail', branch: CustomerBranch[]): void;
|
(e: 'viewDetail', branch: CustomerBranch, index: number): void;
|
||||||
(e: 'dialog'): void;
|
(e: 'dialog'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|
@ -185,31 +186,29 @@ watch(currentStatus, async () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="row q-pa-lg q-col-gutter-xl"
|
class="row q-pa-md q-col-gutter-md"
|
||||||
:class="{ 'justify-center': totalBranch === 0 }"
|
:class="{ 'justify-center': totalBranch === 0 }"
|
||||||
style="min-height: 350px"
|
style="min-height: 350px"
|
||||||
>
|
>
|
||||||
<NoData v-if="totalBranch === 0" :not-found="!!inputSearch" />
|
<NoData v-if="totalBranch === 0" :not-found="!!inputSearch" />
|
||||||
|
|
||||||
<div
|
<div v-for="(br, i) in branch" :key="i" class="col-4">
|
||||||
v-for="(br, i) in branch?.sort((a, b) => a.branchNo - b.branchNo)"
|
|
||||||
:key="i"
|
|
||||||
class="col-4"
|
|
||||||
>
|
|
||||||
<BranchCardCustomer
|
<BranchCardCustomer
|
||||||
:inactive="br.status === 'INACTIVE'"
|
:inactive="br.status === 'INACTIVE'"
|
||||||
:color="customerType"
|
:color="customerType === 'CORP' ? 'corp' : 'pers'"
|
||||||
:badgeField="['status']"
|
:badgeField="['status']"
|
||||||
:data="{
|
:data="{
|
||||||
customerBranchFormTab: br.branchNo,
|
customerBranchFormTab: br.branchNo,
|
||||||
branchName: br.name,
|
branchName: br.name,
|
||||||
address: br.address,
|
address:
|
||||||
|
$i18n.locale === 'en-US'
|
||||||
|
? `${br.addressEN || ''} ${br.subDistrict?.nameEN || ''} ${br.district?.nameEN || ''} ${br.province?.nameEN || ''}`
|
||||||
|
: `${br.address || ''} ${br.subDistrict?.name || ''} ${br.district?.name || ''} ${br.province?.name || ''}`,
|
||||||
telephone: br.telephoneNo,
|
telephone: br.telephoneNo,
|
||||||
businessTypePure: br.bussinessType,
|
businessTypePure: useOptionStore().mapOption(br.bussinessType),
|
||||||
status: 'ดำเนินการอยู่',
|
|
||||||
totalEmployee: br._count?.employee,
|
totalEmployee: br._count?.employee,
|
||||||
}"
|
}"
|
||||||
@view-detail="emit('viewDetail', [br])"
|
@view-detail="$emit('viewDetail', br, i)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ onMounted(async () => {
|
||||||
<q-select
|
<q-select
|
||||||
id="select-business-type"
|
id="select-business-type"
|
||||||
emit-value
|
emit-value
|
||||||
option-value="label"
|
option-value="value"
|
||||||
option-label="label"
|
option-label="label"
|
||||||
map-options
|
map-options
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
|
|
@ -95,7 +95,7 @@ onMounted(async () => {
|
||||||
<q-select
|
<q-select
|
||||||
id="select-job-position"
|
id="select-job-position"
|
||||||
emit-value
|
emit-value
|
||||||
option-value="label"
|
option-value="value"
|
||||||
option-label="label"
|
option-label="label"
|
||||||
map-options
|
map-options
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,7 @@ defineProps<{
|
||||||
class="col-6"
|
class="col-6"
|
||||||
:label="$t('formDialogInputPassportRef')"
|
:label="$t('formDialogInputPassportRef')"
|
||||||
v-model="previousPassportReference"
|
v-model="previousPassportReference"
|
||||||
:rules="[
|
|
||||||
(val: string) =>
|
|
||||||
!!val || $t('inputValidate') + $t('formDialogInputPassportRef'),
|
|
||||||
]"
|
|
||||||
/>
|
/>
|
||||||
<q-input
|
<q-input
|
||||||
for="input-passport-place"
|
for="input-passport-place"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { getRole } from 'src/services/keycloak';
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
const { locale } = useI18n({ useScope: 'global' });
|
const { locale } = useI18n({ useScope: 'global' });
|
||||||
|
|
@ -10,9 +11,9 @@ const name = defineModel<string>('name');
|
||||||
const code = defineModel<string>('code');
|
const code = defineModel<string>('code');
|
||||||
|
|
||||||
const registeredBranchId = defineModel<string>('registeredBranchId');
|
const registeredBranchId = defineModel<string>('registeredBranchId');
|
||||||
const codeOption = ref([]);
|
const codeOption = ref<{ id: string; name: string }[]>([]);
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
outlined?: boolean;
|
outlined?: boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|
@ -31,6 +32,15 @@ onMounted(async () => {
|
||||||
if (locale.value === 'th-th') {
|
if (locale.value === 'th-th') {
|
||||||
codeOption.value = option.tha.typeProduct;
|
codeOption.value = option.tha.typeProduct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!!props.optionsBranch) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
registeredBranchId.value = props.optionsBranch[0].id ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -71,18 +81,25 @@ onMounted(async () => {
|
||||||
map-options
|
map-options
|
||||||
options-dense
|
options-dense
|
||||||
:label="$t('registeredBranch')"
|
:label="$t('registeredBranch')"
|
||||||
class="col-3"
|
class="col-3 "
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="registeredBranchId"
|
v-model="registeredBranchId"
|
||||||
:options="optionsBranch"
|
:options="optionsBranch"
|
||||||
:rules="[(val) => !!val]"
|
:rules="[
|
||||||
|
(val) => {
|
||||||
|
const roles = getRole() || [];
|
||||||
|
const isSpecialRole = ['admin', 'system', 'head_of_admin'].some(role => roles.includes(role));
|
||||||
|
return isSpecialRole || !!val || 'กรุณากรอกข้อมูล';
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
clearable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
for="input-name"
|
for="input-name"
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
:outlined="!readonly"
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:borderless="readonly"
|
:borderless="readonly"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
|
|
@ -94,7 +111,7 @@ onMounted(async () => {
|
||||||
<q-input
|
<q-input
|
||||||
for="input-detail"
|
for="input-detail"
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
:outlined="!readonly"
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:borderless="readonly"
|
:borderless="readonly"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
|
|
@ -108,7 +125,7 @@ onMounted(async () => {
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<q-field
|
<q-field
|
||||||
class="full-width"
|
class="full-width"
|
||||||
:outlined="!readonly"
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:borderless="readonly"
|
:borderless="readonly"
|
||||||
:label="$t('detail')"
|
:label="$t('detail')"
|
||||||
|
|
@ -138,12 +155,12 @@ onMounted(async () => {
|
||||||
<q-input
|
<q-input
|
||||||
for="input-process"
|
for="input-process"
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
:outlined="!readonly"
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:borderless="readonly"
|
:borderless="readonly"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
class="col-4"
|
class="col-4"
|
||||||
:label="$t('processingTime')"
|
:label="$t('productProcessingTime')"
|
||||||
v-model="process"
|
v-model="process"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { getRole } from 'src/services/keycloak';
|
||||||
import useOptionStore from 'src/stores/options';
|
import useOptionStore from 'src/stores/options';
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
|
||||||
const optionStore = useOptionStore();
|
const optionStore = useOptionStore();
|
||||||
|
|
||||||
|
|
@ -13,7 +15,7 @@ const serviceName = defineModel<string>('serviceNameTh');
|
||||||
const serviceDescription = defineModel<string>('serviceDescription');
|
const serviceDescription = defineModel<string>('serviceDescription');
|
||||||
|
|
||||||
const registeredBranchId = defineModel<string | null>('registeredBranchId');
|
const registeredBranchId = defineModel<string | null>('registeredBranchId');
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
outlined?: boolean;
|
outlined?: boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|
@ -77,6 +79,7 @@ defineProps<{
|
||||||
|
|
||||||
<q-select
|
<q-select
|
||||||
id="input-source-nationality"
|
id="input-source-nationality"
|
||||||
|
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
outlined
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
|
|
@ -86,12 +89,19 @@ defineProps<{
|
||||||
map-options
|
map-options
|
||||||
options-dense
|
options-dense
|
||||||
:label="$t('registeredBranch')"
|
:label="$t('registeredBranch')"
|
||||||
class="col-3"
|
class="col-3 "
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="registeredBranchId"
|
v-model="registeredBranchId"
|
||||||
:options="optionsBranch"
|
:options="optionsBranch"
|
||||||
:rules="[(val) => !!val]"
|
:rules="[
|
||||||
|
(val) => {
|
||||||
|
const roles = getRole() || [];
|
||||||
|
const isSpecialRole = ['admin', 'system', 'head_of_admin'].some(role => roles.includes(role));
|
||||||
|
return isSpecialRole || !!val || 'กรุณากรอกข้อมูล';
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
clearable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
|
|
|
||||||
|
|
@ -13,37 +13,40 @@ defineProps<{
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="col-3 app-text-muted">• {{ $t('priceeInformation') }}</div>
|
<div class="col-3 app-text-muted">• {{ $t('priceInformation') }}</div>
|
||||||
<div class="col-9 row q-col-gutter-md">
|
<div class="col-9 row q-col-gutter-md">
|
||||||
<q-input
|
<q-input
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
:outlined="!readonly"
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:borderless="readonly"
|
:borderless="readonly"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
class="col-4"
|
class="col-4"
|
||||||
|
type="number"
|
||||||
:label="$t('salePrice')"
|
:label="$t('salePrice')"
|
||||||
v-model="price"
|
v-model="price"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
:outlined="!readonly"
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:borderless="readonly"
|
:borderless="readonly"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
class="col-4"
|
class="col-4"
|
||||||
|
type="number"
|
||||||
:label="$t('agentPrice')"
|
:label="$t('agentPrice')"
|
||||||
v-model="agentPrice"
|
v-model="agentPrice"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
:dense="dense"
|
:dense="dense"
|
||||||
:outlined="!readonly"
|
outlined
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:borderless="readonly"
|
:borderless="readonly"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
class="col-4"
|
class="col-4"
|
||||||
|
type="number"
|
||||||
:label="$t('processingPrice')"
|
:label="$t('processingPrice')"
|
||||||
v-model="serviceCharge"
|
v-model="serviceCharge"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ withDefaults(
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="relative-position rounded q-pb-lg"
|
class="relative-position rounded q-pb-lg"
|
||||||
:style="`background-color:hsla(${color}/0.1)`"
|
:style="`background-color:hsla(${color}/.2)`"
|
||||||
>
|
>
|
||||||
<div class="row justify-between items-center">
|
<div class="row justify-between items-center">
|
||||||
<q-avatar
|
<q-avatar
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ withDefaults(
|
||||||
<div
|
<div
|
||||||
bordered
|
bordered
|
||||||
:class="{ 'is-add-product': isAddProduct }"
|
:class="{ 'is-add-product': isAddProduct }"
|
||||||
class="column bordered rounded q-pa-sm no-wrap"
|
class="column bordered rounded q-pa-sm no-wrap surface-1"
|
||||||
style="box-shadow: var(--shadow-3); height: 20rem"
|
style="height: 20rem"
|
||||||
@click="$emit('select', data)"
|
@click="$emit('select', data)"
|
||||||
>
|
>
|
||||||
<div class="row flex justify-between text-bold">
|
<div class="row flex justify-between text-bold">
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ defineProps<{
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<q-btn
|
<q-btn
|
||||||
unelevated
|
unelevated
|
||||||
|
id="btn-Add"
|
||||||
@click="$emit('trigger')"
|
@click="$emit('trigger')"
|
||||||
size="lg"
|
size="lg"
|
||||||
class="color-btn"
|
class="color-btn"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-page-sticky position="bottom-right" :offset="[30, 18]">
|
<q-page-sticky position="bottom-right" :offset="[8, 8]">
|
||||||
<q-fab
|
<q-fab
|
||||||
id="btn-add"
|
id="btn-add"
|
||||||
padding="xs"
|
padding="xs"
|
||||||
|
|
@ -9,9 +9,9 @@
|
||||||
direction="up"
|
direction="up"
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot>
|
||||||
|
<q-fab-action padding="xs" color="primary" icon="mdi-account-plus" />
|
||||||
<!-- <q-fab-action padding="xs" color="primary" icon="mdi-account-plus" /> -->
|
</slot>
|
||||||
</q-fab>
|
</q-fab>
|
||||||
</q-page-sticky>
|
</q-page-sticky>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,32 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { computed, ref, onMounted } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
import { Icon } from '@iconify/vue';
|
import { Icon } from '@iconify/vue';
|
||||||
|
import useMyBranch from 'stores/my-branch';
|
||||||
|
import { getUserId, getRole } from 'src/services/keycloak';
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
mini?: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const uid = getUserId();
|
||||||
|
const role = getRole();
|
||||||
|
|
||||||
|
if (!uid) return;
|
||||||
|
|
||||||
|
if (role?.includes('system')) {
|
||||||
|
const result = await userBranch.fetchListOptionBranch();
|
||||||
|
if (result && result.total > 0) currentMyBranch.value = result.result[0];
|
||||||
|
}
|
||||||
|
const result = await userBranch.fetchListMyBranch(uid);
|
||||||
|
if (result && result.total > 0) currentMyBranch.value = result.result[0];
|
||||||
|
});
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const userBranch = useMyBranch();
|
||||||
|
const { currentMyBranch } = storeToRefs(userBranch);
|
||||||
|
|
||||||
const currentRoute = ref<string>('');
|
const currentRoute = ref<string>('');
|
||||||
const currentPath = computed(() => {
|
const currentPath = computed(() => {
|
||||||
|
|
@ -79,55 +102,119 @@ const labelMenu = ref<
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const leftDrawerOpen = defineModel<boolean>('leftDrawerOpen', {
|
const leftDrawerOpen = defineModel<boolean>('leftDrawerOpen', {
|
||||||
default: false,
|
default: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
function navigateTo(label: string, destination: string) {
|
function navigateTo(label: string, destination: string) {
|
||||||
currentRoute.value = label;
|
currentRoute.value = label;
|
||||||
router.push(`${destination}`);
|
router.push(`${destination}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function branchSetting() {}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- Drawer -->
|
<!-- Drawer -->
|
||||||
<q-drawer
|
<q-drawer
|
||||||
|
no-swipe-open
|
||||||
v-model="leftDrawerOpen"
|
v-model="leftDrawerOpen"
|
||||||
side="left"
|
side="left"
|
||||||
:breakpoint="599"
|
:breakpoint="599"
|
||||||
:width="$q.screen.lt.md ? 200 : 300"
|
class="column justify-between no-wrap"
|
||||||
|
:width="mini ? 80 : 256"
|
||||||
|
show-if-above
|
||||||
>
|
>
|
||||||
<div class="main-bar">
|
<!-- :width="$q.screen.lt.sm ? $q.screen.width - 16 : 256" -->
|
||||||
|
<div class="scroll" style="overflow-x: hidden; scrollbar-gutter: stable">
|
||||||
<div
|
<div
|
||||||
class="column items-center justify-center q-pa-xl cursor-pointer"
|
class="flex justify-center items-center q-pl-sm cursor-pointer"
|
||||||
@click="$router.push('/')"
|
@click="$router.push('/')"
|
||||||
id="btn-drawer-home"
|
id="btn-drawer-home"
|
||||||
|
style="height: 128px"
|
||||||
>
|
>
|
||||||
<q-img src="/logo.png" style="width: 70%; height: 70%">
|
<q-img
|
||||||
<template #error>
|
fit="contain"
|
||||||
<img src="/logo.png" alt="" width="100%" />
|
:src="mini ? 'logo_jws.png' : '/logo.png'"
|
||||||
</template>
|
:style="{ filter: `brightness(${$q.dark.isActive ? '1.3' : '1'})` }"
|
||||||
</q-img>
|
style="height: 64px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="drawer-menu" class="q-pl-md q-mr-xs">
|
||||||
|
<q-item
|
||||||
|
v-for="v in labelMenu"
|
||||||
|
dense
|
||||||
|
clickable
|
||||||
|
class="row items-center q-my-xs q-px-xs"
|
||||||
|
:key="v.label"
|
||||||
|
:disable="!!v.disabled"
|
||||||
|
:class="{
|
||||||
|
active: currentPath === v.route,
|
||||||
|
'border-active': currentPath === v.route,
|
||||||
|
dark: $q.dark.isActive,
|
||||||
|
}"
|
||||||
|
@click="navigateTo(v.label, v.route)"
|
||||||
|
>
|
||||||
|
<div class="row justify-center items-center">
|
||||||
|
<Icon :icon="v.icon" width="24px" />
|
||||||
|
<q-tooltip v-if="mini">
|
||||||
|
{{ $t(v.label) }}
|
||||||
|
</q-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!mini" class="q-ml-md" style="white-space: nowrap">
|
||||||
|
{{ $t(v.label) }}
|
||||||
|
</div>
|
||||||
|
</q-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="drawer-menu" class="q-pr-sm">
|
<div
|
||||||
<q-item
|
class="surface-2 q-px-md q-py-sm row items-center no-wrap justify-start"
|
||||||
v-for="v in labelMenu"
|
:class="{ 'justify-center': mini }"
|
||||||
:key="v.label"
|
style="min-height: 56px; overflow-x: hidden"
|
||||||
clickable
|
>
|
||||||
:disable="!!v.disabled"
|
<q-avatar
|
||||||
@click="navigateTo(v.label, v.route)"
|
text-color="white"
|
||||||
class="no-padding"
|
size="md"
|
||||||
:class="{ active: currentPath === v.route, dark: $q.dark.isActive }"
|
:style="`background-color: hsla(var(--violet-${$q.dark.isActive ? '10' : '11'}-hsl)/0.15)`"
|
||||||
|
class="relative-position"
|
||||||
>
|
>
|
||||||
<q-item-section id="btn-drawer-back ">
|
<q-icon
|
||||||
<q-item-label class="q-pl-lg row items-center">
|
name="mdi-home-group"
|
||||||
<div class="box-border-left" />
|
size="sm"
|
||||||
<Icon :icon="v.icon" width="24px" class="q-mr-md" />
|
:style="`color: var(--violet-${$q.dark.isActive ? '10' : '11'})`"
|
||||||
{{ $t(v.label) }}
|
/>
|
||||||
</q-item-label>
|
<div class="dot absolute-bottom-right" />
|
||||||
</q-item-section>
|
</q-avatar>
|
||||||
</q-item>
|
|
||||||
|
<div
|
||||||
|
v-if="!mini"
|
||||||
|
class="text-caption column q-ml-sm"
|
||||||
|
style="white-space: nowrap"
|
||||||
|
>
|
||||||
|
<span class="text-weight-bold">
|
||||||
|
{{
|
||||||
|
($i18n.locale === 'en-US'
|
||||||
|
? currentMyBranch?.nameEN
|
||||||
|
: currentMyBranch?.name) ?? '-'
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{{ currentMyBranch?.code ?? '-' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
v-if="!mini"
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
rounded
|
||||||
|
icon="mdi-cog-outline"
|
||||||
|
size="sm"
|
||||||
|
@click="branchSetting"
|
||||||
|
style="margin-left: auto"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -135,27 +222,47 @@ function navigateTo(label: string, destination: string) {
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
#drawer-menu :deep(.q-item) {
|
#drawer-menu :deep(.q-item) {
|
||||||
color: var(--gray-6);
|
color: var(--gray-6);
|
||||||
border-top-right-radius: 10px;
|
border-radius: var(--radius-2);
|
||||||
border-bottom-right-radius: 10px;
|
|
||||||
}
|
}
|
||||||
#drawer-menu :deep(.q-item.active) {
|
#drawer-menu :deep(.q-item.active) {
|
||||||
--_drawer-item-background-color: var(--brand-1) !important;
|
--_drawer-item-background-color: var(--brand-1) !important;
|
||||||
background-color: var(--_drawer-item-background-color);
|
background-color: var(--_drawer-item-background-color);
|
||||||
color: white;
|
color: white;
|
||||||
border-left: 10px solid $secondary;
|
|
||||||
|
|
||||||
&.dark {
|
// border-left: 10px solid $secondary;
|
||||||
--_drawer-item-background-color: var(--gray-10) !important;
|
}
|
||||||
border: 1px solid var(--brand-1);
|
|
||||||
border-left: 10px solid $secondary;
|
#drawer-menu :deep(.q-item.active)::before {
|
||||||
.box-border-left {
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 10px;
|
content: ' ';
|
||||||
background: $secondary;
|
background: var(--brand-2);
|
||||||
height: 48.5px;
|
border-radius: 99rem;
|
||||||
top: -1px;
|
width: 6px;
|
||||||
left: -10px;
|
left: -0.6rem;
|
||||||
}
|
top: 18%;
|
||||||
}
|
bottom: 18%;
|
||||||
|
cursor: context-menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.q-drawer) {
|
||||||
|
transition: 0.1s width ease-in-out;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: var(--size-4);
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.q-drawer__content) {
|
||||||
|
border-radius: var(--radius-2);
|
||||||
|
background: var(--surface-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
background-color: var(--teal-6);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1.5px solid white;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,22 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import AppBox from 'components/app/AppBox.vue';
|
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
branch: {
|
branch: {
|
||||||
|
icon: string;
|
||||||
count: number;
|
count: number;
|
||||||
label: string;
|
label: string;
|
||||||
color: 'pink' | 'purple' | 'green' | 'orange';
|
color:
|
||||||
|
| 'pink'
|
||||||
|
| 'purple'
|
||||||
|
| 'green'
|
||||||
|
| 'orange'
|
||||||
|
| 'cyan'
|
||||||
|
| 'yellow'
|
||||||
|
| 'red'
|
||||||
|
| 'magenta';
|
||||||
}[];
|
}[];
|
||||||
dark?: boolean;
|
dark?: boolean;
|
||||||
labelI18n?: boolean;
|
labelI18n?: boolean;
|
||||||
nowrap?: boolean;
|
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
labelI18n: false,
|
labelI18n: false,
|
||||||
|
|
@ -19,113 +25,101 @@ const props = withDefaults(
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="row no-wrap" style="gap: var(--size-4)" :class="{ dark }">
|
||||||
class="row full-width"
|
<div
|
||||||
style="gap: var(--size-4)"
|
|
||||||
:class="{ dark, 'no-wrap': nowrap }"
|
|
||||||
>
|
|
||||||
<AppBox
|
|
||||||
v-for="v in props.branch"
|
v-for="v in props.branch"
|
||||||
:key="v.label"
|
class="no-padding stat-card"
|
||||||
class="bordered stat-card__wave"
|
|
||||||
:class="{ [`stat-card__${v.color}`]: true }"
|
:class="{ [`stat-card__${v.color}`]: true }"
|
||||||
style="
|
:key="v.label"
|
||||||
padding: 12px 16px;
|
|
||||||
height: 75px;
|
|
||||||
min-width: 232px;
|
|
||||||
box-shadow: var(--shadow-2);
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<svg
|
<div class="stat-card__content row items-center q-pa-sm">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<div class="col-4 text-center">
|
||||||
viewBox="0 0 1440 320"
|
<q-avatar
|
||||||
style="width: 100%"
|
size="lg"
|
||||||
>
|
style="background-color: hsla(0 0% 100% /0.2)"
|
||||||
<path
|
text-color="white"
|
||||||
class="box-path"
|
:icon="v.icon"
|
||||||
d="M0,256L40,245.3C80,235,160,213,240,202.7C320,192,400,192,480,170.7C560,149,640,107,720,106.7C800,107,880,149,960,154.7C1040,160,1120,128,1200,96C1280,64,1360,32,1400,16L1440,0L1440,320L1400,320C1360,320,1280,320,1200,320C1120,320,1040,320,960,320C880,320,800,320,720,320C640,320,560,320,480,320C400,320,320,320,240,320C160,320,80,320,40,320L0,320Z"
|
/>
|
||||||
></path>
|
</div>
|
||||||
</svg>
|
<div class="col-6 justify-center column">
|
||||||
|
<div class="col-6 ellipsis text-bold" style="width: 100%">
|
||||||
|
{{ labelI18n ? $t(v.label) : v.label }}
|
||||||
|
<q-tooltip
|
||||||
|
anchor="top middle"
|
||||||
|
self="bottom middle"
|
||||||
|
:offset="[10, 10]"
|
||||||
|
>
|
||||||
|
{{ labelI18n ? $t(v.label) : v.label }}
|
||||||
|
</q-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="stat-card__content">
|
<div class="col-6">{{ v.count }}</div>
|
||||||
<div class="text-h5 text-weight-bold">{{ v.count }}</div>
|
|
||||||
<div class="text-weight-bold text-no-wrap">
|
|
||||||
{{ labelI18n ? $t(v.label) : v.label }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AppBox>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.stat-card {
|
.stat-card {
|
||||||
--_color: var(--gray-6);
|
border-radius: var(--radius-2);
|
||||||
display: grid;
|
overflow: hidden;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
box-shadow: var(--shadow-2);
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1024px) {
|
|
||||||
.stat-card {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1920px) {
|
|
||||||
.stat-card {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card__wave {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
& svg {
|
|
||||||
width: 200px;
|
|
||||||
position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
bottom: 0;
|
|
||||||
opacity: 0.1;
|
|
||||||
|
|
||||||
& .box-path {
|
|
||||||
fill: var(--_color);
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card__content {
|
.stat-card__content {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
color: var(--_color);
|
color: hsla(var(--gray-0-hsl) / 1);
|
||||||
|
background: hsla(var(--_color) / 1);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card__purple {
|
.stat-card__purple {
|
||||||
--_color: var(--violet-11);
|
--_color: var(--violet-11-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card__pink {
|
.stat-card__pink {
|
||||||
--_color: var(--pink-6);
|
--_color: var(--pink-6-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card__green {
|
.stat-card__green {
|
||||||
--_color: var(--teal-10);
|
--_color: var(--teal-10-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card__cyan {
|
||||||
|
--_color: var(--cyan-7-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card__red {
|
||||||
|
--_color: var(--red-6-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card__yellow {
|
||||||
|
--_color: var(--orange-4-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card__orange {
|
.stat-card__orange {
|
||||||
--_color: var(--orange-5);
|
--_color: var(--orange-5-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card__magenta {
|
||||||
|
--_color: var(--pink-8-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .stat-card__purple {
|
.dark .stat-card__purple {
|
||||||
--_color: var(--purple-7);
|
--_color: var(--violet-10-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .stat-card__green {
|
.dark .stat-card__green {
|
||||||
--_color: var(--teal-7);
|
--_color: var(--teal-8-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .stat-card__orange {
|
.dark .stat-card__orange {
|
||||||
--_color: var(--orange-8);
|
--_color: var(--orange-6-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .stat-card__magenta {
|
||||||
|
--_color: var(--pink-7-hsl);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { CustomerBranchCreate } from 'stores/customer/types';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
edit?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const customerBranch = defineModel<CustomerBranchCreate[]>('customerBranch', {
|
const customerBranch = defineModel<CustomerBranchCreate[]>('customerBranch', {
|
||||||
|
|
@ -17,6 +18,8 @@ const index = ref<number>(0);
|
||||||
function addData() {
|
function addData() {
|
||||||
index.value++;
|
index.value++;
|
||||||
customerBranch.value.push({
|
customerBranch.value.push({
|
||||||
|
code: '',
|
||||||
|
branchNo: undefined,
|
||||||
address: '',
|
address: '',
|
||||||
addressEN: '',
|
addressEN: '',
|
||||||
provinceId: '',
|
provinceId: '',
|
||||||
|
|
@ -91,7 +94,8 @@ function close(index: number) {
|
||||||
v-for="(v, index) in customerBranch"
|
v-for="(v, index) in customerBranch"
|
||||||
:key="index"
|
:key="index"
|
||||||
:name="index"
|
:name="index"
|
||||||
:label="`${$t('customerBranchFormTab')} ${index + 1}`"
|
:label="`${$t('customerBranchFormTab')} `"
|
||||||
|
:disable="tab !== index && edit"
|
||||||
@click="tab = index"
|
@click="tab = index"
|
||||||
no-caps
|
no-caps
|
||||||
:class="tab === index ? '' : 'bordered-b bordered-r'"
|
:class="tab === index ? '' : 'bordered-b bordered-r'"
|
||||||
|
|
@ -114,7 +118,9 @@ function close(index: number) {
|
||||||
<q-tab-panels v-model="tab" class="rounded-borders">
|
<q-tab-panels v-model="tab" class="rounded-borders">
|
||||||
<q-tab-panel
|
<q-tab-panel
|
||||||
:id="`tab-branch-${index}`"
|
:id="`tab-branch-${index}`"
|
||||||
v-for="(v, index) in customerBranch"
|
v-for="(v, index) in customerBranch.sort(
|
||||||
|
(a, b) => (a.branchNo ?? 0) - (b.branchNo ?? 0),
|
||||||
|
)"
|
||||||
:key="index"
|
:key="index"
|
||||||
:name="index"
|
:name="index"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -315,11 +315,11 @@ defineEmits<{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.color__purple {
|
&.color__purple {
|
||||||
--_color: var(--purple-11-hsl);
|
--_color: var(--violet-11-hsl);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.color__green {
|
&.color__green {
|
||||||
--_color: var(--teal-9-hsl);
|
--_color: var(--teal-10-hsl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,275 +5,242 @@ import AppBox from 'components/app/AppBox.vue';
|
||||||
import AppCircle from 'components/app/AppCircle.vue';
|
import AppCircle from 'components/app/AppCircle.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
list: {
|
data: {
|
||||||
id: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
detail?: { label: string; value: string }[];
|
code: string;
|
||||||
male?: boolean;
|
male?: boolean;
|
||||||
female?: boolean;
|
female?: boolean;
|
||||||
disabled?: boolean;
|
|
||||||
badge?: string;
|
|
||||||
img?: string;
|
img?: string;
|
||||||
}[];
|
detail?: { icon: string; value: string }[];
|
||||||
gridColumns?: number;
|
};
|
||||||
|
tag?: [{ color: string; value: string }];
|
||||||
|
disabled?: boolean;
|
||||||
noHover?: boolean;
|
noHover?: boolean;
|
||||||
noAction?: boolean;
|
noAction?: boolean;
|
||||||
noDetail?: boolean;
|
|
||||||
noBg?: boolean;
|
noBg?: boolean;
|
||||||
detailColumnCount?: number;
|
|
||||||
canEditProfile?: boolean;
|
|
||||||
history?: boolean;
|
history?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
(e: 'editProfile'): void;
|
(e: 'editProfile'): void;
|
||||||
(e: 'history', id: string): void;
|
(e: 'history'): void;
|
||||||
(e: 'deleteCard', id: string): void;
|
(e: 'deleteCard'): void;
|
||||||
(
|
(e: 'updateCard', action: 'FORM' | 'INFO', isEdit?: boolean): void;
|
||||||
e: 'updateCard',
|
(e: 'enterCard', action: 'FORM' | 'INFO'): void;
|
||||||
action: 'FORM' | 'INFO',
|
(e: 'toggleStatus', status: boolean): void;
|
||||||
id: string,
|
|
||||||
isEdit?: boolean,
|
|
||||||
): void;
|
|
||||||
(e: 'enterCard', action: 'FORM' | 'INFO', id: string): void;
|
|
||||||
(e: 'toggleStatus', id: string, status: boolean): void;
|
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<AppBox
|
||||||
class="person-container"
|
bordered
|
||||||
:style="`grid-template-columns: repeat( ${
|
no-padding
|
||||||
gridColumns
|
class="column person-box"
|
||||||
? `${gridColumns}, 1fr`
|
:class="{
|
||||||
: $q.screen.gt.sm
|
'person-box__disabled': disabled,
|
||||||
? '4, 1fr'
|
'person-box__no-hover': noHover,
|
||||||
: $q.screen.gt.xs
|
'person-box__no-detail': !data.detail,
|
||||||
? '2, 1fr'
|
'person-box__no-bg': noBg,
|
||||||
: '1, 1fr'
|
}"
|
||||||
})`"
|
@click="$emit('enterCard', 'INFO')"
|
||||||
>
|
>
|
||||||
<AppBox
|
<div class="column items-center">
|
||||||
bordered
|
<!-- kebab menu -->
|
||||||
class="column person-box"
|
<div class="full-width flex" v-if="!noAction">
|
||||||
:class="{
|
<div style="margin-right: auto">
|
||||||
'person-box__disabled': v.disabled,
|
<span
|
||||||
'person-box__no-hover': noHover,
|
class="tags"
|
||||||
'person-box__no-detail': noDetail,
|
v-for="v in tag"
|
||||||
'person-box__no-bg': noBg,
|
:class="{ [`tags__${v.color}`]: true }"
|
||||||
}"
|
|
||||||
@click="$emit('enterCard', 'INFO', v.id)"
|
|
||||||
v-for="(v, i) in list"
|
|
||||||
:key="i"
|
|
||||||
>
|
|
||||||
<div class="q-pa-sm column items-center">
|
|
||||||
<!-- kebab menu -->
|
|
||||||
<div class="full-width text-right" v-if="!noAction">
|
|
||||||
<q-btn
|
|
||||||
v-if="history"
|
|
||||||
flat
|
|
||||||
round
|
|
||||||
class="app-text-muted-2"
|
|
||||||
padding="xs"
|
|
||||||
icon="mdi-history"
|
|
||||||
size="sm"
|
|
||||||
@click.stop="$emit('history', v.id)"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<q-btn
|
|
||||||
flat
|
|
||||||
round
|
|
||||||
padding="xs"
|
|
||||||
class="app-text-muted-2"
|
|
||||||
icon="mdi-dots-vertical"
|
|
||||||
size="sm"
|
|
||||||
@click.stop
|
|
||||||
>
|
>
|
||||||
<q-menu class="bordered">
|
{{ v.value }}
|
||||||
<q-list v-close-popup>
|
|
||||||
<q-item
|
|
||||||
clickable
|
|
||||||
dense
|
|
||||||
class="row q-py-sm"
|
|
||||||
style="white-space: nowrap"
|
|
||||||
@click="$emit('enterCard', 'INFO', v.id)"
|
|
||||||
>
|
|
||||||
<q-icon
|
|
||||||
name="mdi-eye-outline"
|
|
||||||
class="col-3"
|
|
||||||
size="xs"
|
|
||||||
style="color: hsl(var(--green-6-hsl))"
|
|
||||||
/>
|
|
||||||
<span class="col-9 q-px-md flex items-center">
|
|
||||||
{{ $t('viewDetail') }}
|
|
||||||
</span>
|
|
||||||
</q-item>
|
|
||||||
<q-item
|
|
||||||
dense
|
|
||||||
clickable
|
|
||||||
class="row q-py-sm"
|
|
||||||
style="white-space: nowrap"
|
|
||||||
@click="$emit('updateCard', 'INFO', v.id, true)"
|
|
||||||
v-close-popup
|
|
||||||
>
|
|
||||||
<q-icon
|
|
||||||
name="mdi-pencil-outline"
|
|
||||||
class="col-3"
|
|
||||||
size="xs"
|
|
||||||
style="color: hsl(var(--cyan-6-hsl))"
|
|
||||||
/>
|
|
||||||
<span class="col-9 q-px-md flex items-center">
|
|
||||||
{{ $t('edit') }}
|
|
||||||
</span>
|
|
||||||
</q-item>
|
|
||||||
<q-item
|
|
||||||
dense
|
|
||||||
clickable
|
|
||||||
@click="$emit('deleteCard', v.id)"
|
|
||||||
v-close-popup
|
|
||||||
>
|
|
||||||
<q-icon
|
|
||||||
name="mdi-trash-can-outline"
|
|
||||||
size="xs"
|
|
||||||
class="col-3 app-text-negative"
|
|
||||||
/>
|
|
||||||
<span class="col-9 q-px-md flex items-center">
|
|
||||||
{{ $t('delete') }}
|
|
||||||
</span>
|
|
||||||
</q-item>
|
|
||||||
<q-item dense>
|
|
||||||
<q-item-section class="q-py-sm">
|
|
||||||
<div class="q-pa-sm surface-2 rounded">
|
|
||||||
<q-toggle
|
|
||||||
dense
|
|
||||||
size="sm"
|
|
||||||
@click="
|
|
||||||
$emit('toggleStatus', v.id, v.disabled === false)
|
|
||||||
"
|
|
||||||
:model-value="!v.disabled"
|
|
||||||
val="xs"
|
|
||||||
padding="none"
|
|
||||||
>
|
|
||||||
<div class="q-ml-xs">
|
|
||||||
{{
|
|
||||||
!v.disabled
|
|
||||||
? $t('switchOnLabel')
|
|
||||||
: $t('switchOffLabel')
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
</q-toggle>
|
|
||||||
</div>
|
|
||||||
</q-item-section>
|
|
||||||
</q-item>
|
|
||||||
</q-list>
|
|
||||||
</q-menu>
|
|
||||||
</q-btn>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- profile -->
|
|
||||||
<div style="position: relative">
|
|
||||||
<AppCircle
|
|
||||||
bordered
|
|
||||||
class="avatar"
|
|
||||||
style="border: 2px solid var(--border-color)"
|
|
||||||
:class="{ 'edit-profile': canEditProfile }"
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
if (canEditProfile) $emit('editProfile');
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<q-img
|
|
||||||
:src="v.img"
|
|
||||||
style="object-fit: cover; width: 100%; height: 100%"
|
|
||||||
/>
|
|
||||||
<div class="status-circle">
|
|
||||||
<q-icon
|
|
||||||
:name="`mdi-${v.disabled ? 'close' : 'check'}`"
|
|
||||||
:style="`color:${v.disabled ? 'var(--gray-6)' : 'white'}`"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AppCircle>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- name symbol -->
|
|
||||||
<span class="items-center row q-my-sm">
|
|
||||||
{{ v.name }}
|
|
||||||
<Icon
|
|
||||||
class="q-pl-sm"
|
|
||||||
:class="{
|
|
||||||
'symbol-gender': v.male || v.female,
|
|
||||||
'symbol-gender__male': !v.disabled && v.male,
|
|
||||||
'symbol-gender__female': !v.disabled && v.female,
|
|
||||||
'symbol-gender__disable': v.disabled,
|
|
||||||
}"
|
|
||||||
:icon="`material-symbols:${v.male ? 'male' : 'female'}`"
|
|
||||||
width="24px"
|
|
||||||
/>
|
|
||||||
<!-- <Icon class="locale q-pl-sm" icon="circle-flags:th" width="24px" /> -->
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-if="v.badge"
|
|
||||||
class="badge q-px-sm"
|
|
||||||
:class="{
|
|
||||||
'bg-gender': v.male || v.female,
|
|
||||||
'bg-gender__male': !v.disabled && v.male,
|
|
||||||
'bg-gender__female': !v.disabled && v.female,
|
|
||||||
'bg-gender__disable': v.disabled,
|
|
||||||
empty: !v.male && !v.female,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ v.badge }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- detail -->
|
|
||||||
<q-separator v-if="!noDetail" />
|
|
||||||
<div
|
|
||||||
v-if="!noDetail"
|
|
||||||
class="q-pt-sm q-px-md q-pb-md person-detail rounded-b full-width"
|
|
||||||
:class="{
|
|
||||||
'bg-gender': v.male || v.female,
|
|
||||||
'bg-gender__light':
|
|
||||||
(!v.disabled && v.male) || (!v.disabled && v.female),
|
|
||||||
'bg-gender__male': !v.disabled && v.male,
|
|
||||||
'bg-gender__female': !v.disabled && v.female,
|
|
||||||
'bg-gender__disable': v.disabled,
|
|
||||||
}"
|
|
||||||
:style="
|
|
||||||
(detailColumnCount &&
|
|
||||||
`grid-template-columns: repeat(${detailColumnCount}, 1fr);`) ||
|
|
||||||
''
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div v-for="(d, j) in v.detail" :key="j">
|
|
||||||
<span class="app-text-muted-2">
|
|
||||||
{{ d.label }}
|
|
||||||
</span>
|
</span>
|
||||||
<span>{{ d.value || '-' }}</span>
|
</div>
|
||||||
|
<q-btn
|
||||||
|
v-if="history"
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
class="app-text-muted-2"
|
||||||
|
padding="xs"
|
||||||
|
icon="mdi-history"
|
||||||
|
size="sm"
|
||||||
|
@click.stop="$emit('history')"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
:key="data.code"
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
padding="xs"
|
||||||
|
class="app-text-muted-2"
|
||||||
|
icon="mdi-dots-vertical"
|
||||||
|
size="sm"
|
||||||
|
@click.stop
|
||||||
|
>
|
||||||
|
<q-menu class="bordered">
|
||||||
|
<q-list v-close-popup>
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
dense
|
||||||
|
class="row q-py-sm"
|
||||||
|
style="white-space: nowrap"
|
||||||
|
@click.stop="$emit('enterCard', 'INFO')"
|
||||||
|
>
|
||||||
|
<q-icon
|
||||||
|
name="mdi-eye-outline"
|
||||||
|
class="col-3"
|
||||||
|
size="xs"
|
||||||
|
style="color: hsl(var(--green-6-hsl))"
|
||||||
|
/>
|
||||||
|
<span class="col-9 q-px-md flex items-center">
|
||||||
|
{{ $t('viewDetail') }}
|
||||||
|
</span>
|
||||||
|
</q-item>
|
||||||
|
<q-item
|
||||||
|
dense
|
||||||
|
clickable
|
||||||
|
class="row q-py-sm"
|
||||||
|
style="white-space: nowrap"
|
||||||
|
@click="$emit('updateCard', 'INFO', true)"
|
||||||
|
v-close-popup
|
||||||
|
>
|
||||||
|
<q-icon
|
||||||
|
name="mdi-pencil-outline"
|
||||||
|
class="col-3"
|
||||||
|
size="xs"
|
||||||
|
style="color: hsl(var(--cyan-6-hsl))"
|
||||||
|
/>
|
||||||
|
<span class="col-9 q-px-md flex items-center">
|
||||||
|
{{ $t('edit') }}
|
||||||
|
</span>
|
||||||
|
</q-item>
|
||||||
|
<q-item
|
||||||
|
dense
|
||||||
|
clickable
|
||||||
|
@click="$emit('deleteCard')"
|
||||||
|
v-close-popup
|
||||||
|
>
|
||||||
|
<q-icon
|
||||||
|
name="mdi-trash-can-outline"
|
||||||
|
size="xs"
|
||||||
|
class="col-3 app-text-negative"
|
||||||
|
/>
|
||||||
|
<span class="col-9 q-px-md flex items-center">
|
||||||
|
{{ $t('delete') }}
|
||||||
|
</span>
|
||||||
|
</q-item>
|
||||||
|
<q-item dense>
|
||||||
|
<q-item-section class="q-py-sm">
|
||||||
|
<div class="q-pa-sm surface-2 rounded">
|
||||||
|
<q-toggle
|
||||||
|
dense
|
||||||
|
size="sm"
|
||||||
|
@click="$emit('toggleStatus', disabled === false)"
|
||||||
|
:model-value="!disabled"
|
||||||
|
val="xs"
|
||||||
|
padding="none"
|
||||||
|
>
|
||||||
|
<div class="q-ml-xs">
|
||||||
|
{{
|
||||||
|
!disabled ? $t('switchOnLabel') : $t('switchOffLabel')
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</q-toggle>
|
||||||
|
</div>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-menu>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- profile -->
|
||||||
|
|
||||||
|
<AppCircle
|
||||||
|
bordered
|
||||||
|
class="avatar"
|
||||||
|
style="border: 2px solid var(--border-color); overflow: visible"
|
||||||
|
@click="$emit('editProfile')"
|
||||||
|
>
|
||||||
|
<q-img
|
||||||
|
:src="data.img ?? '/no-profile.png'"
|
||||||
|
style="
|
||||||
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #error>
|
||||||
|
<div
|
||||||
|
style="background: none"
|
||||||
|
class="full-width full-height items-center justify-center flex"
|
||||||
|
>
|
||||||
|
<q-img src="/no-profile.png" width="5rem" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</q-img>
|
||||||
|
<div class="avatar__status"></div>
|
||||||
|
</AppCircle>
|
||||||
|
|
||||||
|
<!-- name symbol -->
|
||||||
|
<span class="items-center row">
|
||||||
|
{{ data.name }}
|
||||||
|
<Icon
|
||||||
|
v-if="data.male || data.female"
|
||||||
|
class="q-pl-xs"
|
||||||
|
:class="{
|
||||||
|
'symbol-gender': data.male || data.female,
|
||||||
|
'symbol-gender__male': !disabled && data.male,
|
||||||
|
'symbol-gender__female': !disabled && data.female,
|
||||||
|
'symbol-gender__disable': disabled,
|
||||||
|
}"
|
||||||
|
:icon="`material-symbols:${data.male ? 'male' : 'female'}`"
|
||||||
|
width="24px"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span style="color: hsl(var(--text-mute)); scale: 0.9">
|
||||||
|
{{ data.code || '-' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- detail -->
|
||||||
|
<q-separator v-if="data.detail" class="q-my-sm q-mx-md" />
|
||||||
|
|
||||||
|
<div class="row" v-for="v in data.detail" :key="v.value" v-if="data.detail">
|
||||||
|
<div class="column items-center" style="width: min-content">
|
||||||
|
<div class="detail-icon">
|
||||||
|
<q-icon size="md" style="scale: 0.5" :name="v.icon" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AppBox>
|
<div class="col row items-center full-width">
|
||||||
</div>
|
<span class="ellipsis">{{ v.value || '-' }}</span>
|
||||||
|
<q-tooltip
|
||||||
|
anchor="bottom left"
|
||||||
|
self="bottom left"
|
||||||
|
:offset="[10, 20]"
|
||||||
|
:delay="500"
|
||||||
|
>
|
||||||
|
{{ v.value || '-' }}
|
||||||
|
</q-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AppBox>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.person-box {
|
.person-box {
|
||||||
background-color: var(--surface-2);
|
background-color: var(--surface-1);
|
||||||
border-radius: var(--radius-2) !important;
|
|
||||||
transition: 100ms ease-in-out;
|
transition: 100ms ease-in-out;
|
||||||
padding: 0;
|
padding: var(--size-2);
|
||||||
|
|
||||||
&.person-box__disabled {
|
&.person-box__disabled {
|
||||||
opacity: 0.4;
|
opacity: 0.5;
|
||||||
|
filter: grayscale(0.9);
|
||||||
|
|
||||||
.status-circle {
|
.status-circle {
|
||||||
background-color: var(--surface-1);
|
background-color: var(--surface-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.locale {
|
|
||||||
filter: grayscale();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.person-box__no-detail {
|
&.person-box__no-detail {
|
||||||
|
|
@ -284,6 +251,13 @@ defineEmits<{
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& .detail-icon {
|
||||||
|
color: hsl(var(--text-mute-2));
|
||||||
|
background-color: hsla(var(--stone-6-hsl) / 0.15);
|
||||||
|
border-radius: 50%;
|
||||||
|
scale: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
& .bg-gender {
|
& .bg-gender {
|
||||||
color: hsla(var(--_fg));
|
color: hsla(var(--_fg));
|
||||||
background-color: hsl(var(--_bg));
|
background-color: hsl(var(--_bg));
|
||||||
|
|
@ -297,16 +271,6 @@ defineEmits<{
|
||||||
color: unset;
|
color: unset;
|
||||||
background-color: hsla(var(--_bg) / 0.1);
|
background-color: hsla(var(--_bg) / 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.bg-gender__male {
|
|
||||||
--_fg: 0 100 100%;
|
|
||||||
--_bg: var(--gender-male);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bg-gender__female {
|
|
||||||
--_fg: 0 100 100%;
|
|
||||||
--_bg: var(--gender-female);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& .symbol-gender {
|
& .symbol-gender {
|
||||||
|
|
@ -325,23 +289,6 @@ defineEmits<{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& .person-detail {
|
|
||||||
display: grid;
|
|
||||||
flex-grow: 1;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
gap: var(--size-2);
|
|
||||||
overflow-x: scroll;
|
|
||||||
|
|
||||||
& > * {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
& > :first-child {
|
|
||||||
font-size: var(--font-size-0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& .status-circle {
|
& .status-circle {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
|
|
@ -360,11 +307,6 @@ defineEmits<{
|
||||||
--_hover: hsl(var(--gender-male));
|
--_hover: hsl(var(--gender-male));
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: var(--shadow-2);
|
box-shadow: var(--shadow-2);
|
||||||
|
|
||||||
& .person-detail {
|
|
||||||
--_hover: hsl(var(--_bg));
|
|
||||||
box-shadow: inset 0em -5px hsl(var(--_bg));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,17 +316,25 @@ defineEmits<{
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
block-size: 7rem;
|
block-size: 5rem;
|
||||||
}
|
transform: rotate(45deg);
|
||||||
|
|
||||||
.badge {
|
& .avatar__status {
|
||||||
display: inline-block;
|
content: ' ';
|
||||||
border-radius: var(--radius-6);
|
display: block;
|
||||||
background-color: var(--surface-2);
|
block-size: 1rem;
|
||||||
text-wrap: nowrap;
|
aspect-ratio: 1;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
right: -0.5rem;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
top: calc(50% - 0.5rem);
|
||||||
|
bottom: calc(50% - 0.5rem);
|
||||||
|
background-color: hsla(var(--positive-bg) / 1);
|
||||||
|
}
|
||||||
|
|
||||||
&.empty {
|
& :deep(.q-img) {
|
||||||
background-color: var(--surface-tab);
|
transform: rotate(-45deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,4 +346,60 @@ defineEmits<{
|
||||||
opacity: 80%;
|
opacity: 80%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tags {
|
||||||
|
display: inline-block;
|
||||||
|
color: hsla(var(--_color) / 1);
|
||||||
|
background: hsla(var(--_color) / 0.15);
|
||||||
|
border-radius: var(--radius-2);
|
||||||
|
padding-inline: var(--size-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__purple {
|
||||||
|
--_color: var(--violet-11-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__pink {
|
||||||
|
--_color: var(--pink-6-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__green {
|
||||||
|
--_color: var(--teal-10-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__cyan {
|
||||||
|
--_color: var(--cyan-7-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__red {
|
||||||
|
--_color: var(--red-6-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__yellow {
|
||||||
|
--_color: var(--orange-4-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__orange {
|
||||||
|
--_color: var(--orange-5-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags__magenta {
|
||||||
|
--_color: var(--pink-8-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tags__purple {
|
||||||
|
--_color: var(--violet-10-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tags__green {
|
||||||
|
--_color: var(--teal-8-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tags__orange {
|
||||||
|
--_color: var(--orange-6-hsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tags__magenta {
|
||||||
|
--_color: var(--pink-7-hsl);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@ html {
|
||||||
|
|
||||||
--brand-1: #035aa1;
|
--brand-1: #035aa1;
|
||||||
--brand-2: #f50000;
|
--brand-2: #f50000;
|
||||||
--border-color: var(--gray-4);
|
--border-color: var(--gray-2);
|
||||||
--foreground: black;
|
--foreground: black;
|
||||||
--background: var(--gray-1);
|
--background: var(--gray-2);
|
||||||
--surface-0: var(--background);
|
--surface-0: var(--background);
|
||||||
--surface-1: white;
|
--surface-1: white;
|
||||||
--surface-2: var(--gray-0);
|
--surface-2: var(--gray-0);
|
||||||
|
|
@ -46,15 +46,15 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
:where(.dark, .body--dark) {
|
:where(.dark, .body--dark) {
|
||||||
--brand-1: var(--blue-5);
|
--brand-1: #035aa1;
|
||||||
--brand-2: #f50000;
|
--brand-2: #f50000;
|
||||||
--border-color: var(--gray-7);
|
--border-color: var(--gray-7);
|
||||||
--foreground: white;
|
--foreground: white;
|
||||||
--background: var(--gray-10);
|
--background: var(--gray-11);
|
||||||
--surface-0: var(--background);
|
--surface-0: var(--background);
|
||||||
--surface-1: var(--gray-11);
|
--surface-1: var(--gray-10);
|
||||||
--surface-2: var(--gray-10);
|
--surface-2: var(--gray-9);
|
||||||
--surface-3: var(--gray-9);
|
--surface-3: var(--gray-11);
|
||||||
|
|
||||||
--surface-tab: var(--gray-9);
|
--surface-tab: var(--gray-9);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ $primary: var(--brand-1);
|
||||||
$secondary: var(--brand-2);
|
$secondary: var(--brand-2);
|
||||||
$accent: #9c27b0;
|
$accent: #9c27b0;
|
||||||
|
|
||||||
$dark: var(--gray-11);
|
$dark: var(--gray-10);
|
||||||
$dark-page: var(--gray-10);
|
$dark-page: var(--gray-11);
|
||||||
|
|
||||||
$positive: #00bd9d;
|
$positive: #00bd9d;
|
||||||
$negative: var(--red-9);
|
$negative: var(--red-9);
|
||||||
|
|
@ -24,6 +24,7 @@ $separator-dark-color: var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-field__control {
|
.q-field__control {
|
||||||
|
background: var(--surface-1);
|
||||||
color: $primary;
|
color: $primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ export default {
|
||||||
branchManagementCaption: 'Manage All Branch',
|
branchManagementCaption: 'Manage All Branch',
|
||||||
branchInHQ: 'Branch within the main office',
|
branchInHQ: 'Branch within the main office',
|
||||||
|
|
||||||
|
office: 'Office',
|
||||||
branchLabel: 'Branch',
|
branchLabel: 'Branch',
|
||||||
branchHQLabel: 'Headquarters',
|
branchHQLabel: 'Headquarters',
|
||||||
branchName: 'Branch Name',
|
branchName: 'Branch Name',
|
||||||
|
|
@ -20,4 +21,6 @@ export default {
|
||||||
branchLabelStatus: 'Branch Status',
|
branchLabelStatus: 'Branch Status',
|
||||||
|
|
||||||
registeredBranch: 'Registered Branch',
|
registeredBranch: 'Registered Branch',
|
||||||
|
|
||||||
|
branchStatTitle: 'Summary data of branch',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ export default {
|
||||||
customerEmployeeTooltipCaption: 'Click + to add an employee',
|
customerEmployeeTooltipCaption: 'Click + to add an employee',
|
||||||
customerEmployerAdd: 'Add employer',
|
customerEmployerAdd: 'Add employer',
|
||||||
customerEmployeeAdd: 'Add employee',
|
customerEmployeeAdd: 'Add employee',
|
||||||
|
|
||||||
|
nameEmployee:'Name Employee',
|
||||||
|
|
||||||
EMPLOYER: 'Employer',
|
EMPLOYER: 'Employer',
|
||||||
EMPLOYEE: 'Employee',
|
EMPLOYEE: 'Employee',
|
||||||
customerEmployerStatTitle: 'Employer data summary',
|
customerEmployerStatTitle: 'Employer data summary',
|
||||||
|
|
@ -53,4 +56,7 @@ export default {
|
||||||
editBy: 'Edit by',
|
editBy: 'Edit by',
|
||||||
valueBefore: 'Before',
|
valueBefore: 'Before',
|
||||||
valueAfter: 'After',
|
valueAfter: 'After',
|
||||||
|
|
||||||
|
serviceWorkTotal: 'Service Work Total',
|
||||||
|
priceInformation: 'Price Information',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,6 @@ export default {
|
||||||
corporationEnglish: 'English company name',
|
corporationEnglish: 'English company name',
|
||||||
|
|
||||||
companyOwnerName: 'Company Owner Name',
|
companyOwnerName: 'Company Owner Name',
|
||||||
|
|
||||||
|
corporation: 'Corporation',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ export default {
|
||||||
formDialogInputNationality: 'Nationality',
|
formDialogInputNationality: 'Nationality',
|
||||||
|
|
||||||
formDialogTitlePersonnelAddress: 'Personnel Address',
|
formDialogTitlePersonnelAddress: 'Personnel Address',
|
||||||
|
formDialogTitleEmployerAddress: 'Employer Address',
|
||||||
formDialogTitleAddressPure: 'Address',
|
formDialogTitleAddressPure: 'Address',
|
||||||
formDialogTitleAddressPureEN: 'Address in English',
|
formDialogTitleAddressPureEN: 'Address in English',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ export default {
|
||||||
displayField: 'Display Fields',
|
displayField: 'Display Fields',
|
||||||
deleteConfirmTitle: 'Comfirm Deletion',
|
deleteConfirmTitle: 'Comfirm Deletion',
|
||||||
deleteConfirmMessage: 'Do you want to delete this item?',
|
deleteConfirmMessage: 'Do you want to delete this item?',
|
||||||
|
headquartersNotEstablished: 'You have not yet established the headquarters. You need to establish the headquarters before you can create personnel.',
|
||||||
|
|
||||||
changePassword: 'Change Password',
|
changePassword: 'Change Password',
|
||||||
signature: 'Signature',
|
signature: 'Signature',
|
||||||
addSignature: 'Add Signature',
|
addSignature: 'Add Signature',
|
||||||
|
|
@ -59,6 +61,9 @@ export default {
|
||||||
baseOnDevice: 'Base on Device',
|
baseOnDevice: 'Base on Device',
|
||||||
person: 'Person',
|
person: 'Person',
|
||||||
recordsPage: 'Showing {resultcurrentPage} out of {total} records',
|
recordsPage: 'Showing {resultcurrentPage} out of {total} records',
|
||||||
|
showing: 'Showing',
|
||||||
|
dataSum: 'Data Summaries',
|
||||||
|
createdAt: 'Created At',
|
||||||
...status,
|
...status,
|
||||||
...main,
|
...main,
|
||||||
...address,
|
...address,
|
||||||
|
|
|
||||||
75
src/i18n/en-US/object.ts
Normal file
75
src/i18n/en-US/object.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
export default {
|
||||||
|
branchManagement: {
|
||||||
|
label: {
|
||||||
|
branchManagementCaption: 'Manage All Branch',
|
||||||
|
branchLabel: 'Branch',
|
||||||
|
branchHQLabel: 'Headquarters',
|
||||||
|
},
|
||||||
|
|
||||||
|
table: {
|
||||||
|
title: {
|
||||||
|
office: 'Office',
|
||||||
|
ddress: 'Address',
|
||||||
|
// formDialogInputTelephone: 'Telephone Number',
|
||||||
|
telephone: 'Telephone Number',
|
||||||
|
type: 'Type',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
input: {
|
||||||
|
label: {
|
||||||
|
search: 'Search',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
manu: {
|
||||||
|
branchName: 'Branch Name',
|
||||||
|
branchLabelTel: 'Branch Telephone No',
|
||||||
|
branchLabelAddress: 'Branch Address',
|
||||||
|
branchLabelType: 'Branch Type',
|
||||||
|
viewDetail: 'View Detail',
|
||||||
|
edit: 'Edit',
|
||||||
|
delete: 'Delete',
|
||||||
|
switchOnLabel: 'Open',
|
||||||
|
switchOffLabel: 'Close',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
formDialog: {
|
||||||
|
section: {
|
||||||
|
formDialogTitleInformation: 'Basic Information',
|
||||||
|
formDialogTitleContact: 'Contact Information',
|
||||||
|
formDialogTitleAddress: ' Head office address information',
|
||||||
|
formDialogTitleLocation: 'Head Office Location',
|
||||||
|
formDialogTitleImg: 'Office Image',
|
||||||
|
subtopic: {
|
||||||
|
formDialogAddress: 'Address in Thai',
|
||||||
|
formDialogAddressEN: 'Address in English',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
formDialogInputCode: 'Head Office Code',
|
||||||
|
formDialogInputBrId: 'Branch Code',
|
||||||
|
formDialogInputTaxNo: 'Tax Identification Number',
|
||||||
|
formDialogInputNameSubBranch: 'Branch Name',
|
||||||
|
formDialogInputNameSubBranchEn: 'Branch Name (English)',
|
||||||
|
formDialogInputEmailSubBranch: 'Branch Contact Email',
|
||||||
|
formDialogInputTelephoneSubBranch: 'Branch Telephone Number',
|
||||||
|
formDialogInputContactName: 'Contact',
|
||||||
|
formDialogInputTelephoneContact: 'Contact Telephone Number',
|
||||||
|
address: 'Address',
|
||||||
|
province: 'Province',
|
||||||
|
district: 'District',
|
||||||
|
subDistrict: 'Sub-district',
|
||||||
|
zipCode: 'Zip Code',
|
||||||
|
},
|
||||||
|
|
||||||
|
button: {
|
||||||
|
formDialogUploadQrCode: 'Upload QR Code',
|
||||||
|
formDialogBtnLocation: 'Start sharing location',
|
||||||
|
formDialogBtnImg: 'Add Office Image',
|
||||||
|
agree: 'Ok',
|
||||||
|
cancel: 'Cancel',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -12,7 +12,7 @@ export default {
|
||||||
DELEGATE: 'Delegate',
|
DELEGATE: 'Delegate',
|
||||||
AGENCY: 'Agency',
|
AGENCY: 'Agency',
|
||||||
|
|
||||||
personnelStatTitle: 'Summary data of ',
|
personnelStatTitle: 'Summary data',
|
||||||
|
|
||||||
personnelCardUserType: 'Type',
|
personnelCardUserType: 'Type',
|
||||||
personnelCardTelephone: 'Telephone',
|
personnelCardTelephone: 'Telephone',
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ export default {
|
||||||
|
|
||||||
service: 'Service',
|
service: 'Service',
|
||||||
product: 'Product',
|
product: 'Product',
|
||||||
|
productGroup: 'Product Group: {name}',
|
||||||
|
productType: 'Product Type: {name}',
|
||||||
|
|
||||||
messageTooltipNoProduct: 'No Product and Service Groups',
|
messageTooltipNoProduct: 'No Product and Service Groups',
|
||||||
messageTooltipProductCreate: 'Click + for product and service groups.',
|
messageTooltipProductCreate: 'Click + for product and service groups.',
|
||||||
|
|
@ -19,8 +21,9 @@ export default {
|
||||||
|
|
||||||
productCode: 'Product Code',
|
productCode: 'Product Code',
|
||||||
productName: 'Product Name',
|
productName: 'Product Name',
|
||||||
processingTime: 'Processing Time (Day)',
|
productDetail: 'Product Detail',
|
||||||
priceeInformation: 'Price Information',
|
productProcessingTime: 'Processing Time (Day)',
|
||||||
|
priceInformation: 'Price Information',
|
||||||
salePrice: 'Sale Price',
|
salePrice: 'Sale Price',
|
||||||
agentPrice: 'Agent Price',
|
agentPrice: 'Agent Price',
|
||||||
processingPrice: 'Processing Price',
|
processingPrice: 'Processing Price',
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ export default {
|
||||||
branchManagementCaption: 'จัดการสาขาทั้งหมด',
|
branchManagementCaption: 'จัดการสาขาทั้งหมด',
|
||||||
branchInHQ: 'สาขาภายในสำนักงานใหญ่',
|
branchInHQ: 'สาขาภายในสำนักงานใหญ่',
|
||||||
|
|
||||||
|
office: 'สำนักงาน',
|
||||||
branchLabel: 'สาขา',
|
branchLabel: 'สาขา',
|
||||||
branchHQLabel: 'สำนักงานใหญ่',
|
branchHQLabel: 'สำนักงานใหญ่',
|
||||||
branchName: 'ชื่อสาขา',
|
branchName: 'ชื่อสาขา',
|
||||||
|
|
@ -20,4 +21,6 @@ export default {
|
||||||
branchLabelStatus: 'สถานะสาขา',
|
branchLabelStatus: 'สถานะสาขา',
|
||||||
|
|
||||||
registeredBranch: 'สาขาที่ลงทะเบียน',
|
registeredBranch: 'สาขาที่ลงทะเบียน',
|
||||||
|
|
||||||
|
branchStatTitle: 'สรุปจัดการสาขา',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ export default {
|
||||||
customerEmployeeTooltipCaption: 'คลิก + เพื่อเพิ่มลูกจ้าง',
|
customerEmployeeTooltipCaption: 'คลิก + เพื่อเพิ่มลูกจ้าง',
|
||||||
customerEmployerAdd: 'เพิ่มนายจ้าง',
|
customerEmployerAdd: 'เพิ่มนายจ้าง',
|
||||||
customerEmployeeAdd: 'เพิ่มลูกจ้าง',
|
customerEmployeeAdd: 'เพิ่มลูกจ้าง',
|
||||||
|
|
||||||
|
nameEmployee:'ชื่อลูกจ้าง',
|
||||||
|
|
||||||
EMPLOYER: 'นายจ้าง',
|
EMPLOYER: 'นายจ้าง',
|
||||||
EMPLOYEE: 'ลูกจ้าง',
|
EMPLOYEE: 'ลูกจ้าง',
|
||||||
customerEmployerStatTitle: 'สรุปจำนวนข้อมูลนายจ้าง',
|
customerEmployerStatTitle: 'สรุปจำนวนข้อมูลนายจ้าง',
|
||||||
|
|
@ -61,4 +64,7 @@ export default {
|
||||||
editBy: 'แก้ไขโดย',
|
editBy: 'แก้ไขโดย',
|
||||||
valueBefore: 'แก้ไขใหม่',
|
valueBefore: 'แก้ไขใหม่',
|
||||||
valueAfter: 'ค่าเดิม',
|
valueAfter: 'ค่าเดิม',
|
||||||
|
|
||||||
|
serviceWorkTotal: 'จำนวนงานทั้งหมด',
|
||||||
|
priceInformation: 'ข้อมูลราคา',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,6 @@ export default {
|
||||||
corporationEnglish: 'ชื่อ บริษัท ภาษาอังกฤษ',
|
corporationEnglish: 'ชื่อ บริษัท ภาษาอังกฤษ',
|
||||||
|
|
||||||
companyOwnerName: 'ชื่อเจ้าของบริษัท',
|
companyOwnerName: 'ชื่อเจ้าของบริษัท',
|
||||||
|
|
||||||
|
corporation: 'ชื่อ บริษัท/นิติบุคคล',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ export default {
|
||||||
formDialogInputNationality: 'สัญชาติ',
|
formDialogInputNationality: 'สัญชาติ',
|
||||||
|
|
||||||
formDialogTitlePersonnelAddress: 'ข้อมูลที่อยู่พนักงาน',
|
formDialogTitlePersonnelAddress: 'ข้อมูลที่อยู่พนักงาน',
|
||||||
|
formDialogTitleEmployerAddress: 'ข้อมูลที่อยู่นายจ้าง',
|
||||||
formDialogTitleAddressPure: 'ที่อยู่',
|
formDialogTitleAddressPure: 'ที่อยู่',
|
||||||
formDialogTitleAddressPureEN: 'ที่อยู่ภาษาอังกฤษ',
|
formDialogTitleAddressPureEN: 'ที่อยู่ภาษาอังกฤษ',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ export default {
|
||||||
displayField: 'ข้อมูลที่แสดง',
|
displayField: 'ข้อมูลที่แสดง',
|
||||||
deleteConfirmTitle: 'ยืนยันการลบข้อมูล',
|
deleteConfirmTitle: 'ยืนยันการลบข้อมูล',
|
||||||
deleteConfirmMessage: 'คุณต้องการลบข้อมูลใช่หรือไม่',
|
deleteConfirmMessage: 'คุณต้องการลบข้อมูลใช่หรือไม่',
|
||||||
|
headquartersNotEstablished: 'ท่านยังไม่ได้สร้างสำนักงานใหญ่ ต้องสร้างสำนักงานใหญ่ก่อนจึงจะสร้าง บุคลากรได้',
|
||||||
changePassword: 'เปลี่ยนรหัสผ่าน',
|
changePassword: 'เปลี่ยนรหัสผ่าน',
|
||||||
signature: 'ลายเซ็น',
|
signature: 'ลายเซ็น',
|
||||||
addSignature: 'เพิ่มลายเซ็น',
|
addSignature: 'เพิ่มลายเซ็น',
|
||||||
|
|
@ -59,6 +60,9 @@ export default {
|
||||||
baseOnDevice: 'สีตามอุปกรณ์',
|
baseOnDevice: 'สีตามอุปกรณ์',
|
||||||
person: 'คน',
|
person: 'คน',
|
||||||
recordsPage: 'แสดง {resultcurrentPage} รายการจาก {total} รายการ',
|
recordsPage: 'แสดง {resultcurrentPage} รายการจาก {total} รายการ',
|
||||||
|
showing: 'แสดงทีละ',
|
||||||
|
dataSum: 'สรุปจำนวนข้อมูล',
|
||||||
|
createdAt: 'สร้างเมื่อ',
|
||||||
...status,
|
...status,
|
||||||
...main,
|
...main,
|
||||||
...address,
|
...address,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export default {
|
||||||
mainCustomerCaption: 'จัดการคนภายในองค์กร',
|
mainCustomerCaption: 'จัดการคนภายในองค์กร',
|
||||||
|
|
||||||
mainProductTitle: 'สินค้าและบริการ',
|
mainProductTitle: 'สินค้าและบริการ',
|
||||||
mainProductCaption: 'รายการสินค้าและบริการ',
|
mainProductCaption: 'ประเภทสินค้าและบริการ',
|
||||||
|
|
||||||
mainQuotationTitle: 'ใบเสนอราคา',
|
mainQuotationTitle: 'ใบเสนอราคา',
|
||||||
mainQuotationCaption: 'รายการใบเสนอราคา',
|
mainQuotationCaption: 'รายการใบเสนอราคา',
|
||||||
|
|
|
||||||
75
src/i18n/th-th/object.ts
Normal file
75
src/i18n/th-th/object.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
export default {
|
||||||
|
branchManagement: {
|
||||||
|
label: {
|
||||||
|
branchManagementCaption: 'จัดการทุกสาขา',
|
||||||
|
branchLabel: 'สาขา',
|
||||||
|
branchHQLabel: 'สำนักงานใหญ่',
|
||||||
|
},
|
||||||
|
|
||||||
|
table: {
|
||||||
|
title: {
|
||||||
|
office: 'สำนักงาน',
|
||||||
|
address: 'ที่อยู่',
|
||||||
|
// formDialogInputTelephone: 'เบอร์โทรศัพท์',
|
||||||
|
telephone: 'เบอร์โทรศัพท์',
|
||||||
|
type: 'ประเภท',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
input: {
|
||||||
|
label: {
|
||||||
|
search: 'ค้นหา',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
manu: {
|
||||||
|
branchName: 'ชื่อสาขา',
|
||||||
|
branchLabelTel: 'เบอร์โทรศัพท์สาขา',
|
||||||
|
branchLabelAddress: 'ที่อยู่สาขา',
|
||||||
|
branchLabelType: 'ประเภทสาขา',
|
||||||
|
viewDetail: 'ดูรายละเอียด',
|
||||||
|
edit: 'แก้ไข',
|
||||||
|
delete: 'ลบ',
|
||||||
|
switchOnLabel: 'เปิด',
|
||||||
|
switchOffLabel: 'ปิด',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
formDialog: {
|
||||||
|
section: {
|
||||||
|
formDialogTitleInformation: 'ข้อมูลพื้นฐาน',
|
||||||
|
formDialogTitleContact: 'ข้อมูลติดต่อ',
|
||||||
|
formDialogTitleAddress: 'ข้อมูลที่อยู่สำนักงานใหญ่',
|
||||||
|
formDialogTitleLocation: 'ตำแหน่งที่ตั้งสำนักงานใหญ่',
|
||||||
|
formDialogTitleImg: 'ภาพสำนักงาน',
|
||||||
|
subtopic: {
|
||||||
|
formDialogAddress: 'ที่อยู่ภาษาไทย',
|
||||||
|
formDialogAddressEN: 'ที่อยู่ภาษาอังกฤษ',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
formDialogInputCode: 'รหัสสำนักงานใหญ่',
|
||||||
|
formDialogInputBrId: 'รหัสสาขา',
|
||||||
|
formDialogInputTaxNo: 'เลขประจำตัวผู้เสียภาษี',
|
||||||
|
formDialogInputNameSubBranch: 'ชื่อสาขา',
|
||||||
|
formDialogInputNameSubBranchEn: 'ชื่อสาขา (ภาษาอังกฤษ)',
|
||||||
|
formDialogInputEmailSubBranch: 'อีเมลติดต่อสาขา',
|
||||||
|
formDialogInputTelephoneSubBranch: 'เบอร์โทรศัพท์สาขา',
|
||||||
|
formDialogInputContactName: 'ชื่อผู้ติดต่อ',
|
||||||
|
formDialogInputTelephoneContact: 'เบอร์โทรศัพท์ผู้ติดต่อ',
|
||||||
|
address: 'ที่อยู่',
|
||||||
|
province: 'จังหวัด',
|
||||||
|
district: 'อำเภอ',
|
||||||
|
subDistrict: 'ตำบล',
|
||||||
|
zipCode: 'รหัสไปรษณีย์',
|
||||||
|
},
|
||||||
|
|
||||||
|
button: {
|
||||||
|
formDialogUploadQrCode: 'อัปโหลด QR Code',
|
||||||
|
formDialogBtnLocation: 'เริ่มแชร์ตำแหน่งที่ตั้ง',
|
||||||
|
formDialogBtnImg: 'เพิ่มภาพสำนักงาน',
|
||||||
|
agree: 'ตกลง',
|
||||||
|
cancel: 'ยกเลิก',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -21,7 +21,8 @@ export default {
|
||||||
|
|
||||||
productCode: 'รหัสสินค้า',
|
productCode: 'รหัสสินค้า',
|
||||||
productName: 'ชื่อสินค้า',
|
productName: 'ชื่อสินค้า',
|
||||||
processingTime: 'ระยะเวลาดำเนินการ (วัน)',
|
productDetail: 'รายละเอียดสินค้า',
|
||||||
|
productProcessingTime: 'ระยะเวลาดำเนินการ (วัน)',
|
||||||
priceeInformation: 'ข้อมูลราคา',
|
priceeInformation: 'ข้อมูลราคา',
|
||||||
salePrice: 'ราคาขาย',
|
salePrice: 'ราคาขาย',
|
||||||
agentPrice: 'ราคาตัวแทน',
|
agentPrice: 'ราคาตัวแทน',
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@ import useOptionStore from 'src/stores/options';
|
||||||
import { dialog } from 'src/stores/utils';
|
import { dialog } from 'src/stores/utils';
|
||||||
import { setLocale } from 'src/utils/datetime';
|
import { setLocale } from 'src/utils/datetime';
|
||||||
import useUtilsStore from 'src/stores/utils';
|
import useUtilsStore from 'src/stores/utils';
|
||||||
|
import useMyBranchStore from 'src/stores/my-branch';
|
||||||
|
|
||||||
|
const useMyBranch = useMyBranchStore();
|
||||||
|
const { fetchListMyBranch } = useMyBranch;
|
||||||
|
|
||||||
interface NotificationButton {
|
interface NotificationButton {
|
||||||
item: string;
|
item: string;
|
||||||
|
|
@ -41,7 +45,10 @@ const userStore = useUserStore();
|
||||||
|
|
||||||
const rawOption = ref();
|
const rawOption = ref();
|
||||||
const canvasModal = ref(false);
|
const canvasModal = ref(false);
|
||||||
|
|
||||||
const leftDrawerOpen = ref(true);
|
const leftDrawerOpen = ref(true);
|
||||||
|
const leftDrawerMini = ref(false);
|
||||||
|
|
||||||
const filterUnread = ref(false);
|
const filterUnread = ref(false);
|
||||||
const unread = ref<number>(1);
|
const unread = ref<number>(1);
|
||||||
// const filterRole = ref<string[]>();
|
// const filterRole = ref<string[]>();
|
||||||
|
|
@ -135,6 +142,8 @@ watch(
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
await fetchListMyBranch(getUserId() ?? '');
|
||||||
|
|
||||||
const getCurLang = localStorage.getItem('currentLanguage');
|
const getCurLang = localStorage.getItem('currentLanguage');
|
||||||
if (getCurLang) currentLanguage.value = getCurLang;
|
if (getCurLang) currentLanguage.value = getCurLang;
|
||||||
if (currentLanguage.value === 'English') {
|
if (currentLanguage.value === 'English') {
|
||||||
|
|
@ -169,22 +178,25 @@ onMounted(async () => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-layout view="lHh Lpr lFf">
|
<q-layout view="lHh Lpr lFf">
|
||||||
<drawer-component v-model:leftDrawerOpen="leftDrawerOpen" />
|
<drawer-component
|
||||||
|
:mini="leftDrawerMini"
|
||||||
|
v-model:left-drawer-open="leftDrawerOpen"
|
||||||
|
/>
|
||||||
|
|
||||||
<q-page-container class="surface-1 q-pa-md">
|
<q-page-container>
|
||||||
<!-- drawer control -->
|
<!-- drawer control -->
|
||||||
<div
|
<div style="position: relative; z-index: 1000" :hidden="$q.screen.lt.sm">
|
||||||
style="position: relative"
|
<div
|
||||||
:style="$q.screen.gt.xs ? 'z-index: 1000' : 'z-index: 10'"
|
|
||||||
>
|
|
||||||
<q-avatar
|
|
||||||
size="36px"
|
size="36px"
|
||||||
style="
|
style="
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
top: 28px;
|
top: 28px;
|
||||||
left: -18px;
|
left: -22px;
|
||||||
background-color: var(--surface-1);
|
background-color: var(--surface-1);
|
||||||
|
border: 4px solid var(--surface-1);
|
||||||
"
|
"
|
||||||
|
class="flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<q-btn
|
<q-btn
|
||||||
flat
|
flat
|
||||||
|
|
@ -197,30 +209,47 @@ onMounted(async () => {
|
||||||
background-color: hsl(var(--negative-bg) / 0.1);
|
background-color: hsl(var(--negative-bg) / 0.1);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
"
|
"
|
||||||
@click="leftDrawerOpen = !leftDrawerOpen"
|
@click="leftDrawerMini = !leftDrawerMini"
|
||||||
>
|
>
|
||||||
<q-icon
|
<q-icon
|
||||||
:name="leftDrawerOpen ? 'mdi-backburger' : 'mdi-forwardburger'"
|
:name="!leftDrawerMini ? 'mdi-backburger' : 'mdi-forwardburger'"
|
||||||
size="16px"
|
size="16px"
|
||||||
style="color: hsl(var(--negative-bg))"
|
style="color: hsl(var(--negative-bg))"
|
||||||
/>
|
/>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</q-avatar>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="surface-3 bordered rounded q-pb-lg scroll column"
|
class="surface-0 scroll column"
|
||||||
style="height: calc(100vh - 32px); flex-wrap: nowrap"
|
style="height: 100vh; flex-wrap: nowrap; padding-bottom: var(--size-4)"
|
||||||
>
|
>
|
||||||
<!-- header -->
|
<!-- header -->
|
||||||
<div
|
<div
|
||||||
class="q-px-lg row items-center justify-between q-pb-md surface-3 q-pt-lg"
|
class="q-px-lg surface-0 row items-center justify-start q-pb-md q-pt-lg"
|
||||||
style="position: sticky; top: 0; z-index: 8"
|
style="position: sticky; top: 0; z-index: 8"
|
||||||
>
|
>
|
||||||
|
<q-btn
|
||||||
|
v-if="$q.screen.lt.sm"
|
||||||
|
icon="mdi-menu"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
class="q-mr-md"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
leftDrawerMini = false;
|
||||||
|
leftDrawerOpen = !leftDrawerOpen;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<span
|
<span
|
||||||
class="title-gradient text-weight-bold"
|
class="title-gradient text-weight-bold"
|
||||||
:class="{ 'text-h6': $q.screen.gt.xs }"
|
:class="{ 'text-h6': $q.screen.gt.xs }"
|
||||||
|
:style="{
|
||||||
|
filter: `brightness(${$q.dark.isActive ? '2' : '1'})`,
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
utilsStore.currentTitle?.title
|
utilsStore.currentTitle?.title
|
||||||
|
|
@ -230,16 +259,29 @@ onMounted(async () => {
|
||||||
: 'Jobs Worker Service'
|
: 'Jobs Worker Service'
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
<span class="text-caption">
|
<div class="flex items-center" style="gap: var(--size-1)">
|
||||||
{{
|
<template v-for="(item, i) in utilsStore.currentTitle.path">
|
||||||
utilsStore.currentTitle?.caption
|
<span
|
||||||
? $t(utilsStore.currentTitle?.caption)
|
class="text-caption cursor-pointer"
|
||||||
: ''
|
@click="item.handler?.()"
|
||||||
}}
|
>
|
||||||
</span>
|
{{
|
||||||
|
item.text
|
||||||
|
? $t(item.text, {
|
||||||
|
...(item.argsi18n || {}),
|
||||||
|
})
|
||||||
|
: ''
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
<q-icon
|
||||||
|
name="mdi-chevron-right"
|
||||||
|
v-if="i + 1 !== utilsStore.currentTitle.path.length"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row q-gutter-x-md items-center">
|
<div class="row q-gutter-x-md items-center" style="margin-left: auto">
|
||||||
<!-- notification -->
|
<!-- notification -->
|
||||||
<q-btn
|
<q-btn
|
||||||
round
|
round
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -99,7 +99,7 @@ const menu = [
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
utilsStore.currentTitle.title = '';
|
utilsStore.currentTitle.title = '';
|
||||||
utilsStore.currentTitle.caption = '';
|
utilsStore.currentTitle.path = [{ text: '' }];
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ export type Branch = {
|
||||||
telephoneNo: string;
|
telephoneNo: string;
|
||||||
lineId: string;
|
lineId: string;
|
||||||
contact: BranchContact[];
|
contact: BranchContact[];
|
||||||
|
_count:{
|
||||||
|
branch:number
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BranchWithChildren = Branch & { branch: Branch[] };
|
export type BranchWithChildren = Branch & { branch: Branch[] };
|
||||||
|
|
@ -64,6 +67,6 @@ export type BranchUserStats = {
|
||||||
id: string;
|
id: string;
|
||||||
nameEN: string;
|
nameEN: string;
|
||||||
name: string;
|
name: string;
|
||||||
count: 0;
|
count: number;
|
||||||
isHeadOffice: boolean;
|
isHeadOffice: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -336,11 +336,13 @@ const useCustomerStore = defineStore('api-customer', () => {
|
||||||
transactionId?: string;
|
transactionId?: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
const { code, branchNo, ...playload } = data;
|
||||||
|
|
||||||
const res = await api.put<
|
const res = await api.put<
|
||||||
Customer & {
|
Customer & {
|
||||||
branch: CustomerBranch[];
|
branch: CustomerBranch[];
|
||||||
}
|
}
|
||||||
>(`/customer-branch/${id}`, data, {
|
>(`/customer-branch/${id}`, playload, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Session-Id': flow?.sessionId,
|
'X-Session-Id': flow?.sessionId,
|
||||||
'X-Rtid': flow?.refTransactionId || flowStore.rtid,
|
'X-Rtid': flow?.refTransactionId || flowStore.rtid,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { Status } from '../types';
|
||||||
export type CustomerType = 'CORP' | 'PERS';
|
export type CustomerType = 'CORP' | 'PERS';
|
||||||
|
|
||||||
export type Customer = {
|
export type Customer = {
|
||||||
|
registeredBranchId: string;
|
||||||
imageUrl: string;
|
imageUrl: string;
|
||||||
id: string;
|
id: string;
|
||||||
code: string;
|
code: string;
|
||||||
|
|
@ -63,7 +64,7 @@ export type CustomerBranch = {
|
||||||
|
|
||||||
export type CustomerBranchCreate = {
|
export type CustomerBranchCreate = {
|
||||||
code?: string;
|
code?: string;
|
||||||
branchNo: number;
|
branchNo?: number;
|
||||||
address: string;
|
address: string;
|
||||||
addressEN: string;
|
addressEN: string;
|
||||||
provinceId?: string | null;
|
provinceId?: string | null;
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ const useEmployeeStore = defineStore('api-employee', () => {
|
||||||
transactionId?: string;
|
transactionId?: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const { image, ...payload } = data;
|
const { code, image, ...payload } = data;
|
||||||
const res = await api.post<
|
const res = await api.post<
|
||||||
Employee & { profileImageUrl: string; profileImageUploadUrl: string }
|
Employee & { profileImageUrl: string; profileImageUploadUrl: string }
|
||||||
>('/employee', payload, {
|
>('/employee', payload, {
|
||||||
|
|
@ -104,7 +104,7 @@ const useEmployeeStore = defineStore('api-employee', () => {
|
||||||
transactionId?: string;
|
transactionId?: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const { image, ...payload } = data;
|
const { code, image, ...payload } = data;
|
||||||
const res = await api.put<
|
const res = await api.put<
|
||||||
Employee & { imageUrl: string; profileImageUploadUrl: string }
|
Employee & { imageUrl: string; profileImageUploadUrl: string }
|
||||||
>(`/employee/${id}`, payload, {
|
>(`/employee/${id}`, payload, {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import { District, Province, SubDistrict } from '../address';
|
||||||
import { Status } from '../types';
|
import { Status } from '../types';
|
||||||
import { User } from '../user/types';
|
import { User } from '../user/types';
|
||||||
|
|
||||||
|
import { Customer , CustomerBranch } from '../customer/types';
|
||||||
|
|
||||||
export type Employee = {
|
export type Employee = {
|
||||||
id: string;
|
id: string;
|
||||||
code: string;
|
code: string;
|
||||||
|
|
@ -45,14 +47,16 @@ export type Employee = {
|
||||||
district: District | null;
|
district: District | null;
|
||||||
province: Province | null;
|
province: Province | null;
|
||||||
profileImageUrl: string | null;
|
profileImageUrl: string | null;
|
||||||
|
customerBranch: CustomerBranch & { customer: Customer } ;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EmployeeCreate = {
|
export type EmployeeCreate = {
|
||||||
|
|
||||||
|
code: string;
|
||||||
image: File | null;
|
image: File | null;
|
||||||
customerBranchId: string;
|
customerBranchId: string;
|
||||||
|
|
||||||
status?: Status;
|
status?: Status;
|
||||||
|
|
||||||
nrcNo: string;
|
nrcNo: string;
|
||||||
|
|
||||||
dateOfBirth: Date | null;
|
dateOfBirth: Date | null;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ import { Branch } from '../branch/types';
|
||||||
import useFlowStore from '../flow';
|
import useFlowStore from '../flow';
|
||||||
|
|
||||||
const useMyBranch = defineStore('useMyBranchStore', () => {
|
const useMyBranch = defineStore('useMyBranchStore', () => {
|
||||||
|
const myBranch = ref<Branch[]>();
|
||||||
|
const currentMyBranch = ref<Branch>();
|
||||||
|
|
||||||
const flowStore = useFlowStore();
|
const flowStore = useFlowStore();
|
||||||
async function fetchListOptionBranch<
|
async function fetchListOptionBranch<
|
||||||
Options extends {
|
Options extends {
|
||||||
|
|
@ -52,8 +55,37 @@ const useMyBranch = defineStore('useMyBranchStore', () => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchListMyBranch(
|
||||||
|
userId: string,
|
||||||
|
flow?: {
|
||||||
|
sessionId?: string;
|
||||||
|
refTransactionId?: string;
|
||||||
|
transactionId?: string;
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const res = await api.get<Pagination<Branch[]>>(`/user/${userId}/branch`, {
|
||||||
|
headers: {
|
||||||
|
'X-Session-Id': flow?.sessionId,
|
||||||
|
'X-Rtid': flow?.refTransactionId || flowStore.rtid,
|
||||||
|
'X-Tid': flow?.transactionId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res) return false;
|
||||||
|
if (res.status === 200) {
|
||||||
|
myBranch.value = res.data.result;
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
myBranch,
|
||||||
|
currentMyBranch,
|
||||||
|
|
||||||
fetchListOptionBranch,
|
fetchListOptionBranch,
|
||||||
|
fetchListMyBranch,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,11 @@ import {
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import useFlowStore from '../flow';
|
import useFlowStore from '../flow';
|
||||||
|
|
||||||
|
import useMyBranchStore from 'src/stores/my-branch';
|
||||||
|
|
||||||
const useProductServiceStore = defineStore('api-product-service', () => {
|
const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
|
const useMyBranch = useMyBranchStore();
|
||||||
|
|
||||||
// Product Type
|
// Product Type
|
||||||
const flowStore = useFlowStore();
|
const flowStore = useFlowStore();
|
||||||
|
|
||||||
|
|
@ -301,6 +305,10 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
v !== undefined && params.append(k, v.toString());
|
v !== undefined && params.append(k, v.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useMyBranch.myBranch?.length !== 0 && useMyBranch.myBranch) {
|
||||||
|
params.append('registeredBranchId', useMyBranch.myBranch[0].id);
|
||||||
|
}
|
||||||
|
|
||||||
const query = params.toString();
|
const query = params.toString();
|
||||||
|
|
||||||
const res = await api.get<Pagination<ProductList[]>>(
|
const res = await api.get<Pagination<ProductList[]>>(
|
||||||
|
|
@ -429,6 +437,10 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
v !== undefined && params.append(k, v.toString());
|
v !== undefined && params.append(k, v.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useMyBranch.myBranch?.length !== 0 && useMyBranch.myBranch) {
|
||||||
|
params.append('registeredBranchId', useMyBranch.myBranch[0].id);
|
||||||
|
}
|
||||||
|
|
||||||
const query = params.toString();
|
const query = params.toString();
|
||||||
|
|
||||||
const res = await api.get<Pagination<Service[]>>(
|
const res = await api.get<Pagination<Service[]>>(
|
||||||
|
|
@ -733,6 +745,10 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
v !== undefined && params.append(k, v.toString());
|
v !== undefined && params.append(k, v.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useMyBranch.myBranch?.length !== 0 && useMyBranch.myBranch) {
|
||||||
|
params.append('registeredBranchId', useMyBranch.myBranch[0].id);
|
||||||
|
}
|
||||||
|
|
||||||
const query = params.toString();
|
const query = params.toString();
|
||||||
|
|
||||||
const res = await api.get<Pagination<ServiceAndProduct[]>>(
|
const res = await api.get<Pagination<ServiceAndProduct[]>>(
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ export type UserAttachmentDelete = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserTypeStats = {
|
export type UserTypeStats = {
|
||||||
|
[x: string]: number;
|
||||||
USER: number;
|
USER: number;
|
||||||
MESSENGER: number;
|
MESSENGER: number;
|
||||||
DELEGATE: number;
|
DELEGATE: number;
|
||||||
|
|
|
||||||
|
|
@ -95,9 +95,21 @@ export function formatNumberDecimal(num: number, point: number): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
const useUtilsStore = defineStore('utilsStore', () => {
|
const useUtilsStore = defineStore('utilsStore', () => {
|
||||||
const currentTitle = ref<{ title: string; caption: string }>({
|
const currentTitle = ref<{
|
||||||
|
title: string;
|
||||||
|
path: {
|
||||||
|
text: string;
|
||||||
|
argsi18n?: Record<string, string>;
|
||||||
|
handler?: () => unknown;
|
||||||
|
}[];
|
||||||
|
}>({
|
||||||
title: '',
|
title: '',
|
||||||
caption: '',
|
path: [
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
handler: () => {},
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue