init
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
---
|
||||
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.
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
sessionId: session-260727-090636-1x6i
|
||||
---
|
||||
|
||||
# Requirements
|
||||
|
||||
### Overview & Goals
|
||||
The goal of this task is to adapt the frontend data-loading policy for channels and categories. Previously, all channels and categories were fetched globally once upon initial load. Now, whenever the user swaps servers (or enters a server view), channels and categories should be reloaded specifically for that active server using the backend query parameters (`server_id`) implemented in the previous backend task.
|
||||
|
||||
### Scope
|
||||
- **In Scope**:
|
||||
- Updating `useChannelStore` and `useCategoryStore` in Pinia to accept a `serverId` query parameter when fetching channels and categories.
|
||||
- Updating `src/pages/server/index.vue` (and/or router navigation / lifecycle hooks) to trigger fetching of channels and categories filtered by the current `serverId` whenever the active server changes.
|
||||
- Resetting or clearing channel and category state appropriately when switching servers.
|
||||
- **Out of Scope**:
|
||||
- Backend changes (already completed in previous task).
|
||||
- Changes to other entities (servers, messages, etc.) unless directly related to channel/category scoping.
|
||||
|
||||
### User Stories
|
||||
- **As a user**, when I switch from one server to another, I want the channels and categories list to be reloaded automatically for the newly selected server so that I only see relevant content.
|
||||
|
||||
### Functional Requirements
|
||||
1. **Store Actions (`fetchChannels`, `fetchCategories`)**:
|
||||
- Both actions must accept an optional `serverId?: string`.
|
||||
- When `serverId` is provided, requests must be made to `/channels?server_id=...` and `/categories?server_id=...`.
|
||||
2. **Server View Component (`/src/pages/server/index.vue`)**:
|
||||
- On component mount or when `serverId` route parameter changes (e.g. via `watch(() => route.params.serverId, ...)`), trigger fetching of channels and categories for the new `serverId`.
|
||||
- Clear existing channels/categories or show loading states during the fetch transition.
|
||||
|
||||
# Technical Design
|
||||
|
||||
### Current Implementation
|
||||
- Currently, `useSessionStore.loadInitialData()` calls `serverStore.fetchServers()`, `categoryStore.fetchCategories()`, and `channelStore.fetchChannels()` without parameters, retrieving all records from `/channels` and `/categories`.
|
||||
- `src/pages/server/index.vue` displays `channels` from `useChannelStore`, but does not trigger refetching when switching between different servers.
|
||||
|
||||
### Key Decisions
|
||||
- **Query Parameter Usage**: Leverage the backend endpoints `/channels?server_id=<id>` and `/categories?server_id=<id>` that were created previously.
|
||||
- **Store & Lifecycle Integration**: Use Vue router route watchers in `src/pages/server/index.vue` (or a dedicated composable/watcher) to detect `serverId` changes and invoke store fetch actions.
|
||||
|
||||
### Proposed Changes
|
||||
1. **`src/stores/channel.ts`**:
|
||||
- Modify `fetchChannels(serverId?: string)` to build query string `?server_id=${serverId}` if `serverId` is provided.
|
||||
2. **`src/stores/category.ts`**:
|
||||
- Modify `fetchCategories(serverId?: string)` to build query string `?server_id=${serverId}` if `serverId` is provided.
|
||||
3. **`src/pages/server/index.vue`**:
|
||||
- Add a watcher on `route.params.serverId` (or `serverId` prop).
|
||||
- On mount and when `serverId` changes, call `channelStore.fetchChannels(serverId)` and `categoryStore.fetchCategories(serverId)`.
|
||||
|
||||
### File Structure
|
||||
- **Modified Files**:
|
||||
- `frontend/src/stores/channel.ts`
|
||||
- `frontend/src/stores/category.ts`
|
||||
- `frontend/src/pages/server/index.vue`
|
||||
|
||||
### Risks & Mitigations
|
||||
- **Race conditions during rapid server switching**: Mitigated by handling loading states or canceling/ignoring stale promises if necessary, or simply allowing the latest fetch response to overwrite the store state.
|
||||
|
||||
# Delivery Steps
|
||||
|
||||
### ✓ Step 1: Update channel and category stores to support server-scoped fetching
|
||||
Update Pinia stores for channels and categories to support filtered fetching by server_id.
|
||||
- Update `useChannelStore.fetchChannels(serverId?: string)` to accept an optional `serverId` and pass it as a query parameter (`/channels?server_id=...`).
|
||||
- Update `useCategoryStore.fetchCategories(serverId?: string)` to accept an optional `serverId` and pass it as a query parameter (`/categories?server_id=...`).
|
||||
- Clear channels and categories when no server is selected or when swapping servers.
|
||||
|
||||
### ✓ Step 2: Integrate server-scoped data loading into server view and router navigation
|
||||
Integrate server-scoped loading into the server view lifecycle and route changes.
|
||||
- Update `/src/pages/server/index.vue` to watch `serverId` (or trigger on route parameter change / component mount) and fetch channels and categories specifically for the active `serverId`.
|
||||
- Clear channels and categories when switching between servers or leaving the server view.
|
||||
- Ensure proper loading states and error handling during server switching.
|
||||
Reference in New Issue
Block a user