This commit is contained in:
michael committed 2026-10-08 09:03:15 +02:00
1 parent fc0dfd0556
commit 649dd6f028
20 files changed
+3725 -988

No files matched your search

+103 -2
View File
@@ -7,6 +7,7 @@ import type {
Organization,
PeriodOverview,
PeriodType,
ProjectTeamspaceSubentry,
ProjectSummary,
RecurringBilling,
StatisticsOverview,
@@ -125,6 +126,51 @@ export type ZammadSyncJob = {
finishedAt: string | null;
};
export type TeamspaceProjectIdSyncItem = {
entryId: string;
projectId: string;
ticketNumber: string;
teamspaceProject: string;
previousApiProjectId: string | null;
apiProjectId: string | null;
apiProjectUrl: string | null;
status: "updated" | "current" | "missing" | "ambiguous";
message: string | null;
};
export type TeamspaceProjectIdSyncResult = {
checkedEntries: number;
matched: number;
updated: number;
alreadyCurrent: number;
missing: number;
ambiguous: number;
cleared: number;
remoteProjectsScanned: number;
remoteProjectIds: number;
remoteSubprojectsScanned: number;
subentriesSynced: number;
subentriesRemoved: number;
duplicateRemoteProjectIds: string[];
items: TeamspaceProjectIdSyncItem[];
};
export type TeamspaceProjectSubentrySyncResult = {
projectId: string;
checkedEntries: number;
remoteProjectsScanned: number;
subentriesSynced: number;
subentriesRemoved: number;
};
export type TeamspaceAllSubentrySyncResult = {
checkedProjects: number;
checkedEntries: number;
remoteProjectsScanned: number;
subentriesSynced: number;
subentriesRemoved: number;
};
export type TicketZammadMailSessionItem = {
articleId: number;
ticketNumber: string;
@@ -248,8 +294,11 @@ export function updateCurrentUser(payload: {
currentPassword?: string;
newPassword?: string;
zammadApiToken?: string;
teamspaceDeviceId?: string;
teamspaceDevicePassword?: string;
zammadEmailSessionWebhookEnabled?: boolean;
sessionBillingPromptEnabled?: boolean;
teamspaceTimeTrackingEnabled?: boolean;
zammadSessionNoteDefaultEnabled?: boolean;
zammadTimeUnitRoundingEnabled?: boolean;
zammadTimeUnitRoundingMinutes?: number;
@@ -432,6 +481,17 @@ export function saveZammadSettings(payload: { baseUrl: string; apiKey?: string }
});
}
export function getTeamspaceSettings() {
return request<{ settings: { baseUrl: string } }>("/api/admin/teamspace/settings");
}
export function saveTeamspaceSettings(payload: { baseUrl: string }) {
return request<{ settings: { baseUrl: string } }>("/api/admin/teamspace/settings", {
method: "PUT",
body: JSON.stringify(payload)
});
}
export function syncZammadOrganizations(payload: { baseUrl?: string; apiKey?: string }) {
return request<{ synced: number; skipped: number; removed: number; unlinkedTickets: number; unlinkedSessions: number }>("/api/admin/zammad/organizations/sync", {
method: "POST",
@@ -537,6 +597,39 @@ export function applyZammadMailSessionsFromPreview(previewJobId: string, article
}, onJobStarted);
}
export function syncTeamspaceProjectIds() {
return request<{ result: TeamspaceProjectIdSyncResult }>("/api/teamspace/project-ids/sync", {
method: "POST",
timeoutMs: 5 * 60 * 1000
});
}
export function syncProjectTeamspaceSubentries(projectId: string) {
return request<{ result: TeamspaceProjectSubentrySyncResult }>(`/api/projects/${projectId}/teamspace-subentries/sync`, {
method: "POST",
timeoutMs: 5 * 60 * 1000
});
}
export function syncAllTeamspaceSubentries() {
return request<{ result: TeamspaceAllSubentrySyncResult }>("/api/teamspace/subentries/sync", {
method: "POST",
timeoutMs: 5 * 60 * 1000
});
}
export function updateProjectTeamspaceSubentry(
subentryId: string,
payload: {
alias: string;
}
) {
return request<{ subentry: ProjectTeamspaceSubentry }>(`/api/project-teamspace-subentries/${subentryId}`, {
method: "PATCH",
body: JSON.stringify(payload)
});
}
export function getRecurringBillings() {
return request<{ recurringBillings: RecurringBilling[] }>("/api/recurring-billings");
}
@@ -861,10 +954,18 @@ export function updateSessionDetails(
});
}
export function updateTicketDayBilling(ticketId: string, day: string, billedMinutes: number | null, projectTeamspaceEntryId?: string | null) {
export function updateTicketDayBilling(
ticketId: string,
day: string,
billedMinutes: number | null,
projectTeamspaceEntryId?: string | null
) {
return request(`/api/tickets/${ticketId}/day-billings/${day}`, {
method: "PATCH",
body: JSON.stringify({ billedMinutes, projectTeamspaceEntryId: projectTeamspaceEntryId ?? null })
body: JSON.stringify({
billedMinutes,
projectTeamspaceEntryId: projectTeamspaceEntryId ?? null
})
});
}