--- sessionId: session-260727-093242-giao --- # Requirements ### Overview & Goals The goal of this task is to add an "Add Server" button and creation functionality to the frontend application, allowing users to create new servers directly from the UI. Backend entrypoints (`POST /servers`) are already fully implemented in Rust. ### Scope - **In Scope:** - Update `frontend/src/stores/server.ts` to include a `createServer` action communicating with `POST /servers`. - Update `frontend/src/layouts/AppLayout.vue` to add an "Add Server" button in the left rail navigation drawer alongside existing server avatars. - Add a server creation modal dialog (`v-dialog`) with input fields for server name and optional password. - Handle loading states, validation (server name required), error handling, and automatically select or route to the newly created server. - **Out of Scope:** - Modifying backend server logic or endpoints (already implemented). - Server permission editing UI enhancements (unless directly related to server creation flow). ### User Stories - **As a user**, I want to click an "Add Server" button in the sidebar so that I can create a new server. - **As a user**, I want a modal dialog where I can enter the server name and optional password so that my server is properly configured upon creation. - **As a user**, I want the server list in the sidebar to update immediately when a new server is created so that I can switch to it right away. ### Functional Requirements - **Sidebar Button:** An intuitive '+' or add icon button rendered in the rail navigation drawer of `AppLayout.vue`. - **Creation Dialog:** A Vuetify modal dialog (`v-dialog`) containing: - Text field for server name (required). - Optional password field (optional). - Cancel and Create buttons with loading state handling. - **Store Integration:** `useServerStore` must provide a `createServer` action that performs `POST /servers` with the appropriate payload (`{ name, password, is_default }`). # Technical Design ### Current Implementation - **Backend:** `POST /servers` is implemented in `src/routes/server/handlers.rs` and accepts `CreateServerRequest` (`name`, `password`, `is_default`), returning `ServerResponse`. Note that it requires `Superuser` authorization (`_admin: Superuser`). - **Frontend Stores:** `frontend/src/stores/server.ts` currently fetches servers via `GET /servers` into `state.servers`. - **Frontend Layout:** `frontend/src/layouts/AppLayout.vue` renders a rail navigation drawer listing existing servers as avatars with router links to `/server/${server.id}`. ### Key Decisions - **Placement of Add Server Button:** Placed at the bottom or top of the server list inside the rail navigation drawer of `AppLayout.vue`, consistent with Discord-like and existing channel creation patterns (`New Channel` button in `frontend/src/pages/server/index.vue`). - **Dialog Pattern:** Reusing the exact modal dialog pattern (`v-dialog`, `v-card`, `v-text-field`, `v-btn`) already established in `frontend/src/pages/server/index.vue` for creating channels. ### Proposed Changes 1. **Server Store (`frontend/src/stores/server.ts`):** - Add `createServer` action: ```typescript async createServer(payload: { name: string; password?: string | null; is_default?: boolean }) { const api = useApi(); const response = await api.post("/servers", payload); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'Failed to create server'); } const newServer = await response.json(); this.servers.push(newServer); return newServer; } ``` 2. **AppLayout (`frontend/src/layouts/AppLayout.vue`):** - Add a state ref for dialog visibility (`showDialog`), form data (`formData`), and submission status (`isSubmitting`). - Add an add server button (`v-avatar` with `icon="mdi-plus"` or `v-btn`) inside the rail drawer. - Add `v-dialog` template with inputs for server name and password. - Wire `handleSubmit` to invoke `serverStore.createServer()`. ### File Structure - **Modified Files:** - `frontend/src/stores/server.ts` - `frontend/src/layouts/AppLayout.vue` ### Architecture Diagram ```mermaid graph LR User -->|Clicks Add Server| AppLayout AppLayout -->|Opens Dialog| Dialog[v-dialog] Dialog -->|Submits Form| ServerStore[useServerStore] ServerStore -->|POST /servers| Backend[Rust Backend API] Backend -->|Created Server| ServerStore ServerStore -->|Updates servers list| AppLayout ``` # Testing ### Validation Approach - **Verification:** Ensure the Vue application builds successfully with TypeScript and Vite. - **Manual/UI Verification Scenarios:** 1. Open the application layout (`AppLayout.vue`). 2. Click the plus button in the sidebar. 3. Verify the "Create Server" dialog appears with name and password fields. 4. Submit a valid server name and verify that a POST request is sent to `/servers`, the dialog closes, and the new server avatar appears in the sidebar. 5. Verify validation prevents submission when the server name is empty. ### Key Scenarios - **Successful Creation:** Server is successfully created and appended to the sidebar list. - **Validation Error:** Empty server name disables the create button or shows an alert. - **API Error Handling:** Catch and log API failures gracefully. # Delivery Steps ### Step 1: Extend server Pinia store with createServer action Extend the server Pinia store with createServer action. - Update `frontend/src/stores/server.ts` to include `createServer(payload: { name: string; password?: string | null; is_default?: boolean })`. - Handle error states, API POST requests to `/servers`, and state updates to push the newly created server to `this.servers`. ### Step 2: Add Add Server UI button and creation dialog to AppLayout Add 'Add Server' UI button and creation dialog to AppLayout. - Update `frontend/src/layouts/AppLayout.vue` to add a '+' or 'Add Server' button in the rail navigation drawer. - Implement a reactive modal dialog (`v-dialog`) with form fields for server name and optional password. - Wire up form submission to call `serverStore.createServer()`, handle loading state, and close/reset the dialog on success. ### Step 3: Verify frontend integration and build Verify build and test integration. - Ensure TypeScript types, Vuetify components, and pinia store integration are correct. - Verify frontend compilation without errors.