mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-04 17:48:50 +01:00
* feat(sharepoint): integrate SharePoint file picker and download workflow Introduces end‑to‑end SharePoint import support: * Token exchange with Microsoft Graph and scope management (`useSharePointToken`) * Re‑usable hooks: `useSharePointPicker`, `useSharePointDownload`, `useSharePointFileHandling` * FileSearch dropdown now offers **From Local Machine** / **From SharePoint** sources and gracefully falls back when SharePoint is disabled * Agent upload model, `AttachFileMenu`, and `DropdownPopup` extended for SharePoint files and sub‑menus * Blurry overlay with progress indicator and `maxSelectionCount` limit during downloads * Cache‑flush utility (`config/flush-cache.js`) supporting Redis & filesystem, with dry‑run and npm script * Updated `SharePointIcon` (uses `currentColor`) and new i18n keys * Bug fixes: placeholder syntax in progress message, picker event‑listener cleanup * Misc style and performance optimizations * Fix ESLint warnings --------- Co-authored-by: Atef Bellaaj <slalom.bellaaj@external.daimlertruck.com>
640 lines
17 KiB
TypeScript
640 lines
17 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
export type ExtFilters =
|
|
| 'folder'
|
|
| 'site'
|
|
| 'documentLibrary'
|
|
| 'list'
|
|
| 'onenote'
|
|
| 'file'
|
|
| 'media'
|
|
| 'photo'
|
|
| 'video'
|
|
| 'audio'
|
|
| 'document'
|
|
| 'listItem'
|
|
| 'playlist'
|
|
| 'syntexTemplate'
|
|
| 'syntexSnippet'
|
|
| 'syntexField'
|
|
| `.${string}`;
|
|
|
|
//NOTE: IItem type references the following docs: https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0#properties
|
|
export type IItem = Record<string, any>;
|
|
export type SPPickerConfig = {
|
|
sdk: '8.0';
|
|
/**
|
|
* Establishes the messaging parameters used to setup the post message communications between
|
|
* picker and host application
|
|
*/
|
|
messaging: {
|
|
/**
|
|
* A unique id assigned by the host app to this File Picker instance.
|
|
* This should ideally be a new GUID generated by the host.
|
|
*/
|
|
channelId: string;
|
|
/**
|
|
* The host app's authority, used as the target origin for post-messaging.
|
|
*/
|
|
origin: string;
|
|
/**
|
|
* Whether or not the host app window will need to identify itself.
|
|
*/
|
|
identifyParent?: boolean;
|
|
/**
|
|
* Whether or not the client app must wait for a 'configure' command to be sent by the host before rendering.
|
|
*/
|
|
waitForConfiguration?: boolean;
|
|
/**
|
|
* Override timeout for acknowledgement messages.
|
|
*/
|
|
acknowledgeTimeout?: number;
|
|
/**
|
|
* Override timeout for the initialization handshake.
|
|
*/
|
|
initializeTimeout?: number;
|
|
/**
|
|
* Override timeout for command responses.
|
|
*/
|
|
resultTimeout?: number;
|
|
};
|
|
/**
|
|
* Configuration for the entry location to which the File Picker will navigate on load.
|
|
* The File Picker app will prioritize path-based navigation if provided, falling back to other address forms
|
|
* on error (in case of Site redirection or content rename) or if path information is not provided.
|
|
*/
|
|
entry: {
|
|
sharePoint?: {
|
|
/**
|
|
* Specify an exact SharePoint content location by path segments.
|
|
*/
|
|
byPath?: {
|
|
/**
|
|
* Full URL to the root of a Web, or server-relative URL.
|
|
* @example
|
|
* 'https://contoso-my.sharepoint.com/personal/user_contoso_com'
|
|
* @example
|
|
* '/path/to/web'
|
|
* @example
|
|
* 'subweb'
|
|
*/
|
|
web?: string;
|
|
/**
|
|
* Full URL or path segement to identity a List.
|
|
* If not preceded with a `/` or a URL scheme, this is assumed to be a list in the specified web.
|
|
* @example
|
|
* 'Shared Documents'
|
|
* @example
|
|
* '/path/to/web/Shared Documents'
|
|
* @example
|
|
* 'https://contoso.sharepoint.com/path/to/web/Shared Documents'
|
|
*/
|
|
list?: string;
|
|
/**
|
|
* Path segment to a folder within a list, or a server-relative URL to a folder.
|
|
* @example
|
|
* 'General'
|
|
* @example
|
|
* 'foo/bar'
|
|
* @example
|
|
* '/path/to/web/Shared Documents/General'
|
|
*/
|
|
folder?: string;
|
|
/**
|
|
* Auto fallback to root folder if the specified entry sub folder doesn't exist.
|
|
*/
|
|
fallbackToRoot?: boolean;
|
|
};
|
|
};
|
|
/**
|
|
* Indicates that File Picker should start in the Site Pivot
|
|
* This pivot is only supported in OneDrive for Business
|
|
*/
|
|
site?: {};
|
|
/**
|
|
* Indicates that File Picker should start in the OAL (My Organization) Pivot
|
|
* This pivot is only supported in OneDrive for Business
|
|
*/
|
|
myOrganization?: {};
|
|
/**
|
|
* Indicates that the File Picker should start in the user's OneDrive.
|
|
*/
|
|
oneDrive?: {
|
|
/**
|
|
* Specifies that File Picker should start in the user's Files tab.
|
|
*/
|
|
files?: {
|
|
/**
|
|
* Path segment for sub-folder within the user's OneDrive for Business.
|
|
* @example
|
|
* 'Pictures'
|
|
* @example
|
|
* '/personal/user_contoso_com/Documents/Attachments'
|
|
*/
|
|
folder?: string;
|
|
/**
|
|
* Auto fallback to root folder if the specified entry sub folder doesn't exist.
|
|
*/
|
|
fallbackToRoot?: boolean;
|
|
};
|
|
/**
|
|
* Indicates that File Picker should start in the user's recent files.
|
|
*/
|
|
recent?: {};
|
|
/**
|
|
* Indicates that File Picker should start in the files shared with the user.
|
|
*/
|
|
sharedWithMe?: {};
|
|
/**
|
|
* Indicates that File Picker should start in the user's photos.
|
|
* This pivot is only available in OneDrive for Consumer
|
|
*/
|
|
photos?: {};
|
|
};
|
|
sortBy?: {
|
|
/**
|
|
* Name of the field *in SharePoint* on which to sort.
|
|
*/
|
|
fieldName: string;
|
|
/**
|
|
* Whether or not to sort in ascending order. Default is `true`.
|
|
*/
|
|
isAscending?: boolean;
|
|
};
|
|
filterBy?: {
|
|
/**
|
|
* Name of the field *in SharePoint* on which to filter on.
|
|
*/
|
|
fieldName: string;
|
|
/**
|
|
* Filter value
|
|
*/
|
|
value: string;
|
|
};
|
|
};
|
|
/**
|
|
* Specifies how to enable a Search behavior.
|
|
*/
|
|
search?: {
|
|
enabled: boolean;
|
|
};
|
|
/**
|
|
* Configuration for handling authentication requests from the embedded app.
|
|
* Presence of this object (even if empty) indicates that the host will handle authentication.
|
|
* Omitting this will make the embedded content attempt to rely on cookies.
|
|
*/
|
|
authentication?: {
|
|
/**
|
|
* @default true
|
|
*/
|
|
enabled?: boolean;
|
|
/**
|
|
* Indicates support for individual token types.
|
|
*/
|
|
tokens?: {
|
|
/**
|
|
* @defaultValue true
|
|
*/
|
|
graph?: boolean;
|
|
/**
|
|
* @defaultValue true
|
|
*/
|
|
sharePoint?: boolean;
|
|
/**
|
|
* @defaultValue false
|
|
*/
|
|
substrate?: boolean;
|
|
};
|
|
/**
|
|
* Indicates that the host app can handle 'claims' challenges.
|
|
*/
|
|
claimsChallenge?: {
|
|
/**
|
|
* @default false
|
|
*/
|
|
enabled?: boolean;
|
|
};
|
|
};
|
|
/**
|
|
* Configures what types of items are allowed to be picked within the experience.
|
|
* Note that the default configuration accounts for the expected authentication capabilities of the host app.
|
|
* Depending on what else is enabled by the host, the host may be expected to provide tokens for more services and scopes.
|
|
*/
|
|
typesAndSources?: {
|
|
/**
|
|
* Specifies the general category of items picked. Switches between 'file' vs. 'folder' picker mode,
|
|
* or a general-purpose picker.
|
|
* @default 'all'
|
|
*/
|
|
mode?: 'files' | 'folders' | 'all';
|
|
/**
|
|
* `filters` options: file extension, i.e. .xlsx, .docx, .ppt, etc.
|
|
* `filters` options: 'photo', 'folder', 'video', 'documentLibrary'
|
|
*/
|
|
filters?: ExtFilters[];
|
|
/**
|
|
* Specifies a filter for *where* the item may come from.
|
|
*/
|
|
locations?: {
|
|
/**
|
|
* Items may only come from the user's OneDrive.
|
|
*/
|
|
oneDrive?: {};
|
|
/**
|
|
* Items may only come from a specific location within SharePoint.
|
|
*/
|
|
sharePoint?: {
|
|
byPath?: {
|
|
web?: string;
|
|
list?: string;
|
|
folder?: string;
|
|
};
|
|
};
|
|
};
|
|
/**
|
|
* Specifies filtering based on user access level.
|
|
*/
|
|
access?: {
|
|
/**
|
|
* Filter for requires user access level for picked items. Default is `'read'`.
|
|
*/
|
|
mode?: 'read' | 'read-write';
|
|
};
|
|
/**
|
|
* Specifies which pivots the user may access while browsing files and lists.
|
|
* Note that if a pivot is disabled here but still targeted in `entry`, it will still be visible in the nav.
|
|
*/
|
|
pivots?: {
|
|
/**
|
|
* Show "My files".
|
|
*/
|
|
oneDrive?: boolean;
|
|
/**
|
|
* Show "Recent".
|
|
*/
|
|
recent?: boolean;
|
|
/**
|
|
* Show "Shared"
|
|
*/
|
|
shared?: boolean;
|
|
/**
|
|
* Show "Quick access".
|
|
*/
|
|
sharedLibraries?: boolean;
|
|
/**
|
|
* Show "My organization".
|
|
* This pivot is only supported in OneDrive for Business
|
|
*/
|
|
myOrganization?: boolean;
|
|
/**
|
|
* Show the site pivot
|
|
* This pivot is only supported in OneDrive for Business
|
|
*/
|
|
site?: boolean;
|
|
};
|
|
};
|
|
/**
|
|
* Configuration for what item types may be selected within the picker and returned to the host.
|
|
*/
|
|
selection?: {
|
|
/**
|
|
* Controls how selection works within the list.
|
|
* @default 'single' for the Picker.
|
|
*/
|
|
mode?: 'single' | 'multiple' | 'pick';
|
|
/**
|
|
* Whether or not to allow the user to maintain a selection across folders and pivots.
|
|
*/
|
|
enablePersistence?: boolean;
|
|
/**
|
|
* Whether or not the host expects to be notified whenever selection changes.
|
|
*/
|
|
enableNotifications?: boolean;
|
|
/**
|
|
* The maximum number of items which may be selected.
|
|
*/
|
|
maximumCount?: number;
|
|
/**
|
|
* A set of items to pre-select.
|
|
*/
|
|
sourceItems?: IItem[];
|
|
};
|
|
/**
|
|
* Configures how commands behave within the experience.
|
|
*/
|
|
commands?: {
|
|
/**
|
|
* Specifies the behavior for file-picking.
|
|
*/
|
|
pick?: {
|
|
/**
|
|
* A special action to perform when picking the file, before handing the result
|
|
* back to the host app.
|
|
*/
|
|
action?: 'select' | 'share' | 'download' | 'move';
|
|
/**
|
|
* A custom label to apply to the button which picks files.
|
|
* This must be localized by the host app if supplied.
|
|
*/
|
|
label?: string;
|
|
/**
|
|
* Configures the 'move' action for picking files.
|
|
*/
|
|
move?: {
|
|
sourceItems?: IItem[];
|
|
};
|
|
/**
|
|
* Configures the 'copy' action for picking files.
|
|
*/
|
|
copy?: {
|
|
sourceItems?: IItem[];
|
|
};
|
|
/**
|
|
* Configures the 'select' action for picking files.
|
|
*/
|
|
select?: {
|
|
/**
|
|
* Specify if we want download urls to be returned when items are selected.
|
|
*/
|
|
urls?: {
|
|
download?: boolean;
|
|
};
|
|
};
|
|
};
|
|
/**
|
|
* Specifies the behavior for closing the experience.
|
|
*/
|
|
close?: {
|
|
/**
|
|
* A custom label to apply to the 'cancel' button.
|
|
* This must be localized by the host app if supplied.
|
|
*/
|
|
label?: string;
|
|
};
|
|
/**
|
|
* Behavior for a "Browse this device" command to pick local files.
|
|
*/
|
|
browseThisDevice?: {
|
|
enabled?: boolean;
|
|
label?: string;
|
|
mode?: 'upload' | 'pick';
|
|
};
|
|
/**
|
|
* Behavior for a "From a link" command to pick from a link.
|
|
*/
|
|
fromALink?: {
|
|
enabled?: boolean;
|
|
mode?: 'nav' | 'pivot';
|
|
};
|
|
/**
|
|
* Behavior for a "Switch account" command.
|
|
*/
|
|
switchAccount?: {
|
|
mode?: 'host' | 'none';
|
|
};
|
|
/**
|
|
* Behavior for a "Manage accounts" command.
|
|
*/
|
|
manageAccounts?: {
|
|
mode?: 'host' | 'none';
|
|
label?: string;
|
|
};
|
|
/**
|
|
* Behavior for "Upload"
|
|
*/
|
|
upload?: {
|
|
enabled?: boolean;
|
|
};
|
|
/**
|
|
* Behavior for "Create folder"
|
|
*/
|
|
createFolder?: {
|
|
enabled?: boolean;
|
|
};
|
|
/**
|
|
* Behavior for "Filter by" in the column headers.
|
|
*/
|
|
filterByColumn?: {
|
|
mode?: 'panel' | 'menu';
|
|
};
|
|
/**
|
|
* How to handle actions defined by custom formatters.
|
|
*/
|
|
customFormatter?: {
|
|
actions?: {
|
|
key: string;
|
|
mode?: 'host' | 'none';
|
|
}[];
|
|
};
|
|
/**
|
|
* How to handle specified values for `key` in custom commands
|
|
* in the tray, nav, or command bar.
|
|
*/
|
|
custom?: {
|
|
actions?: {
|
|
key: string;
|
|
/**
|
|
* Filters defining what types of items the action operates on.
|
|
* If specified, the action will only be available for items which match the given filters.
|
|
*/
|
|
filters?: ExtFilters[];
|
|
/**
|
|
* How the action is invoked.
|
|
* 'host': Invokes a `custom` command message against the host app.
|
|
* 'none': Disables the action.
|
|
*/
|
|
mode?: 'host' | 'none';
|
|
/**
|
|
* Selection criteria to which the item applies.
|
|
*/
|
|
selection?: 'single' | 'multiple' | 'current' | 'none';
|
|
}[];
|
|
};
|
|
};
|
|
/**
|
|
* Specifies accessibility cues such as auto-focus behaviors.
|
|
*/
|
|
accessibility?: {
|
|
/**
|
|
* Whether or not to 'trap focus' within the component. If this is enabled, tab-stops will loop from the last element back to the left navigation automatically.
|
|
* This is useful if the components's frame is hosted as the only content of a modal overlay and focus should not jump to the outside content.
|
|
*
|
|
* @default false
|
|
*/
|
|
enableFocusTrap?: boolean;
|
|
/**
|
|
* Whether or not the component should immediately grab focus once the content has loaded.
|
|
*
|
|
* @default true
|
|
*/
|
|
trapFocusOnLoad?: boolean;
|
|
/**
|
|
* Whether or not to force the currently-focused element within the component to be highlighted.
|
|
* By default, the focused element is highlighted if the user navigates elements with the keyboard but not when the user interacts via the mouse.
|
|
* However, if a host application launches the component due to keyboard input it should set this flag to `true` to ensure continuity of behavior.
|
|
*
|
|
* @default false
|
|
*/
|
|
showFocusOnLoad?: boolean;
|
|
};
|
|
tray?: {
|
|
/**
|
|
* Configures the commands normally used to pick files or close the picker.
|
|
*/
|
|
commands?: {
|
|
/**
|
|
* A key to differentiate the command from others.
|
|
*/
|
|
key: string;
|
|
/**
|
|
* A custom string for the command.
|
|
* Must be localized by the host.
|
|
*/
|
|
label?: string;
|
|
/**
|
|
* The action to perform when the button is clicked.
|
|
*/
|
|
action: 'pick' | 'close' | 'custom';
|
|
/**
|
|
* If `'pick'` is specified, which pick behavior to use.
|
|
*/
|
|
pick?: {
|
|
action: 'select' | 'share' | 'download' | 'move';
|
|
};
|
|
/**
|
|
* Whether the button should show as the primary button.
|
|
*/
|
|
primary?: boolean;
|
|
/**
|
|
* Whether the button should remain visible at all times even if unavailable.
|
|
*/
|
|
permanent?: boolean;
|
|
}[];
|
|
/**
|
|
* Whether or not the picker tray might be provided by the host instead.
|
|
* @defaultValue 'default'
|
|
*/
|
|
mode?: 'host' | 'default';
|
|
/**
|
|
* Configures a component to render in the picker tray to the left of the commands.
|
|
* @default 'selection-summary'
|
|
*/
|
|
prompt?: 'keep-sharing' | 'selection-summary' | 'selection-editor' | 'save-as' | 'none';
|
|
/**
|
|
* Configures use of the 'save-as' prompt.
|
|
*/
|
|
saveAs?: {
|
|
/**
|
|
* Default file name to show in 'save-as' prompt.
|
|
*/
|
|
fileName?: string;
|
|
};
|
|
/**
|
|
* Settings for handling conflicts with existing file names.
|
|
*/
|
|
conflicts?: {
|
|
/**
|
|
* How to handle when a file name matches an existing file.
|
|
* `'warn'` - Show a prompt to ask the user to confirm the choice.
|
|
* `'block'` - Block the choice as an error.
|
|
* `'accept'` - Accept the choice automatically.
|
|
* `'none'` - Do not try to match with existing items.
|
|
*/
|
|
mode?: 'warn' | 'block' | 'accept' | 'none';
|
|
};
|
|
/**
|
|
* Configures use of the 'keep-sharing' prompt.
|
|
*/
|
|
keepSharing?: {
|
|
active?: boolean;
|
|
};
|
|
};
|
|
leftNav?: {
|
|
/**
|
|
* Whether or not a Left Nav should be rendered by the embedded content.
|
|
*/
|
|
enabled?: boolean;
|
|
/**
|
|
* Mode of presentation of the nav.
|
|
* If the nav is enabled but this is set to `host`, the embedded app
|
|
* will show a button to ask the host app to show a nav.
|
|
*/
|
|
mode?: 'host' | 'default';
|
|
/**
|
|
* Indicates whether the left nav will be initially modal.
|
|
*/
|
|
initialModality?: 'modal' | 'hidden';
|
|
|
|
/**
|
|
* Type of left nav
|
|
*/
|
|
preset?: 'oneDrive' | 'current-site';
|
|
|
|
/**
|
|
* Custom commands to insert at the end of the left nav. Will appear before the default set.
|
|
*/
|
|
commands?: {
|
|
/**
|
|
* Name to use when notifying the host that the command is being invoked.
|
|
*/
|
|
key: string;
|
|
/**
|
|
* Localized string to use for the button text.
|
|
*/
|
|
label: string;
|
|
/**
|
|
* Type of action which will be performed when the command is clicked.
|
|
* 'custom': Configured via `commands.custom`.
|
|
*/
|
|
action: 'custom' | 'pick' | 'close' | 'browse-this-device';
|
|
/**
|
|
* Name of a Fluent icon to use for the command button.
|
|
*/
|
|
icon?: string;
|
|
}[];
|
|
};
|
|
/**
|
|
* The theme to use for the file-picker. Will change the coloring.
|
|
* Note: custom theme objects are expected in addition to the strings below
|
|
* @default 'default': Light theme
|
|
*/
|
|
theme?: 'default' | 'dark' | 'lists';
|
|
list?: {
|
|
/**
|
|
* A custom override for the initial list layout.
|
|
*/
|
|
layout?: {
|
|
/**
|
|
* Sets the preferred starting layout for the initial content.
|
|
*/
|
|
type?: 'details' | 'compact-details' | 'tiles';
|
|
};
|
|
/**
|
|
* Configures scrolling behavior within the Picker.
|
|
*/
|
|
scrolling?: {
|
|
enableStickyHeaders?: boolean;
|
|
};
|
|
};
|
|
/**
|
|
* Provides a header title for the Picker.
|
|
*/
|
|
title?: string;
|
|
/**
|
|
* Specifies customizations for specific pivots
|
|
*/
|
|
pivots?: {
|
|
/**
|
|
* Customize the site pivot
|
|
*/
|
|
site?: {
|
|
byPath?: {
|
|
/**
|
|
* Chose the site url to use for this pivot
|
|
* Required to show the site pivot, if undefined
|
|
* the site pivot will not be shown
|
|
*/
|
|
web?: string;
|
|
};
|
|
};
|
|
};
|
|
};
|