fix project life and plug-and-replay on peripherals

This commit is contained in:
2025-11-11 20:13:27 +01:00
parent 621c1922ca
commit b094019ed9
12 changed files with 326 additions and 262 deletions

View File

@@ -99,7 +99,7 @@
</div>
{/if}
<Tooltip message={tooltipMessage} show={tooltipShowing} position={tooltipPosition}></Tooltip>
<div class="list" style="color: {$colors.white}; display: {listShowing ? "block" : "none"};"
<div class="list" style="color: {$colors.white}; display: {listShowing ? "block" : "none"}; border: 2px solid {$colors.second}; background-color: {$colors.first};"
on:mouseleave={hideList}>
{#each Array.from(choices) as [key, value]}
<div class="item" on:click={() => handleclick({key})}>{value}</div>
@@ -125,7 +125,6 @@
.list {
z-index: 200;
padding: 0.2em;
backdrop-filter: blur(20px);
margin-top: 0.2em;
position: absolute;
width: auto;

View File

@@ -15,13 +15,14 @@
export let signalizable = false;
export let signalized = false;
export let selected = false;
export let status = "disconnected";
export let status = "PERIPHERAL_DISCONNECTED";
// Emit a delete event when the device is being removed
const dispatch = createEventDispatcher();
function remove(event){
dispatch('delete')
}
function add(event){
dispatch('add')
}
@@ -37,11 +38,11 @@
</script>
<div class="card" on:dblclick={dblclick}>
<div class="{selected ? "selected" : "unselected"} {status == "connecting" ? "waiting" : ""}" on:mousedown={click} style="color: {(status == "disconnected") ? $colors.first : $colors.white};">
<div class="{selected ? "selected" : "unselected"} {status == "PERIPHERAL_CONNECTING" ? "waiting" : ""}" on:mousedown={click} style="color: {(status == "PERIPHERAL_DISCONNECTED") ? $colors.first : $colors.white};">
<div style="z-index: 1;">
<p>{#if status == "disconnected" }<i class='bx bx-no-signal' style="font-size:100%; color: var(--nok-color);"></i> {/if}{title}</p>
<p>{#if status == "PERIPHERAL_DISCONNECTED" }<i class='bx bx-no-signal' style="font-size:100%; color: var(--nok-color);"></i> {/if}{title}</p>
<h6 class="subtitle">{type} {location != '' ? "- " : ""}<i>{location}</i></h6>
{#if status == "disconnected"}
{#if status == "PERIPHERAL_DISCONNECTED"}
<h6><b>Disconnected</b></h6>
{:else}
<h6>{line1}</h6>
@@ -50,9 +51,9 @@
</div>
<div class="actions">
<InfoButton on:click={add} color="{(status == "disconnected") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { addable ? 'flex' : 'none' }" icon='bxs-message-square-add' interactive message={$_("projectHardwareAddTooltip")}/>
<InfoButton on:click={remove} color="{(status == "disconnected") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { removable ? 'flex' : 'none' }" icon='bx-trash' interactive message={$_("projectHardwareDeleteTooltip")}/>
<InfoButton style="margin: 0.2em; display: { (status == "activated" || status == "deactivated") ? 'flex' : 'none' }" background={ (status == "activated") ? $colors.ok : (status == "deactivated") ? $colors.nok : null} icon='bx-pulse' hide={!signalizable}/>
<InfoButton on:click={add} color="{(status == "PERIPHERAL_DISCONNECTED") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { addable ? 'flex' : 'none' }" icon='bxs-message-square-add' interactive message={$_("projectHardwareAddTooltip")}/>
<InfoButton on:click={remove} color="{(status == "PERIPHERAL_DISCONNECTED") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { removable ? 'flex' : 'none' }" icon='bx-trash' interactive message={$_("projectHardwareDeleteTooltip")}/>
<InfoButton style="margin: 0.2em; display: { (status == "PERIPHERAL_ACTIVATED" || status == "PERIPHERAL_DEACTIVATED") ? 'flex' : 'none' }" background={ (status == "PERIPHERAL_ACTIVATED") ? $colors.ok : (status == "PERIPHERAL_DEACTIVATED") ? $colors.nok : null} icon='bx-pulse' hide={!signalizable}/>
</div>
</div>
</div>

View File

@@ -11,20 +11,8 @@
// Add the peripheral to the project
function addPeripheral(peripheral){
// Add the peripheral to the project (backend)
AddPeripheral(peripheral).then((serialNumber) => {
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[serialNumber]: {
...storedPeripherals[serialNumber],
Name: peripheral.Name,
ProtocolName: peripheral.ProtocolName,
SerialNumber: serialNumber,
isSaved: true,
},
}})
$needProjectSave = true
}).catch((error) => {
AddPeripheral(peripheral)
.catch((error) => {
console.log("Unable to add the peripheral to the project: " + error)
generateToast('danger', 'bx-error', $_("addPeripheralErrorToast"))
})
@@ -33,27 +21,8 @@
// Remove the peripheral from the project
function removePeripheral(peripheral) {
// Delete the peripheral from the project (backend)
RemovePeripheral(peripheral.ProtocolName, peripheral.SerialNumber).then(() => {
// If the peripheral is not detected, we can delete it form the store
// If not, we only pass the isSaved key to false
let peripheralsList = get(peripherals)
let lastDetectedProperty = peripheralsList[peripheral.SerialNumber]?.isDetected
let needToDelete = (lastDetectedProperty !== true) ? true : false
peripherals.update((storedPeripherals) => {
if (needToDelete){
delete storedPeripherals[peripheral.SerialNumber];
return { ...storedPeripherals };
}
storedPeripherals[peripheral.SerialNumber].isSaved = false
return { ...storedPeripherals };
})
$needProjectSave = true
// If the peripheral is currently selected, unselect it
if (selectedPeripheralSN == peripheral.SerialNumber) {
selectedPeripheralSN = null
selectedPeripheralSettings = {}
}
}).catch((error) => {
RemovePeripheral(peripheral)
.catch((error) => {
console.log("Unable to remove the peripheral from the project: " + error)
generateToast('danger', 'bx-error', $_("removePeripheralErrorToast"))
})
@@ -76,7 +45,7 @@
}
}
// Unselect the peripheral if it is disconnect
// Unselect the peripheral if it is disconnected
$: {
Object.entries($peripherals).filter(([serialNumber, peripheral]) => {
if (!peripheral.isDetected && peripheral.isSaved && selectedPeripheralSN == serialNumber) {
@@ -120,7 +89,7 @@
if(!peripheral.isSaved)
addPeripheral(peripheral)
}}
status="connected" title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={"S/N: " + peripheral.SerialNumber} addable={!peripheral.isSaved}/>
status="PERIPHERAL_CONNECTED" title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={"S/N: " + peripheral.SerialNumber} addable={!peripheral.isSaved}/>
{/if}
{/each}
<p style="color: var(--first-color);"><i class='bx bxs-network-chart' ></i> {$_("projectHardwareOthersLabel")}</p>
@@ -134,7 +103,7 @@
{#if savedPeripheralNumber > 0}
{#each Object.entries($peripherals) as [serialNumber, peripheral]}
{#if peripheral.isSaved}
<DeviceCard status="{peripheral.Status}" on:delete={() => removePeripheral(peripheral)} on:dblclick={() => removePeripheral(peripheral)} on:click={() => selectPeripheral(peripheral)}
<DeviceCard status="{peripheral.status}" on:delete={() => removePeripheral(peripheral)} on:dblclick={() => removePeripheral(peripheral)} on:click={() => selectPeripheral(peripheral)}
title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} selected={serialNumber == selectedPeripheralSN} removable signalizable/>
{/if}
{/each}

View File

@@ -3,68 +3,91 @@ import { peripherals, generateToast, needProjectSave, showInformation } from './
import { get } from "svelte/store"
import { _ } from 'svelte-i18n'
function addPeripheral (peripheralInfo){
// When a new peripheral is detected, add it to the map and:
// - Pass the isDetected key to true
// - Set the isSaved key to the last value
let peripheralsList = get(peripherals)
let lastSavedProperty = peripheralsList[peripheralInfo.SerialNumber]?.isSaved
peripheralInfo.isDetected = true
peripheralInfo.isSaved = (lastSavedProperty === true) ? true : false
peripherals.update((peripherals) => {
peripherals[peripheralInfo.SerialNumber] = peripheralInfo
return {...peripherals}
})
// New peripheral has been added to the system
function peripheralArrival (peripheralInfo){
// If not exists, add it to the map
// isDetected key to true
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isDetected: true,
},
}})
console.log("Hardware has been added to the system");
generateToast('info', 'bxs-hdd', get(_)("peripheralArrivalToast") + ' <b>' + peripheralInfo.Name + '</b>')
}
function removePeripheral (peripheralInfo){
console.log("Hardware has been removed from the system");
// When a peripheral is disconnected, pass its isDetected key to false
// If the isSaved key is set to false, we can completely remove the peripheral from the list
let peripheralsList = get(peripherals)
let lastSavedProperty = peripheralsList[peripheralInfo.SerialNumber]?.isSaved
let needToDelete = (lastSavedProperty !== true) ? true : false
peripherals.update((storedPeripherals) => {
if (needToDelete){
delete storedPeripherals[peripheralInfo.SerialNumber];
return { ...storedPeripherals };
}
storedPeripherals[peripheralInfo.SerialNumber].isDetected = false
storedPeripherals[peripheralInfo.SerialNumber].Status = "disconnected"
return {...storedPeripherals}
})
generateToast('warning', 'bxs-hdd', get(_)("peripheralRemovalToast") + ' <b>' + peripheralInfo.Name + '</b>')
}
// Peripheral is removed from the system
function peripheralRemoval (peripheralInfo){
// If not exists, add it to the map
// isDetected key to false
function updatePeripheral(peripheral, status){
console.log("Hardware status has been updated to " + status);
// When a peripheral status is updated, update it in the store
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheral.SerialNumber]: {
...storedPeripherals[peripheral.SerialNumber],
isSaved: true,
Status: status,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isDetected: false,
status: "PERIPHERAL_DISCONNECTED",
},
}})
console.log("Hardware has been removed from the system");
generateToast('warning', 'bxs-hdd', get(_)("peripheralRemovalToast") + ' <b>' + peripheralInfo.Name + '</b>')
}
// Update peripheral status
function peripheralUpdateStatus(peripheralInfo, status){
// If not exists, add it to the map
// change status key
peripherals.update((storedPeripherals) => {
console.log(status)
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
status: status,
},
}})
console.log("Hardware status has been updated to " + status);
}
// Load the peripheral in the project
function loadPeripheral (peripheralInfo) {
peripherals.update((storedPeripherals) => {
// Add the saved peripherals of the project
// If already exists pass the isSaved key to true, if not create the peripheral and set it to disconnected
// Add the peripheral to the list of peripherals, with the last isDetected key and the isSaved key to true
let lastDetectedKey = storedPeripherals[peripheralInfo.SerialNumber]?.isDetected
storedPeripherals[peripheralInfo.SerialNumber] = peripheralInfo
storedPeripherals[peripheralInfo.SerialNumber].isDetected = (lastDetectedKey === true) ? true : false
storedPeripherals[peripheralInfo.SerialNumber].isSaved = true
return {...storedPeripherals}
})
//TODO: Lors d'un chargement/déchargement natif au démarrage, il ne doit pas y avoir de nécessité de sauvegarder
needProjectSave.set(true)
// If not exists, add it to the map
// isSaved key to true
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isSaved: true,
},
}})
console.log("Hardware has been added to the project");
//TODO: Lors d'un chargement/déchargement natif au démarrage, il ne doit pas y avoir de nécessité de sauvegarder
needProjectSave.set(true)
}
function loadProject (showInfo){
@@ -75,19 +98,27 @@ function loadProject (showInfo){
generateToast('info', 'bx-folder-open', get(_)("projectOpenedToast") + ' <b>' + showInfo.Name + '</b>')
}
// Unload the hardware from the project
function unloadPeripheral (peripheralInfo) {
peripherals.update((storedPeripherals) => {
// Set all the isSaved keys to false and delete the disconnected peripherals
storedPeripherals[peripheralInfo.SerialNumber].isSaved = false
if (!storedPeripherals[peripheralInfo.SerialNumber].isDetected) {
delete storedPeripherals[peripheralInfo.SerialNumber]
}
return {...storedPeripherals}
})
// If not exists, add it to the map
// isSaved key to false
//TODO: Lors d'un chargement/déchargement natif au démarrage, il ne doit pas y avoir de nécessité de sauvegarder
needProjectSave.set(true)
}
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isSaved: false,
},
}})
console.log("Hardware has been removed from the project");
//TODO: Lors d'un chargement/déchargement natif au démarrage, il ne doit pas y avoir de nécessité de sauvegarder
needProjectSave.set(true)
}
let initialized = false
@@ -96,13 +127,13 @@ export function initRuntimeEvents(){
initialized = true
// Handle the event when a new peripheral is detected
EventsOn('PERIPHERAL_ARRIVAL', addPeripheral)
EventsOn('PERIPHERAL_ARRIVAL', peripheralArrival)
// Handle the event when a peripheral is removed from the system
EventsOn('PERIPHERAL_REMOVAL', removePeripheral)
EventsOn('PERIPHERAL_REMOVAL', peripheralRemoval)
// Handle the event when a peripheral status is updated
EventsOn('PERIPHERAL_STATUS', updatePeripheral)
EventsOn('PERIPHERAL_STATUS', peripheralUpdateStatus)
// Handle the event when a new project need to be loaded
EventsOn('LOAD_PROJECT', loadProject)

View File

@@ -34,4 +34,15 @@ export const secondSize = writable("14px")
export const thirdSize = writable("20px")
// List of current hardware
export let peripherals = writable({})
export let peripherals = writable({})
// Peripheral structure :
// Name string `yaml:"name"` // Name of the peripheral
// SerialNumber string `yaml:"sn"` // S/N of the peripheral
// ProtocolName string `yaml:"protocol"` // Protocol name of the peripheral
// Settings map[string]interface{} `yaml:"settings"` // Peripheral settings
// isSaved // if the peripheral is saved in the project
// isDetected // if the peripheral is detected by the system
// status // the status of connection