feat: unique IDs to UI components for testing
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 6s

This commit is contained in:
Aif 2025-11-11 10:02:13 +07:00
parent 2b1e3b12a4
commit 637eeab3c2
4 changed files with 72 additions and 12 deletions

View file

@ -295,6 +295,7 @@ function assignTempGroup() {
class="bordered-b"
>
<q-expansion-item
:id="`expansion-product-${product.code}`"
dense
class="overflow-hidden"
switch-toggle-side
@ -348,6 +349,7 @@ function assignTempGroup() {
</FormGroupHead>
<div class="q-pa-md full-width">
<TableEmployee
:id="`table-employee-${product.code}`"
checkbox-on
check-all
select-ready
@ -371,9 +373,15 @@ function assignTempGroup() {
</section>
<template #footer>
<CancelButton class="q-ml-auto" outlined @click="close" />
<CancelButton
id="btn-dialog-cancel"
class="q-ml-auto"
outlined
@click="close"
/>
<SaveButton
:label="$t('general.select')"
id="btn-dialog-select"
class="q-ml-sm"
icon="mdi-check"
solid

View file

@ -225,6 +225,7 @@ function disableCheckAll() {
<template>
<q-table
flat
id="table-employee"
bordered
row-key="id"
v-bind="props"
@ -273,6 +274,7 @@ function disableCheckAll() {
>
<q-th v-if="checkboxOn" class="relative-position">
<q-checkbox
id="checkbox-check-all"
v-if="checkAll"
:disable="disableCheckAll()"
:model-value="
@ -305,6 +307,7 @@ function disableCheckAll() {
class="absolute-right row items-center"
>
<q-btn
id="btn-change-all-status"
flat
dense
rounded
@ -339,6 +342,7 @@ function disableCheckAll() {
{{ $t(`taskOrder.status.Complete`) }}
</q-item>
<q-item
id="menu-item-redo"
clickable
v-close-popup
class="items-center"
@ -358,6 +362,7 @@ function disableCheckAll() {
{{ $t(`taskOrder.status.Redo`) }}
</q-item>
<q-item
id="menu-item-restart"
clickable
v-close-popup
class="items-center"
@ -379,6 +384,7 @@ function disableCheckAll() {
</q-list>
<q-list v-if="!validate" dense>
<q-item
id="menu-item-success"
clickable
v-close-popup
class="items-center"
@ -398,6 +404,7 @@ function disableCheckAll() {
{{ $t(`taskOrder.status.Success`) }}
</q-item>
<q-item
id="menu-item-failed"
clickable
v-close-popup
class="items-center"
@ -480,6 +487,7 @@ function disableCheckAll() {
<q-td>
<span
class="cursor-pointer link"
:id="`link-request-list-${props.row.request.code}`"
@click="goToRequestList(props.row.request.id)"
>
{{ props.row.request.code }}
@ -489,6 +497,7 @@ function disableCheckAll() {
<q-td>
<span
class="cursor-pointer link"
:id="`link-quotation-${props.row.request.quotation?.code}`"
@click="goToQuotation(props.row.request.quotation)"
>
{{ props.row.request.quotation?.code }}
@ -496,7 +505,11 @@ function disableCheckAll() {
</q-td>
<q-td v-if="stepOn" class="text-left">
<div v-if="props.row._template" class="column text-left">
<div
v-if="props.row._template"
class="column text-left"
:id="`template-step-${props.row.request.code}`"
>
<span>{{ props.row._template.templateName }}</span>
<span class="app-text-muted text-caption">
{{ $t('flow.stepNo', { msg: props.row._template.step }) }}
@ -522,7 +535,10 @@ function disableCheckAll() {
</template>
</q-img>
</q-avatar>
<div class="column text-left q-ml-sm">
<div
class="column text-left q-ml-sm"
:id="`employee-name-${props.row.request.employee?.code}`"
>
<div>
{{ getEmployeeName(props.row, { locale: $i18n.locale }) }}
</div>
@ -532,6 +548,7 @@ function disableCheckAll() {
</div>
</div>
<Icon
:id="`icon-gender-${props.row.request.employee?.code}`"
class="q-ml-md"
:class="`app-text-${props.row.request.employee?.gender}`"
:icon="`material-symbols:${props.row.request.employee?.gender}`"
@ -539,13 +556,18 @@ function disableCheckAll() {
/>
</div>
</q-td>
<q-td>{{ calculateAge(props.row.request.employee?.dateOfBirth) }}</q-td>
<q-td>
<q-td :id="`employee-age-${props.row.request.employee?.code}`">
{{ calculateAge(props.row.request.employee?.dateOfBirth) }}
</q-td>
<q-td :id="`employee-nationality-${props.row.request.employee?.code}`">
{{
useOptionStore().mapOption(props.row.request.employee?.nationality)
}}
</q-td>
<q-td>
<q-td
:id="`quotation-due-date-${props.row.request.quotation?.code}`"
v-if="!statusOn"
>
{{
dateFormatJS({
date: props.row.request.quotation?.dueDate,
@ -555,13 +577,16 @@ function disableCheckAll() {
})
}}
</q-td>
<q-td>
<q-td
:id="`expiration-date-${props.row.request.quotation?.code}`"
v-if="!statusOn"
>
<ExpirationDate
:expiration-date="new Date(props.row.request.quotation?.dueDate)"
/>
</q-td>
<q-td>
<q-td v-if="!statusOn">
<BadgeComponent
v-if="props.row.request.quotation?.urgent"
icon="mdi-fire"

View file

@ -123,6 +123,7 @@ function taskOrderStatus(value: TaskStatus) {
<span
class="row items-center justify-between full-width"
style="min-height: 31.01px"
id="header-product-list"
>
{{ $t('general.information', { msg: $t('taskOrder.productList') }) }}
<AddButton
@ -135,6 +136,7 @@ function taskOrderStatus(value: TaskStatus) {
<main class="q-px-md q-py-sm surface-1">
<q-table
id="table-product-list"
:columns="
creditNote
? productColumn.filter(
@ -180,7 +182,7 @@ function taskOrderStatus(value: TaskStatus) {
} & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
>
<q-tr class="text-center">
<q-td>
<q-td :id="`product-order-${props.rowIndex}`">
{{ props.rowIndex + 1 }}
</q-td>
<q-td>
@ -206,6 +208,7 @@ function taskOrderStatus(value: TaskStatus) {
</q-td>
<q-td class="text-left" v-if="!creditNote">
<BadgeComponent
:id="`badge-status-${props.row.product.code}`"
hide-icon
:hsla-color="taskOrderStatus(props.row.product.taskStatus)"
:title="`${$t(`taskOrder.status.${props.row.product.taskStatus}`)} ${!!props.row.product.totalNotStatusComplete ? $t('general.totalPeople', { meg: props.row.product.totalNotStatusComplete }) : ''}`"
@ -230,6 +233,7 @@ function taskOrderStatus(value: TaskStatus) {
<!-- TODO: display price detail -->
<q-td align="center" v-if="!creditNote">
<q-input
:id="`input-discount-${props.row.product.code}`"
:readonly
:bg-color="readonly ? 'transparent' : ''"
dense
@ -311,6 +315,7 @@ function taskOrderStatus(value: TaskStatus) {
</q-td>
<q-td>
<q-btn
:id="`btn-toggle-employee-${props.row.product.code}`"
dense
flat
class="rounded"
@ -351,7 +356,9 @@ function taskOrderStatus(value: TaskStatus) {
})
}}
</span>
<div class="surface-3 q-px-sm rounded">{{ taskList.length }}</div>
<div class="surface-3 q-px-sm rounded" id="total-product-count">
{{ taskList.length }}
</div>
</div>
</main>
</q-expansion-item>

View file

@ -814,7 +814,7 @@ watch(
>
<section class="banner" :class="{ dark: $q.dark.isActive }"></section>
<div style="flex: 1" class="row items-center">
<RouterLink to="/task-order">
<RouterLink to="/task-order" id="link-task-order">
<q-img src="/icons/favicon-512x512.png" width="3rem" />
</RouterLink>
<span class="column text-h6 text-bold q-ml-md">
@ -863,6 +863,7 @@ watch(
<!-- TODO: replace step and status -->
<StateButton
v-for="i in statusTabForm"
:id="`btn-status-${i.title}`"
:key="i.title"
:label="$t(`taskOrder.${i.title}`)"
:status-active="i.active?.()"
@ -916,6 +917,7 @@ watch(
"
>
<DocumentExpansion
id="expansion-document"
:readonly="!['create', 'edit'].includes(state.mode || '')"
v-model:registered-branch-id="currentFormData.registeredBranchId"
v-model:institution-id="currentFormData.institutionId"
@ -935,6 +937,7 @@ watch(
/>
</q-form>
<ProductExpansion
id="expansion-product"
ref="refProductExpansion"
v-if="
view === TaskOrderStatus.Pending ||
@ -947,6 +950,7 @@ watch(
/>
<PaymentExpansion
id="expansion-payment"
v-model:summary-price="summaryPrice"
:complete="view === TaskOrderStatus.Complete"
v-if="
@ -956,6 +960,7 @@ watch(
/>
<AdditionalFileExpansion
id="expansion-additional-file"
:readonly="!['create', 'edit'].includes(state.mode || '')"
v-if="
view === TaskOrderStatus.Pending ||
@ -1014,6 +1019,7 @@ watch(
/>
<!-- TODO: blind remark, urgent -->
<RemarkExpansion
id="expansion-remark"
v-if="
view === TaskOrderStatus.Pending ||
view === TaskOrderStatus.Complete
@ -1038,6 +1044,7 @@ watch(
"
>
<InfoMessengerExpansion
:id="`expansion-messenger-${messengerIndex}`"
v-for="(v, messengerIndex) in messengerListGroup"
:key="messengerIndex"
:gender="getMessengerName(v.responsibleUser, { gender: true })"
@ -1073,6 +1080,7 @@ watch(
class="bordered-b"
>
<q-expansion-item
:id="`expansion-product-${productIndex}`"
dense
class="overflow-hidden"
switch-toggle-side
@ -1246,6 +1254,7 @@ watch(
<nav class="row justify-end">
<MainButton
class="q-mr-auto"
id="btn-view-example"
v-if="currentFormData.id"
outlined
icon="mdi-play-box-outline"
@ -1260,10 +1269,16 @@ watch(
{{ $t('general.view', { msg: $t('general.example') }) }}
</MainButton>
<div class="row" style="gap: var(--size-2)">
<UndoButton outlined @click="undo()" v-if="state.mode === 'edit'" />
<UndoButton
id="btn-undo"
outlined
@click="undo()"
v-if="state.mode === 'edit'"
/>
<CancelButton
v-if="state.mode !== 'edit'"
:label="$t('dialog.action.close')"
id="btn-close"
outlined
@click="closeTab()"
/>
@ -1275,12 +1290,14 @@ watch(
"
>
<SaveButton
id="btn-save"
v-if="state.mode && ['create', 'edit'].includes(state.mode)"
@click="() => formDocument.submit()"
solid
/>
<EditButton
v-else
id="btn-edit"
class="no-print"
@click="state.mode = 'edit'"
solid
@ -1288,6 +1305,7 @@ watch(
</template>
<SaveButton
v-if="
canAccess('taskOrder', 'edit') &&
state.mode !== 'create' &&
view === TaskOrderStatus.Validate &&
fullTaskOrder?.taskOrderStatus !== TaskOrderStatus.Pending &&
@ -1326,6 +1344,7 @@ watch(
"
:label="$t('taskOrder.confirmEndWork')"
icon="mdi-check"
id="btn-confirm-end-work"
solid
></SaveButton>
</div>
@ -1335,6 +1354,7 @@ watch(
<!-- SEC: Dialog -->
<SelectReadyRequestWork
id="dialog-select-request-work"
:task-list-group="taskListGroup"
:fetch-params="{ readyToTask: true }"
v-model:open="pageState.productDialog"