mirror of
https://github.com/Gimanh/taskview-community.git
synced 2026-09-21 01:53:29 +00:00
wip: notifications
This commit is contained in:
@@ -1,14 +1,25 @@
|
||||
import TvApiBase from './base';
|
||||
import type { AppResponse } from '@/api/base.types';
|
||||
import type { KanbanArgAddColumn, KanbanArgDeleteColumn, KanbanArgUpdateColumn, KanbanArgUpdateTasksOrder, KanbanColumnItem, KanbanResponseDeleteColumn, KanbanResponseTasksForColumn, KanbanResponseTasksOrderForColumnAndCursor, KanbanResponseUpdateColumn, KanbanResponseUpdateTasksOrder } from './kanban.types';
|
||||
import type { KanbanArgAddColumn, KanbanArgDeleteColumn, KanbanArgUpdateColumn, KanbanArgUpdateTasksOrder, KanbanColumnItem, KanbanFilters, KanbanResponseDeleteColumn, KanbanResponseTasksForColumn, KanbanResponseTasksOrderForColumnAndCursor, KanbanResponseUpdateColumn, KanbanResponseUpdateTasksOrder } from './kanban.types';
|
||||
import type { Task } from './tasks.api.types';
|
||||
|
||||
export default class TvKanban extends TvApiBase {
|
||||
protected moduleUrl = '/module/kanban';
|
||||
|
||||
public async fetchTasksForColumn(goalId: number, columnId: number | null, cursor: string | number | null) {
|
||||
public async fetchTasksForColumn(goalId: number, columnId: number | null, cursor: string | number | null, filters?: KanbanFilters) {
|
||||
const params = new URLSearchParams();
|
||||
if (filters) {
|
||||
if (filters.listIds && filters.listIds.length > 0) {
|
||||
params.set('listIds', filters.listIds.join(','));
|
||||
}
|
||||
if (filters.assigneeIds && filters.assigneeIds.length > 0) {
|
||||
params.set('assigneeIds', filters.assigneeIds.join(','));
|
||||
}
|
||||
}
|
||||
const query = params.toString();
|
||||
const url = `${this.moduleUrl}/tasks/${goalId}/${columnId}/${cursor}${query ? `?${query}` : ''}`;
|
||||
return this.request(
|
||||
this.$axios.get<AppResponse<KanbanResponseTasksForColumn>>(`${this.moduleUrl}/tasks/${goalId}/${columnId}/${cursor}`)
|
||||
this.$axios.get<AppResponse<KanbanResponseTasksForColumn>>(url)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import type { Task } from "./tasks.api.types";
|
||||
|
||||
export type KanbanFilters = {
|
||||
listIds?: number[];
|
||||
assigneeIds?: number[];
|
||||
};
|
||||
|
||||
export type KanbanColumnItem = {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
export enum NotificationType {
|
||||
DEADLINE = 'deadline',
|
||||
ASSIGN = 'assign',
|
||||
MENTION = 'mention',
|
||||
COMMENT = 'comment',
|
||||
STATUS_CHANGE = 'status_change',
|
||||
}
|
||||
|
||||
export enum NotificationChannel {
|
||||
PUSH = 'push',
|
||||
WEBSOCKET = 'websocket',
|
||||
EMAIL = 'email',
|
||||
}
|
||||
|
||||
export interface Notification {
|
||||
id: number;
|
||||
userId: number;
|
||||
taskId: number | null;
|
||||
type: NotificationType;
|
||||
title: string;
|
||||
body: string | null;
|
||||
read: boolean;
|
||||
@@ -20,3 +35,20 @@ export type NotificationResponseConnectionToken = {
|
||||
token: string | null;
|
||||
url: string | null;
|
||||
};
|
||||
|
||||
type Minutes = string;
|
||||
type IsEnabled = boolean;
|
||||
export interface NotificationPreferencesSettings {
|
||||
global?: Partial<Record<NotificationType, {
|
||||
channels?: Partial<Record<NotificationChannel, IsEnabled>>;
|
||||
intervals?: Record<Minutes, IsEnabled>;
|
||||
}>>;
|
||||
projects?: Record<string, Partial<Record<NotificationType, {
|
||||
channels?: Partial<Record<NotificationChannel, IsEnabled>>;
|
||||
intervals?: Record<Minutes, IsEnabled>;
|
||||
}>>>;
|
||||
}
|
||||
|
||||
export type NotificationResponsePreferences = {
|
||||
settings: NotificationPreferencesSettings;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import TvApiBase from "./base";
|
||||
import type { AppResponse } from "./base.types";
|
||||
import type { NotificationResponseFetch, NotificationResponseMarkRead, NotificationResponseConnectionToken } from "./notifications.api.types";
|
||||
import type { NotificationResponseFetch, NotificationResponseMarkRead, NotificationResponseConnectionToken, NotificationResponsePreferences, NotificationPreferencesSettings } from "./notifications.api.types";
|
||||
|
||||
export default class TvNotificationsApi extends TvApiBase {
|
||||
protected moduleUrl = '/module/notifications';
|
||||
@@ -36,4 +36,36 @@ export default class TvNotificationsApi extends TvApiBase {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public async registerDevice(token: string, platform: 'android' | 'ios', timezone: string) {
|
||||
return this.request(
|
||||
this.$axios.post<AppResponse<boolean>>(
|
||||
`${this.moduleUrl}/device/register`, { token, platform, timezone }
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public async unregisterDevice(token: string) {
|
||||
return this.request(
|
||||
this.$axios.post<AppResponse<boolean>>(
|
||||
`${this.moduleUrl}/device/unregister`, { token }
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public async getPreferences() {
|
||||
return this.request(
|
||||
this.$axios.get<AppResponse<NotificationResponsePreferences>>(
|
||||
`${this.moduleUrl}/preferences`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public async savePreferences(settings: NotificationPreferencesSettings) {
|
||||
return this.request(
|
||||
this.$axios.put<AppResponse<boolean>>(
|
||||
`${this.moduleUrl}/preferences`, { settings }
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import TvApiBase from './base';
|
||||
import type { AppResponse } from '@/api/base.types';
|
||||
import type {
|
||||
WebhookArgCreate,
|
||||
WebhookArgDelete,
|
||||
WebhookArgUpdate,
|
||||
WebhookDeliveryItem,
|
||||
WebhookItem,
|
||||
WebhookResponseCreate,
|
||||
} from './webhooks.types';
|
||||
|
||||
export default class TvWebhooks extends TvApiBase {
|
||||
protected moduleUrl = '/module/webhooks';
|
||||
|
||||
public async fetch(goalId: number) {
|
||||
return this.request(
|
||||
this.$axios.get<AppResponse<WebhookItem[]>>(`${this.moduleUrl}`, { params: { goalId } })
|
||||
);
|
||||
}
|
||||
|
||||
public async create(data: WebhookArgCreate) {
|
||||
return this.request(
|
||||
this.$axios.post<AppResponse<WebhookResponseCreate>>(`${this.moduleUrl}`, data)
|
||||
);
|
||||
}
|
||||
|
||||
public async update(data: WebhookArgUpdate) {
|
||||
return this.request(
|
||||
this.$axios.patch<AppResponse<WebhookItem>>(`${this.moduleUrl}`, data)
|
||||
);
|
||||
}
|
||||
|
||||
public async delete(data: WebhookArgDelete) {
|
||||
return this.request(
|
||||
this.$axios.delete<AppResponse<boolean>>(`${this.moduleUrl}`, { data })
|
||||
);
|
||||
}
|
||||
|
||||
public async rotateSecret(id: number) {
|
||||
return this.request(
|
||||
this.$axios.post<AppResponse<{ secret: string }>>(`${this.moduleUrl}/rotate-secret`, { id })
|
||||
);
|
||||
}
|
||||
|
||||
public async testDelivery(id: number) {
|
||||
return this.request(
|
||||
this.$axios.post<AppResponse<{ success: boolean; responseCode?: number }>>(`${this.moduleUrl}/test`, { id })
|
||||
);
|
||||
}
|
||||
|
||||
public async fetchDeliveries(webhookId: number, options?: { cursor?: number; status?: string }) {
|
||||
return this.request(
|
||||
this.$axios.get<AppResponse<WebhookDeliveryItem[]>>(`${this.moduleUrl}/deliveries/${webhookId}`, { params: options })
|
||||
);
|
||||
}
|
||||
|
||||
public async retryDelivery(deliveryId: number) {
|
||||
return this.request(
|
||||
this.$axios.post<AppResponse<{ success: boolean; responseCode?: number }>>(`${this.moduleUrl}/retry`, { id: deliveryId })
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
export type WebhookItem = {
|
||||
id: number;
|
||||
goalId: number;
|
||||
url: string;
|
||||
events: string[];
|
||||
isActive: boolean;
|
||||
createdAt: string | null;
|
||||
updatedAt: string | null;
|
||||
};
|
||||
|
||||
export type WebhookArgCreate = {
|
||||
goalId: number;
|
||||
url: string;
|
||||
events: string[];
|
||||
};
|
||||
|
||||
export type WebhookResponseCreate = {
|
||||
webhook: WebhookItem;
|
||||
secret: string;
|
||||
};
|
||||
|
||||
export type WebhookArgUpdate = {
|
||||
id: number;
|
||||
url?: string;
|
||||
events?: string[];
|
||||
isActive?: boolean;
|
||||
};
|
||||
|
||||
export type WebhookArgDelete = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
export type WebhookDeliveryItem = {
|
||||
id: number;
|
||||
webhookId: number;
|
||||
event: string;
|
||||
payload: unknown;
|
||||
status: string;
|
||||
responseCode: number | null;
|
||||
attempts: number;
|
||||
lastAttemptAt: string | null;
|
||||
createdAt: string | null;
|
||||
};
|
||||
|
||||
export const WEBHOOK_EVENTS = [
|
||||
'task.created',
|
||||
'task.updated',
|
||||
'task.deleted',
|
||||
'task.assigneesChanged',
|
||||
] as const;
|
||||
|
||||
export type WebhookEvent = typeof WEBHOOK_EVENTS[number];
|
||||
Reference in New Issue
Block a user