KI-AGENT: Kalender, Terminbearbeitung und Dateivorschau verbessern
This commit is contained in:
@@ -54,13 +54,15 @@ export type Project = {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type EventState = 'Entwurf' | 'Final';
|
||||
|
||||
export type CalendarEvent = {
|
||||
id: number;
|
||||
name: string;
|
||||
startDate: string;
|
||||
endDate?: string | null;
|
||||
eventtype?: string | null;
|
||||
state?: string | null;
|
||||
state?: EventState | null;
|
||||
repeatInterval?: string | null;
|
||||
project?: number | { id?: number; name?: string } | null;
|
||||
customer?: number | { id?: number; name?: string } | null;
|
||||
@@ -724,7 +726,7 @@ export async function createEvent(
|
||||
notes?: string | null;
|
||||
link?: string | null;
|
||||
eventtype?: string;
|
||||
state?: 'Entwurf' | 'Final';
|
||||
state?: EventState;
|
||||
repeatInterval?: string;
|
||||
}
|
||||
): Promise<CalendarEvent> {
|
||||
@@ -735,6 +737,18 @@ export async function createEvent(
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateEvent(
|
||||
token: string,
|
||||
eventId: number,
|
||||
payload: Partial<Pick<CalendarEvent, 'name' | 'startDate' | 'endDate' | 'project' | 'customer' | 'notes' | 'link' | 'eventtype' | 'state' | 'repeatInterval'>>
|
||||
): Promise<CalendarEvent> {
|
||||
return apiRequest<CalendarEvent>(`/api/resource/events/${eventId}`, {
|
||||
method: 'PUT',
|
||||
token,
|
||||
body: payload,
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchEventById(token: string, eventId: number): Promise<CalendarEvent> {
|
||||
return apiRequest<CalendarEvent>(`/api/resource/events/${eventId}`, { token });
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { File, Paths } from 'expo-file-system';
|
||||
import * as Sharing from 'expo-sharing';
|
||||
|
||||
import type { ProjectFile } from '@/src/lib/api';
|
||||
import { getApiBaseUrlSync } from '@/src/lib/server-config';
|
||||
|
||||
export function getOpenableFileUrl(rawUrl: string): string {
|
||||
@@ -7,3 +11,28 @@ export function getOpenableFileUrl(rawUrl: string): string {
|
||||
const path = rawUrl.startsWith('/') ? rawUrl : `/${rawUrl}`;
|
||||
return `${apiBaseUrl}${path}`;
|
||||
}
|
||||
|
||||
function safeFilename(file: ProjectFile): string {
|
||||
const fallback = `dokument-${file.id}`;
|
||||
const rawName = String(file.name || file.path?.split('/').pop() || fallback);
|
||||
return rawName.replace(/[^a-zA-Z0-9äöüÄÖÜß._-]/g, '_');
|
||||
}
|
||||
|
||||
export async function openAuthenticatedFile(file: ProjectFile, token: string): Promise<void> {
|
||||
if (!file.url) throw new Error('Für dieses Dokument ist kein Download verfügbar.');
|
||||
|
||||
const target = new File(Paths.cache, `${file.id}-${safeFilename(file)}`);
|
||||
const downloaded = await File.downloadFileAsync(getOpenableFileUrl(file.url), target, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
idempotent: true,
|
||||
});
|
||||
|
||||
if (!(await Sharing.isAvailableAsync())) {
|
||||
throw new Error('Die Dokumentvorschau ist auf diesem Gerät nicht verfügbar.');
|
||||
}
|
||||
|
||||
await Sharing.shareAsync(downloaded.uri, {
|
||||
mimeType: file.mimeType || undefined,
|
||||
dialogTitle: safeFilename(file),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user