jws-frontend/src/pages/09_task-order/TaskStatusComponent.vue
puriphatt 16bcecc8d6
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 10s
feat: add support for 'Restart' task status in task order management
2025-02-26 15:20:10 +07:00

194 lines
5.5 KiB
Vue

<script lang="ts" setup>
import { TaskStatus } from 'src/stores/task-order/types';
import { taskStatusReceiveToggle, taskStatusOrderToggle } from './constants';
import { computed } from 'vue';
const props = defineProps<{
readonly?: boolean;
noAction?: boolean;
type?: 'order' | 'receive';
status: string | TaskStatus | undefined;
}>();
defineEmits<{
(e: 'changeStatus', status: TaskStatus): void;
(e: 'clickFailed'): void;
}>();
const statusList = [
...taskStatusReceiveToggle,
...taskStatusOrderToggle,
{
value: TaskStatus.Validate,
icon: 'mdi-file-check-outline',
color: 'positive',
},
{
value: TaskStatus.Canceled,
icon: 'mdi-file-remove-outline',
color: 'negative',
},
];
const currStatus = computed(() =>
statusList.find((v) => v.value === props.status),
);
function inactiveCheck() {
if (props.type === 'order') {
return (
currStatus.value?.value === TaskStatus.InProgress ||
currStatus.value?.value === TaskStatus.Redo ||
currStatus.value?.value === TaskStatus.Success ||
currStatus.value?.value === TaskStatus.Complete ||
currStatus.value?.value === TaskStatus.Canceled ||
currStatus.value?.value === TaskStatus.Restart
);
}
if (props.type === 'receive') {
return (
currStatus.value?.value === TaskStatus.Failed ||
currStatus.value?.value === TaskStatus.Success ||
currStatus.value?.value === TaskStatus.Complete ||
currStatus.value?.value === TaskStatus.Redo ||
currStatus.value?.value === TaskStatus.Validate ||
currStatus.value?.value === TaskStatus.Canceled
);
}
}
</script>
<template>
<div
v-if="readonly"
class="row rounded bordered surface-2 items-center justify-center q-pa-xs no-wrap"
:style="`color: hsl(var(--${currStatus?.color}-bg))`"
>
<q-icon :name="currStatus?.icon" class="q-pr-xs" size="xs" />
{{ $t(`taskOrder.status.${status}`) }}
</div>
<div v-else class="row items-center justify-center no-wrap">
<q-btn-dropdown
dense
unelevated
:label="
currStatus?.value === TaskStatus.Validate && type === 'order'
? $t('taskOrder.done')
: currStatus?.value === TaskStatus.Redo && type === 'receive'
? $t(`taskOrder.status.receive.Canceled`)
: $t(`taskOrder.status.${status}`)
"
class="text-capitalize text-weight-regular product-status rounded"
:class="{
'inactive hide-icon q-pr-md': inactiveCheck(),
'hide-icon q-pr-md': noAction,
warning:
currStatus?.value === TaskStatus.Pending ||
currStatus?.value === TaskStatus.InProgress,
positive:
currStatus?.value === TaskStatus.Complete ||
currStatus?.value === TaskStatus.Success ||
currStatus?.value === TaskStatus.Validate,
negative:
currStatus?.value === TaskStatus.Failed ||
currStatus?.value === TaskStatus.Redo ||
currStatus?.value === TaskStatus.Canceled ||
currStatus?.value === TaskStatus.Restart,
'pointer-events-none': {
order: !['Success', 'Failed', 'Validate', 'Redo'].includes(
status || '',
),
receive: status !== TaskStatus.InProgress,
}[type ?? 'order'],
}"
:menu-offset="[0, 8]"
dropdown-icon="mdi-chevron-down"
content-class="bordered rounded"
@click.stop
:icon="currStatus?.icon"
>
<q-list v-if="!noAction" dense>
<q-item
v-for="(v, index) in type === 'order'
? {
Success: taskStatusOrderToggle.filter(
(v) => v.value === TaskStatus.Complete,
),
Failed: taskStatusOrderToggle.filter(
(v) =>
v.value === TaskStatus.Redo ||
v.value === TaskStatus.Restart,
),
Validate: taskStatusOrderToggle.filter(
(v) => v.value !== TaskStatus.InProgress,
),
}[status ?? '']
: {
InProgress: taskStatusReceiveToggle.filter((v) =>
[TaskStatus.Success, TaskStatus.Failed].includes(v.value),
),
}[status ?? '']"
:key="index"
clickable
v-close-popup
@click="$emit('changeStatus', v.value)"
class="items-center"
>
<q-icon
:style="`color: hsl(var(--${v.color}-bg))`"
:name="v.icon"
class="q-pr-sm"
size="xs"
></q-icon>
{{ $t(`taskOrder.status.${v.value}`) }}
</q-item>
</q-list>
</q-btn-dropdown>
<q-btn
v-if="currStatus?.value === TaskStatus.Failed"
flat
dense
rounded
color="negative"
icon="mdi-shield-alert-outline"
@click="$emit('clickFailed')"
/>
<div style="width: 31.94px" v-else></div>
</div>
</template>
<style scoped>
.product-status {
padding-left: 8px;
border-radius: 20px;
color: hsl(var(--_color));
background: hsla(var(--_color) / 0.15);
&.warning {
--_color: var(--warning-bg);
}
&.positive {
--_color: var(--positive-bg);
}
&.negative {
--_color: var(--negative-bg);
}
&.inactive {
--_color: var(--stone-7-hsl);
opacity: 0.8;
cursor: default;
}
}
.pointer-events-none {
pointer-events: none;
}
:deep(
.hide-icon
i.q-icon.mdi.mdi-chevron-down.q-btn-dropdown__arrow.q-btn-dropdown__arrow-container
) {
display: none;
}
</style>