Skip to content

Commit 5ca1042

Browse files
committed
feat: améliorer la gestion des menus avec des styles de badge et de bouton, et réorganiser les parties du menu
1 parent 954cefb commit 5ca1042

File tree

7 files changed

+115
-28
lines changed

7 files changed

+115
-28
lines changed

apps/web/default/menus.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@ entries:
44
path: "/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[^additionalFields.attributes.supannPerson.supannTypeEntiteAffectation]=/etd/i"
55
color: primary
66
part: Affectations
7-
badgeValue: ETD
87

98
- icon: mdi-account-tie
109
label: Administratifs
1110
path: "/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[^additionalFields.attributes.supannPerson.supannTypeEntiteAffectation]=/adm/i"
1211
color: primary
1312
part: Affectations
14-
badgeValue: ADM
1513

1614
- icon: mdi-account-group
1715
label: Enseignants
1816
path: "/identities?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[^additionalFields.attributes.supannPerson.supannTypeEntiteAffectation]=/esn/i"
1917
color: primary
2018
part: Affectations
21-
badgeValue: ESN
2219

apps/web/src/components/core/pan-filters.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ q-toolbar(dense flat)
4646
)
4747
q-separator(vertical)
4848
q-btn-dropdown.text-secondary(
49+
dropdown-icon="mdi-dots-vertical"
4950
flat dense
5051
)
5152
q-list(dense)

apps/web/src/components/layouts/default/drawer.vue

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@ q-drawer.flex(v-model="drawer" side="left" :mini="true" :breakpoint="0" bordered
77
q-item-section(avatar)
88
q-icon(name="mdi-home")
99
q-separator
10-
q-list(v-for="part in menuParts" :key="part")
11-
div(v-for="menu in getMenuByPart(part)")
10+
q-list(v-for="(part, i) in menuParts" :key="i")
11+
div(v-for="menu in getMenuByPart(part.label)")
1212
q-item(v-if="menu.hideInMenuBar !== true"
13-
:key="part" clickable v-ripple
14-
:href="encodePath(menu.path)" :active="encodePath(menu.path) === $route.fullPath" active-class="q-item--active"
13+
:key="i" clickable v-ripple
14+
:href="encodePath(menu.path)" :active="encodePath(menu.path) === $route.fullPath"
15+
active-class="q-item--active"
1516
)
1617
q-separator(v-if='encodePath(menu.path) === $route.fullPath' vertical color='primary' size="5px" style='position: absolute; left: 0; height: 100%; margin-top: -8px;')
1718
q-item-section(avatar)
18-
q-icon(:name="menu.icon" :color="menu.color")
19+
q-icon(
20+
:style='getButtonStyle(menu)'
21+
:name="menu.icon"
22+
:color="menu.color"
23+
:class="{ 'gradient-icon': isGradient(menu) }"
24+
)
1925
q-badge(
2026
v-if="menu.badge"
27+
:style='getBadgeStyle(menu)'
2128
:color="menu.badge.color"
2229
:class='["text-" + menu.badge.textColor || "text-white"]'
2330
v-text='menu.badge.value'
@@ -56,5 +63,48 @@ export default defineNuxtComponent({
5663
encodePath,
5764
}
5865
},
66+
methods: {
67+
isGradient(item) {
68+
const c = item.drawerColor || item.color || ''
69+
return typeof c === 'string' && c.startsWith('linear-gradient')
70+
},
71+
getBadgeStyle(item) {
72+
const badgeColor = item.badge?.color?.startsWith('linear-gradient') || item.badge?.color?.startsWith('#') ? item.badge.color : ''
73+
const badgeTextColor = item.badge?.textColor?.startsWith('linear-gradient') || item.badge?.textColor?.startsWith('#') ? item.badge.textColor : ''
74+
75+
return {
76+
background: badgeColor || '',
77+
color: badgeTextColor || '',
78+
}
79+
},
80+
getButtonStyle(item) {
81+
const drawerColor = item.drawerColor?.startsWith('linear-gradient') || item.drawerColor?.startsWith('#') ? item.drawerColor : ''
82+
const color = item.color?.startsWith('linear-gradient') || item.color?.startsWith('#') ? item.color : ''
83+
84+
const finalColor = drawerColor || color || ''
85+
86+
if (finalColor && finalColor.startsWith('linear-gradient')) {
87+
return {
88+
WebkitBackgroundClip: 'text',
89+
WebkitTextFillColor: 'transparent',
90+
backgroundClip: 'text',
91+
background: finalColor,
92+
color: 'transparent',
93+
}
94+
}
95+
96+
return {
97+
color: finalColor,
98+
}
99+
},
100+
},
59101
})
60102
</script>
103+
104+
<style lang="scss" scoped>
105+
.gradient-icon {
106+
background-clip: text !important;
107+
-webkit-background-clip: text !important;
108+
color: transparent !important;
109+
}
110+
</style>

