mirror of
https://github.com/Mail-0/Zero.git
synced 2026-06-28 14:56:48 +00:00
Enhance email composer functionality and UI improvements. Updated draft handling to clean email addresses and format message content. Implemented auto-save feature for drafts and improved state management in sidebar components. Cleaned up unused imports and adjusted styling for better consistency.
This commit is contained in:
@@ -112,8 +112,22 @@ export function EmailComposer({
|
||||
|
||||
useEffect(() => {
|
||||
if (draft) {
|
||||
if (draft.to) form.setValue('to', draft.to);
|
||||
if (draft.content) form.setValue('message', draft.content);
|
||||
if (draft.to)
|
||||
form.setValue(
|
||||
'to',
|
||||
draft.to.map((email) => email.replace(/[<>]/g, '')),
|
||||
);
|
||||
if (draft.content) {
|
||||
editor.commands.setContent({
|
||||
type: 'doc',
|
||||
content: draft.content.split(/\r?\n/).map((line) => {
|
||||
return {
|
||||
type: 'paragraph',
|
||||
content: line.trim().length === 0 ? [] : [{ type: 'text', text: line }],
|
||||
};
|
||||
}),
|
||||
});
|
||||
}
|
||||
if (draft.subject) form.setValue('subject', draft.subject);
|
||||
}
|
||||
}, [draft]);
|
||||
@@ -252,6 +266,7 @@ export function EmailComposer({
|
||||
initialValue: initialMessage,
|
||||
isReadOnly: isLoading,
|
||||
onLengthChange: (length) => {
|
||||
setHasUnsavedChanges(true);
|
||||
setMessageLength(length);
|
||||
},
|
||||
onModEnter: () => {
|
||||
@@ -316,21 +331,23 @@ export function EmailComposer({
|
||||
|
||||
const handleGenerateReply = async () => {};
|
||||
|
||||
const saveDraft = useCallback(async () => {
|
||||
console.log('trying to save email');
|
||||
if (!hasUnsavedChanges) return;
|
||||
if (!toEmails.length || !subjectInput || !messageContent) return;
|
||||
const saveDraft = async () => {
|
||||
const values = getValues();
|
||||
|
||||
if (!hasUnsavedChanges) return;
|
||||
const messageText = editor.getText();
|
||||
console.log(values, messageText);
|
||||
if (!values.to.length || !values.subject.length || !messageText.length) return;
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const draftData = {
|
||||
to: values?.to?.join(', '),
|
||||
cc: values?.cc?.join(', '),
|
||||
bcc: values?.bcc?.join(', '),
|
||||
subject: values?.subject,
|
||||
message: values?.message,
|
||||
attachments: values?.attachments,
|
||||
to: values.to.join(', '),
|
||||
cc: values.cc?.join(', '),
|
||||
bcc: values.bcc?.join(', '),
|
||||
subject: values.subject,
|
||||
message: messageText,
|
||||
attachments: values.attachments,
|
||||
id: draftId,
|
||||
};
|
||||
|
||||
@@ -339,21 +356,20 @@ export function EmailComposer({
|
||||
if (response?.id && response.id !== draftId) {
|
||||
setDraftId(response.id);
|
||||
}
|
||||
|
||||
setHasUnsavedChanges(false);
|
||||
// toast.success(`Draft saved successfully: ${response.id}`);
|
||||
} catch (error) {
|
||||
console.error('Error saving draft:', error);
|
||||
toast.error('Failed to save draft');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
setHasUnsavedChanges(false);
|
||||
}
|
||||
}, [toEmails, subjectInput, messageContent, attachments, draftId, hasUnsavedChanges]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasUnsavedChanges) return;
|
||||
|
||||
const autoSaveTimer = setTimeout(() => {
|
||||
console.log('timeout set');
|
||||
saveDraft();
|
||||
}, 3000);
|
||||
|
||||
|
||||
@@ -76,7 +76,9 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
{...props}
|
||||
className={`flex select-none flex-col items-center ${state === 'collapsed' ? '' : ''}`}
|
||||
>
|
||||
<div className={`relative z-20 flex w-full flex-col ${state === 'collapsed' ? 'px-0' : 'md:px-2'}`}>
|
||||
<div
|
||||
className={`relative z-20 flex w-full flex-col ${state === 'collapsed' ? 'px-0' : 'md:px-2'}`}
|
||||
>
|
||||
<SidebarHeader className="flex flex-col gap-2 pt-[18px]">
|
||||
<NavUser />
|
||||
<AnimatePresence mode="wait">
|
||||
@@ -130,13 +132,15 @@ function ComposeButton() {
|
||||
const [dialogOpen, setDialogOpen] = useQueryState('isComposeOpen');
|
||||
const [, setDraftId] = useQueryState('draftId');
|
||||
const [, setTo] = useQueryState('to');
|
||||
const [, setActiveReplyId] = useQueryState('activeReplyId');
|
||||
const [, setMode] = useQueryState('mode');
|
||||
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
setDialogOpen(open ? 'true' : null);
|
||||
if (!open) {
|
||||
setDraftId(null);
|
||||
setTo(null);
|
||||
}
|
||||
setDraftId(null);
|
||||
setTo(null);
|
||||
setActiveReplyId(null);
|
||||
setMode(null);
|
||||
};
|
||||
return (
|
||||
<Dialog open={!!dialogOpen} onOpenChange={handleOpenChange}>
|
||||
@@ -156,7 +160,7 @@ function ComposeButton() {
|
||||
</button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent className="h-screen w-screen max-w-none border-none bg-[#FAFAFA] dark:bg-[#141414] p-0 shadow-none">
|
||||
<DialogContent className="h-screen w-screen max-w-none border-none bg-[#FAFAFA] p-0 shadow-none dark:bg-[#141414]">
|
||||
<CreateEmail />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -30,6 +30,7 @@ import { useSearchValue } from '@/hooks/use-search-value';
|
||||
import { clearBulkSelectionAtom } from '../mail/use-mail';
|
||||
import { Label as UILabel } from '@/components/ui/label';
|
||||
import { type MessageKey } from '@/config/navigation';
|
||||
import { Command, SettingsIcon } from 'lucide-react';
|
||||
import { type NavItem } from '@/config/navigation';
|
||||
import { createLabel } from '@/hooks/use-labels';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -39,7 +40,7 @@ import { Badge } from '@/components/ui/badge';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { GoldenTicketModal } from '../golden';
|
||||
import { useStats } from '@/hooks/use-stats';
|
||||
import { Command, SettingsIcon } from 'lucide-react';
|
||||
import { CurvedArrow } from '../icons/icons';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useRef, useCallback } from 'react';
|
||||
import { BASE_URL } from '@/lib/constants';
|
||||
@@ -51,7 +52,6 @@ import { useAtom } from 'jotai';
|
||||
import { toast } from 'sonner';
|
||||
import * as React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { CurvedArrow } from '../icons/icons';
|
||||
|
||||
interface IconProps extends React.SVGProps<SVGSVGElement> {
|
||||
ref?: React.Ref<SVGSVGElement>;
|
||||
@@ -95,7 +95,7 @@ export function NavMain({ items }: NavMainProps) {
|
||||
|
||||
const formColor = form.watch('color');
|
||||
|
||||
const { labels } = useLabels();
|
||||
const { labels, mutate } = useLabels();
|
||||
const { state } = useSidebar();
|
||||
|
||||
// Check if these are bottom navigation items by looking at the first section's title
|
||||
@@ -216,6 +216,9 @@ export function NavMain({ items }: NavMainProps) {
|
||||
loading: 'Creating label...',
|
||||
success: 'Label created successfully',
|
||||
error: 'Failed to create label',
|
||||
finally: () => {
|
||||
mutate();
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error creating label:', error);
|
||||
@@ -287,12 +290,16 @@ export function NavMain({ items }: NavMainProps) {
|
||||
<DialogTitle>Create New Label</DialogTitle>
|
||||
</DialogHeader>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4" onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
|
||||
e.preventDefault();
|
||||
form.handleSubmit(onSubmit)();
|
||||
}
|
||||
}}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-4"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
|
||||
e.preventDefault();
|
||||
form.handleSubmit(onSubmit)();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="space-y-4 py-4">
|
||||
<div className="space-y-2">
|
||||
<FormField
|
||||
@@ -315,27 +322,54 @@ export function NavMain({ items }: NavMainProps) {
|
||||
<div className="grid grid-cols-7 gap-4">
|
||||
{[
|
||||
// Row 1 - Grayscale
|
||||
'#000000', '#434343', '#666666', '#999999', '#cccccc', '#ffffff',
|
||||
'#000000',
|
||||
'#434343',
|
||||
'#666666',
|
||||
'#999999',
|
||||
'#cccccc',
|
||||
'#ffffff',
|
||||
// Row 2 - Warm colors
|
||||
'#fb4c2f', '#ffad47', '#fad165', '#ff7537', '#cc3a21', '#8a1c0a',
|
||||
'#fb4c2f',
|
||||
'#ffad47',
|
||||
'#fad165',
|
||||
'#ff7537',
|
||||
'#cc3a21',
|
||||
'#8a1c0a',
|
||||
// Row 3 - Cool colors
|
||||
'#16a766', '#43d692', '#4a86e8', '#285bac', '#3c78d8', '#0d3472',
|
||||
'#16a766',
|
||||
'#43d692',
|
||||
'#4a86e8',
|
||||
'#285bac',
|
||||
'#3c78d8',
|
||||
'#0d3472',
|
||||
// Row 4 - Purple tones
|
||||
'#a479e2', '#b99aff', '#653e9b', '#3d188e', '#f691b3', '#994a64',
|
||||
'#a479e2',
|
||||
'#b99aff',
|
||||
'#653e9b',
|
||||
'#3d188e',
|
||||
'#f691b3',
|
||||
'#994a64',
|
||||
// Row 5 - Pastels
|
||||
'#f6c5be', '#ffe6c7', '#c6f3de', '#c9daf8',
|
||||
'#f6c5be',
|
||||
'#ffe6c7',
|
||||
'#c6f3de',
|
||||
'#c9daf8',
|
||||
].map((color) => (
|
||||
<button
|
||||
key={color}
|
||||
type="button"
|
||||
className={`h-10 w-10 rounded-[4px] border-[0.5px] border-white/10 ${
|
||||
formColor?.backgroundColor === color ? 'ring-2 ring-blue-500' : ''
|
||||
formColor?.backgroundColor === color
|
||||
? 'ring-2 ring-blue-500'
|
||||
: ''
|
||||
}`}
|
||||
style={{ backgroundColor: color }}
|
||||
onClick={() => form.setValue('color', {
|
||||
backgroundColor: color,
|
||||
textColor: '#ffffff'
|
||||
})}
|
||||
onClick={() =>
|
||||
form.setValue('color', {
|
||||
backgroundColor: color,
|
||||
textColor: '#ffffff',
|
||||
})
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -353,7 +387,7 @@ export function NavMain({ items }: NavMainProps) {
|
||||
</Button>
|
||||
<Button className="h-8" type="submit">
|
||||
Create Label
|
||||
<div className="flex h-5 items-center justify-center gap- rounded-sm bg-white/10 px-1 dark:bg-black/10">
|
||||
<div className="gap- flex h-5 items-center justify-center rounded-sm bg-white/10 px-1 dark:bg-black/10">
|
||||
<Command className="h-2 w-2 text-white dark:text-[#929292]" />
|
||||
<CurvedArrow className="mt-1.5 h-3 w-3 fill-white dark:fill-[#929292]" />
|
||||
</div>
|
||||
|
||||
10
packages/db/migrations/0023_narrow_maria_hill.sql
Normal file
10
packages/db/migrations/0023_narrow_maria_hill.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE "mail0_writing_style_matrix" (
|
||||
"connectionId" text NOT NULL,
|
||||
"numMessages" integer NOT NULL,
|
||||
"style" jsonb NOT NULL,
|
||||
"updatedAt" timestamp DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "mail0_writing_style_matrix_connectionId_pk" PRIMARY KEY("connectionId")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "mail0_user_settings" ALTER COLUMN "settings" SET DEFAULT '{"language":"en","timezone":"UTC","dynamicContent":false,"externalImages":true,"customPrompt":"","trustedSenders":[],"isOnboarded":false,"colorTheme":"system"}'::jsonb;--> statement-breakpoint
|
||||
ALTER TABLE "mail0_writing_style_matrix" ADD CONSTRAINT "mail0_writing_style_matrix_connectionId_mail0_connection_id_fk" FOREIGN KEY ("connectionId") REFERENCES "public"."mail0_connection"("id") ON DELETE no action ON UPDATE no action;
|
||||
822
packages/db/migrations/meta/0023_snapshot.json
Normal file
822
packages/db/migrations/meta/0023_snapshot.json
Normal file
@@ -0,0 +1,822 @@
|
||||
{
|
||||
"id": "813a611e-fc31-496c-bbc8-fa9bf294be62",
|
||||
"prevId": "48978eb5-c4ac-4240-b3e1-d407666cb354",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.mail0_account": {
|
||||
"name": "mail0_account",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"account_id": {
|
||||
"name": "account_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"provider_id": {
|
||||
"name": "provider_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"access_token": {
|
||||
"name": "access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"refresh_token": {
|
||||
"name": "refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"id_token": {
|
||||
"name": "id_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"access_token_expires_at": {
|
||||
"name": "access_token_expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"refresh_token_expires_at": {
|
||||
"name": "refresh_token_expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"scope": {
|
||||
"name": "scope",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"password": {
|
||||
"name": "password",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mail0_account_user_id_mail0_user_id_fk": {
|
||||
"name": "mail0_account_user_id_mail0_user_id_fk",
|
||||
"tableFrom": "mail0_account",
|
||||
"tableTo": "mail0_user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_connection": {
|
||||
"name": "mail0_connection",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"picture": {
|
||||
"name": "picture",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"access_token": {
|
||||
"name": "access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"refresh_token": {
|
||||
"name": "refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"scope": {
|
||||
"name": "scope",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"provider_id": {
|
||||
"name": "provider_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mail0_connection_user_id_mail0_user_id_fk": {
|
||||
"name": "mail0_connection_user_id_mail0_user_id_fk",
|
||||
"tableFrom": "mail0_connection",
|
||||
"tableTo": "mail0_user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"mail0_connection_user_id_email_unique": {
|
||||
"name": "mail0_connection_user_id_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"user_id",
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_early_access": {
|
||||
"name": "mail0_early_access",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"is_early_access": {
|
||||
"name": "is_early_access",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"has_used_ticket": {
|
||||
"name": "has_used_ticket",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"mail0_early_access_email_unique": {
|
||||
"name": "mail0_early_access_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_note": {
|
||||
"name": "mail0_note",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"thread_id": {
|
||||
"name": "thread_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'default'"
|
||||
},
|
||||
"is_pinned": {
|
||||
"name": "is_pinned",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"order": {
|
||||
"name": "order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mail0_note_user_id_mail0_user_id_fk": {
|
||||
"name": "mail0_note_user_id_mail0_user_id_fk",
|
||||
"tableFrom": "mail0_note",
|
||||
"tableTo": "mail0_user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_session": {
|
||||
"name": "mail0_session",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"token": {
|
||||
"name": "token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"ip_address": {
|
||||
"name": "ip_address",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"user_agent": {
|
||||
"name": "user_agent",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mail0_session_user_id_mail0_user_id_fk": {
|
||||
"name": "mail0_session_user_id_mail0_user_id_fk",
|
||||
"tableFrom": "mail0_session",
|
||||
"tableTo": "mail0_user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"mail0_session_token_unique": {
|
||||
"name": "mail0_session_token_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"token"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_summary": {
|
||||
"name": "mail0_summary",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"message_id": {
|
||||
"name": "message_id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"connection_id": {
|
||||
"name": "connection_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"saved": {
|
||||
"name": "saved",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"tags": {
|
||||
"name": "tags",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"suggested_reply": {
|
||||
"name": "suggested_reply",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_user": {
|
||||
"name": "mail0_user",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email_verified": {
|
||||
"name": "email_verified",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"default_connection_id": {
|
||||
"name": "default_connection_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"custom_prompt": {
|
||||
"name": "custom_prompt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"mail0_user_email_unique": {
|
||||
"name": "mail0_user_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_user_hotkeys": {
|
||||
"name": "mail0_user_hotkeys",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"shortcuts": {
|
||||
"name": "shortcuts",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mail0_user_hotkeys_user_id_mail0_user_id_fk": {
|
||||
"name": "mail0_user_hotkeys_user_id_mail0_user_id_fk",
|
||||
"tableFrom": "mail0_user_hotkeys",
|
||||
"tableTo": "mail0_user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_user_settings": {
|
||||
"name": "mail0_user_settings",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"settings": {
|
||||
"name": "settings",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'{\"language\":\"en\",\"timezone\":\"UTC\",\"dynamicContent\":false,\"externalImages\":true,\"customPrompt\":\"\",\"trustedSenders\":[],\"isOnboarded\":false,\"colorTheme\":\"system\"}'::jsonb"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mail0_user_settings_user_id_mail0_user_id_fk": {
|
||||
"name": "mail0_user_settings_user_id_mail0_user_id_fk",
|
||||
"tableFrom": "mail0_user_settings",
|
||||
"tableTo": "mail0_user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"mail0_user_settings_user_id_unique": {
|
||||
"name": "mail0_user_settings_user_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"user_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_verification": {
|
||||
"name": "mail0_verification",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"identifier": {
|
||||
"name": "identifier",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.mail0_writing_style_matrix": {
|
||||
"name": "mail0_writing_style_matrix",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"connectionId": {
|
||||
"name": "connectionId",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"numMessages": {
|
||||
"name": "numMessages",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"style": {
|
||||
"name": "style",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"updatedAt": {
|
||||
"name": "updatedAt",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"mail0_writing_style_matrix_connectionId_mail0_connection_id_fk": {
|
||||
"name": "mail0_writing_style_matrix_connectionId_mail0_connection_id_fk",
|
||||
"tableFrom": "mail0_writing_style_matrix",
|
||||
"tableTo": "mail0_connection",
|
||||
"columnsFrom": [
|
||||
"connectionId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"mail0_writing_style_matrix_connectionId_pk": {
|
||||
"name": "mail0_writing_style_matrix_connectionId_pk",
|
||||
"columns": [
|
||||
"connectionId"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"roles": {},
|
||||
"policies": {},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,13 @@
|
||||
"when": 1744482381255,
|
||||
"tag": "0022_round_violations",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 23,
|
||||
"version": "7",
|
||||
"when": 1746049703463,
|
||||
"tag": "0023_narrow_maria_hill",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user