Skip to content

Commit 5808f95

Browse files
committed
Refactor identity state fetching and enhance badge functionality
1 parent 69c2f13 commit 5808f95

File tree

13 files changed

+241
-206
lines changed

13 files changed

+241
-206
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"moment": "^2.30.1",
3434
"openapi-fetch": "^0.8.2",
3535
"pinia": "^2.1.7",
36+
"qs": "^6.14.0",
3637
"quasar": "^2.15.4",
3738
"radash": "^12.1.0",
3839
"reconnecting-eventsource": "^1.6.2",

src/components/appbar/RightButtons.vue

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ div
2323
</template>
2424

2525
<script lang="ts" setup>
26-
import { useIdentityStateStore } from "~/stores/identityState"
27-
import {ref} from "vue";
28-
let settings=ref(false)
26+
import { useIdentityStateStore } from '~/stores/identityState'
27+
import { ref } from 'vue'
28+
let settings = ref(false)
2929
3030
const identityStateStore = useIdentityStateStore()
3131
@@ -55,8 +55,8 @@ const buttons = [
5555
]
5656
5757
const emits = defineEmits(['syncing'])
58-
function displaySettings(){
59-
settings.value=true
58+
function displaySettings() {
59+
settings.value = true
6060
}
6161
async function syncAll() {
6262
emits('syncing', { count: badgesValues.value.TO_SYNC })
@@ -66,8 +66,7 @@ async function syncAll() {
6666
async: true,
6767
},
6868
})
69-
await identityStateStore.fetchToSyncCount()
70-
await identityStateStore.fetchSyncedCount()
69+
await identityStateStore.fetchAllStateCount()
7170
}
7271
7372
async function toggleDebug() {
@@ -81,5 +80,4 @@ async function toggleDebug() {
8180
query,
8281
})
8382
}
84-
8583
</script>

