diff --git a/control/frontend/src/components/ControlView.svelte b/control/frontend/src/components/ControlView.svelte
index 41c6c4a..3805bc3 100644
--- a/control/frontend/src/components/ControlView.svelte
+++ b/control/frontend/src/components/ControlView.svelte
@@ -1,9 +1,17 @@
diff --git a/control/frontend/src/components/DisplayGroupObject.svelte b/control/frontend/src/components/DisplayGroupObject.svelte
index 16455e1..51b0cf9 100644
--- a/control/frontend/src/components/DisplayGroupObject.svelte
+++ b/control/frontend/src/components/DisplayGroupObject.svelte
@@ -13,11 +13,12 @@
} from '../ts/stores/displays';
import DNDGrip from './DNDGrip.svelte';
import { fade } from 'svelte/transition';
- import type { DisplayGroup } from '../ts/types';
+ import type { DisplayGroup, MenuOption } from '../ts/types';
import { selected_display_ids } from '../ts/stores/select';
- let { display_group } = $props<{
+ let { display_group, get_display_menu_options } = $props<{
display_group: DisplayGroup;
+ get_display_menu_options: (display_id: string) => MenuOption[]
}>();
let hovering_selectable = $state(false);
@@ -76,7 +77,7 @@
class="outline-none"
role="figure"
>
-
+
{/each}
diff --git a/control/frontend/src/components/DisplayObject.svelte b/control/frontend/src/components/DisplayObject.svelte
index d84fc66..02470a5 100644
--- a/control/frontend/src/components/DisplayObject.svelte
+++ b/control/frontend/src/components/DisplayObject.svelte
@@ -8,11 +8,12 @@
import DNDGrip from './DNDGrip.svelte';
import { Menu, Pencil, Pin, PinOff, Trash2, VideoOff, X } from 'lucide-svelte';
import OnlineState from './OnlineState.svelte';
- import type { Display } from '../ts/types';
+ import type { Display, MenuOption } from '../ts/types';
import { is_selected, select, selected_display_ids } from '../ts/stores/select';
- let { display } = $props<{
+ let { display, get_display_menu_options } = $props<{
display: Display;
+ get_display_menu_options: (display_id: string) => MenuOption[];
}>();
let hovering_unselectable = $state(false);
@@ -121,17 +122,7 @@
click_function={(e) => {
e.stopPropagation();
}}
- menu_options={[
- {
- icon: Pencil,
- name: 'Bildschirm bearbeiten'
- },
- {
- icon: Trash2,
- name: 'Bildschirm löschen',
- class: 'text-red-400 hover:text-stone-200 hover:!bg-red-400 active:!bg-red-500'
- }
- ]}
+ menu_options={get_display_menu_options(display.id)}
>
diff --git a/control/frontend/src/components/DisplayView.svelte b/control/frontend/src/components/DisplayView.svelte
index 9cf529f..64a6b02 100644
--- a/control/frontend/src/components/DisplayView.svelte
+++ b/control/frontend/src/components/DisplayView.svelte
@@ -16,7 +16,7 @@
next_height_step_size,
pinned_display_id
} from '../ts/stores/ui_behavior';
- import { type Display, type DisplayGroup } from '../ts/types';
+ import { type Display, type DisplayGroup, type MenuOption } from '../ts/types';
import Button from './Button.svelte';
import OnlineState from './OnlineState.svelte';
import { cubicOut } from 'svelte/easing';
@@ -26,11 +26,33 @@
import { flip } from 'svelte/animate';
import DisplayGroupObject from './DisplayGroupObject.svelte';
+ let { handle_display_deletion, handle_display_editing } = $props<{
+ handle_display_deletion: (display_id: string) => void;
+ handle_display_editing: (display_id: string) => void;
+ }>();
+
let displays_scroll_box: HTMLElement;
let pinned_display: Display | null = $derived(
get_display_by_id($pinned_display_id || '', $displays)
);
+
+ function get_display_menu_options(display_id: string): MenuOption[] {
+ return [
+ {
+ icon: Pencil,
+ name: 'Bildschirm bearbeiten',
+ on_select: () => {handle_display_editing(display_id)},
+ },
+ {
+ icon: Trash2,
+ name: 'Bildschirm löschen',
+ class: 'text-red-400 hover:text-stone-200 hover:!bg-red-400 active:!bg-red-500',
+ on_select: () => {handle_display_deletion(display_id)},
+ }
+ ];
+ }
+
function select_all(current_displays: DisplayGroup[], current_selected_display_ids: string[]) {
const new_value = !all_selected(current_displays, current_selected_display_ids);
for (const display_group of current_displays) {
@@ -89,17 +111,7 @@
click_function={(e) => {
e.stopPropagation();
}}
- menu_options={[
- {
- icon: Pencil,
- name: 'Bildschirm bearbeiten'
- },
- {
- icon: Trash2,
- name: 'Bildschirm löschen',
- class: 'text-red-400 hover:text-stone-200 hover:!bg-red-400 active:!bg-red-500'
- }
- ]}
+ menu_options={get_display_menu_options($pinned_display_id)}
>
@@ -159,7 +171,7 @@
: 'Alle auswählen'}
-
+
{#if $displays.length === 1 && $displays[0].data.length === 0}
- Es wurden noch keine Bildschirme hinzugefügt. Klicke oben rechts auf und "Neuen
- Bildschirm hinzufügen".
+ Es wurden noch keine Bildschirme hinzugefügt. Klicke oben rechts auf und "Neuen Bildschirm hinzufügen".
{:else}
{#each $displays as display_group (display_group.id)}
@@ -217,7 +230,7 @@
animate:flip={{ duration: dnd_flip_duration_ms, easing: cubicOut }}
class="outline-none"
>
-
+
{/each}
{/if}
diff --git a/control/frontend/src/components/PopUp.svelte b/control/frontend/src/components/PopUp.svelte
index af453cd..1d38031 100644
--- a/control/frontend/src/components/PopUp.svelte
+++ b/control/frontend/src/components/PopUp.svelte
@@ -38,7 +38,7 @@
e.stopPropagation()}
>
- {@render content.snippet()}
+ {@render content.snippet(content.snippet_arg)}
diff --git a/control/frontend/src/routes/+page.svelte b/control/frontend/src/routes/+page.svelte
index d543f85..9789314 100644
--- a/control/frontend/src/routes/+page.svelte
+++ b/control/frontend/src/routes/+page.svelte
@@ -1,5 +1,5 @@
-{#snippet add_new_display()}
+{#snippet remove_display_popup(display_id: string)}
+
+ Soll der Bildschirm "{get_display_by_id(display_id, $displays)?.name || '?'}" wirklich gelöscht
+ werden? Dadurch wird es von diesem Controller nicht mehr erreichbar. Die Installation auf dem
+ Gerät bleibt bestehen. Mit dem erneuten Hinzufügen des Bildschirms wird er wieder steuerbar.
+
+
+ Abbrechen
+ {
+ remove_display(display_id);
+ popup_close_function();
+ }}>Löschen
+
+{/snippet}
+
+{#snippet add_new_display_popup(existing_display_id: string | null = null)}
{
- return input.length === 0 || input.length > 50
- ? [false, 'Ungültige Länge']
- : is_display_name_taken(input)
- ? [false, 'Name bereits verwendet']
- : [true, 'Gültiger Name'];
+ if (!!existing_display_id) {
+ if (input === get_display_by_id(existing_display_id, $displays)?.name)
+ return [true, 'Gültiger Name'];
+ }
+ if (input.length === 0 || input.length > 50) return [false, 'Ungültige Länge'];
+ if (is_display_name_taken(input)) return [false, 'Name bereits verwendet'];
+ return [true, 'Gültiger Name'];
}}
/>
@@ -111,18 +171,29 @@
: [false, 'Ungültige MAC-Adresse'];
}}
/>
-
+
+ {#if !!existing_display_id}
+
+
Abbrechen
+ {/if}
Bildschirm hinzufügen
+ click_function={() => {
+ finalize_add_edit_display(existing_display_id);
+ }}
+ >{#if !!existing_display_id}
+ Speichern
+ {:else}
+
Bildschirm hinzufügen
+ {/if}
+
{/snippet}
- {@html SplashScreen}
+
PLG MuDiCS
@@ -146,7 +217,10 @@
-
+
diff --git a/control/frontend/src/ts/stores/displays.ts b/control/frontend/src/ts/stores/displays.ts
index 39164e1..beffe48 100644
--- a/control/frontend/src/ts/stores/displays.ts
+++ b/control/frontend/src/ts/stores/displays.ts
@@ -11,19 +11,44 @@ export const displays: Writable = writable([{
export function is_display_name_taken(name: string): boolean {
- const display_groups = get(displays);
- return display_groups.some(group =>
- group.data.some(display => display.name.trim().toLowerCase() === name.trim().toLowerCase())
- );
+ const display_groups = get(displays);
+ return display_groups.some(group =>
+ group.data.some(display => display.name.trim().toLowerCase() === name.trim().toLowerCase())
+ );
}
-export function add_display(ip: string, mac: string|null, name: string, status: string) {
+export function add_display(ip: string, mac: string | null, name: string, status: string) {
displays.update((displays: DisplayGroup[]) => {
displays[0].data.push({ id: get_uuid(), ip, preview_url: null, preview_timeout_id: null, mac, name, status });
return displays;
});
}
+export function edit_display_data(display_id: string, ip: string, mac: string | null, name: string) {
+ displays.update((display_groups) =>
+ display_groups.map((group) => ({
+ ...group,
+ data: group.data.map((display) => {
+ if (display.id !== display_id) return display;
+ return { ...display, ip: ip, mac: mac, name: name };
+ }),
+ }))
+ );
+}
+
+export function remove_display(display_id: string) {
+ console.log(display_id);
+ displays.update((displays: DisplayGroup[]) => {
+ displays = displays.map(display_group => ({
+ ...display_group,
+ data: display_group.data.filter(display => display.id !== display_id)
+ }));
+ return displays;
+ });
+
+ // TODO remove ID from Files usw.
+}
+
export function all_displays_of_group_selected(display_group: DisplayGroup, current_selected_displays: string[]) {
if (display_group.data.length === 0) return false;
for (const display of display_group.data) {
@@ -139,6 +164,6 @@ function add_testing_displays() {
// add_display("127.0.0.1", "00:1A:2B:3C:4D:5E", name, "Offline");
// }
- // add_display("127.0.0.1", "00:1A:2B:3C:4D:5E", "PC", "Offline");
+ add_display("127.0.0.1", "00:1A:2B:3C:4D:5E", "PC", "Offline");
// add_display("192.168.178.111", "D4:81:D7:C0:DF:3C", "Laptop", "Online");
}
\ No newline at end of file
diff --git a/control/frontend/src/ts/types.ts b/control/frontend/src/ts/types.ts
index 410b398..0cf2c01 100644
--- a/control/frontend/src/ts/types.ts
+++ b/control/frontend/src/ts/types.ts
@@ -1,4 +1,5 @@
import { FileBox, FileImage, FileVideoCamera, ImagePlay, type X } from "lucide-svelte";
+import type { Snippet } from "svelte";
export type SupportedFileType = {
display_name:
@@ -60,7 +61,7 @@ export type Display = {
ip: string;
preview_url: string | null;
preview_timeout_id: number | null;
- mac: string|null;
+ mac: string | null;
name: string;
status: string;
}
@@ -81,7 +82,8 @@ export type MenuOption = {
export type PopupContent = {
open: boolean;
- snippet: any;
+ snippet: Snippet<[string]> | null;
+ snippet_arg?: string;
title: string;
title_class?: string;
title_icon?: typeof X | null;