feat: complete triage, multi-task lists, kanban, workspace wiki, and admin management
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
This commit is contained in:
1 parent
5c4e130862
commit
4ef71b61cd
12 files changed
+3940
-664
No files matched your search
+157
-4
@@ -4,9 +4,14 @@ import {
|
||||
Document,
|
||||
DocumentBlock,
|
||||
ListItem,
|
||||
Organization,
|
||||
PriorityLevel,
|
||||
SharedList,
|
||||
Space,
|
||||
SystemSettings,
|
||||
Team,
|
||||
TeamMember,
|
||||
TaskList,
|
||||
Thought,
|
||||
User,
|
||||
} from './types';
|
||||
@@ -97,7 +102,7 @@ async function request<T>(path: string, options: RequestInit = {}, isRetry = fal
|
||||
}
|
||||
|
||||
export const api = {
|
||||
// --- AUTH ---
|
||||
// --- AUTH & SETTINGS ---
|
||||
async quickStart(): Promise<{ token: string; user: User }> {
|
||||
const res = await request<{ token: string; user: User }>('/api/v1/auth/quickstart', {
|
||||
method: 'POST',
|
||||
@@ -128,6 +133,19 @@ export const api = {
|
||||
return request<{ user: User; stats: DashboardStats }>('/api/v1/auth/me');
|
||||
},
|
||||
|
||||
async updateSettings(patch: {
|
||||
displayName?: string;
|
||||
email?: string;
|
||||
password?: string;
|
||||
discordWebhookUrl?: string;
|
||||
notifyBeforeMinutes?: number;
|
||||
}): Promise<User> {
|
||||
return request<User>('/api/v1/auth/settings', {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(patch),
|
||||
});
|
||||
},
|
||||
|
||||
async getStats(): Promise<DashboardStats> {
|
||||
return request<DashboardStats>('/api/v1/stats');
|
||||
},
|
||||
@@ -141,6 +159,7 @@ export const api = {
|
||||
options?: {
|
||||
target?: 'inbox' | 'task' | 'list_item' | 'document';
|
||||
targetListId?: string;
|
||||
taskListId?: string;
|
||||
}
|
||||
): Promise<Thought> {
|
||||
try {
|
||||
@@ -153,6 +172,7 @@ export const api = {
|
||||
dueDate,
|
||||
target: options?.target || 'inbox',
|
||||
targetListId: options?.targetListId || '',
|
||||
taskListId: options?.taskListId || '',
|
||||
}),
|
||||
});
|
||||
return thought;
|
||||
@@ -169,6 +189,7 @@ export const api = {
|
||||
status: 'inbox',
|
||||
isCompleted: false,
|
||||
dueDate,
|
||||
taskListId: options?.taskListId || '',
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
queue.push(offlineThought);
|
||||
@@ -193,6 +214,7 @@ export const api = {
|
||||
priority: item.priority,
|
||||
source: item.source,
|
||||
dueDate: item.dueDate || '',
|
||||
taskListId: item.taskListId || '',
|
||||
}),
|
||||
});
|
||||
synced++;
|
||||
@@ -220,6 +242,7 @@ export const api = {
|
||||
options?: {
|
||||
convertTo?: 'task' | 'document' | 'list_item';
|
||||
targetListId?: string;
|
||||
taskListId?: string;
|
||||
dueDate?: string;
|
||||
}
|
||||
): Promise<Thought> {
|
||||
@@ -229,18 +252,28 @@ export const api = {
|
||||
action,
|
||||
convertTo: options?.convertTo || '',
|
||||
targetListId: options?.targetListId || '',
|
||||
taskListId: options?.taskListId || '',
|
||||
dueDate: options?.dueDate || '',
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
||||
async getTasks(): Promise<Thought[]> {
|
||||
return request<Thought[]>('/api/v1/tasks');
|
||||
async getTasks(taskListId?: string): Promise<Thought[]> {
|
||||
const query = taskListId ? `?taskListId=${encodeURIComponent(taskListId)}` : '';
|
||||
return request<Thought[]>(`/api/v1/tasks${query}`);
|
||||
},
|
||||
|
||||
async updateThought(
|
||||
thoughtId: string,
|
||||
patch: { content?: string; isCompleted?: boolean; dueDate?: string; priority?: PriorityLevel }
|
||||
patch: {
|
||||
content?: string;
|
||||
isCompleted?: boolean;
|
||||
dueDate?: string;
|
||||
priority?: PriorityLevel;
|
||||
taskListId?: string;
|
||||
kanbanStatus?: 'todo' | 'in_progress' | 'done';
|
||||
notes?: string;
|
||||
}
|
||||
): Promise<Thought> {
|
||||
return request<Thought>(`/api/v1/thoughts/${thoughtId}`, {
|
||||
method: 'PATCH',
|
||||
@@ -256,6 +289,42 @@ export const api = {
|
||||
return request<{ purged: number }>('/api/v1/thoughts/discarded/purge', { method: 'DELETE' });
|
||||
},
|
||||
|
||||
// --- TASK LISTS ---
|
||||
async getTaskLists(): Promise<TaskList[]> {
|
||||
return request<TaskList[]>('/api/v1/task-lists');
|
||||
},
|
||||
|
||||
async createTaskList(payload: {
|
||||
title: string;
|
||||
icon?: string;
|
||||
color?: string;
|
||||
spaceId?: string;
|
||||
}): Promise<TaskList> {
|
||||
return request<TaskList>('/api/v1/task-lists', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
},
|
||||
|
||||
async updateTaskList(
|
||||
id: string,
|
||||
patch: {
|
||||
title?: string;
|
||||
icon?: string;
|
||||
color?: string;
|
||||
spaceId?: string;
|
||||
}
|
||||
): Promise<TaskList> {
|
||||
return request<TaskList>(`/api/v1/task-lists/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(patch),
|
||||
});
|
||||
},
|
||||
|
||||
async deleteTaskList(id: string): Promise<void> {
|
||||
await request(`/api/v1/task-lists/${id}`, { method: 'DELETE' });
|
||||
},
|
||||
|
||||
// --- WORKSPACE DOCUMENTS ---
|
||||
async getDocuments(): Promise<Document[]> {
|
||||
return request<Document[]>('/api/v1/documents');
|
||||
@@ -268,6 +337,7 @@ export const api = {
|
||||
async createDocument(payload: {
|
||||
title: string;
|
||||
icon?: string;
|
||||
folderPath?: string;
|
||||
blocks?: DocumentBlock[];
|
||||
tags?: string[];
|
||||
isPinned?: boolean;
|
||||
@@ -283,6 +353,7 @@ export const api = {
|
||||
patch: {
|
||||
title?: string;
|
||||
icon?: string;
|
||||
folderPath?: string;
|
||||
blocks?: DocumentBlock[];
|
||||
tags?: string[];
|
||||
isPinned?: boolean;
|
||||
@@ -360,6 +431,88 @@ export const api = {
|
||||
});
|
||||
},
|
||||
|
||||
// --- ORGANIZATIONS & TEAMS ---
|
||||
async getOrganizations(): Promise<Organization[]> {
|
||||
return request<Organization[]>('/api/v1/organizations');
|
||||
},
|
||||
|
||||
async createOrganization(name: string): Promise<Organization> {
|
||||
return request<Organization>('/api/v1/organizations', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ name }),
|
||||
});
|
||||
},
|
||||
|
||||
async getOrgTeams(orgId: string): Promise<Team[]> {
|
||||
return request<Team[]>(`/api/v1/organizations/${orgId}/teams`);
|
||||
},
|
||||
|
||||
async createOrgTeam(orgId: string, name: string, description: string): Promise<Team> {
|
||||
return request<Team>(`/api/v1/organizations/${orgId}/teams`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ name, description }),
|
||||
});
|
||||
},
|
||||
|
||||
async getUserTeams(): Promise<Team[]> {
|
||||
return request<Team[]>('/api/v1/teams');
|
||||
},
|
||||
|
||||
async addTeamMember(teamId: string, userId: string, role = 'editor'): Promise<void> {
|
||||
await request(`/api/v1/teams/${teamId}/members`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ userId, role }),
|
||||
});
|
||||
},
|
||||
|
||||
async removeTeamMember(teamId: string, userId: string): Promise<void> {
|
||||
await request(`/api/v1/teams/${teamId}/members/${userId}`, { method: 'DELETE' });
|
||||
},
|
||||
|
||||
// --- ADMIN PANEL ---
|
||||
async adminGetUsers(): Promise<User[]> {
|
||||
return request<User[]>('/api/v1/admin/users');
|
||||
},
|
||||
|
||||
async adminCreateUser(payload: { email: string; password: string; displayName: string; role: string }): Promise<User> {
|
||||
return request<User>('/api/v1/admin/users', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
},
|
||||
|
||||
async adminUpdateUser(
|
||||
id: string,
|
||||
patch: { displayName?: string; email?: string; role?: string; isActive?: boolean; discordWebhookUrl?: string }
|
||||
): Promise<User> {
|
||||
return request<User>(`/api/v1/admin/users/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(patch),
|
||||
});
|
||||
},
|
||||
|
||||
async adminResetPassword(id: string, password: string): Promise<void> {
|
||||
await request(`/api/v1/admin/users/${id}/password`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ password }),
|
||||
});
|
||||
},
|
||||
|
||||
async adminDeleteUser(id: string): Promise<void> {
|
||||
await request(`/api/v1/admin/users/${id}`, { method: 'DELETE' });
|
||||
},
|
||||
|
||||
async adminGetSettings(): Promise<SystemSettings> {
|
||||
return request<SystemSettings>('/api/v1/admin/settings');
|
||||
},
|
||||
|
||||
async adminUpdateSettings(settings: SystemSettings): Promise<SystemSettings> {
|
||||
return request<SystemSettings>('/api/v1/admin/settings', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(settings),
|
||||
});
|
||||
},
|
||||
|
||||
// --- API KEYS, WEBHOOKS & EXPORT ---
|
||||
async getAPIKeys(): Promise<APIKey[]> {
|
||||
return request<APIKey[]>('/api/v1/keys');
|
||||
|
||||
@@ -5,6 +5,10 @@ export interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
displayName: string;
|
||||
role: 'admin' | 'member';
|
||||
isActive: boolean;
|
||||
discordWebhookUrl?: string;
|
||||
notifyBeforeMinutes?: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
@@ -20,11 +24,58 @@ export interface Thought {
|
||||
convertedType?: 'task' | 'document' | 'list_item';
|
||||
convertedRefId?: string;
|
||||
dueDate?: string;
|
||||
taskListId?: string;
|
||||
kanbanStatus?: 'todo' | 'in_progress' | 'done';
|
||||
notes?: string;
|
||||
alarmSent?: boolean;
|
||||
createdAt: string;
|
||||
triagedAt?: string;
|
||||
}
|
||||
|
||||
export type BlockType = 'h1' | 'h2' | 'h3' | 'paragraph' | 'todo' | 'bullet' | 'code' | 'callout' | 'divider';
|
||||
export interface TaskList {
|
||||
id: string;
|
||||
userId: string;
|
||||
spaceId?: string;
|
||||
title: string;
|
||||
icon: string;
|
||||
color: string;
|
||||
tasksCount?: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface Organization {
|
||||
id: string;
|
||||
name: string;
|
||||
ownerId: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface Team {
|
||||
id: string;
|
||||
orgId: string;
|
||||
name: string;
|
||||
description: string;
|
||||
members?: TeamMember[];
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface TeamMember {
|
||||
teamId: string;
|
||||
userId: string;
|
||||
displayName: string;
|
||||
email: string;
|
||||
role: 'owner' | 'editor' | 'viewer';
|
||||
joinedAt: string;
|
||||
}
|
||||
|
||||
export interface SystemSettings {
|
||||
sharingMode: 'open' | 'teams_only' | 'strict_private';
|
||||
allowRegistration: boolean;
|
||||
instanceName: string;
|
||||
}
|
||||
|
||||
export type BlockType = 'h1' | 'h2' | 'h3' | 'paragraph' | 'todo' | 'bullet' | 'code' | 'callout' | 'divider' | 'table' | 'progress';
|
||||
|
||||
export interface DocumentBlock {
|
||||
id: string;
|
||||
@@ -43,6 +94,7 @@ export interface Document {
|
||||
content: string;
|
||||
blocks: DocumentBlock[];
|
||||
tags: string[];
|
||||
folderPath?: string;
|
||||
isPinned: boolean;
|
||||
isArchived: boolean;
|
||||
createdAt: string;
|
||||
|
||||
Reference in new issue
Block a user