import { Action, useNavigation, ActionPanel, Form, Icon, getPreferenceValues, showToast, Toast } from "@raycast/api"; import { MutatePromise, useForm, FormValidation, useFetch } from "@raycast/utils"; import { Page, UniversalInboxPreferences } from "../types"; import { Notification } from "../notification"; import { TaskPriority } from "../task"; import { handleErrors } from "../api"; import utc from "dayjs/plugin/utc"; import { useState } from "react"; import fetch from "node-fetch"; import dayjs from "dayjs"; dayjs.extend(utc); interface CreateTaskFromNotificationProps { notification: Notification; mutate: MutatePromise | undefined>; } interface TaskCreationFormValues { title: string; project: string; dueAt: Date | null; priority: string; } interface ProjectSummary { name: string; source_id: string; } interface TaskCreation { title: string; project: ProjectSummary; due_at?: { type: "DateTimeWithTz"; content: string }; priority: TaskPriority; } export function CreateTaskFromNotification({ notification, mutate }: CreateTaskFromNotificationProps) { const preferences = getPreferenceValues(); const { pop } = useNavigation(); const [searchText, setSearchText] = useState(""); const { isLoading, data: projects } = useFetch>( `${preferences.universalInboxBaseUrl}/api/tasks/projects/search?matches=${searchText}`, { keepPreviousData: true, headers: { Authorization: `Bearer ${preferences.apiKey}`, }, }, ); const { handleSubmit, itemProps } = useForm({ initialValues: { title: notification.title, dueAt: new Date(), priority: `${TaskPriority.P4 as number}`, }, async onSubmit(values) { const project = projects?.find((p) => p.source_id === values.project); if (!project) { throw new Error("Project not found"); } const taskCreation: TaskCreation = { title: values.title, project: project, due_at: values.dueAt ? { type: "DateTimeWithTz", content: dayjs(values.dueAt).utc().format() } : undefined, priority: parseInt(values.priority) as TaskPriority, }; await createTaskFromNotification(taskCreation, notification, mutate); pop(); }, validation: { title: FormValidation.Required, project: FormValidation.Required, priority: FormValidation.Required, }, }); return (
} > {projects?.map((project) => { return ; })} ); } async function createTaskFromNotification( taskCreation: TaskCreation, notification: Notification, mutate: MutatePromise | undefined>, ) { const preferences = getPreferenceValues(); const toast = await showToast({ style: Toast.Style.Animated, title: "Creating task from notification" }); try { await mutate( handleErrors( fetch(`${preferences.universalInboxBaseUrl}/api/notifications/${notification.id}/task`, { method: "POST", body: JSON.stringify(taskCreation), headers: { "Content-Type": "application/json", Authorization: `Bearer ${preferences.apiKey}`, }, }), ), { optimisticUpdate(page) { if (page) { page.content = page.content.filter((n) => n.id !== notification.id); } return page; }, }, ); toast.style = Toast.Style.Success; toast.title = "Task successfully created"; } catch (error) { toast.style = Toast.Style.Failure; toast.title = "Failed to create task from notification"; toast.message = (error as Error).message; throw error; } }