Files
adam-acs/inertia/pages/Commands.vue
T
Kevin L'HereecandCopilot d1c65dbf1e chore: initial commit — AdonisJS v7 TR-069 ACS
- Docker infrastructure (Dockerfile, docker-compose.yml, genieacs-sim)
- AdonisJS v7 app with Inertia.js + Vue 3
- MongoDB integration
- CWMP/TR-069 state machine engine
- Configuration engine with compliance tracking
- Branding: ADAM ACS (favicon, navbar, locales)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-29 16:46:37 +02:00

163 lines
6.7 KiB
Vue

<script setup lang="ts">
import { ref, computed } from 'vue'
import { router, Link } from '@inertiajs/vue3'
import { useI18n } from 'vue-i18n'
import TitleBar from '../components/TitleBar.vue'
const { t } = useI18n()
const { commands, filters } = defineProps<{
commands: any[]
filters: { device: string; status: string; action: string; mode: string }
}>()
const localFilters = ref({
device: filters.device || '',
status: filters.status || '',
action: filters.action || '',
mode: filters.mode || '',
})
const statuses = ['PENDING', 'WAITING', 'SENT', 'COMPLETED', 'FAILED']
const actions = [
'GET_PARAMETER_VALUES', 'GET_PARAMETER_NAMES', 'GET_PARAMETER_ATTRIBUTES',
'SET_PARAMETER_VALUES', 'SET_PARAMETER_ATTRIBUTES',
'DOWNLOAD', 'UPLOAD', 'REBOOT', 'FACTORY_RESET', 'SCHEDULE_INFORM', 'REFRESH',
]
const modes = ['NI', 'I']
const hasActiveFilters = computed(() => {
return Object.values(localFilters.value).some((v) => v !== '')
})
function applyFilters() {
const params: Record<string, string> = {}
if (localFilters.value.device) params.device = localFilters.value.device
if (localFilters.value.status) params.status = localFilters.value.status
if (localFilters.value.action) params.action = localFilters.value.action
if (localFilters.value.mode) params.mode = localFilters.value.mode
const qs = new URLSearchParams(params).toString()
router.visit(`/commands${qs ? '?' + qs : ''}`, { preserveState: false })
}
function clearFilters() {
localFilters.value = { device: '', status: '', action: '', mode: '' }
router.visit('/commands', { preserveState: false })
}
function removeFilter(key: keyof typeof localFilters.value) {
localFilters.value[key] = ''
applyFilters()
}
</script>
<template>
<TitleBar section="commands" />
<div class="container-xxl py-4">
<!-- Filters bar -->
<div class="card border-0 shadow-sm mb-3">
<div class="card-body p-3">
<div class="row g-2 align-items-end">
<div class="col-md-3">
<label class="form-label small text-muted mb-1">{{ t('labels.deviceIdentifier') }}</label>
<input
type="text"
class="form-control form-control-sm font-monospace"
v-model="localFilters.device"
:placeholder="t('placeholder.search')"
@keyup.enter="applyFilters"
/>
</div>
<div class="col-md-2">
<label class="form-label small text-muted mb-1">{{ t('labels.status') }}</label>
<select class="form-select form-select-sm" v-model="localFilters.status" @change="applyFilters">
<option value="">—</option>
<option v-for="s in statuses" :key="s" :value="s">{{ s }}</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label small text-muted mb-1">{{ t('labels.action') }}</label>
<select class="form-select form-select-sm" v-model="localFilters.action" @change="applyFilters">
<option value="">—</option>
<option v-for="a in actions" :key="a" :value="a">{{ a }}</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label small text-muted mb-1">{{ t('labels.mode') }}</label>
<select class="form-select form-select-sm" v-model="localFilters.mode" @change="applyFilters">
<option value="">—</option>
<option v-for="m in modes" :key="m" :value="m">{{ m }}</option>
</select>
</div>
<div class="col-md-2 d-flex gap-1">
<button class="btn btn-primary btn-sm" @click="applyFilters">Filtrer</button>
<button v-if="hasActiveFilters" class="btn btn-outline-secondary btn-sm" @click="clearFilters">✕</button>
</div>
</div>
</div>
</div>
<!-- Active filters badges -->
<div v-if="hasActiveFilters" class="mb-3 d-flex gap-2 flex-wrap">
<span v-if="filters.device" class="badge bg-light text-dark border d-flex align-items-center gap-1">
Équipement: <strong class="font-monospace">{{ filters.device }}</strong>
<button class="btn-close btn-close-sm ms-1" style="font-size: 0.6rem;" @click="removeFilter('device')"></button>
</span>
<span v-if="filters.status" class="badge bg-light text-dark border d-flex align-items-center gap-1">
Statut: <strong>{{ filters.status }}</strong>
<button class="btn-close btn-close-sm ms-1" style="font-size: 0.6rem;" @click="removeFilter('status')"></button>
</span>
<span v-if="filters.action" class="badge bg-light text-dark border d-flex align-items-center gap-1">
Action: <strong>{{ filters.action }}</strong>
<button class="btn-close btn-close-sm ms-1" style="font-size: 0.6rem;" @click="removeFilter('action')"></button>
</span>
<span v-if="filters.mode" class="badge bg-light text-dark border d-flex align-items-center gap-1">
Mode: <strong>{{ filters.mode }}</strong>
<button class="btn-close btn-close-sm ms-1" style="font-size: 0.6rem;" @click="removeFilter('mode')"></button>
</span>
</div>
<!-- Results count -->
<p class="text-muted small mb-2">{{ commands.length }} résultat(s)</p>
<!-- Table -->
<div class="table-responsive">
<table class="table table-sm table-hover table-striped">
<thead class="table-light">
<tr>
<th>{{ t('labels.deviceIdentifier') }}</th>
<th>{{ t('labels.action') }}</th>
<th>{{ t('labels.status') }}</th>
<th>{{ t('labels.mode') }}</th>
<th>{{ t('labels.priority') }}</th>
<th>{{ t('labels.creationDate') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="cmd in commands" :key="cmd._id">
<td class="font-monospace small">{{ cmd.deviceIdentifier }}</td>
<td class="small">{{ cmd.action }}</td>
<td>
<span class="badge" :class="{
'bg-success': cmd.status === 'COMPLETED',
'bg-danger': cmd.status === 'FAILED',
'bg-warning text-dark': cmd.status === 'PENDING',
'bg-info': cmd.status === 'SENT',
'bg-secondary': cmd.status === 'WAITING',
}">{{ cmd.status }}</span>
</td>
<td class="small">{{ cmd.mode }}</td>
<td class="small">{{ cmd.priority }}</td>
<td class="small">{{ cmd.createdAt ? new Date(cmd.createdAt).toLocaleString() : '' }}</td>
</tr>
<tr v-if="commands.length === 0">
<td colspan="6" class="text-center text-muted py-3">Aucune commande trouvée.</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>