feat: archived boards (#386)

* init: schema migration, isArchived added to
board table. refactor: board repo for isArchived filtering

* init: archived, unarchived API procedures. refactor: all query

* fix: migration error

* feat: add tabbed navigation for boards view

* Implemented a Listbox for mobile and a tabbed navigation for desktop to switch between "Boards" and "Archived" views.
* Introduced state management for active tab selection.
* Updated UI components to reflect the new navigation structure.

* init: frontend/boards lists & tabs

* chore: fixed font styling and spacing

* init:boardDropdown / boardView.

* chore:added translations

* Remove .cursor plan file from repo

* fix:build erros

* revert: remove locales changes

* fix:reverted changes under locales, replaced the archive and unarchive endpoints. Reorder migrations

* fix:migration issue

* fix: update journal.json

---------

Co-authored-by: Henry <henry_ball@hotmail.co.uk>
This commit is contained in:
Eliott Herbert-Byrnes
2026-02-26 21:39:15 +00:00
committed by GitHub
parent 9cb1fb5218
commit af36fb133a
24 changed files with 6899 additions and 121 deletions

View File

@@ -44,7 +44,7 @@ export const getAllByWorkspaceId = async (
db: dbClient,
workspaceId: number,
userId: string,
opts?: { type?: "regular" | "template" },
opts?: { type?: "regular" | "template"; archived?: boolean },
) => {
const boardsData = await db.query.boards.findMany({
columns: {
@@ -78,6 +78,7 @@ export const getAllByWorkspaceId = async (
eq(boards.workspaceId, workspaceId),
isNull(boards.deletedAt),
opts?.type ? eq(boards.type, opts.type) : undefined,
opts?.archived !== undefined ? eq(boards.isArchived, opts.archived) : undefined,
),
});
@@ -102,6 +103,7 @@ export const getIdByPublicId = async (db: dbClient, boardPublicId: string) => {
columns: {
id: true,
type: true,
isArchived: true,
},
where: eq(boards.publicId, boardPublicId),
});
@@ -195,6 +197,7 @@ export const getByPublicId = async (
name: true,
slug: true,
visibility: true,
isArchived: true,
},
with: {
userFavorites: {
@@ -628,6 +631,7 @@ export const update = async (
slug: string | undefined;
visibility: BoardVisibilityStatus | undefined;
boardPublicId: string;
isArchived?: boolean;
},
) => {
const [result] = await db
@@ -637,6 +641,7 @@ export const update = async (
slug: boardInput.slug,
visibility: boardInput.visibility,
updatedAt: new Date(),
...(boardInput.isArchived !== undefined && { isArchived: boardInput.isArchived })
})
.where(eq(boards.publicId, boardInput.boardPublicId))
.returning({

View File

@@ -30,22 +30,22 @@ const SYSTEM_ROLES: {
description: string;
hierarchyLevel: number;
}[] = [
{
name: "admin",
description: "Full access to all workspace features",
hierarchyLevel: 100,
},
{
name: "member",
description: "Standard member with create and edit permissions",
hierarchyLevel: 50,
},
{
name: "guest",
description: "View-only access",
hierarchyLevel: 10,
},
];
{
name: "admin",
description: "Full access to all workspace features",
hierarchyLevel: 100,
},
{
name: "member",
description: "Standard member with create and edit permissions",
hierarchyLevel: 50,
},
{
name: "guest",
description: "View-only access",
hierarchyLevel: 10,
},
];
export const getCount = async (db: dbClient) => {
const result = await db
@@ -250,7 +250,7 @@ export const getBySlugWithBoards = (db: dbClient, workspaceSlug: string) => {
slug: true,
name: true,
},
where: and(isNull(boards.deletedAt), eq(boards.visibility, "public")),
where: and(isNull(boards.deletedAt), eq(boards.visibility, "public"), eq(boards.isArchived, false)),
orderBy: [asc(boards.name)]
},
},