src/components/jsonFormRendererApi.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ const validations = defineModel('validations', {
6767
6868
const createTranslator = (locale) => (key: string, defaultMessage: string | undefined, context: { error: ErrorObject }) => {
6969
const regex = /^(?!.*\s)([a-zA-Z0-9_-]+)(\.[a-zA-Z0-9_-]+)*$/
70-
if (regex.test(key) || defaultMessage) {
70+
if (regex.test(key) || defaultMessage || !context.error.schema) {
7171
return defaultMessage
7272
}
7373
74+
console.debug('Translating', key, 'with context', context)
75+
7476
const err = [context.error]
7577
localize[locale](err)
7678
@@ -98,6 +100,8 @@ const data = defineModel('data', {
98100
function onChange(event: JsonFormsChangeEvent) {
99101
data.value = event.data
100102
103+
console.log('onChange', event)
104+
101105
if (!event.data) {
102106
console.error('error', event.errors)
103107
throw createError({

src/composables/useIdentityStates.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import { omit } from "radash";
2+
13
type useIdentityStateReturnType = {
24
getStateColor: (state: number) => string;
35
getStateName: (state: number) => string;
46
getStateInfos: (state: number) => { color: string, name: string, value: number };
7+
getStateBadge: (state: number) => { color: string, name: string };
58
};
69

710
export enum IdentityState {
@@ -57,6 +60,10 @@ export function useIdentityStates(): useIdentityStateReturnType {
5760
};
5861
}
5962

60-
return { getStateColor, getStateName, getStateInfos };
63+
function getStateBadge(state: number): { color: string, name: string, icon: string } {
64+
return omit(getStateInfos(state), ['value']);
65+
}
66+
67+
return { getStateColor, getStateName, getStateInfos, getStateBadge };
6168
}
6269

src/composables/useMenu.ts

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { useIdentityAffectationStore } from "~/stores/identityAffectation"
21
import { IdentityState, useIdentityStates } from "./useIdentityStates"
3-
import { useIdentityStateStore } from "~/stores/identityState"
2+
import qs from 'qs'
43

5-
const { getStateInfos } = useIdentityStates()
4+
const { getStateBadge } = useIdentityStates()
65
const config = useAppConfig()
76

87
type Badge = {
9-
name: string
108
color: string
11-
value: string
9+
name?: string
10+
value?: string
1211
}
1312

1413
type Menu = {
@@ -17,19 +16,19 @@ type Menu = {
1716
path: string
1817
color: string
1918
part: string
20-
badgeValue?: string
2119
badge?: Badge
22-
hideInMenuBar?:boolean
20+
hideInMenuBar?: boolean
2321
}
2422

25-
function useMenu(identityStateStore, identityAffectationStore) {
23+
function useMenu(identityStateStore) {
2624
const menuParts = ref(['Données', 'Listes', 'Affectations', 'Etats', 'Activation'])
27-
const menus = ref([
25+
const menus = ref<Menu[]>([
2826
{
2927
icon: 'mdi-account',
3028
label: 'Liste des identités',
31-
path: '/identities?sort[metadata.lastUpdatedAt]=desc&skip=0',
29+
path: '/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters',
3230
color: 'primary',
31+
badge: { color: 'primary' },
3332
part: 'Données',
3433
hideInMenuBar: false
3534
},
@@ -69,44 +68,44 @@ function useMenu(identityStateStore, identityAffectationStore) {
6968
label: 'A valider',
7069
path: `/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[@state][]=${IdentityState.TO_VALIDATE}`,
7170
color: 'primary',
71+
badge: getStateBadge(IdentityState.TO_VALIDATE),
7272
part: 'Etats',
73-
badgeValue: 'TO_VALIDATE',
7473
hideInMenuBar: false
7574
},
7675
{
7776
icon: 'mdi-account-alert',
7877
label: 'A compléter',
7978
path: `/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[@state][]=${IdentityState.TO_COMPLETE}`,
8079
color: 'primary',
80+
badge: getStateBadge(IdentityState.TO_COMPLETE),
8181
part: 'Etats',
82-
badgeValue: 'TO_COMPLETE',
8382
hideInMenuBar: false
8483
},
8584
{
8685
icon: 'mdi-sync',
8786
label: 'A synchroniser',
8887
path: `/identities/readonly?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[@state][]=${IdentityState.TO_SYNC}`,
8988
color: 'primary',
89+
badge: getStateBadge(IdentityState.TO_SYNC),
9090
part: 'Etats',
91-
badgeValue: 'TO_SYNC',
9291
hideInMenuBar: false
9392
},
9493
{
9594
icon: 'mdi-loading',
9695
label: 'En cours de synchro.',
9796
path: `/identities/readonly?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[@state][]=${IdentityState.PROCESSING}`,
9897
color: 'primary',
98+
badge: getStateBadge(IdentityState.PROCESSING),
9999
part: 'Etats',
100-
badgeValue: 'PROCESSING',
101100
hideInMenuBar: false
102101
},
103102
{
104103
icon: 'mdi-check',
105104
label: 'Synchronisées',
106105
path: `/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[@state][]=${IdentityState.SYNCED}`,
106+
badge: getStateBadge(IdentityState.SYNCED),
107107
color: 'primary',
108108
part: 'Etats',
109-
badgeValue: 'SYNCED',
110109
hideInMenuBar: false
111110
},
112111
{
@@ -123,8 +122,8 @@ function useMenu(identityStateStore, identityAffectationStore) {
123122
label: 'En erreur',
124123
path: `/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[@state][]=${IdentityState.ON_ERROR}`,
125124
color: 'primary',
125+
badge: getStateBadge(IdentityState.ON_ERROR),
126126
part: 'Etats',
127-
badgeValue: 'ON_ERROR',
128127
hideInMenuBar: false
129128
},
130129
{
@@ -133,6 +132,7 @@ function useMenu(identityStateStore, identityAffectationStore) {
133132
path: '/identities?limit=10&skip=0&filters[&filters[%23initState]=0&sort[metadata.lastUpdatedAt]=desc',
134133
color: 'negative',
135134
part: 'Activation',
135+
badge: { color: 'grey' },
136136
hideInMenuBar: false
137137
},
138138
{
@@ -141,6 +141,7 @@ function useMenu(identityStateStore, identityAffectationStore) {
141141
path: '/identities?limit=10&skip=0&filters[&filters[%23initState]=1&sort[metadata.lastUpdatedAt]=desc',
142142
color: 'warning',
143143
part: 'Activation',
144+
badge: { color: 'grey' },
144145
hideInMenuBar: false
145146
},
146147
{
@@ -149,6 +150,7 @@ function useMenu(identityStateStore, identityAffectationStore) {
149150
path: '/identities?limit=10&skip=0&filters[&filters[%23initState]=2&sort[metadata.lastUpdatedAt]=desc',
150151
color: 'positive',
151152
part: 'Activation',
153+
badge: { color: 'grey' },
152154
hideInMenuBar: false
153155
},
154156
{
@@ -161,41 +163,60 @@ function useMenu(identityStateStore, identityAffectationStore) {
161163
},
162164
])
163165

164-
const badgesValues = ref({
165-
TO_VALIDATE: computed(() => (identityStateStore.getToValidateCount > 9999 ? '9999+' : identityStateStore.getToValidateCount)),
166-
TO_COMPLETE: computed(() => (identityStateStore.getToCompleteCount > 9999 ? '9999+' : identityStateStore.getToCompleteCount)),
167-
TO_SYNC: computed(() => (identityStateStore.getToSyncCount > 9999 ? '9999+' : identityStateStore.getToSyncCount)),
168-
PROCESSING: computed(() => (identityStateStore.getProcessingCount > 9999 ? '9999+' : identityStateStore.getProcessingCount)),
169-
SYNCED: computed(() => (identityStateStore.getSyncedCount > 9999 ? '9999+' : identityStateStore.getSyncedCount)),
170-
ON_ERROR: computed(() => (identityStateStore.getOnErrorCount > 9999 ? '9999+' : identityStateStore.getOnErrorCount)),
171-
ETD: computed(() => (identityAffectationStore.getEtdCount > 9999 ? '9999+' : identityAffectationStore.getEtdCount)),
172-
ADM: computed(() => (identityAffectationStore.getAdmCount > 9999 ? '9999+' : identityAffectationStore.getAdmCount)),
173-
ESN: computed(() => (identityAffectationStore.getEsnCount > 9999 ? '9999+' : identityAffectationStore.getEsnCount)),
174-
})
166+
function normalizeLabel(label: string): string {
167+
return label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, '').replace(/ /g, '_').replace(/\./g, '')
168+
}
175169

176170
function getMenu(): Menu[] {
177-
const menuWithBadgeValue: Menu[] = menus.value.reduce((acc: Menu[], menu) => {
178-
const badgeType = menu.badgeValue ? menu.badgeValue : 'UNKNOWN'
179-
const stateInfo = getStateInfos(IdentityState[badgeType])
180-
const badgeInfos: Badge = {
181-
name: stateInfo.name,
182-
color: stateInfo.color === 'grey' ? 'primary' : stateInfo.color,
183-
value: badgesValues.value[badgeType] || '0',
184-
}
171+
const menuList: Menu[] = menus.value.reduce((acc: Menu[], menu) => {
172+
const label = normalizeLabel(menu.label)
173+
const stateValue = identityStateStore.getStateValue(label)
174+
const value = stateValue > 9999 ? '9999+' : stateValue?.toString() || '0'
175+
176+
console.log('stateValue', label, stateValue, value)
177+
178+
// const badgeType = menu.badgeValue ? menu.badgeValue : 'UNKNOWN'
179+
// const stateInfo = getStateInfos(IdentityState[badgeType])
180+
// const badge: Badge = {
181+
182+
// // name: label,
183+
// // name: stateInfo.name,
184+
// // color: 'red',
185+
// // color: stateInfo.color === 'grey' ? 'primary' : stateInfo.color,
186+
// value,
187+
// }
185188
acc.push({
186189
...menu,
187-
badge: menu.badgeValue ? badgeInfos : undefined
190+
badge: menu.badge ? <Badge>{
191+
...menu?.badge,
192+
value,
193+
} : undefined,
188194
})
189195
return acc
190196
}, [])
191-
return menuWithBadgeValue
197+
return menuList
192198
}
193199

194200
function getMenuByPart(part: string): Menu[] {
195201
return getMenu().filter((menu) => menu.part === part)
196202
}
197203

198-
return { getMenu, menuParts, badgesValues, getMenuByPart }
204+
async function initialize() {
205+
const filters = {}
206+
for (const menu of menus.value) {
207+
if (menu.path && menu.badge) {
208+
const label = normalizeLabel(menu.label)
209+
const params = new URL(window.location.host + menu.path).searchParams
210+
const queryString = qs.parse(params.toString())
211+
212+
filters[label] = queryString['filters']
213+
}
214+
}
215+
216+
await identityStateStore.initialize(filters)
217+
}
218+
219+
return { getMenu, menuParts, getMenuByPart, initialize }
199220
}
200221

201222
export { useMenu }

src/layouts/default.vue

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ q-layout(view="hHh LpR lff" style="margin-top: -1px;")
1717
)
1818
q-item-section(avatar)
1919
q-icon(:name="menu.icon" :color="menu.color")
20-
q-badge(v-if="menu.badgeValue" :color="menu.badge.color" floating) {{ menu.badge.value }}
20+
q-badge(v-if="menu.badge" :color="menu.badge.color" floating) {{ menu.badge.value }}
2121
q-separator
2222
q-page-container
2323
nuxt-page
@@ -81,7 +81,6 @@ q-layout(view="hHh LpR lff" style="margin-top: -1px;")
8181
import { ref } from 'vue'
8282
import { IdentityState } from '~/composables'
8383
import { useIdentityStateStore } from '~/stores/identityState'
84-
import { useIdentityAffectationStore } from '~/stores/identityAffectation'
8584
import { useMenu } from '~/composables'
8685
import ReconnectingEventSource from 'reconnecting-eventsource'
8786
@@ -143,7 +142,7 @@ var es = new ReconnectingEventSource(esUrl)
143142
// console.log('identityStateStore.getProcessingCount', identityStateStore.getProcessingCount)
144143
145144
const eventSeamless = ref(false)
146-
const eventSeamlessTotal = ref(identityStateStore.getProcessingCount)
145+
const eventSeamlessTotal = ref(identityStateStore.getStateValue(IdentityState.PROCESSING))
147146
const eventSeamlessCurrent = ref(0)
148147
const eventSeamlessCurrentJobs = ref({})
149148
@@ -157,8 +156,8 @@ async function onmessage(event) {
157156
158157
if (/^job:/.test(data.channel)) {
159158
if (eventSeamlessTotal.value === 0) {
160-
await identityStateStore.fetchProcessingCount()
161-
eventSeamlessTotal.value = identityStateStore.getProcessingCount
159+
await identityStateStore.fetchAllStateCount()
160+
eventSeamlessTotal.value = identityStateStore.getStateValue(IdentityState.PROCESSING)
162161
}
163162
}
164163
@@ -199,16 +198,11 @@ function syncing(payload: { count: number }) {
199198
const drawer = ref(true)
200199
201200
const router = useRouter()
202-
const identityAffectationStore = useIdentityAffectationStore()
203-
const { fetchAllStateCount } = identityStateStore
204-
const { fetchAllAffectationCount } = identityAffectationStore
205-
await identityStateStore.fetchAllStateCount()
206-
await identityAffectationStore.fetchAllAffectationCount()
201+
// await identityStateStore.fetchAllStateCount()
207202
208-
const { getMenu, badgesValues, menuParts, getMenuByPart } = useMenu(identityStateStore, identityAffectationStore)
203+
const { getMenu, menuParts, getMenuByPart, initialize } = useMenu(identityStateStore)
209204
210-
// const { fetchAllStateCount } = identityStore
211-
// await identityStore.fetchAllStateCount()
205+
await initialize()
212206
213207
function push(path: string) {
214208
router.push(path)

src/pages/identities/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ onMounted(() => {
9090
9191
async function refreshTarget(target: Identity) {
9292
twopan.value.read(target)
93-
await identityStateStore.fetchToSyncCount()
93+
await identityStateStore.fetchAllStateCount()
9494
refreshEvent()
9595
}
9696

src/pages/identities/readonly.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import type { components, operations } from '#build/types/service-api'
5454
import { useErrorHandling } from '#imports'
5555
import { useIdentityStates, useIdentityInitStates } from '~/composables'
5656
import { identity } from '@vueuse/core'
57-
import { useIdentityStateStore } from "~/stores/identityState"
57+
import { useIdentityStateStore } from '~/stores/identityState'
5858
type Identity = components['schemas']['IdentitiesDto']
5959
type Response = operations['IdentitiesController_search']['responses']['200']['content']['application/json']
6060
@@ -79,7 +79,7 @@ onMounted(() => {
7979
8080
async function refreshTarget(target: Identity) {
8181
twopan.value.read(target)
82-
await identityStateStore.fetchToSyncCount()
82+
await identityStateStore.fetchAllStateCount()
8383
refreshEvent()
8484
}
8585
@@ -119,7 +119,7 @@ const { columns, visibleColumns, columnsType } = useColumnsIdentites()
119119
const selected = ref([])
120120
121121
function clearSelected() {
122-
(twopan as any).value.clearSelected()
122+
;(twopan as any).value.clearSelected()
123123
}
124124
125125
function refreshEvent() {

0 commit comments

Comments
 (0)