openModal('Service Equipment', eq.name, eq.equipment_type + (eq.brand ? ' — ' + eq.brand : ''))"
+ @add-submission="openWizardForAddress(loc)"
+ @add-service="openAddService(loc)"
+ @add-rebate="openAddService(loc, 'rabais')"
+ @add-equipment="openAddEquipment(loc)"
+ />
@@ -1137,14 +1061,13 @@ import { authFetch } from 'src/api/auth'
import { BASE_URL, ERP_DESK_URL } from 'src/config/erpnext'
import { HUB_URL } from 'src/config/hub'
import { formatDate, formatDateTime, formatMoney, staffColor, staffInitials, noteAuthorName } from 'src/composables/useFormatters'
-import { locStatusClass, ticketStatusClass, invStatusClass, deviceColorClass, priorityClass } from 'src/composables/useStatusClasses'
+import { locStatusClass, ticketStatusClass, invStatusClass, priorityClass } from 'src/composables/useStatusClasses'
import { useDetailModal } from 'src/composables/useDetailModal'
import { useSubscriptionGroups, isRebate, subMainLabel, sectionTotal, annualPrice } from 'src/composables/useSubscriptionGroups'
import { useSubscriptionActions } from 'src/composables/useSubscriptionActions'
import { useCustomerNotes } from 'src/composables/useCustomerNotes'
import { useConversations } from 'src/composables/useConversations'
import { invoiceCols, paymentCols, ticketCols, voipCols, paymentMethodCols, arrangementCols, quotationCols, serviceContractCols } from 'src/config/table-columns'
-import { deviceLucideIcon } from 'src/config/device-icons'
import DetailModal from 'src/components/shared/DetailModal.vue'
import DataTable from 'src/components/shared/DataTable.vue'
import CustomerHeader from 'src/components/customer/CustomerHeader.vue'
@@ -1166,6 +1089,7 @@ import { locInlineFields, equipTypeOptions, equipStatusOptions, defaultSectionsO
import { useUserPrefs } from 'src/composables/useUserPrefs'
import { erpPdfUrl } from 'src/utils/erp-pdf'
import RewardDialog from 'src/components/customer/RewardDialog.vue'
+import DeviceStrip from 'src/components/customer/DeviceStrip.vue'
const $q = useQuasar()
const { can } = usePermissions()
@@ -1176,7 +1100,9 @@ const ticketsExpanded = ref(false)
const invoicesExpanded = ref(false)
const paymentsExpanded = ref(false)
-const { fetchStatus, fetchOltStatus, getDevice, isOnline, combinedStatus, signalQuality, rebootDevice, refreshDeviceParams } = useDeviceStatus()
+// Device status still needed at the page level to seed the shared map (fetchStatus/fetchOltStatus
+// passed to useClientData); DeviceStrip consumes the same singleton composable for display.
+const { fetchStatus, fetchOltStatus } = useDeviceStatus()
const {
modalOpen, modalLoading, modalDoctype, modalDocName, modalTitle,
@@ -1509,40 +1435,6 @@ async function confirmDeleteSub (sub) {
function onDispatchCreated (job) { modalDispatchJobs.value.push(job) }
-function formatTimeAgo (dateStr) {
- if (!dateStr) return ''
- const diff = Date.now() - new Date(dateStr).getTime()
- const mins = Math.floor(diff / 60000)
- if (mins < 1) return 'à l\'instant'
- if (mins < 60) return `il y a ${mins}m`
- const hrs = Math.floor(mins / 60)
- return hrs < 24 ? `il y a ${hrs}h` : `il y a ${Math.floor(hrs / 24)}j`
-}
-
-function signalColor (serial) {
- const q = signalQuality(serial)
- return q === 'excellent' ? '#4ade80' : q === 'good' ? '#a3e635' : q === 'fair' ? '#fbbf24' : '#f87171'
-}
-
-async function doReboot (eq) {
- try {
- await rebootDevice(eq.serial_number)
- Notify.create({ type: 'positive', message: `Redémarrage envoyé: ${eq.serial_number}`, position: 'top' })
- } catch (e) {
- Notify.create({ type: 'negative', message: `Erreur: ${e.message}`, position: 'top' })
- }
-}
-
-async function doRefreshParams (eq) {
- try {
- await refreshDeviceParams(eq.serial_number)
- Notify.create({ type: 'info', message: `Rafraîchissement lancé: ${eq.serial_number}`, position: 'top' })
- setTimeout(() => fetchStatus([eq]), 3000)
- } catch (e) {
- Notify.create({ type: 'negative', message: `Erreur: ${e.message}`, position: 'top' })
- }
-}
-
const locCollapsed = reactive({})
const locHasSubs = (locName) => subscriptions.value.some(s => s.service_location === locName)
const toggleLocCollapse = (locName) => { locCollapsed[locName] = locCollapsed[locName] === false }