feat: store details translation
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
|
@ -0,0 +1,51 @@
|
||||||
|
interface Store {
|
||||||
|
id_structure: number
|
||||||
|
nom: string
|
||||||
|
ip_master: string
|
||||||
|
telephone: string
|
||||||
|
photoLink: string
|
||||||
|
enseigne: string
|
||||||
|
nb_caisses: number
|
||||||
|
adresse: string
|
||||||
|
caisses: Caisse[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Caisse {
|
||||||
|
id_caisse: number
|
||||||
|
ip: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Replication {
|
||||||
|
pendingReplications: number
|
||||||
|
minPendingReplicationDate: string
|
||||||
|
maxPendingReplicationDate: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Transaction {
|
||||||
|
backOfficeTransactions: number
|
||||||
|
minBackOfficeTransactionDate: string
|
||||||
|
maxBackOfficeTransactionDate: string
|
||||||
|
backOfficeBusinessDate: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface XstoreTransaction {
|
||||||
|
count: number
|
||||||
|
minDate: string
|
||||||
|
minDateT: string
|
||||||
|
minDateH: string
|
||||||
|
maxDate: string
|
||||||
|
maxDateT: string
|
||||||
|
maxDateH: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StoreData {
|
||||||
|
store: Store
|
||||||
|
replication: Replication
|
||||||
|
transaction: Transaction
|
||||||
|
openingTransaction: XstoreTransaction
|
||||||
|
closingTransaction: XstoreTransaction
|
||||||
|
saleTransaction: XstoreTransaction
|
||||||
|
xstoreVersion: string
|
||||||
|
xstoreVersionDate: string
|
||||||
|
xstoreVersionCustomer: string
|
||||||
|
}
|
||||||
|
|
@ -9,4 +9,12 @@ export default [
|
||||||
to: { name: 'store-list' },
|
to: { name: 'store-list' },
|
||||||
icon: { icon: 'tabler-file' },
|
icon: { icon: 'tabler-file' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Obi',
|
||||||
|
icon: { icon: 'tabler-file' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Dotsoft',
|
||||||
|
icon: { icon: 'tabler-file' },
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,12 @@ export default [
|
||||||
to: { name: 'store-list' },
|
to: { name: 'store-list' },
|
||||||
icon: { icon: 'tabler-file' },
|
icon: { icon: 'tabler-file' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Obi',
|
||||||
|
icon: { icon: 'tabler-file' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Dotsoft',
|
||||||
|
icon: { icon: 'tabler-file' },
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,11 @@
|
||||||
<div>
|
<div>
|
||||||
<VCard
|
<VCard
|
||||||
class="mb-6"
|
class="mb-6"
|
||||||
title="Kick start your project 🚀"
|
title="XSTORE HELPDESK DASHBOARD 🚀"
|
||||||
>
|
>
|
||||||
<VCardText>All the best for your new project.</VCardText>
|
<VCardText>A cet endroit bientôt des statistiques</VCardText>
|
||||||
<VCardText>
|
|
||||||
Please make sure to read our <a
|
|
||||||
href="https://demos.pixinvent.com/vuexy-vuejs-admin-template/documentation/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
class="text-decoration-none"
|
|
||||||
>
|
|
||||||
Template Documentation
|
|
||||||
</a> to understand where to go from here and how to use our template.
|
|
||||||
</VCardText>
|
|
||||||
</VCard>
|
|
||||||
|
|
||||||
<VCard title="Want to integrate JWT? 🔒">
|
<VCardText>👉 Cliquez maintenant sur Boutique :)</VCardText>
|
||||||
<VCardText>We carefully crafted JWT flow so you can implement JWT with ease and with minimum efforts.</VCardText>
|
|
||||||
<VCardText>Please read our JWT Documentation to get more out of JWT authentication.</VCardText>
|
|
||||||
</VCard>
|
</VCard>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ import StoreHeader from '@/views/pages/store/view/StoreHeader.vue'
|
||||||
import StoreTabAdmin from '@/views/pages/store/view/StoreTabAdmin.vue'
|
import StoreTabAdmin from '@/views/pages/store/view/StoreTabAdmin.vue'
|
||||||
import StoreTabGeneral from '@/views/pages/store/view/StoreTabGeneral.vue'
|
import StoreTabGeneral from '@/views/pages/store/view/StoreTabGeneral.vue'
|
||||||
import StoreTabItem from '@/views/pages/store/view/StoreTabItem.vue'
|
import StoreTabItem from '@/views/pages/store/view/StoreTabItem.vue'
|
||||||
|
import StoreTabRemote from '@/views/pages/store/view/StoreTabRemote.vue'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
const route = useRoute('store-details')
|
const route = useRoute('store-details')
|
||||||
|
|
||||||
|
|
@ -12,9 +15,10 @@ console.log(route.query.dbHost)
|
||||||
|
|
||||||
// tabs
|
// tabs
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ title: 'General', icon: 'tabler-users', tab: 'general' },
|
{ title: 'General', icon: 'tabler-settings', tab: 'general' },
|
||||||
{ title: 'Item', icon: 'tabler-lock', tab: 'item' },
|
{ title: t('Item'), icon: 'tabler-shirt-sport', tab: 'item' },
|
||||||
{ title: 'Admin', icon: 'tabler-file-text', tab: 'admin' },
|
{ title: t('Remote'), icon: 'tabler-brand-openvpn', tab: 'remote' },
|
||||||
|
{ title: 'Admin', icon: 'tabler-lock', tab: 'admin' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const { data: storeData } = await useApi<any>(`/stores/${route.query.storeId}/details?dbHost=${route.query.dbHost}`)
|
const { data: storeData } = await useApi<any>(`/stores/${route.query.storeId}/details?dbHost=${route.query.dbHost}`)
|
||||||
|
|
@ -49,19 +53,24 @@ const { data: storeData } = await useApi<any>(`/stores/${route.query.storeId}/de
|
||||||
class="mt-6 disable-tab-transition"
|
class="mt-6 disable-tab-transition"
|
||||||
:touch="false"
|
:touch="false"
|
||||||
>
|
>
|
||||||
<!-- General -->
|
<!-- 👉 General -->
|
||||||
<VWindowItem>
|
<VWindowItem>
|
||||||
<StoreTabGeneral :store-data="storeData" />
|
<StoreTabGeneral :store-data="storeData" />
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
|
|
||||||
<!-- item -->
|
<!-- 👉 Item -->
|
||||||
<VWindowItem>
|
<VWindowItem>
|
||||||
<StoreTabItem />
|
<StoreTabItem />
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
|
|
||||||
<!-- admin -->
|
<!-- 👉 Remote Access -->
|
||||||
<VWindowItem>
|
<VWindowItem>
|
||||||
<StoreTabAdmin />
|
<StoreTabRemote :store-data="storeData" />
|
||||||
|
</VWindowItem>
|
||||||
|
|
||||||
|
<!-- 👉 Admin -->
|
||||||
|
<VWindowItem>
|
||||||
|
<StoreTabAdmin :store-data="storeData" />
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
</VWindow>
|
</VWindow>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ const headers = computed(() => [
|
||||||
{ title: t('Phone'), key: 'telephone', sortable: false },
|
{ title: t('Phone'), key: 'telephone', sortable: false },
|
||||||
{ title: t('Brand'), key: 'enseigne' },
|
{ title: t('Brand'), key: 'enseigne' },
|
||||||
{ title: t('Country'), key: 'pays' },
|
{ title: t('Country'), key: 'pays' },
|
||||||
|
{ title: '', key: 'actions', sortable: false },
|
||||||
])
|
])
|
||||||
|
|
||||||
const selectedCountry = ref()
|
const selectedCountry = ref()
|
||||||
|
|
@ -75,6 +76,23 @@ const filteredStoresList = computed(() => {
|
||||||
|
|
||||||
return filtered
|
return filtered
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const selectedStore = ref(null)
|
||||||
|
const isDialogVisible = ref(false)
|
||||||
|
|
||||||
|
const openPosList = (store: any) => {
|
||||||
|
selectedStore.value = store
|
||||||
|
isDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Store {
|
||||||
|
id_structure: number
|
||||||
|
caisses: Caisse[]
|
||||||
|
}
|
||||||
|
interface Caisse {
|
||||||
|
id_caisse: number
|
||||||
|
ip: string
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -166,18 +184,81 @@ const filteredStoresList = computed(() => {
|
||||||
:page="options.page"
|
:page="options.page"
|
||||||
:options="options"
|
:options="options"
|
||||||
>
|
>
|
||||||
|
<!-- Store details hyperlink -->
|
||||||
<template #item.nom="{ item }">
|
<template #item.nom="{ item }">
|
||||||
<RouterLink :to="`/store/details?dbHost=${item.ip_master}&storeId=${item.id_structure}`">
|
<RouterLink :to="`/store/details?dbHost=${item.ip_master}&storeId=${item.id_structure}`">
|
||||||
{{ item.nom }}
|
{{ item.nom }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Pos count -->
|
||||||
<template #item.nbcaisses="{ item }">
|
<template #item.nbcaisses="{ item }">
|
||||||
<VIcon v-if="item.nbcaisses > 1 && item.nbcaisses <= 9">
|
<VIcon v-if="item.nbcaisses > 1 && item.nbcaisses <= 9">
|
||||||
{{ `tabler-square-rounded-number-${item.nbcaisses}` }}
|
{{ `tabler-square-rounded-number-${item.nbcaisses}` }}
|
||||||
</VIcon>
|
</VIcon>
|
||||||
<span v-else-if="item.nbcaisses > 9">{{ item.nbcaisses }}</span>
|
<span v-else-if="item.nbcaisses > 9">{{ item.nbcaisses }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Actions -->
|
||||||
|
<template #item.actions="{ item }">
|
||||||
|
<IconBtn>
|
||||||
|
<VIcon icon="tabler-dots-vertical" />
|
||||||
|
<VMenu activator="parent">
|
||||||
|
<VList>
|
||||||
|
<VListItem
|
||||||
|
value="connect"
|
||||||
|
prepend-icon="tabler-numbers"
|
||||||
|
@click="openPosList(item)"
|
||||||
|
>
|
||||||
|
POS
|
||||||
|
</VListItem>
|
||||||
|
</VList>
|
||||||
|
</VMenu>
|
||||||
|
</IconBtn>
|
||||||
|
</template>
|
||||||
</VDataTable>
|
</VDataTable>
|
||||||
|
|
||||||
|
<VDialog
|
||||||
|
v-model="isDialogVisible"
|
||||||
|
max-width="600"
|
||||||
|
>
|
||||||
|
<!-- Dialog close btn -->
|
||||||
|
<DialogCloseBtn @click="isDialogVisible = !isDialogVisible" />
|
||||||
|
|
||||||
|
<!-- Dialog Content -->
|
||||||
|
<VCard title="Connect to invidual POS">
|
||||||
|
<VCardText>
|
||||||
|
<div v-if="selectedStore && (selectedStore as Store).caisses">
|
||||||
|
<div
|
||||||
|
v-for="(caisse, index) in (selectedStore as Store).caisses"
|
||||||
|
:key="index"
|
||||||
|
class="d-flex align-items-center mb-5"
|
||||||
|
>
|
||||||
|
<VTextField
|
||||||
|
v-model="caisse.ip"
|
||||||
|
label="IP"
|
||||||
|
class="me-3"
|
||||||
|
/>
|
||||||
|
<VBtn
|
||||||
|
:to="`/store/details?dbHost=${caisse.ip}&storeId=${(selectedStore as Store).id_structure}&workstationId=${caisse.id_caisse}`"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Pos {{ caisse.id_caisse }}
|
||||||
|
</VBtn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VCardText>
|
||||||
|
<VCardText class="d-flex justify-end flex-wrap gap-3">
|
||||||
|
<VBtn
|
||||||
|
variant="tonal"
|
||||||
|
color="secondary"
|
||||||
|
@click="isDialogVisible = false"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</VBtn>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VDialog>
|
||||||
</VCol>
|
</VCol>
|
||||||
</vcard>
|
</vcard>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,31 @@
|
||||||
"Search": "بحث",
|
"Search": "بحث",
|
||||||
"Name": "الاسم",
|
"Name": "الاسم",
|
||||||
"Phone": "هاتف",
|
"Phone": "هاتف",
|
||||||
|
"Mode": "الوضع",
|
||||||
|
"Value": "القيمة",
|
||||||
|
"Item": "العنصر",
|
||||||
|
"Remote": "متصل",
|
||||||
|
"Option": "خيار",
|
||||||
|
"Stock": "المخزون",
|
||||||
|
"Price": "السعر",
|
||||||
|
"ITEM_ID": "ID العنصر",
|
||||||
|
"PRICE": "السعر",
|
||||||
|
"TYPE": "TYPE",
|
||||||
|
"PARENT": "PARENT",
|
||||||
|
"LEVEL": "LEVEL",
|
||||||
|
"EFFECTIVE DATE": "EFFECTIVE DATE",
|
||||||
|
"EXPIRATION DATE": "EXPIRATION DATE",
|
||||||
|
"DATE_CREATE": "CREATE DATE",
|
||||||
|
"USER_CREATE": "CREATE USER",
|
||||||
|
"DATE_UPDATE": "UPDATE DATE",
|
||||||
|
"USER_UPDATE": "UPDATE USER",
|
||||||
|
"Reload": "تحديث",
|
||||||
|
"WorkStation": "القطعة العملية",
|
||||||
|
"SignatureString": "Signature string",
|
||||||
|
"SignatureSource": "Signature source",
|
||||||
|
"Submit": "Submit",
|
||||||
|
"You can search for a reference, reference-color or reference-color-size.": "You can search for a reference, reference-color or reference-color-size.",
|
||||||
|
"Minimum 5 characters long": "Minimum 5 characters long",
|
||||||
"---------------------------": "---------------------------",
|
"---------------------------": "---------------------------",
|
||||||
"UI Elements": "عناصر واجهة المستخدم",
|
"UI Elements": "عناصر واجهة المستخدم",
|
||||||
"Forms & Tables": "النماذج والجداول",
|
"Forms & Tables": "النماذج والجداول",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,31 @@
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
"Phone": "Phone",
|
"Phone": "Phone",
|
||||||
|
"Mode": "Mode",
|
||||||
|
"Value": "Value",
|
||||||
|
"Item": "Item",
|
||||||
|
"Remote": "Remote",
|
||||||
|
"Option": "Option",
|
||||||
|
"Stock": "Stock",
|
||||||
|
"Price": "Price",
|
||||||
|
"ITEM_ID": "ITEM ID",
|
||||||
|
"PRICE": "PRICE",
|
||||||
|
"TYPE": "TYPE",
|
||||||
|
"PARENT": "PARENT",
|
||||||
|
"LEVEL": "LEVEL",
|
||||||
|
"EFFECTIVE DATE": "EFFECTIVE DATE",
|
||||||
|
"EXPIRATION DATE": "EXPIRATION DATE",
|
||||||
|
"DATE_CREATE": "CREATE DATE",
|
||||||
|
"USER_CREATE": "CREATE USER",
|
||||||
|
"DATE_UPDATE": "UPDATE DATE",
|
||||||
|
"USER_UPDATE": "UPDATE USER",
|
||||||
|
"Reload": "Reload",
|
||||||
|
"WorkStation": "Workstation",
|
||||||
|
"SignatureString": "Signature string",
|
||||||
|
"SignatureSource": "Signature source",
|
||||||
|
"Submit": "Submit",
|
||||||
|
"You can search for a reference, reference-color or reference-color-size.": "You can search for a reference, reference-color or reference-color-size.",
|
||||||
|
"Minimum 5 characters long": "Minimum 5 characters long",
|
||||||
"---------------------------": "---------------------------",
|
"---------------------------": "---------------------------",
|
||||||
"UI Elements": "UI Elements",
|
"UI Elements": "UI Elements",
|
||||||
"Forms & Tables": "Forms & Tables",
|
"Forms & Tables": "Forms & Tables",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"Home": "Acceuil",
|
"Home": "Accueil",
|
||||||
"Store": "Boutique",
|
"Store": "Boutique",
|
||||||
"List of stores": "Liste des boutiques",
|
"List of stores": "Liste des boutiques",
|
||||||
"Country": "Pays",
|
"Country": "Pays",
|
||||||
|
|
@ -8,6 +8,31 @@
|
||||||
"Search": "Chercher",
|
"Search": "Chercher",
|
||||||
"Name": "Nom",
|
"Name": "Nom",
|
||||||
"Phone": "Téléphone",
|
"Phone": "Téléphone",
|
||||||
|
"Mode": "Mode",
|
||||||
|
"Value": "Valeur",
|
||||||
|
"Item": "Article",
|
||||||
|
"Remote": "Accès distant",
|
||||||
|
"Option": "Option",
|
||||||
|
"Stock": "Stock",
|
||||||
|
"Price": "Prix",
|
||||||
|
"ITEM_ID": "ITEM ID",
|
||||||
|
"PRICE": "PRIX",
|
||||||
|
"TYPE": "TYPE",
|
||||||
|
"PARENT": "PARENT",
|
||||||
|
"LEVEL": "NIVEAU",
|
||||||
|
"EFFECTIVE DATE": "DATE EFFECTIVE",
|
||||||
|
"EXPIRATION DATE": "DATE EXPIRATION",
|
||||||
|
"DATE_CREATE": "DATE CREATION",
|
||||||
|
"USER_CREATE": "UTIL. CREATION",
|
||||||
|
"DATE_UPDATE": "DATE MAJ",
|
||||||
|
"USER_UPDATE": "UTIL. MAJ",
|
||||||
|
"Reload": "Rafraichir",
|
||||||
|
"WorkStation": "Caisse",
|
||||||
|
"SignatureString": "Chaine de Signature",
|
||||||
|
"SignatureSource": "Signature source",
|
||||||
|
"Submit": "Valider",
|
||||||
|
"You can search for a reference, reference-color or reference-color-size.": "Vous pouvez chercher une reference, reference-couleur ou reference-couleur-taille.",
|
||||||
|
"Minimum 5 characters long": "Minimum 5 caractères",
|
||||||
"---------------------------": "---------------------------",
|
"---------------------------": "---------------------------",
|
||||||
"UI Elements": "ÉLÉMENTS DE L'UI",
|
"UI Elements": "ÉLÉMENTS DE L'UI",
|
||||||
"Forms & Tables": "Formulaires et tableaux",
|
"Forms & Tables": "Formulaires et tableaux",
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { StoreData } from '@/models/storeData'
|
||||||
import UserProfileHeaderBg from '@images/pages/user-profile-header-bg.png'
|
import UserProfileHeaderBg from '@images/pages/user-profile-header-bg.png'
|
||||||
|
|
||||||
interface Store {
|
|
||||||
id_structure: number
|
|
||||||
nom: string
|
|
||||||
ip: string
|
|
||||||
telephone: string
|
|
||||||
photoLink: string
|
|
||||||
enseigne: string
|
|
||||||
adresse: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StoreHeaderData {
|
|
||||||
store: Store
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
storeData: StoreHeaderData
|
storeData: StoreData
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
|
|
@ -42,7 +29,7 @@ const props = defineProps<Props>()
|
||||||
|
|
||||||
<div class="user-profile-info w-100 mt-16 pt-6 pt-sm-0 mt-sm-0">
|
<div class="user-profile-info w-100 mt-16 pt-6 pt-sm-0 mt-sm-0">
|
||||||
<h5 class="text-h5 text-center text-sm-start font-weight-medium mb-3">
|
<h5 class="text-h5 text-center text-sm-start font-weight-medium mb-3">
|
||||||
{{ props?.storeData.store.id_structure }} - {{ props?.storeData.store.nom }}
|
{{ props.storeData.store.id_structure }} - {{ props.storeData.store.nom }}
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<div class="d-flex align-center justify-center justify-sm-space-between flex-wrap gap-4">
|
<div class="d-flex align-center justify-center justify-sm-space-between flex-wrap gap-4">
|
||||||
|
|
@ -54,7 +41,7 @@ const props = defineProps<Props>()
|
||||||
class="me-1"
|
class="me-1"
|
||||||
/>
|
/>
|
||||||
<span class="text-body-1">
|
<span class="text-body-1">
|
||||||
{{ props?.storeData.store.enseigne }}
|
{{ props.storeData.store.enseigne }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
@ -65,7 +52,7 @@ const props = defineProps<Props>()
|
||||||
class="me-1"
|
class="me-1"
|
||||||
/>
|
/>
|
||||||
<span class="text-body-1">
|
<span class="text-body-1">
|
||||||
{{ props?.storeData.store.telephone }}
|
{{ props.storeData.store.telephone }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
@ -76,17 +63,27 @@ const props = defineProps<Props>()
|
||||||
class="me-1"
|
class="me-1"
|
||||||
/>
|
/>
|
||||||
<span class="text-body-1">
|
<span class="text-body-1">
|
||||||
{{ props?.storeData.store.adresse }}
|
{{ props.storeData.store.adresse }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<VBtn
|
<div class="d-flex align-center gap-4">
|
||||||
prepend-icon="tabler-check"
|
<VAvatar
|
||||||
color="success"
|
color="primary"
|
||||||
|
variant="tonal"
|
||||||
|
size="42"
|
||||||
>
|
>
|
||||||
Connected
|
<VIcon icon="tabler-git-merge" />
|
||||||
</VBtn>
|
</VAvatar>
|
||||||
|
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<span class="text-h5 font-weight-medium">{{ props.storeData.xstoreVersion }} ({{ props.storeData.xstoreVersionCustomer }})</span>
|
||||||
|
<span class="text-sm">
|
||||||
|
{{ props.storeData.xstoreVersionDate }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,21 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { StoreData } from '@/models/storeData'
|
||||||
|
import StoreTabAdminH from '@/views/pages/store/view/StoreTabAdminH.vue'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
storeData: StoreData
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<VCard title="STORE TAB ADMIN">
|
<VRow>
|
||||||
<VCardText>We carefully crafted JWT flow so you can implement JWT with ease and with minimum efforts.</VCardText>
|
<VCol cols="12">
|
||||||
<VCardText>Please read our JWT Documentation to get more out of JWT authentication.</VCardText>
|
<StoreTabAdminH :store-data="storeData" />
|
||||||
</VCard>
|
</VCol>
|
||||||
|
</VRow>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { StoreData } from '@/models/storeData'
|
||||||
|
import StoreTabAdminHsequence from '@/views/pages/store/view/StoreTabAdminHsequence.vue'
|
||||||
|
import StoreTabAdminHsignature from '@/views/pages/store/view/StoreTabAdminHsignature.vue'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
storeData: StoreData
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentTab = ref('tab-1')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VCard>
|
||||||
|
<VTabs
|
||||||
|
v-model="currentTab"
|
||||||
|
grow
|
||||||
|
stacked
|
||||||
|
>
|
||||||
|
<VTab>
|
||||||
|
<VIcon
|
||||||
|
start
|
||||||
|
icon="tabler-123"
|
||||||
|
/>
|
||||||
|
Sequence
|
||||||
|
</VTab>
|
||||||
|
|
||||||
|
<VTab>
|
||||||
|
<VIcon
|
||||||
|
start
|
||||||
|
icon="tabler-certificate"
|
||||||
|
/>
|
||||||
|
Signature
|
||||||
|
</VTab>
|
||||||
|
</VTabs>
|
||||||
|
|
||||||
|
<VCardText style="padding: 5px !important;">
|
||||||
|
<VWindow
|
||||||
|
v-model="currentTab"
|
||||||
|
class="ms-3"
|
||||||
|
>
|
||||||
|
<VWindowItem value="tab-1">
|
||||||
|
<StoreTabAdminHsequence :store-data="storeData" />
|
||||||
|
</VWindowItem>
|
||||||
|
<VWindowItem value="tab-2">
|
||||||
|
<StoreTabAdminHsignature :store-data="storeData" />
|
||||||
|
</VWindowItem>
|
||||||
|
</VWindow>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { VDataTable } from 'vuetify/labs/VDataTable'
|
||||||
|
import type { StoreData } from '@/models/storeData'
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const route = useRoute('store-details')
|
||||||
|
|
||||||
|
const headers = computed(() => [
|
||||||
|
{ title: 'WSK', key: 'wkstnId' },
|
||||||
|
{ title: t('Name'), key: 'sequenceId' },
|
||||||
|
{ title: t('Mode'), key: 'sequenceMode' },
|
||||||
|
{ title: t('Value'), key: 'sequenceNbr' },
|
||||||
|
{ title: t('DATE_CREATE'), key: 'createDate' },
|
||||||
|
{ title: t('USER_CREATE'), key: 'createUserId' },
|
||||||
|
{ title: t('DATE_UPDATE'), key: 'updateDate' },
|
||||||
|
{ title: t('USER_UPDATE'), key: 'updateUserId' },
|
||||||
|
])
|
||||||
|
|
||||||
|
const selectedWkStn = ref()
|
||||||
|
const selectedSequenceMode = ref()
|
||||||
|
const searchQuery = ref('')
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
storeData: StoreData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data table options
|
||||||
|
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
const data = ref([]) // Initialisez data comme un tableau vide
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
const response = await useApi<any>(createUrl(`/stores/${props.storeData.store.id_structure}/sequence?dbHost=${route.query.dbHost}`))
|
||||||
|
|
||||||
|
data.value = response.data.value
|
||||||
|
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const wkstn = computed(() => {
|
||||||
|
const allWkstns = data.value.map((store: { wkstnId: any }) => store.wkstnId)
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
const uniqueWkstns = allWkstns.filter((wkstn: any, index: any, self: string | any[]) => self.indexOf(wkstn) === index)
|
||||||
|
const sortedWkstns = uniqueWkstns.sort()
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
return sortedWkstns.map((wkstn: any) => ({ title: wkstn, value: wkstn }))
|
||||||
|
})
|
||||||
|
|
||||||
|
const seqmode = computed(() => {
|
||||||
|
const allSeqModes = data.value.map((store: { sequenceMode: any }) => store.sequenceMode)
|
||||||
|
|
||||||
|
const uniqueSeqModes = allSeqModes.filter((seqmod: any, index: any, self: string | any[]) => self.indexOf(seqmod) === index)
|
||||||
|
const sortedSeqModes = uniqueSeqModes.sort()
|
||||||
|
|
||||||
|
return sortedSeqModes.map((seqmod: any) => ({ title: seqmod, value: seqmod }))
|
||||||
|
})
|
||||||
|
|
||||||
|
const filteredSequenceList = computed(() => {
|
||||||
|
let filtered = data.value
|
||||||
|
|
||||||
|
// If a workstation is selected, filter the records for this number
|
||||||
|
if (selectedWkStn.value !== undefined && selectedWkStn.value !== null)
|
||||||
|
filtered = filtered.filter((store: { wkstnId: any }) => store.wkstnId === selectedWkStn.value)
|
||||||
|
|
||||||
|
// If a sequence mode is selected, filter the records for this mode
|
||||||
|
if (selectedSequenceMode.value !== undefined && selectedSequenceMode.value !== null)
|
||||||
|
filtered = filtered.filter((store: { sequenceMode: any }) => store.sequenceMode === selectedSequenceMode.value)
|
||||||
|
|
||||||
|
// If a search query is provided, filter the records for this query
|
||||||
|
if (searchQuery.value) {
|
||||||
|
filtered = filtered.filter((store: { [s: string]: unknown } | ArrayLike<unknown>) =>
|
||||||
|
Object.values(store).some(value =>
|
||||||
|
String(value).toLowerCase().includes(searchQuery.value.toLowerCase()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 👉 stores -->
|
||||||
|
<VCard class="mb-6">
|
||||||
|
<VCardText>
|
||||||
|
<VRow>
|
||||||
|
<!-- 👉 Select country -->
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
sm="4"
|
||||||
|
>
|
||||||
|
<AppSelect
|
||||||
|
v-model="selectedWkStn"
|
||||||
|
:placeholder="$t('WorkStation')"
|
||||||
|
:items="wkstn"
|
||||||
|
clearable
|
||||||
|
clear-icon="tabler-x"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
|
||||||
|
<!-- 👉 Select Brand -->
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
sm="4"
|
||||||
|
>
|
||||||
|
<AppSelect
|
||||||
|
v-model="selectedSequenceMode"
|
||||||
|
:placeholder="$t('Mode')"
|
||||||
|
:items="seqmode"
|
||||||
|
clearable
|
||||||
|
clear-icon="tabler-x"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardText>
|
||||||
|
|
||||||
|
<VDivider class="my-4" />
|
||||||
|
|
||||||
|
<div class="d-flex flex-wrap gap-4 mx-5">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<!-- 👉 Search -->
|
||||||
|
<AppTextField
|
||||||
|
v-model="searchQuery"
|
||||||
|
:placeholder="$t('Search')"
|
||||||
|
density="compact"
|
||||||
|
style="inline-size: 200px;"
|
||||||
|
class="me-3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<VSpacer />
|
||||||
|
<div class="d-flex gap-4 flex-wrap align-center">
|
||||||
|
<VBtn
|
||||||
|
color="primary"
|
||||||
|
prepend-icon="tabler-reload"
|
||||||
|
@click="fetchData"
|
||||||
|
>
|
||||||
|
{{ $t('Reload') }}
|
||||||
|
</VBtn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<VDivider class="mt-4" />
|
||||||
|
|
||||||
|
<VCol cols="12">
|
||||||
|
<div v-if="isLoading">
|
||||||
|
<VProgressCircular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 👉 Datatable -->
|
||||||
|
<VDataTable
|
||||||
|
v-else
|
||||||
|
:headers="headers"
|
||||||
|
:items="filteredSequenceList"
|
||||||
|
:items-per-page="options.itemsPerPage"
|
||||||
|
:page="options.page"
|
||||||
|
:options="options"
|
||||||
|
density="compact"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { VDataTable } from 'vuetify/labs/VDataTable'
|
||||||
|
import type { StoreData } from '@/models/storeData'
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const route = useRoute('store-details')
|
||||||
|
|
||||||
|
const headers = computed(() => [
|
||||||
|
{ title: 'WSK', key: 'wkstnId' },
|
||||||
|
{ title: t('Name'), key: 'signatureId' },
|
||||||
|
{ title: t('Mode'), key: 'signatureMode' },
|
||||||
|
{ title: t('SignatureString'), key: 'signatureString' },
|
||||||
|
{ title: t('SignatureSource'), key: 'signatureSource' },
|
||||||
|
{ title: t('DATE_CREATE'), key: 'createDate' },
|
||||||
|
{ title: t('USER_CREATE'), key: 'createUserId' },
|
||||||
|
{ title: t('DATE_UPDATE'), key: 'updateDate' },
|
||||||
|
{ title: t('USER_UPDATE'), key: 'updateUserId' },
|
||||||
|
])
|
||||||
|
|
||||||
|
const selectedWkStn = ref()
|
||||||
|
const selectedSignatureMode = ref()
|
||||||
|
const searchQuery = ref('')
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
storeData: StoreData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data table options
|
||||||
|
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
const data = ref([]) // Initialisez data comme un tableau vide
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
const response = await useApi<any>(createUrl(`/stores/${props.storeData.store.id_structure}/signature?dbHost=${route.query.dbHost}`))
|
||||||
|
|
||||||
|
data.value = response.data.value
|
||||||
|
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const wkstn = computed(() => {
|
||||||
|
const allWkstns = data.value.map((store: { wkstnId: any }) => store.wkstnId)
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
const uniqueWkstns = allWkstns.filter((wkstn: any, index: any, self: string | any[]) => self.indexOf(wkstn) === index)
|
||||||
|
const sortedWkstns = uniqueWkstns.sort()
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
return sortedWkstns.map((wkstn: any) => ({ title: wkstn, value: wkstn }))
|
||||||
|
})
|
||||||
|
|
||||||
|
const signmode = computed(() => {
|
||||||
|
const allSignModes = data.value.map((store: { signMode: any }) => store.signMode)
|
||||||
|
|
||||||
|
const uniqueSignMoeds = allSignModes.filter((signmod: any, index: any, self: string | any[]) => self.indexOf(signmod) === index)
|
||||||
|
const sortedSignMoeds = uniqueSignMoeds.sort()
|
||||||
|
|
||||||
|
return sortedSignMoeds.map((signmod: any) => ({ title: signmod, value: signmod }))
|
||||||
|
})
|
||||||
|
|
||||||
|
const filteredSigantureList = computed(() => {
|
||||||
|
let filtered = data.value
|
||||||
|
|
||||||
|
// If a workstation is selected, filter the records for this number
|
||||||
|
if (selectedWkStn.value !== undefined && selectedWkStn.value !== null)
|
||||||
|
filtered = filtered.filter((store: { wkstnId: any }) => store.wkstnId === selectedWkStn.value)
|
||||||
|
|
||||||
|
// If a signature mode is selected, filter the records for this mode
|
||||||
|
if (selectedSignatureMode.value !== undefined && selectedSignatureMode.value !== null)
|
||||||
|
filtered = filtered.filter((store: { signMode: any }) => store.signMode === selectedSignatureMode.value)
|
||||||
|
|
||||||
|
// If a search query is provided, filter the records for this query
|
||||||
|
if (searchQuery.value) {
|
||||||
|
filtered = filtered.filter((store: { [s: string]: unknown } | ArrayLike<unknown>) =>
|
||||||
|
Object.values(store).some(value =>
|
||||||
|
String(value).toLowerCase().includes(searchQuery.value.toLowerCase()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 👉 stores -->
|
||||||
|
<VCard class="mb-6">
|
||||||
|
<VCardText>
|
||||||
|
<VRow>
|
||||||
|
<!-- 👉 Select country -->
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
sm="4"
|
||||||
|
>
|
||||||
|
<AppSelect
|
||||||
|
v-model="selectedWkStn"
|
||||||
|
:placeholder="$t('WorkStation')"
|
||||||
|
:items="wkstn"
|
||||||
|
clearable
|
||||||
|
clear-icon="tabler-x"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
|
||||||
|
<!-- 👉 Select Brand -->
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
sm="4"
|
||||||
|
>
|
||||||
|
<AppSelect
|
||||||
|
v-model="selectedSignatureMode"
|
||||||
|
:placeholder="$t('Mode')"
|
||||||
|
:items="signmode"
|
||||||
|
clearable
|
||||||
|
clear-icon="tabler-x"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardText>
|
||||||
|
|
||||||
|
<VDivider class="my-4" />
|
||||||
|
|
||||||
|
<div class="d-flex flex-wrap gap-4 mx-5">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<!-- 👉 Search -->
|
||||||
|
<AppTextField
|
||||||
|
v-model="searchQuery"
|
||||||
|
:placeholder="$t('Search')"
|
||||||
|
density="compact"
|
||||||
|
style="inline-size: 200px;"
|
||||||
|
class="me-3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<VSpacer />
|
||||||
|
<div class="d-flex gap-4 flex-wrap align-center">
|
||||||
|
<VBtn
|
||||||
|
color="primary"
|
||||||
|
prepend-icon="tabler-reload"
|
||||||
|
@click="fetchData"
|
||||||
|
>
|
||||||
|
{{ $t('Reload') }}
|
||||||
|
</VBtn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<VDivider class="mt-4" />
|
||||||
|
|
||||||
|
<VCol cols="12">
|
||||||
|
<div v-if="isLoading">
|
||||||
|
<VProgressCircular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 👉 Datatable -->
|
||||||
|
<VDataTable
|
||||||
|
v-else
|
||||||
|
:headers="headers"
|
||||||
|
:items="filteredSigantureList"
|
||||||
|
:items-per-page="options.itemsPerPage"
|
||||||
|
:page="options.page"
|
||||||
|
:options="options"
|
||||||
|
density="compact"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -1,33 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
interface Store {
|
import type { StoreData } from '@/models/storeData'
|
||||||
id_structure: number
|
|
||||||
nom: string
|
|
||||||
ip: string
|
|
||||||
telephone: string
|
|
||||||
photoLink: string
|
|
||||||
enseigne: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Replication {
|
|
||||||
pendingReplicationOk: boolean
|
|
||||||
pendingReplications: number
|
|
||||||
minPendingReplicationDate: string
|
|
||||||
maxPendingReplicationDate: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Transaction {
|
|
||||||
backOfficeTransactionOk: boolean
|
|
||||||
backOfficeTransactions: number
|
|
||||||
minBackOfficeTransactionDate: string
|
|
||||||
maxBackOfficeTransactionDate: string
|
|
||||||
backOfficeBusinessDate: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StoreData {
|
|
||||||
store: Store
|
|
||||||
replication: Replication
|
|
||||||
transaction: Transaction
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
storeData: StoreData
|
storeData: StoreData
|
||||||
|
|
@ -37,14 +9,185 @@ const props = defineProps<Props>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 👉 User fullName -->
|
<VRow class="py-6">
|
||||||
<h6 class="text-h4 mt-4">
|
<!-- 👉 Business date & opening hours -->
|
||||||
{{ props.storeData.store.id_structure }}
|
<VCol
|
||||||
</h6>
|
cols="12"
|
||||||
|
md="3"
|
||||||
|
:class="$vuetify.display.mdAndUp ? 'border-e' : 'border-b'"
|
||||||
|
>
|
||||||
|
<div class="ape-3">
|
||||||
|
<div class="d-flex justify-space-between flex-wrap gap-4 flex-column flex-xs-row">
|
||||||
<div>
|
<div>
|
||||||
<VCard title="STORE TAB GENERAL">
|
<div class="d-flex mb-4">
|
||||||
<VCardText>We carefully crafted JWT flow so you can implement JWT with ease and with minimum efforts.</VCardText>
|
<VAvatar
|
||||||
<VCardText>Please read our JWT Documentation to get more out of JWT authentication.</VCardText>
|
variant="tonal"
|
||||||
</VCard>
|
color="primary"
|
||||||
|
rounded
|
||||||
|
size="54"
|
||||||
|
class="text-primary me-4"
|
||||||
|
>
|
||||||
|
<VIcon
|
||||||
|
icon="tabler-calendar-event"
|
||||||
|
size="38"
|
||||||
|
/>
|
||||||
|
</VAvatar>
|
||||||
|
<div>
|
||||||
|
<span class="text-base">Business date</span>
|
||||||
|
<h4 class="text-h4 font-weight-medium text-primary">
|
||||||
|
{{ storeData.openingTransaction.maxDateT }}
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex">
|
||||||
|
<VAvatar
|
||||||
|
variant="tonal"
|
||||||
|
color="info"
|
||||||
|
rounded
|
||||||
|
size="54"
|
||||||
|
class="text-primary me-4"
|
||||||
|
>
|
||||||
|
<VIcon
|
||||||
|
icon="tabler-clock-hour-10"
|
||||||
|
size="38"
|
||||||
|
/>
|
||||||
|
</VAvatar>
|
||||||
|
<div>
|
||||||
|
<span class="text-base">Opening hours</span>
|
||||||
|
<h4 class="text-h4 font-weight-medium text-info">
|
||||||
|
{{ storeData.openingTransaction.maxDateH }}{{ storeData.closingTransaction.maxDateH ? ` / ${storeData.closingTransaction.maxDateH}` : '' }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VCol>
|
||||||
|
|
||||||
|
<!-- 👉 Pending Replication -->
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
md="3"
|
||||||
|
:class="$vuetify.display.mdAndUp ? 'border-e' : 'border-b'"
|
||||||
|
>
|
||||||
|
<div class="d-flex justify-space-between align-center">
|
||||||
|
<div class="d-flex flex-column ps-3">
|
||||||
|
<h5 class="text-h5 text-high-emphasis mb-0 text-no-wrap">
|
||||||
|
Pending replication
|
||||||
|
</h5>
|
||||||
|
<div class="text-h3 mb-2">
|
||||||
|
{{ props.storeData.replication.pendingReplications }}
|
||||||
|
</div>
|
||||||
|
<span class="mb-1">
|
||||||
|
<div>
|
||||||
|
<VChip
|
||||||
|
variant="tonal"
|
||||||
|
color="secondary"
|
||||||
|
style="inline-size:45px"
|
||||||
|
>
|
||||||
|
Min
|
||||||
|
</VChip>
|
||||||
|
{{ props.storeData.replication.minPendingReplicationDate }}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span class="mb-1">
|
||||||
|
<div>
|
||||||
|
<VChip
|
||||||
|
variant="tonal"
|
||||||
|
color="secondary"
|
||||||
|
style="inline-size:45px"
|
||||||
|
>
|
||||||
|
Max
|
||||||
|
</VChip>
|
||||||
|
{{ props.storeData.replication.maxPendingReplicationDate }}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VCol>
|
||||||
|
|
||||||
|
<!-- 👉 XSTORE Ticket -->
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
md="3"
|
||||||
|
:class="$vuetify.display.mdAndUp ? 'border-e' : 'border-b'"
|
||||||
|
>
|
||||||
|
<div class="d-flex justify-space-between align-center">
|
||||||
|
<div class="d-flex flex-column ps-3">
|
||||||
|
<h5 class="text-h5 text-high-emphasis mb-0 text-no-wrap">
|
||||||
|
XSTORE Tickets
|
||||||
|
</h5>
|
||||||
|
<div class="text-h3 mb-2">
|
||||||
|
{{ props.storeData.saleTransaction.count }}
|
||||||
|
</div>
|
||||||
|
<span class="mb-1">
|
||||||
|
<div>
|
||||||
|
<VChip
|
||||||
|
variant="tonal"
|
||||||
|
color="secondary"
|
||||||
|
style="inline-size:45px"
|
||||||
|
>
|
||||||
|
Min
|
||||||
|
</VChip>
|
||||||
|
{{ props.storeData.saleTransaction.minDate }}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span class="mb-1">
|
||||||
|
<div>
|
||||||
|
<VChip
|
||||||
|
variant="tonal"
|
||||||
|
color="secondary"
|
||||||
|
style="inline-size:45px"
|
||||||
|
>
|
||||||
|
Max
|
||||||
|
</VChip>
|
||||||
|
{{ props.storeData.saleTransaction.maxDate }}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VCol>
|
||||||
|
|
||||||
|
<!-- 👉 DOTSOFT Tickets -->
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
md="3"
|
||||||
|
>
|
||||||
|
<div class="d-flex justify-space-between align-center">
|
||||||
|
<div class="d-flex flex-column ps-3">
|
||||||
|
<h5 class="text-h5 text-high-emphasis mb-0 text-no-wrap">
|
||||||
|
DOTSOFT Tickets
|
||||||
|
</h5>
|
||||||
|
<div class="text-h3 mb-2">
|
||||||
|
{{ props.storeData.transaction.backOfficeTransactions }}
|
||||||
|
</div>
|
||||||
|
<span class="mb-1">
|
||||||
|
<div>
|
||||||
|
<VChip
|
||||||
|
variant="tonal"
|
||||||
|
color="secondary"
|
||||||
|
style="inline-size:45px"
|
||||||
|
>
|
||||||
|
Min
|
||||||
|
</VChip>
|
||||||
|
{{ props.storeData.transaction.minBackOfficeTransactionDate }}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span class="mb-1">
|
||||||
|
<div>
|
||||||
|
<VChip
|
||||||
|
variant="tonal"
|
||||||
|
color="secondary"
|
||||||
|
style="inline-size:45px"
|
||||||
|
>
|
||||||
|
Max
|
||||||
|
</VChip>
|
||||||
|
{{ props.storeData.transaction.maxBackOfficeTransactionDate }}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,84 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { provide, ref } from 'vue'
|
||||||
|
import { VForm } from 'vuetify/components/VForm'
|
||||||
|
import StoreTabItemH from '@/views/pages/store/view/StoreTabItemH.vue'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const itemForm = ref('')
|
||||||
|
const injItemForm = ref('')
|
||||||
|
const refItemForm = ref<VForm>()
|
||||||
|
|
||||||
|
provide('item', injItemForm)
|
||||||
|
|
||||||
|
const validateItemForm = () => {
|
||||||
|
refItemForm.value?.validate().then(valid => {
|
||||||
|
if (valid.valid) {
|
||||||
|
console.log(itemForm.value)
|
||||||
|
injItemForm.value = itemForm.value
|
||||||
|
}
|
||||||
|
else { console.log(`KO:${itemForm.value}`) }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const lengthMinValidator = (value: unknown, length: number) => {
|
||||||
|
if (isEmpty(value))
|
||||||
|
return true
|
||||||
|
|
||||||
|
return String(value).length >= length || `The Min Character field must be at least ${length} characters`
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<VCard title="STORE TAB ITEM">
|
<VRow>
|
||||||
<VCardText>We carefully crafted JWT flow so you can implement JWT with ease and with minimum efforts.</VCardText>
|
<VCol cols="12">
|
||||||
<VCardText>Please read our JWT Documentation to get more out of JWT authentication.</VCardText>
|
<!-- 👉 Item search -->
|
||||||
|
<VCard title="">
|
||||||
|
<VCardText>
|
||||||
|
<VAlert
|
||||||
|
variant="tonal"
|
||||||
|
color="warning"
|
||||||
|
class="mb-4"
|
||||||
|
>
|
||||||
|
<VAlertTitle class="mb-2">
|
||||||
|
{{ $t('You can search for a reference, reference-color or reference-color-size.') }}
|
||||||
|
</VAlertTitle>
|
||||||
|
<span>{{ $t('Minimum 5 characters long') }}</span>
|
||||||
|
</VAlert>
|
||||||
|
|
||||||
|
<VForm
|
||||||
|
ref="refItemForm"
|
||||||
|
@submit.prevent="validateItemForm"
|
||||||
|
>
|
||||||
|
<VRow>
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
md="6"
|
||||||
|
>
|
||||||
|
<AppTextField
|
||||||
|
v-model="itemForm"
|
||||||
|
label="Reference"
|
||||||
|
persistent-placeholder
|
||||||
|
placeholder="QY10010"
|
||||||
|
:rules="[requiredValidator, lengthMinValidator(itemForm, 5)]"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VBtn type="submit">
|
||||||
|
{{ $t('Submit') }}
|
||||||
|
</VBtn>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VForm>
|
||||||
|
</VCardText>
|
||||||
|
|
||||||
|
<VCol cols="12">
|
||||||
|
<StoreTabItemH />
|
||||||
|
</VCol>
|
||||||
</VCard>
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { inject } from 'vue'
|
||||||
|
import StoreTabItemHitem from '@/views/pages/store/view/StoreTabItemHitem.vue'
|
||||||
|
import StoreTabItemHoption from '@/views/pages/store/view/StoreTabItemHoption.vue'
|
||||||
|
import StoreTabItemHprice from '@/views/pages/store/view/StoreTabItemHprice.vue'
|
||||||
|
import StoreTabItemHstock from '@/views/pages/store/view/StoreTabItemHstock.vue'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const item = inject<string>('item')
|
||||||
|
|
||||||
|
const currentTab = ref('tab-1')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VCard>
|
||||||
|
<VTabs
|
||||||
|
v-model="currentTab"
|
||||||
|
grow
|
||||||
|
stacked
|
||||||
|
>
|
||||||
|
<VTab>
|
||||||
|
<VIcon
|
||||||
|
start
|
||||||
|
icon="tabler-shirt-sport"
|
||||||
|
/>
|
||||||
|
{{ $t('Item') }}
|
||||||
|
</VTab>
|
||||||
|
|
||||||
|
<VTab>
|
||||||
|
<VIcon
|
||||||
|
start
|
||||||
|
icon="tabler-report-money"
|
||||||
|
/>
|
||||||
|
{{ $t('Option') }}
|
||||||
|
</VTab>
|
||||||
|
|
||||||
|
<VTab>
|
||||||
|
<VIcon
|
||||||
|
start
|
||||||
|
icon="tabler-currency-euro"
|
||||||
|
/>
|
||||||
|
{{ $t('Price') }}
|
||||||
|
</VTab>
|
||||||
|
|
||||||
|
<VTab>
|
||||||
|
<VIcon
|
||||||
|
start
|
||||||
|
icon="tabler-building-warehouse"
|
||||||
|
/>
|
||||||
|
{{ $t('Stock') }}
|
||||||
|
</VTab>
|
||||||
|
</VTabs>
|
||||||
|
|
||||||
|
<VCardText style="padding: 5px !important;">
|
||||||
|
<VWindow
|
||||||
|
v-model="currentTab"
|
||||||
|
class="ms-3"
|
||||||
|
>
|
||||||
|
<VWindowItem value="tab-1">
|
||||||
|
<StoreTabItemHitem :item="item" />
|
||||||
|
</VWindowItem>
|
||||||
|
<VWindowItem value="tab-2">
|
||||||
|
<StoreTabItemHoption :item="item" />
|
||||||
|
</VWindowItem>
|
||||||
|
<VWindowItem value="tab-3">
|
||||||
|
<StoreTabItemHprice :item="item" />
|
||||||
|
</VWindowItem>
|
||||||
|
<VWindowItem value="tab-4">
|
||||||
|
<StoreTabItemHstock :item="item" />
|
||||||
|
</VWindowItem>
|
||||||
|
</VWindow>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { watchEffect } from 'vue'
|
||||||
|
import { VDataTable } from 'vuetify/labs/VDataTable'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const route = useRoute('store-details')
|
||||||
|
|
||||||
|
// Data table options
|
||||||
|
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
|
||||||
|
|
||||||
|
const fetchedData = ref<Array<Record<string, unknown>>>([])
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
const { data } = await useApi<any>(createUrl(`/items/${props.item}?dbHost=${route.query.dbHost}`))
|
||||||
|
|
||||||
|
fetchedData.value = data.value
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
// eslint-disable-next-line sonarjs/no-collapsible-if
|
||||||
|
if (props.item)
|
||||||
|
// eslint-disable-next-line curly
|
||||||
|
if (!(props.item.trim() === ''))
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// const { t } = useI18n()
|
||||||
|
|
||||||
|
const headers = computed(() => [
|
||||||
|
{ title: t('ITEM_ID'), key: 'itemId' },
|
||||||
|
{ title: t('LEVEL'), key: 'itemLevelCode' },
|
||||||
|
{ title: t('PARENT'), key: 'parentItemId' },
|
||||||
|
{ title: t('TYPE'), key: 'itemTypeCode' },
|
||||||
|
{ title: t('DATE_CREATE'), key: 'createDate' },
|
||||||
|
{ title: t('USER_CREATE'), key: 'createUserId' },
|
||||||
|
{ title: t('DATE_UPDATE'), key: 'updateDate' },
|
||||||
|
{ title: t('USER_UPDATE'), key: 'updateUserId' },
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<VCol>
|
||||||
|
<div v-if="isLoading">
|
||||||
|
<VProgressCircular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<VDataTable
|
||||||
|
v-else
|
||||||
|
:headers="headers"
|
||||||
|
:items="fetchedData"
|
||||||
|
:items-per-page="options.itemsPerPage"
|
||||||
|
:page="options.page"
|
||||||
|
:options="options"
|
||||||
|
density="compact"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { watchEffect } from 'vue'
|
||||||
|
import { VDataTable } from 'vuetify/labs/VDataTable'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const route = useRoute('store-details')
|
||||||
|
|
||||||
|
// Data table options
|
||||||
|
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
const fetchedData = ref<Array<Record<string, unknown>>>([])
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
const { data } = await useApi<any>(createUrl(`/items/${props.item}/options?dbHost=${route.query.dbHost}`))
|
||||||
|
|
||||||
|
fetchedData.value = data.value.map((item: any) => ({
|
||||||
|
...item,
|
||||||
|
level: `${item.levelCode}:${item.levelValue}`,
|
||||||
|
}))
|
||||||
|
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
// eslint-disable-next-line sonarjs/no-collapsible-if
|
||||||
|
if (props.item)
|
||||||
|
// eslint-disable-next-line curly
|
||||||
|
if (!(props.item.trim() === ''))
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// const { t } = useI18n()
|
||||||
|
|
||||||
|
const headers = computed(() => [
|
||||||
|
{ title: t('ITEM_ID'), key: 'itemId' },
|
||||||
|
{ title: 'LEVEL', key: 'level' },
|
||||||
|
{ title: 'VENDABLE', key: 'itemAvailabilityCode' },
|
||||||
|
{ title: 'TAXE', key: 'taxGroupId' },
|
||||||
|
{ title: 'VENDOR', key: 'vendor' },
|
||||||
|
{ title: 'SEASON', key: 'seasonCode' },
|
||||||
|
{ title: t('DATE_CREATE'), key: 'createDate' },
|
||||||
|
{ title: t('USER_CREATE'), key: 'createUserId' },
|
||||||
|
{ title: t('DATE_UPDATE'), key: 'updateDate' },
|
||||||
|
{ title: t('USER_UPDATE'), key: 'updateUserId' },
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<VCol>
|
||||||
|
<div v-if="isLoading">
|
||||||
|
<VProgressCircular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 👉 Datatable -->
|
||||||
|
<VDataTable
|
||||||
|
v-else
|
||||||
|
:headers="headers"
|
||||||
|
:items="fetchedData"
|
||||||
|
:items-per-page="options.itemsPerPage"
|
||||||
|
:page="options.page"
|
||||||
|
:options="options"
|
||||||
|
density="compact"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { watchEffect } from 'vue'
|
||||||
|
import { VDataTable } from 'vuetify/labs/VDataTable'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const route = useRoute('store-details')
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
// Data table options
|
||||||
|
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
|
||||||
|
|
||||||
|
const fetchedData = ref<Array<Record<string, unknown>>>([])
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
const { data } = await useApi<any>(createUrl(`/items/${props.item}/price?dbHost=${route.query.dbHost}`))
|
||||||
|
|
||||||
|
fetchedData.value = data.value.map((item: any) => ({
|
||||||
|
...item,
|
||||||
|
level: `${item.levelCode}:${item.levelValue}`,
|
||||||
|
}))
|
||||||
|
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
// eslint-disable-next-line sonarjs/no-collapsible-if
|
||||||
|
if (props.item)
|
||||||
|
// eslint-disable-next-line curly
|
||||||
|
if (!(props.item.trim() === ''))
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// const { t } = useI18n()
|
||||||
|
|
||||||
|
const headers = computed(() => [
|
||||||
|
{ title: t('ITEM_ID'), key: 'itemId' },
|
||||||
|
{ title: t('LEVEL'), key: 'level' },
|
||||||
|
{ title: t('TYPE'), key: 'itmPricePropertyCode' },
|
||||||
|
{ title: t('EFFECTIVE DATE'), key: 'effectiveDate' },
|
||||||
|
{ title: t('EXPIRATION DATE'), key: 'expirationDate' },
|
||||||
|
{ title: t('PRICE'), key: 'price' },
|
||||||
|
{ title: 'EXTERNAL ID', key: 'externalId' },
|
||||||
|
{ title: t('DATE_CREATE'), key: 'createDate' },
|
||||||
|
{ title: t('USER_CREATE'), key: 'createUserId' },
|
||||||
|
{ title: t('DATE_UPDATE'), key: 'updateDate' },
|
||||||
|
{ title: t('USER_UPDATE'), key: 'updateUserId' },
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<VCol>
|
||||||
|
<div v-if="isLoading">
|
||||||
|
<VProgressCircular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<VDataTable
|
||||||
|
v-else
|
||||||
|
:headers="headers"
|
||||||
|
:items="fetchedData"
|
||||||
|
:items-per-page="options.itemsPerPage"
|
||||||
|
:page="options.page"
|
||||||
|
:options="options"
|
||||||
|
density="compact"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { watchEffect } from 'vue'
|
||||||
|
import { VDataTable } from 'vuetify/labs/VDataTable'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const route = useRoute('store-details')
|
||||||
|
|
||||||
|
// Data table options
|
||||||
|
const options = ref({ page: 1, itemsPerPage: 10, sortBy: [''], sortDesc: [false] })
|
||||||
|
|
||||||
|
const fetchedData = ref<Array<Record<string, unknown>>>([])
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
const { data } = await useApi<any>(createUrl(`/items/${props.item}/stock?dbHost=${route.query.dbHost}`))
|
||||||
|
|
||||||
|
fetchedData.value = data.value
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
// eslint-disable-next-line sonarjs/no-collapsible-if
|
||||||
|
if (props.item)
|
||||||
|
// eslint-disable-next-line curly
|
||||||
|
if (!(props.item.trim() === ''))
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// const { t } = useI18n()
|
||||||
|
|
||||||
|
const headers = computed(() => [
|
||||||
|
{ title: t('ITEM_ID'), key: 'itemId' },
|
||||||
|
{ title: 'LOCATION', key: 'invLocationId' },
|
||||||
|
{ title: 'BUCKET', key: 'bucketId' },
|
||||||
|
{ title: 'STOCK', key: 'unitCount' },
|
||||||
|
{ title: t('DATE_CREATE'), key: 'createDate' },
|
||||||
|
{ title: t('USER_CREATE'), key: 'createUserId' },
|
||||||
|
{ title: t('DATE_UPDATE'), key: 'updateDate' },
|
||||||
|
{ title: t('USER_UPDATE'), key: 'updateUserId' },
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<VCol>
|
||||||
|
<div v-if="isLoading">
|
||||||
|
<VProgressCircular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<VDataTable
|
||||||
|
v-else
|
||||||
|
:headers="headers"
|
||||||
|
:items="fetchedData"
|
||||||
|
:items-per-page="options.itemsPerPage"
|
||||||
|
:page="options.page"
|
||||||
|
:options="options"
|
||||||
|
density="compact"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import type { StoreData } from '@/models/storeData'
|
||||||
|
import logoVNC from '@images/misc/remote_128.png'
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const drive = ['M:', 'N:', 'O:', 'P:', 'Q:', 'R:', 'S:', 'T:']
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
storeData: StoreData
|
||||||
|
}
|
||||||
|
|
||||||
|
const localStoreData = ref()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// use copy a store data to prevent changes of ip field
|
||||||
|
localStoreData.value = JSON.parse(JSON.stringify(props.storeData))
|
||||||
|
localStoreData.value.store.caisses = localStoreData.value.store.caisses.map((caisse: any) => ({
|
||||||
|
...caisse,
|
||||||
|
drive: null, // replace null with the initial value you want to use
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
const openVnc = (ip: string) => {
|
||||||
|
const url = `vnc://${ip}`
|
||||||
|
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
const mountDrive = (ip: string, drive: string) => {
|
||||||
|
const url = `hdpos://monter?lettre=${drive}&ip=${ip}`
|
||||||
|
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VRow>
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
md="6"
|
||||||
|
>
|
||||||
|
<VCard
|
||||||
|
flat
|
||||||
|
border
|
||||||
|
>
|
||||||
|
<VCardText class="text-center">
|
||||||
|
<img
|
||||||
|
:src="logoVNC"
|
||||||
|
size="128"
|
||||||
|
>
|
||||||
|
<div v-if="localStoreData && localStoreData.store.caisses">
|
||||||
|
<div
|
||||||
|
v-for="(caisse, index) in localStoreData.store.caisses"
|
||||||
|
:key="index"
|
||||||
|
class="d-flex align-items-center mb-5"
|
||||||
|
>
|
||||||
|
<VRow>
|
||||||
|
<VCol
|
||||||
|
cols="6"
|
||||||
|
md="6"
|
||||||
|
class="d-flex align-items-center"
|
||||||
|
>
|
||||||
|
<VTextField
|
||||||
|
v-model.lazy="caisse.ip"
|
||||||
|
label="IP"
|
||||||
|
class="me-3"
|
||||||
|
/>
|
||||||
|
<VBtn
|
||||||
|
v-if="caisse.ip"
|
||||||
|
color="primary"
|
||||||
|
@click="openVnc(caisse.ip)"
|
||||||
|
>
|
||||||
|
Pos {{ caisse.id_caisse }}
|
||||||
|
</VBtn>
|
||||||
|
<VBtn
|
||||||
|
v-else
|
||||||
|
disabled
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Pos {{ caisse.id_caisse }}
|
||||||
|
</VBtn>
|
||||||
|
</VCol>
|
||||||
|
|
||||||
|
<VCol
|
||||||
|
cols="12"
|
||||||
|
md="6"
|
||||||
|
class="d-flex align-items-center"
|
||||||
|
>
|
||||||
|
<AppSelect
|
||||||
|
v-model="caisse.drive"
|
||||||
|
:items="drive"
|
||||||
|
label=""
|
||||||
|
density="compact"
|
||||||
|
placeholder="Select"
|
||||||
|
class="me-3"
|
||||||
|
/>
|
||||||
|
<VBtn
|
||||||
|
v-if="caisse.drive"
|
||||||
|
color="primary"
|
||||||
|
@click="mountDrive(caisse.ip, caisse.drive)"
|
||||||
|
>
|
||||||
|
Mount drive {{ caisse.drive }}
|
||||||
|
</VBtn>
|
||||||
|
<VBtn
|
||||||
|
v-else
|
||||||
|
disabled
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Mount drive
|
||||||
|
</VBtn>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</template>
|
||||||