From 374e0da229d2c4a2785fde0a88811fb389838811 Mon Sep 17 00:00:00 2001 From: louispaulb Date: Fri, 3 Jul 2026 09:58:35 -0400 Subject: [PATCH] =?UTF-8?q?feat(ui):=20simpler=20cr=C3=A9neau=20dialog=20?= =?UTF-8?q?=E2=80=94=20skill=20chips=20+=20defaulted=20duration=20+=20prog?= =?UTF-8?q?ressive=20disclosure;=20fix=20address=20autosuggest=20everywher?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applying the "one-click defaults + reveal-on-input + less clutter" pattern the user asked for, on the SuggestSlotsDialog: - Skill chips (4 main, from assignTypes + getTagColor, passed by parent): one click picks the skill AND sets the default duration (SLOT_SKILL_DUR: install 2h, réparation/tv 1h, téléphonie 0.5h…), adjustable. - Progressive disclosure: duration/date/search appear only after an address is chosen (hint otherwise). Less useless info up front. - Selected skill flows into the created job as a tag. Fix (autosuggest broken everywhere): the dialog used a q-menu (needs a click trigger, so v-if never opened it) → switched to the q-list-below pattern. More importantly, useAddressSearch pointed at ERPNext /api/method/search_address (403/perm) → repointed at the reliable hub /rpc/search_addresses (Postgres rqa_addresses, works in dev+prod via the /hub proxy). Fixes autosuggest in UnifiedCreateModal + DispatchPage too. Verified end-to-end: type "54 chateauguay huntingdon" → suggestions appear → pick → Installation chip sets 2h → search returns 8 slots (08:15–10:15). Chips + reveal + green ✓ on validated address. Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/ops/src/composables/useAddressSearch.js | 10 +- apps/ops/src/composables/useUnifiedCreate.js | 1 + .../components/SuggestSlotsDialog.vue | 111 ++++++++++-------- apps/ops/src/pages/PlanificationPage.vue | 14 ++- 4 files changed, 79 insertions(+), 57 deletions(-) diff --git a/apps/ops/src/composables/useAddressSearch.js b/apps/ops/src/composables/useAddressSearch.js index a57ceb0..a12fefe 100644 --- a/apps/ops/src/composables/useAddressSearch.js +++ b/apps/ops/src/composables/useAddressSearch.js @@ -1,8 +1,10 @@ import { ref } from 'vue' +import { HUB_URL } from 'src/config/hub' /** - * Reusable address search composable. - * Searches ERPNext `search_address` whitelisted method with debounce. + * Reusable address search composable (autosuggest RQA). + * Cherche via le hub `/rpc/search_addresses` (Postgres rqa_addresses, trigram) — FIABLE et joignable en dev ET prod + * (le proxy /hub ajoute le jeton). Remplace l'ancien `/api/method/search_address` (ERPNext) qui échouait (403/perm). */ export function useAddressSearch () { const addrResults = ref([]) @@ -15,9 +17,9 @@ export function useAddressSearch () { addrLoading.value = true addrDebounce = setTimeout(async () => { try { - const res = await fetch(`/api/method/search_address?q=${encodeURIComponent(q)}`, { credentials: 'include' }) + const res = await fetch(`${HUB_URL}/rpc/search_addresses`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ search_term: q, result_limit: 8 }) }) const data = await res.json() - addrResults.value = data.results || data.message?.results || [] + addrResults.value = Array.isArray(data) ? data : (data.results || data.message?.results || []) // /rpc renvoie un tableau direct } catch { addrResults.value = [] } addrLoading.value = false }, 300) diff --git a/apps/ops/src/composables/useUnifiedCreate.js b/apps/ops/src/composables/useUnifiedCreate.js index 98385f3..95ab929 100644 --- a/apps/ops/src/composables/useUnifiedCreate.js +++ b/apps/ops/src/composables/useUnifiedCreate.js @@ -217,6 +217,7 @@ export function useUnifiedCreate (mode, opts = {}) { form.duration_h = ctx.duration_h || 1 form.address = ctx.address || '' form.assigned_tech = ctx.assigned_tech || null + form.tags = Array.isArray(ctx.tags) ? ctx.tags.slice() : [] // compétence/type pré-rempli (ex. chip du « Trouver un créneau ») form.scheduled_date = ctx.scheduled_date || '' form.start_time = ctx.start_time || '' form._latitude = ctx._latitude != null ? ctx._latitude : (ctx.latitude != null ? ctx.latitude : null) // coords pré-remplies (réservation par créneau) diff --git a/apps/ops/src/modules/dispatch/components/SuggestSlotsDialog.vue b/apps/ops/src/modules/dispatch/components/SuggestSlotsDialog.vue index 0ebcc5d..2d500f6 100644 --- a/apps/ops/src/modules/dispatch/components/SuggestSlotsDialog.vue +++ b/apps/ops/src/modules/dispatch/components/SuggestSlotsDialog.vue @@ -1,48 +1,50 @@