feat(products): add list and TV visibility icons in operations
Clarify tooltips for product-list vs TV board, keep the same switches in the editor, and show separate status columns. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -52,6 +52,9 @@ export const changeSellActiveProduct = async (id?: number) => {
|
||||
export const changeActiveProduct = async (id: number) => {
|
||||
return await useAxios.get(`/admin/product/active/${id}`)
|
||||
}
|
||||
export const changeShowOnTvProduct = async (id: number) => {
|
||||
return await useAxios.get(`/admin/product/show_on_tv/${id}`)
|
||||
}
|
||||
export const changeVisibilityProduct = async (id: number) => {
|
||||
return await useAxios.get(`/admin/product/hide/${id}`)
|
||||
}
|
||||
|
||||
@@ -496,11 +496,19 @@
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
<div class="product-visibility-panel">
|
||||
<div class="product-visibility-row">
|
||||
<span class="text-sm">نمایش در لیست محصولات</span>
|
||||
<DashboardLabelWithHelp
|
||||
label="نمایش در لیست محصولات"
|
||||
:help="showInListHelp"
|
||||
size="sm"
|
||||
/>
|
||||
<a-switch v-model:checked="form.show_in_list" />
|
||||
</div>
|
||||
<div class="product-visibility-row">
|
||||
<span class="text-sm">نمایش در تابلو TV</span>
|
||||
<DashboardLabelWithHelp
|
||||
label="نمایش در تابلو TV"
|
||||
:help="showOnTvHelp"
|
||||
size="sm"
|
||||
/>
|
||||
<a-switch v-model:checked="form.show_on_tv" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -770,11 +778,13 @@ const cashFeeSellHelp: DashboardHelp = {
|
||||
}
|
||||
|
||||
const showOnTvHelp: DashboardHelp = {
|
||||
description: 'روشن: این محصول در صفحه تابلو قیمت مشتری (/tv) نمایش داده میشود.',
|
||||
description:
|
||||
'مستقل از لیست محصولات است. روشن: این محصول در صفحه تابلو قیمت مشتری (/tv) نمایش داده میشود؛ حتی اگر در لیست محصولات خاموش باشد.',
|
||||
}
|
||||
|
||||
const showInListHelp: DashboardHelp = {
|
||||
description: 'روشن: این محصول در صفحه لیست محصولات اپ مشتری نمایش داده میشود.',
|
||||
description:
|
||||
'مستقل از تابلو TV است. روشن: این محصول در صفحه لیست محصولات اپ مشتری نمایش داده میشود. همان آیکون تیک/ضربدر در ستون عملیات همین وضعیت را عوض میکند.',
|
||||
}
|
||||
|
||||
const autoOpenHelp: DashboardHelp = {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
@toggleBuy="$emit('toggleBuy', $event)"
|
||||
@toggleSell="$emit('toggleSell', $event)"
|
||||
@toggleActive="$emit('toggleActive', $event)"
|
||||
@toggleShowOnTv="$emit('toggleShowOnTv', $event)"
|
||||
@edit="$emit('edit', $event)"
|
||||
@archive="$emit('archive', $event)"
|
||||
/>
|
||||
@@ -43,6 +44,7 @@ defineEmits<{
|
||||
(e: 'toggleBuy', item: Product): void
|
||||
(e: 'toggleSell', item: Product): void
|
||||
(e: 'toggleActive', item: Product): void
|
||||
(e: 'toggleShowOnTv', item: Product): void
|
||||
(e: 'archive', item: Product): void
|
||||
}>()
|
||||
|
||||
|
||||
@@ -24,12 +24,20 @@
|
||||
/>
|
||||
<MobileIconButton
|
||||
plain
|
||||
:key="`active-${row.id}-${row.active}`"
|
||||
:icon="row.active ? 'vuesax-linear:tick-circle' : 'vuesax-linear:close-circle'"
|
||||
:color="row.active ? '#16A34A' : '#DC2626'"
|
||||
:key="`list-${row.id}-${row.show_in_list ?? row.active}`"
|
||||
:icon="(row.show_in_list ?? row.active) ? 'vuesax-linear:tick-circle' : 'vuesax-linear:close-circle'"
|
||||
:color="(row.show_in_list ?? row.active) ? '#16A34A' : '#DC2626'"
|
||||
:size="22"
|
||||
@click="$emit('toggleActive', row)"
|
||||
/>
|
||||
<MobileIconButton
|
||||
plain
|
||||
:key="`tv-${row.id}-${row.show_on_tv}`"
|
||||
icon="vuesax-linear:monitor"
|
||||
:color="row.show_on_tv ? '#16A34A' : '#DC2626'"
|
||||
:size="22"
|
||||
@click="$emit('toggleShowOnTv', row)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -103,6 +111,7 @@ const emit = defineEmits<{
|
||||
(e: 'toggleBuy', item: Product): void
|
||||
(e: 'toggleSell', item: Product): void
|
||||
(e: 'toggleActive', item: Product): void
|
||||
(e: 'toggleShowOnTv', item: Product): void
|
||||
(e: 'edit', item: Product): void
|
||||
(e: 'archive', item: Product): void
|
||||
}>()
|
||||
|
||||
@@ -36,7 +36,9 @@ defineEmits<{
|
||||
(e: 'edit', item: Product): void
|
||||
}>()
|
||||
|
||||
const statusDotClass = computed(() => (props.item.active ? 'bg-green-500' : 'bg-red-400'))
|
||||
const statusDotClass = computed(() =>
|
||||
(props.item.show_in_list ?? props.item.active) ? 'bg-green-500' : 'bg-red-400',
|
||||
)
|
||||
const priceLabel = computed(() => (props.item.price ? usePrice(props.item.price) : '-'))
|
||||
</script>
|
||||
|
||||
|
||||
@@ -75,20 +75,37 @@
|
||||
@click="activeSell(record)"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip class="cursor-pointer" :key="`active-${record.id}-${record.active}`">
|
||||
<template v-if="!record.active" #title><span>فعال کردن محصول</span></template>
|
||||
<template v-else #title><span>غیر فعال کردن محصول</span></template>
|
||||
<a-tooltip class="cursor-pointer" :key="`list-${record.id}-${record.show_in_list ?? record.active}`">
|
||||
<template v-if="!(record.show_in_list ?? record.active)" #title>
|
||||
<span>فعال کردن نمایش در لیست محصولات</span>
|
||||
</template>
|
||||
<template v-else #title>
|
||||
<span>غیرفعال کردن نمایش در لیست محصولات</span>
|
||||
</template>
|
||||
<BaseIcon
|
||||
v-if="!record.active"
|
||||
v-if="!(record.show_in_list ?? record.active)"
|
||||
icon="vuesax-linear:close-circle"
|
||||
color="#DC2626"
|
||||
@click="activeProduct(record)"
|
||||
@click="toggleShowInList(record)"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
icon="vuesax-linear:tick-circle"
|
||||
color="#16A34A"
|
||||
@click="activeProduct(record)"
|
||||
@click="toggleShowInList(record)"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip class="cursor-pointer" :key="`tv-${record.id}-${record.show_on_tv}`">
|
||||
<template v-if="!record.show_on_tv" #title>
|
||||
<span>فعال کردن نمایش در تابلو TV</span>
|
||||
</template>
|
||||
<template v-else #title>
|
||||
<span>غیرفعال کردن نمایش در تابلو TV</span>
|
||||
</template>
|
||||
<BaseIcon
|
||||
icon="vuesax-linear:monitor"
|
||||
:color="record.show_on_tv ? '#16A34A' : '#DC2626'"
|
||||
@click="toggleShowOnTv(record)"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('edit', record)">
|
||||
@@ -118,7 +135,8 @@
|
||||
@edit="emits('edit', $event)"
|
||||
@toggleBuy="activeBuy"
|
||||
@toggleSell="activeSell"
|
||||
@toggleActive="activeProduct"
|
||||
@toggleActive="toggleShowInList"
|
||||
@toggleShowOnTv="toggleShowOnTv"
|
||||
@archive="handleArchive"
|
||||
/>
|
||||
</div>
|
||||
@@ -137,6 +155,7 @@ import {
|
||||
changeActiveProduct,
|
||||
changeBuyActiveProduct,
|
||||
changeSellActiveProduct,
|
||||
changeShowOnTvProduct,
|
||||
getCustomerTable,
|
||||
setActiveTime
|
||||
} from '@/api/product'
|
||||
@@ -232,12 +251,18 @@ const activeBuy = (product: Product) =>
|
||||
await fetch()
|
||||
})
|
||||
|
||||
const activeProduct = (product: Product) =>
|
||||
confirmToggle('آیا مطمئن به انجام این عملیات هستید؟', async () => {
|
||||
const toggleShowInList = (product: Product) =>
|
||||
confirmToggle('نمایش این محصول در لیست محصولات تغییر میکند. آیا مطمئن هستید؟', async () => {
|
||||
await changeActiveProduct(product.id)
|
||||
await fetch()
|
||||
})
|
||||
|
||||
const toggleShowOnTv = (product: Product) =>
|
||||
confirmToggle('نمایش این محصول در تابلو TV تغییر میکند. آیا مطمئن هستید؟', async () => {
|
||||
await changeShowOnTvProduct(product.id)
|
||||
await fetch()
|
||||
})
|
||||
|
||||
function handleArchive(product: Product) {
|
||||
confirmToggle(
|
||||
'آیا این محصول بایگانی شود؟ نمایش، خرید و فروش آن غیرفعال میشود.',
|
||||
|
||||
@@ -104,21 +104,44 @@ export function getProductColumns(): BaseTableColumn[] {
|
||||
},
|
||||
...(isStoreApp() ? [inventoryColumn] : []),
|
||||
{
|
||||
title: 'وضعیت محصول',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
title: 'وضعیت لیست',
|
||||
dataIndex: 'show_in_list',
|
||||
key: 'show_in_list',
|
||||
type: 'Boolean',
|
||||
customRender: (record) => (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag
|
||||
class="px-3 font-bold py-1"
|
||||
textColor={record?.record.active ? '#65a30d' : '#dc2626'}
|
||||
bgColor={record?.record.active ? '#ecfccb' : '#fee2e2'}
|
||||
>
|
||||
{record?.record.active ? 'باز' : 'بسته'}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
customRender: (record) => {
|
||||
const on = record?.record.show_in_list ?? record?.record.active
|
||||
return (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag
|
||||
class="px-3 font-bold py-1"
|
||||
textColor={on ? '#65a30d' : '#dc2626'}
|
||||
bgColor={on ? '#ecfccb' : '#fee2e2'}
|
||||
>
|
||||
{on ? 'باز' : 'بسته'}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'تابلو TV',
|
||||
dataIndex: 'show_on_tv',
|
||||
key: 'show_on_tv',
|
||||
type: 'Boolean',
|
||||
customRender: (record) => {
|
||||
const on = !!record?.record.show_on_tv
|
||||
return (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag
|
||||
class="px-3 font-bold py-1"
|
||||
textColor={on ? '#65a30d' : '#dc2626'}
|
||||
bgColor={on ? '#ecfccb' : '#fee2e2'}
|
||||
>
|
||||
{on ? 'روشن' : 'خاموش'}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'عملیات',
|
||||
|
||||
Reference in New Issue
Block a user