@camstack/addon-admin-ui 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-DjELGD4R.css +1 -0
- package/dist/assets/index-w55PwKyu.js +598 -0
- package/{index.html → dist/index.html} +3 -1
- package/dist/server/addon.d.ts +11 -0
- package/dist/server/addon.js +50 -0
- package/dist/server/addon.js.map +1 -0
- package/package.json +5 -1
- package/src/App.tsx +0 -71
- package/src/components/addons/AddonCard.tsx +0 -339
- package/src/components/addons/AddonUploadZone.tsx +0 -307
- package/src/components/addons/CapabilityBadge.tsx +0 -55
- package/src/components/addons/CapabilityMap.tsx +0 -133
- package/src/components/addons/UpdatesList.tsx +0 -119
- package/src/components/agents/AgentCard.tsx +0 -281
- package/src/components/agents/AgentLogs.tsx +0 -231
- package/src/components/agents/ProcessList.tsx +0 -127
- package/src/components/agents/ProcessTree.tsx +0 -369
- package/src/components/agents/TaskList.tsx +0 -68
- package/src/components/cameras/CameraCard.tsx +0 -60
- package/src/components/cameras/LiveEventsPanel.tsx +0 -91
- package/src/components/cameras/ProviderSection.tsx +0 -50
- package/src/components/cameras/StreamArea.tsx +0 -107
- package/src/components/cameras/tabs/AddonsTab.tsx +0 -113
- package/src/components/cameras/tabs/CameraEventsTab.tsx +0 -129
- package/src/components/cameras/tabs/PipelineTab.tsx +0 -118
- package/src/components/cameras/tabs/StreamsTab.tsx +0 -114
- package/src/components/dashboard/BlockPicker.tsx +0 -54
- package/src/components/dashboard/BlockWrapper.tsx +0 -97
- package/src/components/dashboard/DashboardGrid.tsx +0 -160
- package/src/components/dashboard/block-registry.ts +0 -15
- package/src/components/dashboard/blocks/PipelineStagesBlock.tsx +0 -39
- package/src/components/dashboard/blocks/StorageBlock.tsx +0 -66
- package/src/components/dashboard/blocks/SystemStatusBlock.tsx +0 -67
- package/src/components/dashboard/blocks/index.ts +0 -32
- package/src/components/device/DeviceHeader.tsx +0 -116
- package/src/components/device/FloatingPanel.tsx +0 -132
- package/src/components/device/FloatingPanelManager.tsx +0 -167
- package/src/components/device/PanelContent.tsx +0 -196
- package/src/components/device/QuickConfigWizard.tsx +0 -507
- package/src/components/device/tabs/DetectionConfigTab.tsx +0 -96
- package/src/components/device/tabs/EventsTab.tsx +0 -19
- package/src/components/device/tabs/LogsTab.tsx +0 -22
- package/src/components/device/tabs/OverviewTab.tsx +0 -104
- package/src/components/device/tabs/ProviderSettingsTab.tsx +0 -34
- package/src/components/device/tabs/RecordingTab.tsx +0 -47
- package/src/components/device/tabs/ReplTab.tsx +0 -153
- package/src/components/device/tabs/TrackTrailTab.tsx +0 -49
- package/src/components/device/tabs/ZonesTab.tsx +0 -98
- package/src/components/device/zone-editor/ZoneCanvas.tsx +0 -354
- package/src/components/device/zone-editor/ZoneForm.tsx +0 -128
- package/src/components/device/zone-editor/ZoneList.tsx +0 -150
- package/src/components/form-builder/FormBuilder.tsx +0 -135
- package/src/components/form-builder/FormField.tsx +0 -732
- package/src/components/form-builder/ModelSelector.tsx +0 -239
- package/src/components/integrations/AddDeviceDialog.tsx +0 -205
- package/src/components/integrations/CompactDeviceCard.tsx +0 -35
- package/src/components/integrations/DeviceCard.tsx +0 -29
- package/src/components/integrations/DeviceDiscoveryStep.tsx +0 -105
- package/src/components/integrations/DeviceGrid.tsx +0 -79
- package/src/components/integrations/DeviceGroupHeader.tsx +0 -17
- package/src/components/integrations/DiscoveredDeviceCard.tsx +0 -26
- package/src/components/integrations/IntegrationCard.tsx +0 -40
- package/src/components/integrations/IntegrationWizard.tsx +0 -171
- package/src/components/integrations/ProviderConfigForm.tsx +0 -89
- package/src/components/integrations/ProviderPicker.tsx +0 -91
- package/src/components/integrations/SnapshotPopover.tsx +0 -68
- package/src/components/metrics/AgentLoad.tsx +0 -113
- package/src/components/metrics/IntegrationUsage.tsx +0 -90
- package/src/components/metrics/PipelineStatus.tsx +0 -105
- package/src/components/metrics/ProcessResources.tsx +0 -139
- package/src/components/pipeline/PhaseSettings.tsx +0 -131
- package/src/components/shared/CapabilityBadges.tsx +0 -30
- package/src/components/shared/ProviderIcon.tsx +0 -42
- package/src/components/shared/StatusBadge.tsx +0 -23
- package/src/components/shared/WebRtcPlayer.tsx +0 -211
- package/src/components/timeline/EventMarker.tsx +0 -32
- package/src/components/timeline/TimelineBar.tsx +0 -131
- package/src/components/ui/ConfirmDialog.tsx +0 -115
- package/src/components/ui/ToastContainer.tsx +0 -92
- package/src/contexts/auth-context.tsx +0 -91
- package/src/hooks/useBackendClient.ts +0 -6
- package/src/hooks/useTheme.ts +0 -1
- package/src/i18n/en.json +0 -164
- package/src/i18n/index.ts +0 -29
- package/src/i18n/it.json +0 -164
- package/src/index.css +0 -63
- package/src/layouts/AddonPageLoader.tsx +0 -120
- package/src/layouts/AppLayout.tsx +0 -238
- package/src/layouts/ProtectedRoute.tsx +0 -25
- package/src/lib/addon-page-context.ts +0 -29
- package/src/lib/backend.ts +0 -16
- package/src/main.tsx +0 -21
- package/src/pages/AccessDenied.tsx +0 -22
- package/src/pages/Cameras.tsx +0 -127
- package/src/pages/Dashboard.tsx +0 -6
- package/src/pages/DeviceDetail.tsx +0 -175
- package/src/pages/IntegrationDetail.tsx +0 -224
- package/src/pages/Integrations.tsx +0 -330
- package/src/pages/Login.tsx +0 -106
- package/src/pages/Metrics.tsx +0 -18
- package/src/pages/PipelineConfig.tsx +0 -282
- package/src/pages/Showroom.tsx +0 -351
- package/src/pages/Timeline.tsx +0 -269
- package/src/pages/system/Addons.tsx +0 -525
- package/src/pages/system/Agents.tsx +0 -362
- package/src/pages/system/Logs.tsx +0 -131
- package/src/pages/system/Models.tsx +0 -102
- package/src/pages/system/Processes.tsx +0 -129
- package/src/pages/system/Repl.tsx +0 -148
- package/src/pages/system/Settings.tsx +0 -168
- package/src/pages/system/Users.tsx +0 -174
- package/src/server/addon.ts +0 -54
- package/src/types/config-ui.ts +0 -210
- package/src/types/dashboard.ts +0 -39
- package/tsconfig.json +0 -29
- package/tsconfig.server.json +0 -16
- package/tsup.config.ts +0 -20
- package/vite.config.ts +0 -68
- /package/{public → dist}/brand/logo-dark.svg +0 -0
- /package/{public → dist}/brand/logo-horizontal-dark.svg +0 -0
- /package/{public → dist}/brand/logo-horizontal-light.svg +0 -0
- /package/{public → dist}/brand/logo-light.svg +0 -0
- /package/{public → dist}/brand/logo-wide-dark.svg +0 -0
- /package/{public → dist}/brand/logo-wide-light.svg +0 -0
- /package/{public → dist}/favicon.svg +0 -0
- /package/{public → dist}/vendor/react-jsx-runtime.mjs +0 -0
- /package/{public → dist}/vendor/react.mjs +0 -0
package/src/i18n/en.json
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"nav": {
|
|
3
|
-
"dashboard": "Dashboard",
|
|
4
|
-
"integrations": "Integrations",
|
|
5
|
-
"metrics": "Metrics"
|
|
6
|
-
},
|
|
7
|
-
"system": {
|
|
8
|
-
"title": "System",
|
|
9
|
-
"addons": "Addons",
|
|
10
|
-
"agents": "Agents",
|
|
11
|
-
"processes": "Processes",
|
|
12
|
-
"logs": "Logs",
|
|
13
|
-
"users": "Users",
|
|
14
|
-
"settings": "Settings",
|
|
15
|
-
"repl": "REPL",
|
|
16
|
-
"models": "Models"
|
|
17
|
-
},
|
|
18
|
-
"common": {
|
|
19
|
-
"save": "Save",
|
|
20
|
-
"cancel": "Cancel",
|
|
21
|
-
"delete": "Delete",
|
|
22
|
-
"enable": "Enable",
|
|
23
|
-
"disable": "Disable",
|
|
24
|
-
"edit": "Edit",
|
|
25
|
-
"add": "Add",
|
|
26
|
-
"remove": "Remove",
|
|
27
|
-
"confirm": "Confirm",
|
|
28
|
-
"close": "Close",
|
|
29
|
-
"back": "Back",
|
|
30
|
-
"next": "Next",
|
|
31
|
-
"search": "Search",
|
|
32
|
-
"filter": "Filter",
|
|
33
|
-
"reset": "Reset",
|
|
34
|
-
"apply": "Apply",
|
|
35
|
-
"submit": "Submit",
|
|
36
|
-
"loading": "Loading…",
|
|
37
|
-
"error": "Error",
|
|
38
|
-
"success": "Success",
|
|
39
|
-
"warning": "Warning",
|
|
40
|
-
"info": "Info",
|
|
41
|
-
"noData": "No data available",
|
|
42
|
-
"noResults": "No results found",
|
|
43
|
-
"retry": "Retry",
|
|
44
|
-
"refresh": "Refresh",
|
|
45
|
-
"copy": "Copy",
|
|
46
|
-
"copied": "Copied!",
|
|
47
|
-
"yes": "Yes",
|
|
48
|
-
"no": "No"
|
|
49
|
-
},
|
|
50
|
-
"status": {
|
|
51
|
-
"online": "Online",
|
|
52
|
-
"offline": "Offline",
|
|
53
|
-
"connecting": "Connecting",
|
|
54
|
-
"error": "Error",
|
|
55
|
-
"disabled": "Disabled",
|
|
56
|
-
"enabled": "Enabled",
|
|
57
|
-
"active": "Active",
|
|
58
|
-
"inactive": "Inactive",
|
|
59
|
-
"running": "Running",
|
|
60
|
-
"stopped": "Stopped",
|
|
61
|
-
"pending": "Pending",
|
|
62
|
-
"unknown": "Unknown"
|
|
63
|
-
},
|
|
64
|
-
"auth": {
|
|
65
|
-
"login": "Login",
|
|
66
|
-
"logout": "Logout",
|
|
67
|
-
"username": "Username",
|
|
68
|
-
"password": "Password",
|
|
69
|
-
"signIn": "Sign In",
|
|
70
|
-
"invalidCredentials": "Invalid username or password"
|
|
71
|
-
},
|
|
72
|
-
"theme": {
|
|
73
|
-
"dark": "Dark",
|
|
74
|
-
"light": "Light",
|
|
75
|
-
"system": "System"
|
|
76
|
-
},
|
|
77
|
-
"language": {
|
|
78
|
-
"select": "Language",
|
|
79
|
-
"en": "English",
|
|
80
|
-
"it": "Italian"
|
|
81
|
-
},
|
|
82
|
-
"pages": {
|
|
83
|
-
"dashboard": {
|
|
84
|
-
"title": "Dashboard",
|
|
85
|
-
"subtitle": "Overview of all devices and their status"
|
|
86
|
-
},
|
|
87
|
-
"integrations": {
|
|
88
|
-
"title": "Integrations",
|
|
89
|
-
"subtitle": "Manage camera sources and provider connections"
|
|
90
|
-
},
|
|
91
|
-
"metrics": {
|
|
92
|
-
"title": "Metrics",
|
|
93
|
-
"subtitle": "System performance and usage statistics"
|
|
94
|
-
},
|
|
95
|
-
"agents": {
|
|
96
|
-
"title": "Agents",
|
|
97
|
-
"subtitle": "Manage distributed processing agents"
|
|
98
|
-
},
|
|
99
|
-
"addons": {
|
|
100
|
-
"title": "Addons",
|
|
101
|
-
"subtitle": "Extend functionality with addon modules"
|
|
102
|
-
},
|
|
103
|
-
"settings": {
|
|
104
|
-
"title": "Settings",
|
|
105
|
-
"subtitle": "Configure system-wide preferences"
|
|
106
|
-
},
|
|
107
|
-
"users": {
|
|
108
|
-
"title": "Users",
|
|
109
|
-
"subtitle": "Manage user accounts and permissions"
|
|
110
|
-
},
|
|
111
|
-
"logs": {
|
|
112
|
-
"title": "Logs",
|
|
113
|
-
"subtitle": "View system and device logs"
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
"integrations": {
|
|
117
|
-
"preview": "Preview",
|
|
118
|
-
"snapshotUnavailable": "Snapshot unavailable",
|
|
119
|
-
"noSnapshot": "No snapshot",
|
|
120
|
-
"lastSnapshot": "Last snapshot:",
|
|
121
|
-
"offline": "Offline",
|
|
122
|
-
"active": "Active",
|
|
123
|
-
"available": "Available",
|
|
124
|
-
"noDevices": "No devices.",
|
|
125
|
-
"addFirstDevice": "Add your first device to get started.",
|
|
126
|
-
"import": "+ Import",
|
|
127
|
-
"noProviders": "No providers available. Install a provider addon.",
|
|
128
|
-
"manage": "Manage",
|
|
129
|
-
"integrationName": "Integration name",
|
|
130
|
-
"integrationNamePlaceholder": "e.g. Garage Server",
|
|
131
|
-
"connectionSuccess": "Connection successful!",
|
|
132
|
-
"errorPrefix": "Error:",
|
|
133
|
-
"back": "Back",
|
|
134
|
-
"testing": "Testing...",
|
|
135
|
-
"testConnection": "Test connection",
|
|
136
|
-
"forward": "Next",
|
|
137
|
-
"searchingDevices": "Searching for devices...",
|
|
138
|
-
"foundDevices": "Found {{count}} devices. Select the ones to import.",
|
|
139
|
-
"noDevicesFound": "No devices found.",
|
|
140
|
-
"skip": "Skip",
|
|
141
|
-
"importSelected": "Import selected",
|
|
142
|
-
"newIntegration": "New Integration",
|
|
143
|
-
"configureIntegration": "Configure Integration",
|
|
144
|
-
"importDevices": "Import Devices",
|
|
145
|
-
"addDevice": "Add device",
|
|
146
|
-
"name": "Name",
|
|
147
|
-
"namePlaceholder": "e.g. Entrance Camera",
|
|
148
|
-
"snapshotUrlOptional": "Snapshot URL (optional)",
|
|
149
|
-
"streamUrls": "Stream URLs",
|
|
150
|
-
"addStream": "Add stream",
|
|
151
|
-
"cancel": "Cancel",
|
|
152
|
-
"saving": "Saving...",
|
|
153
|
-
"save": "Save",
|
|
154
|
-
"saveAndNew": "Save and new",
|
|
155
|
-
"test": "Test",
|
|
156
|
-
"stream": "Stream {{number}}:",
|
|
157
|
-
"devices": "devices",
|
|
158
|
-
"rediscover": "Rediscover",
|
|
159
|
-
"config": "Config",
|
|
160
|
-
"integrationNotFound": "Integration not found.",
|
|
161
|
-
"configComingSoon": "Config coming soon.",
|
|
162
|
-
"providerConfig": "Provider Config"
|
|
163
|
-
}
|
|
164
|
-
}
|
package/src/i18n/index.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import i18n from 'i18next'
|
|
2
|
-
import { initReactI18next } from 'react-i18next'
|
|
3
|
-
import en from './en.json'
|
|
4
|
-
import it from './it.json'
|
|
5
|
-
|
|
6
|
-
const STORAGE_KEY = 'camstack_language'
|
|
7
|
-
|
|
8
|
-
const savedLanguage = localStorage.getItem(STORAGE_KEY) ?? 'en'
|
|
9
|
-
|
|
10
|
-
i18n
|
|
11
|
-
.use(initReactI18next)
|
|
12
|
-
.init({
|
|
13
|
-
resources: {
|
|
14
|
-
en: { translation: en },
|
|
15
|
-
it: { translation: it },
|
|
16
|
-
},
|
|
17
|
-
lng: savedLanguage,
|
|
18
|
-
fallbackLng: 'en',
|
|
19
|
-
interpolation: {
|
|
20
|
-
escapeValue: false, // React already escapes values
|
|
21
|
-
},
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// Persist language changes
|
|
25
|
-
i18n.on('languageChanged', (lng) => {
|
|
26
|
-
localStorage.setItem(STORAGE_KEY, lng)
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
export default i18n
|
package/src/i18n/it.json
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"nav": {
|
|
3
|
-
"dashboard": "Dashboard",
|
|
4
|
-
"integrations": "Integrazioni",
|
|
5
|
-
"metrics": "Metriche"
|
|
6
|
-
},
|
|
7
|
-
"system": {
|
|
8
|
-
"title": "Sistema",
|
|
9
|
-
"addons": "Addon",
|
|
10
|
-
"agents": "Agenti",
|
|
11
|
-
"processes": "Processi",
|
|
12
|
-
"logs": "Log",
|
|
13
|
-
"users": "Utenti",
|
|
14
|
-
"settings": "Impostazioni",
|
|
15
|
-
"repl": "REPL",
|
|
16
|
-
"models": "Modelli"
|
|
17
|
-
},
|
|
18
|
-
"common": {
|
|
19
|
-
"save": "Salva",
|
|
20
|
-
"cancel": "Annulla",
|
|
21
|
-
"delete": "Elimina",
|
|
22
|
-
"enable": "Abilita",
|
|
23
|
-
"disable": "Disabilita",
|
|
24
|
-
"edit": "Modifica",
|
|
25
|
-
"add": "Aggiungi",
|
|
26
|
-
"remove": "Rimuovi",
|
|
27
|
-
"confirm": "Conferma",
|
|
28
|
-
"close": "Chiudi",
|
|
29
|
-
"back": "Indietro",
|
|
30
|
-
"next": "Avanti",
|
|
31
|
-
"search": "Cerca",
|
|
32
|
-
"filter": "Filtra",
|
|
33
|
-
"reset": "Reimposta",
|
|
34
|
-
"apply": "Applica",
|
|
35
|
-
"submit": "Invia",
|
|
36
|
-
"loading": "Caricamento…",
|
|
37
|
-
"error": "Errore",
|
|
38
|
-
"success": "Successo",
|
|
39
|
-
"warning": "Avviso",
|
|
40
|
-
"info": "Info",
|
|
41
|
-
"noData": "Nessun dato disponibile",
|
|
42
|
-
"noResults": "Nessun risultato trovato",
|
|
43
|
-
"retry": "Riprova",
|
|
44
|
-
"refresh": "Aggiorna",
|
|
45
|
-
"copy": "Copia",
|
|
46
|
-
"copied": "Copiato!",
|
|
47
|
-
"yes": "Sì",
|
|
48
|
-
"no": "No"
|
|
49
|
-
},
|
|
50
|
-
"status": {
|
|
51
|
-
"online": "Online",
|
|
52
|
-
"offline": "Offline",
|
|
53
|
-
"connecting": "Connessione in corso",
|
|
54
|
-
"error": "Errore",
|
|
55
|
-
"disabled": "Disabilitato",
|
|
56
|
-
"enabled": "Abilitato",
|
|
57
|
-
"active": "Attivo",
|
|
58
|
-
"inactive": "Inattivo",
|
|
59
|
-
"running": "In esecuzione",
|
|
60
|
-
"stopped": "Fermato",
|
|
61
|
-
"pending": "In attesa",
|
|
62
|
-
"unknown": "Sconosciuto"
|
|
63
|
-
},
|
|
64
|
-
"auth": {
|
|
65
|
-
"login": "Accesso",
|
|
66
|
-
"logout": "Esci",
|
|
67
|
-
"username": "Nome utente",
|
|
68
|
-
"password": "Password",
|
|
69
|
-
"signIn": "Accedi",
|
|
70
|
-
"invalidCredentials": "Nome utente o password non validi"
|
|
71
|
-
},
|
|
72
|
-
"theme": {
|
|
73
|
-
"dark": "Scuro",
|
|
74
|
-
"light": "Chiaro",
|
|
75
|
-
"system": "Sistema"
|
|
76
|
-
},
|
|
77
|
-
"language": {
|
|
78
|
-
"select": "Lingua",
|
|
79
|
-
"en": "Inglese",
|
|
80
|
-
"it": "Italiano"
|
|
81
|
-
},
|
|
82
|
-
"pages": {
|
|
83
|
-
"dashboard": {
|
|
84
|
-
"title": "Dashboard",
|
|
85
|
-
"subtitle": "Panoramica di tutti i dispositivi e il loro stato"
|
|
86
|
-
},
|
|
87
|
-
"integrations": {
|
|
88
|
-
"title": "Integrazioni",
|
|
89
|
-
"subtitle": "Gestisci le sorgenti video e le connessioni ai provider"
|
|
90
|
-
},
|
|
91
|
-
"metrics": {
|
|
92
|
-
"title": "Metriche",
|
|
93
|
-
"subtitle": "Statistiche di prestazioni e utilizzo del sistema"
|
|
94
|
-
},
|
|
95
|
-
"agents": {
|
|
96
|
-
"title": "Agenti",
|
|
97
|
-
"subtitle": "Gestisci gli agenti di elaborazione distribuita"
|
|
98
|
-
},
|
|
99
|
-
"addons": {
|
|
100
|
-
"title": "Addon",
|
|
101
|
-
"subtitle": "Estendi le funzionalità con moduli addon"
|
|
102
|
-
},
|
|
103
|
-
"settings": {
|
|
104
|
-
"title": "Impostazioni",
|
|
105
|
-
"subtitle": "Configura le preferenze di sistema"
|
|
106
|
-
},
|
|
107
|
-
"users": {
|
|
108
|
-
"title": "Utenti",
|
|
109
|
-
"subtitle": "Gestisci gli account utente e i permessi"
|
|
110
|
-
},
|
|
111
|
-
"logs": {
|
|
112
|
-
"title": "Log",
|
|
113
|
-
"subtitle": "Visualizza i log di sistema e dei dispositivi"
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
"integrations": {
|
|
117
|
-
"preview": "Anteprima",
|
|
118
|
-
"snapshotUnavailable": "Snapshot non disponibile",
|
|
119
|
-
"noSnapshot": "Nessuno snapshot",
|
|
120
|
-
"lastSnapshot": "Ultimo snapshot:",
|
|
121
|
-
"offline": "Offline",
|
|
122
|
-
"active": "Attivi",
|
|
123
|
-
"available": "Disponibili",
|
|
124
|
-
"noDevices": "Nessun dispositivo.",
|
|
125
|
-
"addFirstDevice": "Aggiungi il primo dispositivo per iniziare.",
|
|
126
|
-
"import": "+ Importa",
|
|
127
|
-
"noProviders": "Nessun provider disponibile. Installa un addon provider.",
|
|
128
|
-
"manage": "Gestisci",
|
|
129
|
-
"integrationName": "Nome integrazione",
|
|
130
|
-
"integrationNamePlaceholder": "es. Server Garage",
|
|
131
|
-
"connectionSuccess": "Connessione riuscita!",
|
|
132
|
-
"errorPrefix": "Errore:",
|
|
133
|
-
"back": "Indietro",
|
|
134
|
-
"testing": "Test...",
|
|
135
|
-
"testConnection": "Test connessione",
|
|
136
|
-
"forward": "Avanti",
|
|
137
|
-
"searchingDevices": "Ricerca dispositivi in corso...",
|
|
138
|
-
"foundDevices": "Trovati {{count}} dispositivi. Seleziona quelli da importare.",
|
|
139
|
-
"noDevicesFound": "Nessun dispositivo trovato.",
|
|
140
|
-
"skip": "Salta",
|
|
141
|
-
"importSelected": "Importa selezionati",
|
|
142
|
-
"newIntegration": "Nuova Integrazione",
|
|
143
|
-
"configureIntegration": "Configura Integrazione",
|
|
144
|
-
"importDevices": "Importa Dispositivi",
|
|
145
|
-
"addDevice": "Aggiungi dispositivo",
|
|
146
|
-
"name": "Nome",
|
|
147
|
-
"namePlaceholder": "es. Camera Ingresso",
|
|
148
|
-
"snapshotUrlOptional": "Snapshot URL (opzionale)",
|
|
149
|
-
"streamUrls": "Stream URLs",
|
|
150
|
-
"addStream": "Aggiungi stream",
|
|
151
|
-
"cancel": "Annulla",
|
|
152
|
-
"saving": "Salvataggio...",
|
|
153
|
-
"save": "Salva",
|
|
154
|
-
"saveAndNew": "Salva e nuova",
|
|
155
|
-
"test": "Test",
|
|
156
|
-
"stream": "Stream {{number}}:",
|
|
157
|
-
"devices": "dispositivi",
|
|
158
|
-
"rediscover": "Riscopri",
|
|
159
|
-
"config": "Config",
|
|
160
|
-
"integrationNotFound": "Integrazione non trovata.",
|
|
161
|
-
"configComingSoon": "Config coming soon.",
|
|
162
|
-
"providerConfig": "Provider Config"
|
|
163
|
-
}
|
|
164
|
-
}
|
package/src/index.css
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
@import "tailwindcss";
|
|
2
|
-
@import "@camstack/ui-library/tailwind/camstack-theme.css";
|
|
3
|
-
|
|
4
|
-
/* Scan ui-library source for Tailwind classes used in shared components */
|
|
5
|
-
@source "../../ui-library/src";
|
|
6
|
-
|
|
7
|
-
/* Force dark mode by default until ThemeProvider kicks in */
|
|
8
|
-
:root {
|
|
9
|
-
color-scheme: dark;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
body {
|
|
13
|
-
margin: 0;
|
|
14
|
-
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
15
|
-
-webkit-font-smoothing: antialiased;
|
|
16
|
-
-moz-osx-font-smoothing: grayscale;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/* No global transitions — use Tailwind transition-* utilities on specific elements */
|
|
20
|
-
|
|
21
|
-
/* Override react-grid-layout default styles to match our theme */
|
|
22
|
-
.react-grid-item.react-grid-placeholder {
|
|
23
|
-
background-color: var(--color-primary) !important;
|
|
24
|
-
opacity: 0.15 !important;
|
|
25
|
-
border-radius: 8px !important;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.react-grid-item > .react-resizable-handle::after {
|
|
29
|
-
border-right-color: var(--color-foreground-subtle) !important;
|
|
30
|
-
border-bottom-color: var(--color-foreground-subtle) !important;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/* Scrollbar styling */
|
|
34
|
-
::-webkit-scrollbar {
|
|
35
|
-
width: 6px;
|
|
36
|
-
height: 6px;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
::-webkit-scrollbar-track {
|
|
40
|
-
background: transparent;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
::-webkit-scrollbar-thumb {
|
|
44
|
-
background-color: var(--color-border);
|
|
45
|
-
border-radius: 3px;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
::-webkit-scrollbar-thumb:hover {
|
|
49
|
-
background-color: var(--color-foreground-subtle);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/* Focus ring for keyboard accessibility */
|
|
53
|
-
:focus-visible {
|
|
54
|
-
outline: 2px solid var(--color-primary);
|
|
55
|
-
outline-offset: 2px;
|
|
56
|
-
border-radius: 4px;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* Input placeholder color */
|
|
60
|
-
input::placeholder,
|
|
61
|
-
textarea::placeholder {
|
|
62
|
-
color: var(--color-foreground-disabled);
|
|
63
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect, Suspense, lazy, type ComponentType } from 'react'
|
|
2
|
-
import { useParams } from 'react-router-dom'
|
|
3
|
-
import { useQuery } from '@tanstack/react-query'
|
|
4
|
-
import { getBackendClient } from '../lib/backend'
|
|
5
|
-
|
|
6
|
-
export interface AddonPageInfo {
|
|
7
|
-
readonly id: string
|
|
8
|
-
readonly addonId: string
|
|
9
|
-
readonly label: string
|
|
10
|
-
readonly icon: string
|
|
11
|
-
readonly path: string
|
|
12
|
-
readonly bundle: string
|
|
13
|
-
readonly bundleUrl: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** Flatten the nested tRPC response into a flat AddonPageInfo */
|
|
17
|
-
export function flattenPages(raw: readonly unknown[]): readonly AddonPageInfo[] {
|
|
18
|
-
return raw.map((item: any) => ({
|
|
19
|
-
id: item.page.id,
|
|
20
|
-
addonId: item.addonId,
|
|
21
|
-
label: item.page.label,
|
|
22
|
-
icon: item.page.icon,
|
|
23
|
-
path: item.page.path,
|
|
24
|
-
bundle: item.page.bundle,
|
|
25
|
-
bundleUrl: item.bundleUrl,
|
|
26
|
-
}))
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** Cache for loaded page components */
|
|
30
|
-
const pageComponentCache = new Map<string, ComponentType<any>>()
|
|
31
|
-
|
|
32
|
-
export function AddonPageLoader() {
|
|
33
|
-
const { pagePath } = useParams<{ pagePath: string }>()
|
|
34
|
-
const client = getBackendClient()
|
|
35
|
-
|
|
36
|
-
const { data: pages } = useQuery({
|
|
37
|
-
queryKey: ['addon-pages'],
|
|
38
|
-
queryFn: async (): Promise<readonly AddonPageInfo[]> => {
|
|
39
|
-
const raw = await client.trpc.addonPages.listPages.query()
|
|
40
|
-
return flattenPages(raw as readonly unknown[])
|
|
41
|
-
},
|
|
42
|
-
staleTime: 60_000,
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
const page = pages?.find((p) => p.path === `/addon/${pagePath}`)
|
|
46
|
-
const [PageComponent, setPageComponent] = useState<ComponentType<any> | null>(null)
|
|
47
|
-
const [error, setError] = useState<string | null>(null)
|
|
48
|
-
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
if (!page) return
|
|
51
|
-
|
|
52
|
-
const cacheKey = `${page.addonId}/${page.bundle}`
|
|
53
|
-
|
|
54
|
-
// Check cache
|
|
55
|
-
const cached = pageComponentCache.get(cacheKey)
|
|
56
|
-
if (cached) {
|
|
57
|
-
setPageComponent(() => cached)
|
|
58
|
-
return
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Dynamic import of the addon page module
|
|
62
|
-
setError(null)
|
|
63
|
-
setPageComponent(null)
|
|
64
|
-
|
|
65
|
-
const url = page.bundleUrl
|
|
66
|
-
import(/* @vite-ignore */ url)
|
|
67
|
-
.then((mod) => {
|
|
68
|
-
const Component = mod.default
|
|
69
|
-
if (typeof Component !== 'function') {
|
|
70
|
-
throw new Error(`Addon page "${page.id}" does not export a default React component`)
|
|
71
|
-
}
|
|
72
|
-
pageComponentCache.set(cacheKey, Component)
|
|
73
|
-
setPageComponent(() => Component)
|
|
74
|
-
})
|
|
75
|
-
.catch((err) => {
|
|
76
|
-
console.error(`[AddonPageLoader] Failed to load ${url}:`, err)
|
|
77
|
-
setError(`Failed to load addon page: ${err.message}`)
|
|
78
|
-
})
|
|
79
|
-
}, [page])
|
|
80
|
-
|
|
81
|
-
if (!pages) {
|
|
82
|
-
return (
|
|
83
|
-
<div className="flex items-center justify-center h-full">
|
|
84
|
-
<div className="animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full" />
|
|
85
|
-
</div>
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!page) {
|
|
90
|
-
return (
|
|
91
|
-
<div className="flex items-center justify-center h-full text-foreground-subtle">
|
|
92
|
-
Addon page not found
|
|
93
|
-
</div>
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (error) {
|
|
98
|
-
return (
|
|
99
|
-
<div className="flex items-center justify-center h-full text-red-400 text-sm">
|
|
100
|
-
{error}
|
|
101
|
-
</div>
|
|
102
|
-
)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (!PageComponent) {
|
|
106
|
-
return (
|
|
107
|
-
<div className="flex items-center justify-center h-full">
|
|
108
|
-
<div className="animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full" />
|
|
109
|
-
</div>
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<PageComponent
|
|
115
|
-
trpc={client.trpc}
|
|
116
|
-
theme={{ isDark: document.documentElement.classList.contains('dark') }}
|
|
117
|
-
navigate={(path: string) => { window.location.href = path }}
|
|
118
|
-
/>
|
|
119
|
-
)
|
|
120
|
-
}
|