From 5eb14c9011b29683d2094c49b309926816f55487 Mon Sep 17 00:00:00 2001 From: Martin Lingstuyl Date: Wed, 13 Nov 2024 09:09:09 +0100 Subject: [PATCH] Adds ability to create files/folders in subfolder using DynamicForm. Closes #1901 --- .../docs/controls/DynamicForm.md | 1 + src/controls/dynamicForm/DynamicForm.tsx | 20 +++++++++++++------ src/controls/dynamicForm/IDynamicFormProps.ts | 7 +++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/documentation/docs/controls/DynamicForm.md b/docs/documentation/docs/controls/DynamicForm.md index 1957dfb9a..0e8f27972 100644 --- a/docs/documentation/docs/controls/DynamicForm.md +++ b/docs/documentation/docs/controls/DynamicForm.md @@ -66,6 +66,7 @@ The `DynamicForm` can be configured with the following properties: | validationErrorDialogProps | IValidationErrorDialogProps | no | Specifies validation error dialog properties | | customIcons | { [ columnInternalName: string ]: string } | no | Specifies custom icons for the form. The key of this dictionary is the column internal name, the value is the Fluent UI icon name. | | storeLastActiveTab | boolean | no | When uploading files: Specifies if last active tab will be stored after the Upload panel has been closed. Note: the value of selected tab is stored in the queryString hash. Default - `true` | +| folderPath | string | no | Library relative folder to create the item in. This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document or Folder. Defaults to the root folder. | ## Validation Error Dialog Properties `IValidationErrorDialogProps` | Property | Type | Required | Description | diff --git a/src/controls/dynamicForm/DynamicForm.tsx b/src/controls/dynamicForm/DynamicForm.tsx index c70fd26a2..8bcaac4ba 100644 --- a/src/controls/dynamicForm/DynamicForm.tsx +++ b/src/controls/dynamicForm/DynamicForm.tsx @@ -31,6 +31,7 @@ import "@pnp/sp/lists"; import "@pnp/sp/content-types"; import "@pnp/sp/folders"; import "@pnp/sp/items"; +import { IFolder } from "@pnp/sp/folders"; import { IInstalledLanguageInfo } from "@pnp/sp/presets/all"; import { cloneDeep, isEqual } from "lodash"; import { ICustomFormatting, ICustomFormattingBodySection, ICustomFormattingNode } from "../../common/utilities/ICustomFormatting"; @@ -605,11 +606,12 @@ export class DynamicForm extends React.Component< /["|*|:|<|>|?|/|\\||]/g, "_" ) // Replace not allowed chars in folder name - : ""; // Empty string will be replaced by SPO with Folder Item ID - const newFolder = await library.rootFolder.addSubFolderUsingPath( - folderTitle - ); + : ""; // Empty string will be replaced by SPO with Folder Item ID + + const folder = !this.props.folderPath ? library.rootFolder : await this.getFolderByPath(this.props.folderPath, library.rootFolder); + const newFolder = await folder.addSubFolderUsingPath( folderTitle ); const fields = await newFolder.listItemAllFields(); + if (fields[idField]) { // Read the ID of the just created folder or Document Set const folderId = fields[idField]; @@ -683,8 +685,9 @@ export class DynamicForm extends React.Component< "_" ) // Replace not allowed chars in folder name : ""; // Empty string will be replaced by SPO with Folder Item ID - - const fileCreatedResult = await library.rootFolder.files.addChunked(encodeURI(itemTitle), await selectedFile.downloadFileContent()); + + const folder = !this.props.folderPath ? library.rootFolder : await this.getFolderByPath(this.props.folderPath, library.rootFolder); + const fileCreatedResult = await folder.files.addChunked(encodeURI(itemTitle), await selectedFile.downloadFileContent()); const fields = await fileCreatedResult.file.listItemAllFields(); if (fields[idField]) { @@ -1476,4 +1479,9 @@ export class DynamicForm extends React.Component< } } + private getFolderByPath = async (listRelativeFolderPath: string, rootFolder: IFolder): Promise => { + const libraryFolder = await rootFolder(); + const folder = sp.web.getFolderByServerRelativePath(`${libraryFolder.ServerRelativeUrl}/${listRelativeFolderPath}`); + return folder; + }; } diff --git a/src/controls/dynamicForm/IDynamicFormProps.ts b/src/controls/dynamicForm/IDynamicFormProps.ts index 0c9cdcff1..cdf048794 100644 --- a/src/controls/dynamicForm/IDynamicFormProps.ts +++ b/src/controls/dynamicForm/IDynamicFormProps.ts @@ -139,4 +139,11 @@ export interface IDynamicFormProps { * @default true */ storeLastActiveTab?: boolean; + + /** + * Library relative folder to create the item in. + * This option is only available for document libraries and works only when the contentTypeId is specified and has a base type of type Document or Folder. + * Defaults to the root folder. + */ + folderPath?: string; }