feat: menu request list (#75)
* feat: i18n * feat: request list * refactor: hide stat transition on app.scss * feat: request list i18n * feat: request list => constants and main page * feat: add store * feat: add fetch data * feat: add utilities fn * feat: add store function / types * refactor: request list type * refactor: request list constants * refactor: quotation card => add customData and badge color props * feat: avatar group components * feat: request list group * refactor: request list => remove tab, add table data * feat: send search query * feat: add parameter * refactor: remove unused function * fix: rename component lits to list * feat: show stats from api * chore: cleanup * refactor: make it type safe * refactor: accept rotate flow id as parameter * feat: use page size component * feat: add component, data display & expansion product * feat: i18n * refactor: constants and request list table * refactor: type code, createdAt, updatedAt * refactor: utils function changThemeMode * feat: request list => view page * refactor: use type instead of infer from value * fix: function getEmployeeName att type * refactor: fetch work list * refactor: loop work list * feat: add i18n duty * feat: add form issue component * feat: add form issue section * fix: store error * refactor: edit by value * refactor: accept basic info from outside instead * feat: add status filter support on fetch * refactor: remove delete button * refactor: wording * feat/fix: request list i18n & constant * feat: document type * feat/refactor: request list => document expansion * refactor: doc expansion use FormGroupHead * refactor: fetch data based on id from route param * refactor: text area disable * feat: properties expansion display (mocking) * refactor: add document at product relation * refactor: edit get value product * feat: get workflow step to show on top * refactor: add type * refactor: add get attachment * refactor: add view attachment * refactor: edit file name * refactor: define props get hide icon * refactor: edit align row * refactor: by value table document * refactor: by value row table * feat: add independent ocr dialog * chore: clean up * refactor: accept more props and small adjustment * fix: error withDefault call * feat: accept default metadata when open * fix: typo * feat: add override hook when finish ocr * feat: reset state on open * feat: detect reader result is actually string * fix: variable name conflict * feat: properties to input component * feat: properties input in properties expansion * feat: properties expansion data (temporary) * refactor: add i18n status work * refactor: edit type work status and add step status * refactor: add edit status work * refactor: edit step work * refactor: properties data type * refactor: filter selected product & specific properties * feat: add emit event * refactor: change variable name for better understanding * refactor: hide step that no properties * refactor: work status type to validate * feat: work status color * refactor: key for filename * refactor: close expansion when change step * refactor: responsive meta data * refactor: product expansion responsive * fix: dark mode step text color * fix: document expansion table no data label * refactor: main page body bordered and overflow hidden * refactor: use utils function instead * refactor: add process * refactor: by value name * refactor: add upload file * refactor: upload file * refactor: by value * fix: option worker type * refactor: fetchRequestAttachment after edit * fix: metadata display * refactor: add class full-height * refactor: edit type * refactor: fetch file * refactor: by value visa * refactor: request list attributes type * fix: properties to input props (placeholder, readonly, disable) * feat: request list properties function * fix: error when no workflow * docs: update comment to fix indent * refactor: step type (attributes) * refactor: add attributes payload on editStatusRequestWork function * feat/refactor: functional form expansion/filter worklist * refactor: set attributes properties after submit * refactor: add request work ready status * feat: request list => form employee component * feat/refactor: form expansion select user/layout * fix: properties readonly --------- Co-authored-by: puriphatt <puriphat@frappet.com> Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
This commit is contained in:
parent
9105dcf7fe
commit
972f6ba13e
36 changed files with 3653 additions and 57 deletions
270
src/pages/08_request-list/TableRequestList.vue
Normal file
270
src/pages/08_request-list/TableRequestList.vue
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
<script setup lang="ts">
|
||||
import { QTable, QTableProps, QTableSlots } from 'quasar';
|
||||
|
||||
import KebabAction from 'components/shared/KebabAction.vue';
|
||||
import QuotationCard from 'src/components/05_quotation/QuotationCard.vue';
|
||||
import BadgeComponent from 'src/components/BadgeComponent.vue';
|
||||
import AvatarGroup from 'src/components/shared/AvatarGroup.vue';
|
||||
|
||||
import { RequestData } from 'src/stores/request-list/types';
|
||||
import { RequestDataStatus } from 'src/stores/request-list/types';
|
||||
import useOptionStore from 'src/stores/options';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
rows: QTableProps['rows'];
|
||||
columns: QTableProps['columns'];
|
||||
grid?: boolean;
|
||||
visibleColumns?: string[];
|
||||
}>(),
|
||||
{
|
||||
row: () => [],
|
||||
column: () => [],
|
||||
grid: false,
|
||||
visibleColumns: () => [],
|
||||
},
|
||||
);
|
||||
|
||||
defineEmits<{
|
||||
(e: 'view', data: RequestData): void;
|
||||
(e: 'edit', id: string): void;
|
||||
(e: 'delete', id: string): void;
|
||||
}>();
|
||||
|
||||
function getCustomerName(
|
||||
record: RequestData,
|
||||
opts?: {
|
||||
locale?: string;
|
||||
noCode?: boolean;
|
||||
},
|
||||
) {
|
||||
const customer = record.quotation.customerBranch;
|
||||
|
||||
return (
|
||||
{
|
||||
['CORP']: {
|
||||
['eng']: customer.registerNameEN,
|
||||
['tha']: customer.registerName,
|
||||
}[opts?.locale || 'eng'],
|
||||
['PERS']:
|
||||
{
|
||||
['eng']: `${useOptionStore().mapOption(customer.namePrefix)} ${customer.firstNameEN} ${customer.lastNameEN}`,
|
||||
['tha']: `${useOptionStore().mapOption(customer.namePrefix)} ${customer.firstName} ${customer.lastName}`,
|
||||
}[opts?.locale || 'eng'] || '-',
|
||||
}[customer.customer.customerType] +
|
||||
(opts?.noCode ? '' : ' ' + `(${customer.code})`)
|
||||
);
|
||||
}
|
||||
|
||||
function getEmployeeName(
|
||||
record: RequestData,
|
||||
opts?: {
|
||||
locale?: string;
|
||||
},
|
||||
) {
|
||||
const employee = record.employee;
|
||||
|
||||
return (
|
||||
{
|
||||
['eng']: `${useOptionStore().mapOption(employee.namePrefix)} ${employee.firstNameEN} ${employee.lastNameEN}`,
|
||||
['tha']: `${useOptionStore().mapOption(employee.namePrefix)} ${employee.firstName} ${employee.lastName}`,
|
||||
}[opts?.locale || 'eng'] || '-'
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<q-table
|
||||
v-bind="props"
|
||||
bordered
|
||||
flat
|
||||
hide-pagination
|
||||
card-container-class="q-col-gutter-sm"
|
||||
:rows-per-page-options="[0]"
|
||||
class="full-width"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr
|
||||
style="background-color: hsla(var(--info-bg) / 0.07)"
|
||||
:props="props"
|
||||
>
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ col.label && $t(col.label) }}
|
||||
</q-th>
|
||||
<q-th></q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
<template
|
||||
v-slot:body="props: {
|
||||
row: RequestData;
|
||||
} & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
|
||||
>
|
||||
<q-tr
|
||||
:class="{ urgent: props.row.quotation.urgent, dark: $q.dark.isActive }"
|
||||
class="text-center"
|
||||
>
|
||||
<q-td v-if="visibleColumns.includes('order')">
|
||||
{{ props.rowIndex + 1 }}
|
||||
</q-td>
|
||||
<q-td v-if="visibleColumns.includes('requestList')" class="text-left">
|
||||
{{ props.row.quotation.workName || '-' }}
|
||||
<div class="text-caption app-text-muted">
|
||||
{{ props.row.code || '-' }}
|
||||
</div>
|
||||
</q-td>
|
||||
<q-td v-if="visibleColumns.includes('employer')" class="text-left">
|
||||
{{
|
||||
getCustomerName(props.row, {
|
||||
noCode: true,
|
||||
locale: $i18n.locale,
|
||||
}) || '-'
|
||||
}}
|
||||
</q-td>
|
||||
<q-td v-if="visibleColumns.includes('employee')" class="text-left">
|
||||
{{ getEmployeeName(props.row, { locale: $i18n.locale }) || '-' }}
|
||||
</q-td>
|
||||
<q-td v-if="visibleColumns.includes('quotationCode')">
|
||||
{{ props.row.quotation.code || '-' }}
|
||||
</q-td>
|
||||
<q-td v-if="visibleColumns.includes('responsiblePerson')">
|
||||
{{ '-' }}
|
||||
</q-td>
|
||||
<q-td v-if="visibleColumns.includes('status')">
|
||||
<BadgeComponent
|
||||
:hsla-color="
|
||||
props.row.requestDataStatus === RequestDataStatus.Pending
|
||||
? '--orange-5-hsl'
|
||||
: props.row.requestDataStatus === RequestDataStatus.InProgress
|
||||
? '--blue-6-hsl'
|
||||
: props.row.requestDataStatus === RequestDataStatus.Completed
|
||||
? '--green-8-hsl'
|
||||
: '--orange-5-hsl'
|
||||
"
|
||||
:title="
|
||||
$t(`requestList.status.${props.row.requestDataStatus}`) || '-'
|
||||
"
|
||||
/>
|
||||
</q-td>
|
||||
<q-td class="text-right">
|
||||
<q-btn
|
||||
:id="`btn-eye-${props.row.quotation.workName}`"
|
||||
icon="mdi-eye-outline"
|
||||
size="sm"
|
||||
dense
|
||||
round
|
||||
flat
|
||||
@click.stop="$emit('view', props.row)"
|
||||
/>
|
||||
|
||||
<KebabAction
|
||||
:idName="`btn-kebab-${props.row.quotation.workName}`"
|
||||
status="'ACTIVE'"
|
||||
hide-toggle
|
||||
@view="$emit('view', props.row)"
|
||||
@edit="$emit('edit', props.row.id)"
|
||||
@delete="$emit('delete', props.row.id)"
|
||||
/>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
<template
|
||||
v-slot:item="props: {
|
||||
row: RequestData;
|
||||
} & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
|
||||
>
|
||||
<div class="col-md-4 col-sm-6 col-12">
|
||||
<QuotationCard
|
||||
:badge-color="
|
||||
props.row.requestDataStatus === RequestDataStatus.Pending
|
||||
? '--orange-5-hsl'
|
||||
: props.row.requestDataStatus === RequestDataStatus.InProgress
|
||||
? '--blue-6-hsl'
|
||||
: props.row.requestDataStatus === RequestDataStatus.Completed
|
||||
? '--green-8-hsl'
|
||||
: '--orange-5-hsl'
|
||||
"
|
||||
hidePreview
|
||||
:urgent="props.row.quotation.urgent"
|
||||
:code="props.row.code"
|
||||
:title="props.row.quotation.workName"
|
||||
:status="$t(`requestList.status.${props.row.requestDataStatus}`)"
|
||||
:custom-data="[
|
||||
{
|
||||
label: $t('customer.employer'),
|
||||
value:
|
||||
getCustomerName(props.row, {
|
||||
noCode: true,
|
||||
locale: $i18n.locale,
|
||||
}) || '-',
|
||||
},
|
||||
{
|
||||
label: $t('customer.employee'),
|
||||
value:
|
||||
getEmployeeName(props.row, { locale: $i18n.locale }) || '-',
|
||||
},
|
||||
{
|
||||
label: $t('requestList.quotationCode'),
|
||||
value: props.row.quotation.code || '-',
|
||||
},
|
||||
{
|
||||
label: $t('flow.responsiblePerson'),
|
||||
value: '',
|
||||
slotName: 'responsiblePerson',
|
||||
},
|
||||
]"
|
||||
@view="$emit('view', props.row)"
|
||||
>
|
||||
<template v-slot:responsiblePerson="{ props }">
|
||||
<div class="col-4 app-text-muted q-pr-sm self-center">
|
||||
{{ props.label }}
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<AvatarGroup />
|
||||
</div>
|
||||
</template>
|
||||
</QuotationCard>
|
||||
</div>
|
||||
</template>
|
||||
</q-table>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(tr:nth-child(2n)) {
|
||||
background: #f9fafc;
|
||||
&.dark {
|
||||
background: hsl(var(--gray-11-hsl) / 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.q-table tr.urgent {
|
||||
background: hsla(var(--red-6-hsl) / 0.03);
|
||||
}
|
||||
|
||||
.q-table tr.urgent td:first-child {
|
||||
&::after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 15%;
|
||||
bottom: 15%;
|
||||
background: var(--red-8);
|
||||
width: 4px;
|
||||
border-radius: 99rem;
|
||||
animation: blink 1s infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0% {
|
||||
background: var(--red-8);
|
||||
}
|
||||
50% {
|
||||
background: var(--red-3);
|
||||
}
|
||||
100% {
|
||||
background: var(--red-8);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue