diff --git a/apps/ops/src/composables/useHelpers.js b/apps/ops/src/composables/useHelpers.js
index 0f27225..e135a26 100644
--- a/apps/ops/src/composables/useHelpers.js
+++ b/apps/ops/src/composables/useHelpers.js
@@ -212,6 +212,26 @@ export const ICON = {
clock: _s(' '),
loader: _s(' '),
truck: _s(' '),
+ // ── Single-color toolbar set (used in dispatch top bar). All inherit
+ // currentColor; CSS sizes them via .sb-icon-svg below. Strokes only,
+ // 2px stroke for crisp rendering at 14-16px display size.
+ user: _s(' '),
+ users: _s(' '),
+ package: _s(' '),
+ sliders: _s(' '),
+ chevDown: _s(' '),
+ map: _s(' '),
+ clipboard:_s(' '),
+ sparkles: _s(' '),
+ signal: _s(' '),
+ rotateCw: _s(' '),
+ alertTri: _s(' '),
+ moreH: _s(' '),
+ pause: _s(' '),
+ play: _s(' '),
+ externalLink: _s(' '),
+ target: _s(' '),
+ calendar: _s(' '),
}
// Job type icon based on service/subject
diff --git a/apps/ops/src/composables/useResourceFilter.js b/apps/ops/src/composables/useResourceFilter.js
index 637f114..817e030 100644
--- a/apps/ops/src/composables/useResourceFilter.js
+++ b/apps/ops/src/composables/useResourceFilter.js
@@ -5,7 +5,10 @@ export function useResourceFilter (store, opts = {}) {
const filterStatus = ref(localStorage.getItem('sbv2-filterStatus') || '')
const filterGroup = ref(localStorage.getItem('sbv2-filterGroup') || '')
const filterTags = ref(JSON.parse(localStorage.getItem('sbv2-filterTags') || '[]'))
- const filterResourceType = ref(localStorage.getItem('sbv2-filterResType') || '') // '' | 'human' | 'material'
+ // Default 'human' = show only techs. Materials are secondary and
+ // accessed via the resource-type dropdown when needed. Once the user
+ // explicitly picks something else (incl. ''), it's persisted.
+ const filterResourceType = ref(localStorage.getItem('sbv2-filterResType') ?? 'human') // '' | 'human' | 'material'
const searchQuery = ref('')
const techSort = ref(localStorage.getItem('sbv2-techSort') || 'default')
const manualOrder = ref(JSON.parse(localStorage.getItem('sbv2-techOrder') || '[]'))
diff --git a/apps/ops/src/pages/DispatchPage.vue b/apps/ops/src/pages/DispatchPage.vue
index eb5d709..034a7c8 100644
--- a/apps/ops/src/pages/DispatchPage.vue
+++ b/apps/ops/src/pages/DispatchPage.vue
@@ -401,8 +401,24 @@ const periodEndStr = computed(() => {
return localDateStr(d)
})
const onPublished = jobNames => store.publishJobsLocal(jobNames)
-const moreMenuOpen = ref(false) // ⋯ dropdown in the top toolbar (right side)
-const viewsMenuOpen = ref(false) // "Vue principale ▾" dropdown (left side)
+const moreMenuOpen = ref(false) // ⋯ dropdown in the top toolbar (right side)
+const viewsMenuOpen = ref(false) // "Vue principale ▾" dropdown (left side)
+const resTypeMenuOpen = ref(false) // Resource type chip dropdown ([👤 45 ▾])
+const resTypeIcon = computed(() =>
+ filterResourceType.value === 'material' ? ICON.package
+ : filterResourceType.value === 'human' ? ICON.users
+ : ICON.users // 'Tous' falls back to the people icon
+)
+const resTypeLabel = computed(() =>
+ filterResourceType.value === 'material' ? 'Matériel'
+ : filterResourceType.value === 'human' ? 'Techs'
+ : 'Toutes les ressources'
+)
+const resTypeCount = computed(() =>
+ filterResourceType.value === 'material' ? materialCount.value
+ : filterResourceType.value === 'human' ? humanCount.value
+ : (humanCount.value + materialCount.value)
+)
const gpsSettingsOpen = ref(false)
const gpsShowInactive = ref(false)
const gpsFilteredTechs = computed(() =>
@@ -968,6 +984,7 @@ function onKeyDown (e) {
selectedJob.value = null; multiSelect.value = []
moreMenuOpen.value = false
viewsMenuOpen.value = false
+ resTypeMenuOpen.value = false
if (geoFixTech.value) cancelTechGeoFix()
}
if (e.key === 'z' && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
@@ -1181,7 +1198,7 @@ onMounted(async () => {
loadOffers()
loadPresets()
document.addEventListener('keydown', onKeyDown)
- document.addEventListener('click', () => { closeCtxMenu(); assistCtx.value = null; techCtx.value = null; moreMenuOpen.value = false; viewsMenuOpen.value = false })
+ document.addEventListener('click', () => { closeCtxMenu(); assistCtx.value = null; techCtx.value = null; moreMenuOpen.value = false; viewsMenuOpen.value = false; resTypeMenuOpen.value = false })
if (!document.getElementById('mapbox-css')) {
const l = document.createElement('link'); l.id='mapbox-css'; l.rel='stylesheet'
l.href='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css'; document.head.appendChild(l)
@@ -1227,10 +1244,33 @@ onUnmounted(() => {
👥 {{ p.name }}
-
- Tous {{ humanCount + materialCount }}
- 👤 {{ humanCount }}
- 🔧 {{ materialCount }}
+
+
+
- 👥 {{ teamJobs.length }}
+
+ {{ teamJobs.length }}
- 🗓 Planning
+
+ Planning