feat: P2.3 Folder Sharing + P2.5 Email Import + P2.6 Contact Import + P2.7 Free/Busy
- P2.3: Folder sharing system — ShareFolderDialog, sharing-store, sharing-settings - P2.5: Email import (.eml, .tgz, .zip) with dedup and progress - P2.6: Contact import (vCard + CSV) with auto-mapping - P2.7: Free/Busy view grid with color-coded slots
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { Email, Mailbox, StateChange, AccountStates, Thread, Identity, EmailAddress, ContactCard, AddressBook, AddressBookRights, VacationResponse, Calendar, CalendarRights, CalendarEvent, CalendarEventFilter, CalendarTask, FileNode, FileNodeRights, Principal, PushSubscription, ScheduledEmail, SendEmailResult, SharedAccount } from "./types";
|
||||
import type { Email, Mailbox, MailboxRights, StateChange, AccountStates, Thread, Identity, EmailAddress, ContactCard, AddressBook, AddressBookRights, VacationResponse, Calendar, CalendarRights, CalendarEvent, CalendarEventFilter, CalendarTask, FileNode, FileNodeRights, Principal, PushSubscription, ScheduledEmail, SendEmailResult, SharedAccount } from "./types";
|
||||
import type { SieveScript, SieveCapabilities } from "./sieve-types";
|
||||
|
||||
/**
|
||||
@@ -315,6 +315,7 @@ export interface IJMAPClient {
|
||||
setCalendarShare(calendarId: string, principalId: string, rights: CalendarRights | null, targetAccountId?: string): Promise<void>;
|
||||
setAddressBookShare(addressBookId: string, principalId: string, rights: AddressBookRights | null, targetAccountId?: string): Promise<void>;
|
||||
setFileNodeShare(fileNodeId: string, principalId: string, rights: FileNodeRights | null, targetAccountId?: string): Promise<void>;
|
||||
setMailboxShare(mailboxId: string, principalId: string, rights: MailboxRights | null, targetAccountId?: string): Promise<void>;
|
||||
|
||||
// ── Accounts (primary + shared/group) ────────────────────────
|
||||
getSharedAccounts(): SharedAccount[];
|
||||
|
||||
+29
-1
@@ -1,4 +1,4 @@
|
||||
import type { Email, Mailbox, StateChange, AccountStates, Thread, Identity, EmailAddress, ContactCard, AddressBook, AddressBookRights, VacationResponse, Calendar, CalendarRights, CalendarEvent, CalendarEventFilter, CalendarTask, FileNode, FileNodeFilter, FileNodeRights, Principal, PushSubscription, EmailSubmission, ScheduledEmail, SendEmailResult, SharedAccount } from "./types";
|
||||
import type { Email, Mailbox, MailboxRights, StateChange, AccountStates, Thread, Identity, EmailAddress, ContactCard, AddressBook, AddressBookRights, VacationResponse, Calendar, CalendarRights, CalendarEvent, CalendarEventFilter, CalendarTask, FileNode, FileNodeFilter, FileNodeRights, Principal, PushSubscription, EmailSubmission, ScheduledEmail, SendEmailResult, SharedAccount } from "./types";
|
||||
import type { SieveScript, SieveCapabilities } from "./sieve-types";
|
||||
import type { IJMAPClient } from "./client-interface";
|
||||
import { toWildcardQuery } from "./search-utils";
|
||||
@@ -4426,6 +4426,34 @@ export class JMAPClient implements IJMAPClient {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add, update, or remove a principal's rights on a mailbox folder.
|
||||
* Pass `rights: null` to revoke access.
|
||||
*/
|
||||
async setMailboxShare(
|
||||
mailboxId: string,
|
||||
principalId: string,
|
||||
rights: MailboxRights | null,
|
||||
targetAccountId?: string,
|
||||
): Promise<void> {
|
||||
const accountId = targetAccountId || this.accountId;
|
||||
const response = await this.request([
|
||||
["Mailbox/set", {
|
||||
accountId,
|
||||
update: { [mailboxId]: { [`shareWith/${principalId}`]: rights } },
|
||||
}, "0"],
|
||||
]);
|
||||
|
||||
const result = response.methodResponses?.[0]?.[1];
|
||||
if (result?.notUpdated?.[mailboxId]) {
|
||||
const err = result.notUpdated[mailboxId];
|
||||
throw new Error(err.description || "Failed to update mailbox share");
|
||||
}
|
||||
if (!result?.updated || !(mailboxId in result.updated)) {
|
||||
throw new Error("Server did not confirm the share update");
|
||||
}
|
||||
}
|
||||
|
||||
private async fetchPaginatedContacts(
|
||||
accountId: string,
|
||||
filter?: Record<string, unknown>,
|
||||
|
||||
+15
-11
@@ -181,6 +181,19 @@ export interface Attachment {
|
||||
disposition?: string;
|
||||
}
|
||||
|
||||
export interface MailboxRights {
|
||||
mayReadItems: boolean;
|
||||
mayAddItems: boolean;
|
||||
mayRemoveItems: boolean;
|
||||
maySetSeen: boolean;
|
||||
maySetKeywords: boolean;
|
||||
mayCreateChild: boolean;
|
||||
mayRename: boolean;
|
||||
mayDelete: boolean;
|
||||
maySubmit: boolean;
|
||||
mayShare?: boolean;
|
||||
}
|
||||
|
||||
export interface Mailbox {
|
||||
id: string;
|
||||
originalId?: string; // Original JMAP ID (for shared mailboxes)
|
||||
@@ -192,22 +205,13 @@ export interface Mailbox {
|
||||
unreadEmails: number;
|
||||
totalThreads: number;
|
||||
unreadThreads: number;
|
||||
myRights: {
|
||||
mayReadItems: boolean;
|
||||
mayAddItems: boolean;
|
||||
mayRemoveItems: boolean;
|
||||
maySetSeen: boolean;
|
||||
maySetKeywords: boolean;
|
||||
mayCreateChild: boolean;
|
||||
mayRename: boolean;
|
||||
mayDelete: boolean;
|
||||
maySubmit: boolean;
|
||||
};
|
||||
myRights: MailboxRights;
|
||||
isSubscribed: boolean;
|
||||
// Shared folder support
|
||||
accountId?: string;
|
||||
accountName?: string;
|
||||
isShared?: boolean;
|
||||
shareWith?: Record<string, MailboxRights> | null;
|
||||
}
|
||||
|
||||
export interface Thread {
|
||||
|
||||
Reference in New Issue
Block a user