// ui/commandEditDialog.js - Dialogue d'édition pour la allowlist des commandes import GObject from 'gi://GObject'; import Gtk from 'gi://Gtk'; import Adw from 'gi://Adw'; /** * Dialogue pour éditer la liste des commandes autorisées */ export const CommandEditDialog = GObject.registerClass( class CommandEditDialog extends Adw.Window { _init(parent, currentAllowlist) { super._init({ transient_for: parent, modal: true, title: 'Edit Allowed Commands', default_width: 500, default_height: 400, }); this._currentAllowlist = [...currentAllowlist]; this._buildUI(); } /** * Construit l'interface du dialogue */ _buildUI() { // Header bar const headerBar = new Adw.HeaderBar(); const cancelButton = new Gtk.Button({ label: 'Cancel', }); cancelButton.connect('clicked', () => { this.emit('response', Gtk.ResponseType.CANCEL); }); headerBar.pack_start(cancelButton); const saveButton = new Gtk.Button({ label: 'Save', }); saveButton.add_css_class('suggested-action'); saveButton.connect('clicked', () => { this.emit('response', Gtk.ResponseType.OK); }); headerBar.pack_end(saveButton); // Toolbar view const toolbarView = new Adw.ToolbarView(); toolbarView.add_top_bar(headerBar); // Main content const contentBox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 12, margin_top: 12, margin_bottom: 12, margin_start: 12, margin_end: 12, }); // Info label const infoLabel = new Gtk.Label({ label: 'Select which commands are allowed to be executed via MQTT:', wrap: true, xalign: 0, }); contentBox.append(infoLabel); // Available commands const availableCommands = ['shutdown', 'reboot', 'sleep', 'hibernate', 'screen']; // List box for commands const listBox = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE, }); listBox.add_css_class('boxed-list'); this._commandCheckboxes = {}; for (const command of availableCommands) { const row = new Adw.ActionRow({ title: command.charAt(0).toUpperCase() + command.slice(1), subtitle: this._getCommandDescription(command), }); const checkbox = new Gtk.CheckButton({ active: this._currentAllowlist.includes(command), valign: Gtk.Align.CENTER, }); this._commandCheckboxes[command] = checkbox; row.add_suffix(checkbox); row.activatable_widget = checkbox; listBox.append(row); } // Scrolled window const scrolledWindow = new Gtk.ScrolledWindow({ vexpand: true, hscrollbar_policy: Gtk.PolicyType.NEVER, }); scrolledWindow.set_child(listBox); contentBox.append(scrolledWindow); // Warning label const warningLabel = new Gtk.Label({ label: '⚠️ Warning: These commands have system-wide effects. Enable only commands you need.', wrap: true, xalign: 0, }); warningLabel.add_css_class('warning'); contentBox.append(warningLabel); toolbarView.set_content(contentBox); this.set_content(toolbarView); } /** * Retourne une description pour chaque commande */ _getCommandDescription(command) { const descriptions = { 'shutdown': 'Power off the system', 'reboot': 'Restart the system', 'sleep': 'Suspend to RAM (sleep mode)', 'hibernate': 'Suspend to disk (hibernate)', 'screen': 'Control screen on/off state', }; return descriptions[command] || 'No description available'; } /** * Récupère la nouvelle allowlist */ getAllowlist() { const allowlist = []; for (const [command, checkbox] of Object.entries(this._commandCheckboxes)) { if (checkbox.active) { allowlist.push(command); } } return allowlist; } });