trace + backup propertie
This commit is contained in:
1 parent
b3b1edec17
commit
ea73e91aa4
8 files changed
+164
-37
No files matched your search
@@ -90,12 +90,30 @@ const routes = {
|
|||||||
tokens: [{"old":"/api/v1/tr069-trace","type":0,"val":"api","end":""},{"old":"/api/v1/tr069-trace","type":0,"val":"v1","end":""},{"old":"/api/v1/tr069-trace","type":0,"val":"tr069-trace","end":""}],
|
tokens: [{"old":"/api/v1/tr069-trace","type":0,"val":"api","end":""},{"old":"/api/v1/tr069-trace","type":0,"val":"v1","end":""},{"old":"/api/v1/tr069-trace","type":0,"val":"tr069-trace","end":""}],
|
||||||
types: placeholder as Registry['tr_069_trace.store']['types'],
|
types: placeholder as Registry['tr_069_trace.store']['types'],
|
||||||
},
|
},
|
||||||
|
'tr_069_trace.raw_config': {
|
||||||
|
methods: ["GET","HEAD"],
|
||||||
|
pattern: '/api/v1/tr069-trace/config',
|
||||||
|
tokens: [{"old":"/api/v1/tr069-trace/config","type":0,"val":"api","end":""},{"old":"/api/v1/tr069-trace/config","type":0,"val":"v1","end":""},{"old":"/api/v1/tr069-trace/config","type":0,"val":"tr069-trace","end":""},{"old":"/api/v1/tr069-trace/config","type":0,"val":"config","end":""}],
|
||||||
|
types: placeholder as Registry['tr_069_trace.raw_config']['types'],
|
||||||
|
},
|
||||||
|
'tr_069_trace.save_raw_config': {
|
||||||
|
methods: ["PUT"],
|
||||||
|
pattern: '/api/v1/tr069-trace/config',
|
||||||
|
tokens: [{"old":"/api/v1/tr069-trace/config","type":0,"val":"api","end":""},{"old":"/api/v1/tr069-trace/config","type":0,"val":"v1","end":""},{"old":"/api/v1/tr069-trace/config","type":0,"val":"tr069-trace","end":""},{"old":"/api/v1/tr069-trace/config","type":0,"val":"config","end":""}],
|
||||||
|
types: placeholder as Registry['tr_069_trace.save_raw_config']['types'],
|
||||||
|
},
|
||||||
'tr_069_trace.destroy': {
|
'tr_069_trace.destroy': {
|
||||||
methods: ["DELETE"],
|
methods: ["DELETE"],
|
||||||
pattern: '/api/v1/tr069-trace/:id',
|
pattern: '/api/v1/tr069-trace/:id',
|
||||||
tokens: [{"old":"/api/v1/tr069-trace/:id","type":0,"val":"api","end":""},{"old":"/api/v1/tr069-trace/:id","type":0,"val":"v1","end":""},{"old":"/api/v1/tr069-trace/:id","type":0,"val":"tr069-trace","end":""},{"old":"/api/v1/tr069-trace/:id","type":1,"val":"id","end":""}],
|
tokens: [{"old":"/api/v1/tr069-trace/:id","type":0,"val":"api","end":""},{"old":"/api/v1/tr069-trace/:id","type":0,"val":"v1","end":""},{"old":"/api/v1/tr069-trace/:id","type":0,"val":"tr069-trace","end":""},{"old":"/api/v1/tr069-trace/:id","type":1,"val":"id","end":""}],
|
||||||
types: placeholder as Registry['tr_069_trace.destroy']['types'],
|
types: placeholder as Registry['tr_069_trace.destroy']['types'],
|
||||||
},
|
},
|
||||||
|
'tr_069_trace.show_log': {
|
||||||
|
methods: ["GET","HEAD"],
|
||||||
|
pattern: '/api/v1/tr069-trace/:id/log',
|
||||||
|
tokens: [{"old":"/api/v1/tr069-trace/:id/log","type":0,"val":"api","end":""},{"old":"/api/v1/tr069-trace/:id/log","type":0,"val":"v1","end":""},{"old":"/api/v1/tr069-trace/:id/log","type":0,"val":"tr069-trace","end":""},{"old":"/api/v1/tr069-trace/:id/log","type":1,"val":"id","end":""},{"old":"/api/v1/tr069-trace/:id/log","type":0,"val":"log","end":""}],
|
||||||
|
types: placeholder as Registry['tr_069_trace.show_log']['types'],
|
||||||
|
},
|
||||||
'configurations_v_1.index': {
|
'configurations_v_1.index': {
|
||||||
methods: ["GET","HEAD"],
|
methods: ["GET","HEAD"],
|
||||||
pattern: '/api/v1/configurations',
|
pattern: '/api/v1/configurations',
|
||||||
|
|||||||
+36
@@ -175,6 +175,30 @@ export interface Registry {
|
|||||||
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['store']>>>
|
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['store']>>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
'tr_069_trace.raw_config': {
|
||||||
|
methods: ["GET","HEAD"]
|
||||||
|
pattern: '/api/v1/tr069-trace/config'
|
||||||
|
types: {
|
||||||
|
body: {}
|
||||||
|
paramsTuple: []
|
||||||
|
params: {}
|
||||||
|
query: {}
|
||||||
|
response: ExtractResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['rawConfig']>>>
|
||||||
|
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['rawConfig']>>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'tr_069_trace.save_raw_config': {
|
||||||
|
methods: ["PUT"]
|
||||||
|
pattern: '/api/v1/tr069-trace/config'
|
||||||
|
types: {
|
||||||
|
body: {}
|
||||||
|
paramsTuple: []
|
||||||
|
params: {}
|
||||||
|
query: {}
|
||||||
|
response: ExtractResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['saveRawConfig']>>>
|
||||||
|
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['saveRawConfig']>>>
|
||||||
|
}
|
||||||
|
}
|
||||||
'tr_069_trace.destroy': {
|
'tr_069_trace.destroy': {
|
||||||
methods: ["DELETE"]
|
methods: ["DELETE"]
|
||||||
pattern: '/api/v1/tr069-trace/:id'
|
pattern: '/api/v1/tr069-trace/:id'
|
||||||
@@ -187,6 +211,18 @@ export interface Registry {
|
|||||||
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['destroy']>>>
|
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['destroy']>>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
'tr_069_trace.show_log': {
|
||||||
|
methods: ["GET","HEAD"]
|
||||||
|
pattern: '/api/v1/tr069-trace/:id/log'
|
||||||
|
types: {
|
||||||
|
body: {}
|
||||||
|
paramsTuple: [ParamValue]
|
||||||
|
params: { id: ParamValue }
|
||||||
|
query: {}
|
||||||
|
response: ExtractResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['showLog']>>>
|
||||||
|
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/tr069_trace_controller').default['showLog']>>>
|
||||||
|
}
|
||||||
|
}
|
||||||
'configurations_v_1.index': {
|
'configurations_v_1.index': {
|
||||||
methods: ["GET","HEAD"]
|
methods: ["GET","HEAD"]
|
||||||
pattern: '/api/v1/configurations'
|
pattern: '/api/v1/configurations'
|
||||||
|
|||||||
Vendored
+3
@@ -24,7 +24,10 @@ export interface ApiDefinition {
|
|||||||
tr069Trace: {
|
tr069Trace: {
|
||||||
index: typeof routes['tr_069_trace.index']
|
index: typeof routes['tr_069_trace.index']
|
||||||
store: typeof routes['tr_069_trace.store']
|
store: typeof routes['tr_069_trace.store']
|
||||||
|
rawConfig: typeof routes['tr_069_trace.raw_config']
|
||||||
|
saveRawConfig: typeof routes['tr_069_trace.save_raw_config']
|
||||||
destroy: typeof routes['tr_069_trace.destroy']
|
destroy: typeof routes['tr_069_trace.destroy']
|
||||||
|
showLog: typeof routes['tr_069_trace.show_log']
|
||||||
}
|
}
|
||||||
configurationsV1: {
|
configurationsV1: {
|
||||||
index: typeof routes['configurations_v_1.index']
|
index: typeof routes['configurations_v_1.index']
|
||||||
|
|||||||
Vendored
+8
@@ -18,7 +18,10 @@ export type ScannedRoutes = {
|
|||||||
'commands.store': { paramsTuple?: []; params?: {} }
|
'commands.store': { paramsTuple?: []; params?: {} }
|
||||||
'tr_069_trace.index': { paramsTuple?: []; params?: {} }
|
'tr_069_trace.index': { paramsTuple?: []; params?: {} }
|
||||||
'tr_069_trace.store': { paramsTuple?: []; params?: {} }
|
'tr_069_trace.store': { paramsTuple?: []; params?: {} }
|
||||||
|
'tr_069_trace.raw_config': { paramsTuple?: []; params?: {} }
|
||||||
|
'tr_069_trace.save_raw_config': { paramsTuple?: []; params?: {} }
|
||||||
'tr_069_trace.destroy': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'tr_069_trace.destroy': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
|
'tr_069_trace.show_log': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
'configurations_v_1.index': { paramsTuple?: []; params?: {} }
|
'configurations_v_1.index': { paramsTuple?: []; params?: {} }
|
||||||
'configurations_v_1.list_tags': { paramsTuple?: []; params?: {} }
|
'configurations_v_1.list_tags': { paramsTuple?: []; params?: {} }
|
||||||
'configurations_v_1.store': { paramsTuple?: []; params?: {} }
|
'configurations_v_1.store': { paramsTuple?: []; params?: {} }
|
||||||
@@ -81,6 +84,8 @@ export type ScannedRoutes = {
|
|||||||
'commands.index': { paramsTuple?: []; params?: {} }
|
'commands.index': { paramsTuple?: []; params?: {} }
|
||||||
'commands.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'commands.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
'tr_069_trace.index': { paramsTuple?: []; params?: {} }
|
'tr_069_trace.index': { paramsTuple?: []; params?: {} }
|
||||||
|
'tr_069_trace.raw_config': { paramsTuple?: []; params?: {} }
|
||||||
|
'tr_069_trace.show_log': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
'configurations_v_1.index': { paramsTuple?: []; params?: {} }
|
'configurations_v_1.index': { paramsTuple?: []; params?: {} }
|
||||||
'configurations_v_1.list_tags': { paramsTuple?: []; params?: {} }
|
'configurations_v_1.list_tags': { paramsTuple?: []; params?: {} }
|
||||||
'configurations_v_1.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'configurations_v_1.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
@@ -112,6 +117,8 @@ export type ScannedRoutes = {
|
|||||||
'commands.index': { paramsTuple?: []; params?: {} }
|
'commands.index': { paramsTuple?: []; params?: {} }
|
||||||
'commands.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'commands.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
'tr_069_trace.index': { paramsTuple?: []; params?: {} }
|
'tr_069_trace.index': { paramsTuple?: []; params?: {} }
|
||||||
|
'tr_069_trace.raw_config': { paramsTuple?: []; params?: {} }
|
||||||
|
'tr_069_trace.show_log': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
'configurations_v_1.index': { paramsTuple?: []; params?: {} }
|
'configurations_v_1.index': { paramsTuple?: []; params?: {} }
|
||||||
'configurations_v_1.list_tags': { paramsTuple?: []; params?: {} }
|
'configurations_v_1.list_tags': { paramsTuple?: []; params?: {} }
|
||||||
'configurations_v_1.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'configurations_v_1.show': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
@@ -142,6 +149,7 @@ export type ScannedRoutes = {
|
|||||||
'firmware_catalog.delete_route': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'firmware_catalog.delete_route': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
}
|
}
|
||||||
PUT: {
|
PUT: {
|
||||||
|
'tr_069_trace.save_raw_config': { paramsTuple?: []; params?: {} }
|
||||||
'configurations_v_1.update': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'configurations_v_1.update': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
'firmware_catalog.update_entry': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'firmware_catalog.update_entry': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
'firmware_catalog.update_route': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
'firmware_catalog.update_route': { paramsTuple: [ParamValue]; params: {'id': ParamValue} }
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { buildSoapEnvelope } from '../protocol/soap.js'
|
|||||||
import { CWMPMessageBuilder } from '../protocol/common/cwmp_message_builder.js'
|
import { CWMPMessageBuilder } from '../protocol/common/cwmp_message_builder.js'
|
||||||
import { StateMachineManager } from '../services/cwmp/state_machine_manager.js'
|
import { StateMachineManager } from '../services/cwmp/state_machine_manager.js'
|
||||||
import { Device, detectDataModelFromParams } from '../domain/device/device.js'
|
import { Device, detectDataModelFromParams } from '../domain/device/device.js'
|
||||||
|
import { reclassifyDeviceFromCatalog } from '../services/parameter_writability.js'
|
||||||
import { DeviceId } from '../domain/device/device_id.js'
|
import { DeviceId } from '../domain/device/device_id.js'
|
||||||
import { DeviceParameter, DeviceProperty } from '../domain/device/device_parameter.js'
|
import { DeviceParameter, DeviceProperty } from '../domain/device/device_parameter.js'
|
||||||
import DeviceModel from '../models/device.js'
|
import DeviceModel from '../models/device.js'
|
||||||
@@ -120,6 +121,12 @@ export default class CwmpController {
|
|||||||
if (paramValues.length > 0) {
|
if (paramValues.length > 0) {
|
||||||
device.updateFromValues(paramValues)
|
device.updateFromValues(paramValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reclassify properties → parameters using catalog when GPN is unsupported
|
||||||
|
if (device.gpnStatus === 'unsupported') {
|
||||||
|
reclassifyDeviceFromCatalog(device)
|
||||||
|
}
|
||||||
|
|
||||||
device.setTmpParamValues(paramValues)
|
device.setTmpParamValues(paramValues)
|
||||||
|
|
||||||
// Detect TR data model from Inform parameter names (Device.* = TR-181, InternetGatewayDevice.* = TR-098)
|
// Detect TR data model from Inform parameter names (Device.* = TR-181, InternetGatewayDevice.* = TR-098)
|
||||||
|
|||||||
@@ -1,18 +1,9 @@
|
|||||||
import { Device } from '../../domain/device/device.js'
|
import { Device } from '../../domain/device/device.js'
|
||||||
import { DeviceParameter } from '../../domain/device/device_parameter.js'
|
|
||||||
import { ParameterType } from '../../domain/shared/types.js'
|
import { ParameterType } from '../../domain/shared/types.js'
|
||||||
import { CWMPTaskQueue, ResultStatus, TaskResult } from './task_queue.js'
|
import { CWMPTaskQueue, ResultStatus, TaskResult } from './task_queue.js'
|
||||||
import { normalizePath } from '../parameter_writability.js'
|
import { reclassifyDeviceFromCatalog } from '../parameter_writability.js'
|
||||||
import DeviceModel from '../../models/device.js'
|
import DeviceModel from '../../models/device.js'
|
||||||
import logger from '@adonisjs/core/services/logger'
|
import logger from '@adonisjs/core/services/logger'
|
||||||
import { createRequire } from 'node:module'
|
|
||||||
|
|
||||||
const require = createRequire(import.meta.url)
|
|
||||||
const tr181Catalog: Array<{ path: string; writable: boolean; deviceClass: string }> =
|
|
||||||
require('../../../config/tr181-catalog.json')
|
|
||||||
const catalogWritableIndex = new Set(
|
|
||||||
tr181Catalog.filter((e) => e.writable).map((e) => e.path)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parameter types (simplified from legacy provisioning domain)
|
// Parameter types (simplified from legacy provisioning domain)
|
||||||
interface SetParameterValue {
|
interface SetParameterValue {
|
||||||
@@ -93,33 +84,8 @@ export class DeviceActionExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reclassify device properties as parameters using the TR-181 catalog.
|
* Get parameter values from device.
|
||||||
* Called when GPN is unsupported — properties that are writable per the catalog
|
|
||||||
* should be moved to parameters so the configuration engine can write to them.
|
|
||||||
*/
|
*/
|
||||||
private reclassifyFromCatalog(device: Device): void {
|
|
||||||
const properties = device.getProperties()
|
|
||||||
let reclassified = 0
|
|
||||||
|
|
||||||
for (const prop of properties) {
|
|
||||||
const normalized = normalizePath(prop.name)
|
|
||||||
if (catalogWritableIndex.has(normalized)) {
|
|
||||||
// Move from properties to parameters (writable)
|
|
||||||
const snap = prop.toSnapshot()
|
|
||||||
device.setParameter(
|
|
||||||
new DeviceParameter(snap.name, snap.value, snap.type, snap.createdAt, snap.updatedAt, snap.notification, snap.accessList)
|
|
||||||
)
|
|
||||||
// Remove from properties map
|
|
||||||
;(device as any)._properties.delete(prop.name)
|
|
||||||
reclassified++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reclassified > 0) {
|
|
||||||
logger.debug({ identifier: device.identifier, reclassified }, '[DeviceAction] Reclassified properties → parameters via catalog')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getParameterValues(
|
async getParameterValues(
|
||||||
device: Device,
|
device: Device,
|
||||||
parameterPaths: string[],
|
parameterPaths: string[],
|
||||||
@@ -208,7 +174,7 @@ export class DeviceActionExecutor {
|
|||||||
if (code === 9000 || code === 9001) {
|
if (code === 9000 || code === 9001) {
|
||||||
device.setGpnStatus('unsupported')
|
device.setGpnStatus('unsupported')
|
||||||
// Reclassify parameters using TR-181 catalog writability
|
// Reclassify parameters using TR-181 catalog writability
|
||||||
this.reclassifyFromCatalog(device)
|
reclassifyDeviceFromCatalog(device)
|
||||||
await this.persistDevice(device)
|
await this.persistDevice(device)
|
||||||
}
|
}
|
||||||
// Autres erreurs (réseau, timeout, 9002+) → gpnStatus inchangé
|
// Autres erreurs (réseau, timeout, 9002+) → gpnStatus inchangé
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { createRequire } from 'node:module'
|
import { createRequire } from 'node:module'
|
||||||
import type { DeviceSnapshot } from '../domain/device/device.js'
|
import type { DeviceSnapshot } from '../domain/device/device.js'
|
||||||
|
import type { Device } from '../domain/device/device.js'
|
||||||
|
import { DeviceParameter } from '../domain/device/device_parameter.js'
|
||||||
|
|
||||||
const require = createRequire(import.meta.url)
|
const require = createRequire(import.meta.url)
|
||||||
const tr181Catalog: Array<{ path: string; writable: boolean; deviceClass: string }> =
|
const tr181Catalog: Array<{ path: string; writable: boolean; deviceClass: string }> =
|
||||||
@@ -7,6 +9,9 @@ const tr181Catalog: Array<{ path: string; writable: boolean; deviceClass: string
|
|||||||
|
|
||||||
// Index chargé une fois au démarrage — O(1) lookup
|
// Index chargé une fois au démarrage — O(1) lookup
|
||||||
const catalogIndex = new Map(tr181Catalog.map((e) => [e.path, e.writable]))
|
const catalogIndex = new Map(tr181Catalog.map((e) => [e.path, e.writable]))
|
||||||
|
const catalogWritableIndex = new Set(
|
||||||
|
tr181Catalog.filter((e) => e.writable).map((e) => e.path)
|
||||||
|
)
|
||||||
|
|
||||||
/** Remplace les segments numériques par {i} pour matcher les entrées du catalogue */
|
/** Remplace les segments numériques par {i} pour matcher les entrées du catalogue */
|
||||||
export function normalizePath(path: string): string {
|
export function normalizePath(path: string): string {
|
||||||
@@ -46,3 +51,27 @@ export function resolveWritability(snapshot: DeviceSnapshot, paramPath: string):
|
|||||||
if (gpnStatus === 'unsupported') return { writable: true, source: 'default' }
|
if (gpnStatus === 'unsupported') return { writable: true, source: 'default' }
|
||||||
return { writable: null, source: 'unknown' }
|
return { writable: null, source: 'unknown' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reclassify device properties as parameters using the TR-181 catalog.
|
||||||
|
* Properties that are writable per the catalog are moved to parameters.
|
||||||
|
* Should be called after updateFromValues when gpnStatus is 'unsupported'.
|
||||||
|
*/
|
||||||
|
export function reclassifyDeviceFromCatalog(device: Device): number {
|
||||||
|
const properties = device.getProperties()
|
||||||
|
let reclassified = 0
|
||||||
|
|
||||||
|
for (const prop of properties) {
|
||||||
|
const normalized = normalizePath(prop.name)
|
||||||
|
if (catalogWritableIndex.has(normalized)) {
|
||||||
|
const snap = prop.toSnapshot()
|
||||||
|
device.setParameter(
|
||||||
|
new DeviceParameter(snap.name, snap.value, snap.type, snap.createdAt, snap.updatedAt, snap.notification, snap.accessList)
|
||||||
|
)
|
||||||
|
;(device as any)._properties.delete(prop.name)
|
||||||
|
reclassified++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reclassified
|
||||||
|
}
|
||||||
@@ -14,6 +14,51 @@ const { device, modelPaths, commands } = defineProps<{
|
|||||||
|
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
const showDeleteConfirm = ref(false)
|
const showDeleteConfirm = ref(false)
|
||||||
|
const isTraced = ref(false)
|
||||||
|
const tracingAction = ref(false)
|
||||||
|
|
||||||
|
// Check if device is already traced
|
||||||
|
async function checkTraceStatus() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/v1/tr069-trace')
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json()
|
||||||
|
const entries = data.entries || []
|
||||||
|
isTraced.value = entries.some((e: any) => e.deviceId === device.identifier)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Silently ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleTrace() {
|
||||||
|
tracingAction.value = true
|
||||||
|
try {
|
||||||
|
if (isTraced.value) {
|
||||||
|
const response = await fetch(`/api/v1/tr069-trace/${encodeURIComponent(device.identifier)}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
})
|
||||||
|
if (response.ok || response.status === 204) {
|
||||||
|
isTraced.value = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const response = await fetch('/api/v1/tr069-trace', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ deviceId: device.identifier }),
|
||||||
|
})
|
||||||
|
if (response.ok) {
|
||||||
|
isTraced.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Silently ignore
|
||||||
|
} finally {
|
||||||
|
tracingAction.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTraceStatus()
|
||||||
|
|
||||||
function deleteDevice() {
|
function deleteDevice() {
|
||||||
router.delete(`/devices/${encodeURIComponent(device.identifier)}`, {
|
router.delete(`/devices/${encodeURIComponent(device.identifier)}`, {
|
||||||
@@ -328,6 +373,21 @@ function getPropertyValue(name: string): string {
|
|||||||
<button class="btn btn-outline-dark btn-sm" @click="openGetModelPopup" :disabled="isLoading">
|
<button class="btn btn-outline-dark btn-sm" @click="openGetModelPopup" :disabled="isLoading">
|
||||||
{{ t('button.getModel') }}
|
{{ t('button.getModel') }}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm"
|
||||||
|
:class="isTraced ? 'btn-warning' : 'btn-outline-primary'"
|
||||||
|
:disabled="tracingAction"
|
||||||
|
@click="toggleTrace"
|
||||||
|
>
|
||||||
|
<svg v-if="!isTraced" xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="me-1" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
|
||||||
|
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
|
||||||
|
</svg>
|
||||||
|
<svg v-else xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="me-1" viewBox="0 0 16 16">
|
||||||
|
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293z"/>
|
||||||
|
</svg>
|
||||||
|
{{ tracingAction ? '…' : (isTraced ? 'Remove TR-069 monitoring' : 'Add to TR-069 monitoring') }}
|
||||||
|
</button>
|
||||||
<button class="btn btn-outline-danger btn-sm ms-auto" @click="showDeleteConfirm = true">
|
<button class="btn btn-outline-danger btn-sm ms-auto" @click="showDeleteConfirm = true">
|
||||||
Supprimer l'équipement
|
Supprimer l'équipement
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in new issue
Block a user