apps/web/src/composables/useMenu.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { useIdentityStates } from './useIdentityStates'
33
import { DefaultMenuParts, MaxMenuBadgeCount, MenuPart } from '~/constants/variables'
44
import { IdentityState } from '~/constants/enums'
55
import qs from 'qs'
6-
import path from 'path'
6+
import type { useIdentityStateStore } from '~/stores/identityState'
7+
import { sort } from 'radash'
78

89
const { getStateBadge } = useIdentityStates()
910
const config = useAppConfig()
@@ -15,8 +16,16 @@ type useMenuReturnType = {
1516
initialize: () => Promise<void>
1617
}
1718

18-
function useMenu(identityStateStore): useMenuReturnType {
19+
function useMenu(identityStateStore: ReturnType<typeof useIdentityStateStore>): useMenuReturnType {
1920
const menuParts = ref(DefaultMenuParts)
21+
22+
if (config?.menus?.parts) {
23+
menuParts.value = sort([...menuParts.value, ...(config.menus?.parts as any) || []], (part) => {
24+
const pos = part.position || 9_999
25+
return pos
26+
})
27+
}
28+
2029
const menus = ref<MenuItem[]>([
2130
{
2231
icon: 'mdi-account',
@@ -116,8 +125,9 @@ function useMenu(identityStateStore): useMenuReturnType {
116125
icon: 'mdi-account-switch-outline',
117126
label: 'Fusionnées',
118127
path: '/identities/table?sort[metadata.lastUpdatedAt]=desc&skip=0&filters[!:primaryEmployeeNumber]=null',
119-
color: 'grey-3',
120-
textColor: 'black',
128+
color: 'linear-gradient(135deg, #7C3AED 0%, #EC4899 50%, #F97316 100%)',
129+
textColor: 'white',
130+
badge: { color: 'linear-gradient(135deg, #7C3AED 0%, #EC4899 50%, #F97316 100%)', textColor: 'white' },
121131
part: MenuPart.ETATS,
122132
hideInMenuBar: false,
123133
},
@@ -178,11 +188,8 @@ function useMenu(identityStateStore): useMenuReturnType {
178188
const menuList: MenuItem[] = menus.value.reduce((acc: MenuItem[], menu) => {
179189
const label = normalizeLabel(menu.label)
180190
const stateValue = identityStateStore.getStateValue(label)
181-
// console.log(`Processing menu ${label} with state value ${stateValue}`)
182191
const value = stateValue > MaxMenuBadgeCount ? MaxMenuBadgeCount + '+' : stateValue?.toString() || '0'
183192

184-
// console.log(`Menu ${menu.label} has state value ${stateValue} and badge value ${value}`)
185-
186193
acc.push({
187194
...menu,
188195
badge: menu.badge ? <BadgeItem>{
@@ -212,10 +219,7 @@ function useMenu(identityStateStore): useMenuReturnType {
212219
const queryString = qs.parse(params.toString())
213220
const qsFilters = {}
214221

215-
// console.log('lab', label, 'qs', queryString)
216-
217222
for (const [key, value] of Object.entries(queryString['filters'] || {})) {
218-
// console.log('Processing filter ' + label, { key, value })
219223
qsFilters[decodeURIComponent(key)] = decodeURIComponent(value as string)
220224
}
221225

apps/web/src/constants/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type MenuItem = {
1212
part: string
1313
color: string
1414
textColor?: string
15+
drawerColor?: string
1516
badge?: BadgeItem
1617
hideInMenuBar?: boolean
1718
}

apps/web/src/constants/variables.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
11
export const MaxMenuBadgeCount = 99999
22

33
export const DefaultMenuParts = [
4-
'Données',
5-
'Listes',
6-
'Affectations',
7-
'Etats',
8-
'Activation',
4+
{
5+
label: 'Données',
6+
position: 10,
7+
},
8+
{
9+
label: 'Listes',
10+
position: 20,
11+
},
12+
{
13+
label: 'Affectations',
14+
position: 30,
15+
},
16+
{
17+
label: 'Etats',
18+
position: 40,
19+
},
20+
{
21+
label: 'Activation',
22+
position: 50,
23+
},
924
]
1025

1126
export enum MenuPart {

apps/web/src/pages/index.vue

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<template lang="pug">
22
q-page.container(padding)
33
.column.no-wrap
4-
div(v-for="(part, i) in menuParts", :key="part")
5-
q-bar.q-pa-lg.q-mb-sm.transparent(v-show='getMenuByPart(part).length' dense)
6-
.text-h5 {{ part }}
4+
div(v-for="(part, i) in menuParts", :key="i")
5+
q-bar.q-pa-lg.q-mb-sm.transparent(v-show='getMenuByPart(part.label).length' dense)
6+
.text-h5 {{ part.label }}
77

88
.row.q-col-gutter-md
9-
.col.col-12.col-sm-6.col-md-4.col-lg-3(v-for="item in getMenuByPart(part)" :key="item.label")
9+
.col.col-12.col-sm-6.col-md-4.col-lg-3(v-for="item in getMenuByPart(part.label)" :key="item.label")
1010
q-btn.q-py-md.fit(
11+
:style='getButtonStyle(item)'
1112
:class='["text-" + item.textColor || "text-white"]'
1213
:color="item.color"
1314
:label="item.label"
@@ -18,12 +19,13 @@ q-page.container(padding)
1819
)
1920
q-badge.text-bold(
2021
v-if="item.badge"
22+
:style='getBadgeStyle(item)'
2123
:class='["text-" + item.badge.textColor || "text-white"]'
2224
:color="item.badge.color"
2325
v-text="item?.badge?.value"
2426
floating
2527
)
26-
q-separator.q-mt-md.q-mb-sm(v-if="i < menuParts.length - 1" v-show='getMenuByPart(part).length')
28+
q-separator.q-mt-md.q-mb-sm(v-if="i < menuParts.length - 1" v-show='getMenuByPart(part.label).length')
2729
</template>
2830

2931
<script lang="ts">
@@ -45,5 +47,22 @@ export default defineNuxtComponent({
4547
getMenuByPart,
4648
}
4749
},
50+
methods: {
51+
getBadgeStyle(item) {
52+
const badgeColor = item.badge?.color?.startsWith('linear-gradient') || item.badge?.color?.startsWith('#') ? item.badge.color : ''
53+
const badgeTextColor = item.badge?.textColor?.startsWith('linear-gradient') || item.badge?.textColor?.startsWith('#') ? item.badge.textColor : ''
54+
55+
return {
56+
background: badgeColor,
57+
color: badgeTextColor,
58+
}
59+
},
60+
getButtonStyle(item) {
61+
return {
62+
background: item.color?.startsWith('linear-gradient') || item.color?.startsWith('#') ? item.color : '',
63+
color: item.textColor?.startsWith('linear-gradient') || item.textColor?.startsWith('#') ? item.textColor : '',
64+
}
65+
},
66+
},
4867
})
4968
</script>

0 commit comments

Comments
 (0)