Anmelden
DE
games/xencenter-xenadmin-xcp-jumphp / src / Form / FolderForm.php · commit fb1b7c9
<?phpnamespace App\Form;use App\Feature\Organize\Organizer;use App\Gui\IconBox;use JumPHP\Gui\Button;use JumPHP\Gui\Form;use JumPHP\Gui\Label;use JumPHP\Gui\ListBox;use JumPHP\Gui\TextBox;/** * One dialog for the folders (forms/FolderForm.form.yaml), by its 'mode': * - move: Move to Folder… of an object: a folder of the list (or the top level), or a new one typed below; * - new: New Folder (under 'parent'); rename: Rename Folder ('path'); renameTag: Rename Tag ('path' = the tag). * Closes with ['organize' => ['mode', 'target', 'folder', 'path']]: OrganizeCommands::apply() makes the XAPI calls. * * @property IconBox $icon * @property Label $heading * @property Label $listLabel * @property ListBox $folders * @property Label $valueLabel * @property TextBox $value * @property Label $hint * @property Label $error * @property Button $ok * @property Button $cancel */final class FolderForm extends Form{    public const TOP = '(top level)';    public function __construct(private \App\Model\Session $session)    {        parent::__construct();    }    /** XAPI's answers, events and the console go on while this dialog is open. */    protected function tick(float $dt): void    {        $this->session->tick($dt);    }    private array $params = [];    protected function loaded(array $params = []): void    {        $this->params = $params;        $mode = (string)($params['mode'] ?? 'move');        $move = $mode === 'move';        $this->folders->visible = $this->listLabel->visible = $move;        $this->icon->kind = $mode === 'renameTag' ? 'tag' : 'folder';        $this->error->text = '';        $this->value->text = (string)($params['value'] ?? '');        if ($move) {            $this->folders->items = [self::TOP, ...array_map('strval', (array)($params['folders'] ?? []))];            $this->folders->selected = max(0, (int)array_search((string)($params['folder'] ?? '') ?: self::TOP, $this->folders->items, true));        }        [$heading, $label, $ok, $hint] = match ($mode) {            'new' => ['New Folder', 'Name of the new folder:', 'Create',                (($params['parent'] ?? '') !== '' ? "In '" . $params['parent'] . "'. " : '') . 'A folder is kept in the pool\'s settings until an object is moved into it.'],            'rename' => ["Rename Folder '" . ($params['path'] ?? '') . "'", 'New name:', 'Rename', 'Its objects and its subfolders follow it. A path starting with / moves it.'],            'renameTag' => ["Rename Tag '" . ($params['path'] ?? '') . "'", 'New name:', 'Rename', 'Every object that has this tag gets the new one.'],            default => ["Move '" . ($params['name'] ?? '') . "' to a folder", 'Or a new folder:', 'Move', 'Folders are kept on the server (other_config "folder"), so every XenCenter sees them.'],        };        $this->heading->text = $heading;        $this->valueLabel->text = $label;        $this->ok->text = $ok;        $this->hint->text = $hint;        $this->setFocus($move ? $this->folders : $this->value);    }    public function onOkClick(mixed $sender = null): void    {        $mode = (string)($this->params['mode'] ?? 'move');        $typed = trim($this->value->text);        $path = (string)($this->params['path'] ?? '');        if ($mode !== 'move' && $typed === '') {            $this->error->text = 'Enter a name.';            return;        }        if ($mode === 'renameTag' && str_contains($typed, ',')) {            $this->error->text = 'A tag has no comma.';            return;        }        $folder = match ($mode) {            'move' => $typed !== '' ? Organizer::normalize($typed) : (($v = $this->folders->value()) === null || $v === self::TOP ? '' : $v),            'new' => Organizer::normalize(str_starts_with($typed, '/') ? $typed : (string)($this->params['parent'] ?? '') . '/' . $typed),            'rename' => Organizer::normalize(str_starts_with($typed, '/') ? $typed : Organizer::parent($path) . '/' . $typed),            default => $typed,        };        if ($mode === 'rename' && ($folder === '' || Organizer::inside($folder, $path))) {            $this->error->text = 'A folder cannot go inside itself.';            return;        }        $this->close(['organize' => ['mode' => $mode, 'target' => $this->params['target'] ?? '', 'folder' => $folder, 'path' => $path]]);    }    public function onCancelClick(Button $sender): void    {        $this->close();    }}