mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-16 20:56:35 +01:00
📁 feat: Integrate SharePoint File Picker and Download Workflow (#8651)
* 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>
This commit is contained in:
parent
b6413b06bc
commit
a955097faf
40 changed files with 2500 additions and 123 deletions
640
client/src/components/SidePanel/Agents/config.ts
Normal file
640
client/src/components/SidePanel/Agents/config.ts
Normal file
|
|
@ -0,0 +1,640 @@
|
|||
/* 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;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue