settings = $settings; $this->ensureDefaultBoards(); $this->tab = new Container('flex flex-col p-4 gap-4 bg-gray-50'); $headerRow = new Container('flex flex-row items-center gap-2'); $headerRow->addComponent(new Label('Kanban Tasks', 'text-xl font-bold text-black flex-1')); $this->newBoardInput = new TextInput( 'Neues Board...', 'w-60 border border-gray-300 rounded px-3 py-2 bg-white text-black text-sm', ); $addBoardButton = new Button( 'Board hinzufügen', 'px-3 py-2 bg-blue-600 rounded hover:bg-blue-700', null, 'text-white text-sm', ); $headerRow->addComponent($this->newBoardInput); $headerRow->addComponent($addBoardButton); $this->tab->addComponent($headerRow); $this->boardsContainer = new Container( 'flex flex-row gap-4 flex-1 overflow-auto bg-gray-100 rounded border border-gray-300 p-3', ); $this->tab->addComponent($this->boardsContainer); $kanbanTab = $this; $addBoardButton->setOnClick(function () use ($kanbanTab) { $name = trim($kanbanTab->newBoardInput->getValue()); if ($name === '') { return; } $boards = $kanbanTab->settings->get('kanban.boards', []); if (!is_array($boards)) { $boards = []; } if (!in_array($name, $boards, true)) { $boards[] = $name; $kanbanTab->settings->set('kanban.boards', $boards); $kanbanTab->settings->save(); } $kanbanTab->newBoardInput->setValue(''); $kanbanTab->renderBoards(); }); $this->renderBoards(); } public function getContainer(): Container { return $this->tab; } public function refresh(): void { $this->renderBoards(); } private function ensureDefaultBoards(): void { $boards = $this->settings->get('kanban.boards', null); if (!is_array($boards) || empty($boards)) { $boards = ['neu', 'in arbeit', 'fertig']; $this->settings->set('kanban.boards', $boards); $this->settings->save(); } } private function renderBoards(): void { $this->boardsContainer->clearChildren(); $boards = $this->settings->get('kanban.boards', []); if (!is_array($boards)) { $boards = []; } $tasks = $this->settings->get('kanban.tasks', []); if (!is_array($tasks)) { $tasks = []; } foreach ($boards as $boardName) { $column = new Container('flex flex-col bg-white rounded shadow-md w-64 max-h-full'); $columnHeader = new Container('px-3 py-2 border-b border-gray-300 bg-gray-100'); $columnHeader->addComponent(new Label($boardName, 'text-sm font-semibold text-gray-800')); $column->addComponent($columnHeader); $columnBody = new Container('flex flex-col gap-2 p-2 overflow-auto'); $boardTasks = array_values(array_filter( $tasks, static fn($task) => ($task['board'] ?? 'neu') === $boardName, )); if (empty($boardTasks)) { $columnBody->addComponent(new Label('Keine Tasks', 'text-xs text-gray-400 italic')); } else { foreach ($boardTasks as $task) { $title = (string) ($task['title'] ?? ''); $serverId = $task['server_id'] ?? null; $serverLabel = $serverId !== null ? ('Server #' . $serverId) : 'Kein Server'; $card = new Container( 'flex flex-col gap-1 px-3 py-2 bg-white border border-gray-200 rounded shadow-sm', ); $card->addComponent(new Label($title, 'text-xs text-gray-900')); $card->addComponent(new Label($serverLabel, 'text-[10px] text-gray-500')); $columnBody->addComponent($card); } } $column->addComponent($columnBody); $this->boardsContainer->addComponent($column); } } }