diff --git a/samples/react-enhanced-page-properties/.nvmrc b/samples/react-enhanced-page-properties/.nvmrc index 5dbac1ed0f..55d1782166 100644 --- a/samples/react-enhanced-page-properties/.nvmrc +++ b/samples/react-enhanced-page-properties/.nvmrc @@ -1 +1 @@ -v16.13.0 \ No newline at end of file +v14.15.0 diff --git a/samples/react-enhanced-page-properties/README.md b/samples/react-enhanced-page-properties/README.md index 64000fa228..6814469481 100644 --- a/samples/react-enhanced-page-properties/README.md +++ b/samples/react-enhanced-page-properties/README.md @@ -4,6 +4,12 @@ This is a web part that goes beyond the standard SharePoint Page Properties web part, offering expanded support for various metadata types and configurations. Effortlessly display key page details based on metadata files, providing a comprehensive view of your content. Streamline information management and enhance user interaction with this versatile and customizable web part. +Currently support following types: +- Single line text +- Multiple line text +- Choice +- Date + ### Configuration - **Title**: Allow to set the displayed title. The built in SharePoint Page Properties web part doesn't allow user to change the displayed title. It will always be **Properties** @@ -11,9 +17,12 @@ This is a web part that goes beyond the standard SharePoint Page Properties web ### Plan for next version -- Support choice field view +- Support taxonomy field view - Support people field view -- Support date time field view +- Support lookup field view +- Support currency field view +- Support hyperlink field view +- Support image field view - Improve web part configuration ![Web part](assets/app.png) @@ -30,7 +39,7 @@ This is a web part that goes beyond the standard SharePoint Page Properties web - [SharePoint Framework](https://docs.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview) - [Microsoft 365 tenant](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment) -> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/m365devprogram) +> Get your own free development tenant by subscribing to [Microsoft 365 developer program](https://aka.ms/m365devprogram) ## Contributors @@ -40,6 +49,7 @@ This is a web part that goes beyond the standard SharePoint Page Properties web Version|Date|Comments -------|----|-------- +1.1|October 23, 2023|Add support for choice and date fields 1.0|September 23, 2023|Initial release ## Minimal path to awesome diff --git a/samples/react-enhanced-page-properties/assets/app.png b/samples/react-enhanced-page-properties/assets/app.png index df3c76c4ac..9bf719ac53 100644 Binary files a/samples/react-enhanced-page-properties/assets/app.png and b/samples/react-enhanced-page-properties/assets/app.png differ diff --git a/samples/react-enhanced-page-properties/assets/sample.json b/samples/react-enhanced-page-properties/assets/sample.json index b54e5bc653..abcef735d0 100644 --- a/samples/react-enhanced-page-properties/assets/sample.json +++ b/samples/react-enhanced-page-properties/assets/sample.json @@ -10,7 +10,7 @@ "This is a web part that goes beyond the standard SharePoint Page Properties web part, offering expanded support for various metadata types and configurations. Effortlessly display key page details based on metadata files, providing a comprehensive view of your content. Streamline information management and enhance user interaction with this versatile and customizable web part." ], "creationDateTime": "2023-09-23", - "updateDateTime": "2023-09-23", + "updateDateTime": "2023-10-10", "products": [ "SharePoint" ], diff --git a/samples/react-enhanced-page-properties/config/package-solution.json b/samples/react-enhanced-page-properties/config/package-solution.json index 52c596c00e..e87fea6e2c 100644 --- a/samples/react-enhanced-page-properties/config/package-solution.json +++ b/samples/react-enhanced-page-properties/config/package-solution.json @@ -3,7 +3,7 @@ "solution": { "name": "Enhanced Page Properties", "id": "54ea24ef-5714-4f81-a9e6-e22f70e0c644", - "version": "1.0.0.0", + "version": "1.1.0.0", "includeClientSideAssets": true, "skipFeatureDeployment": true, "isDomainIsolated": false, diff --git a/samples/react-enhanced-page-properties/package-lock.json b/samples/react-enhanced-page-properties/package-lock.json index 1f50ce350f..14d7629f47 100644 --- a/samples/react-enhanced-page-properties/package-lock.json +++ b/samples/react-enhanced-page-properties/package-lock.json @@ -16,6 +16,7 @@ "@microsoft/sp-property-pane": "1.17.4", "@microsoft/sp-webpart-base": "1.17.4", "@pnp/sp": "^3.17.0", + "date-fns": "^2.30.0", "office-ui-fabric-react": "^7.199.1", "react": "17.0.1", "react-dom": "17.0.1", @@ -844,7 +845,6 @@ "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", - "peer": true, "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -15993,6 +15993,21 @@ "webidl-conversions": "^4.0.2" } }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/dateformat": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", @@ -28306,8 +28321,7 @@ "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "peer": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/regex-not": { "version": "1.0.2", @@ -37462,7 +37476,6 @@ "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", - "peer": true, "requires": { "regenerator-runtime": "^0.13.11" } @@ -49442,6 +49455,14 @@ } } }, + "date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "requires": { + "@babel/runtime": "^7.21.0" + } + }, "dateformat": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", @@ -59113,8 +59134,7 @@ "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "peer": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regex-not": { "version": "1.0.2", diff --git a/samples/react-enhanced-page-properties/package.json b/samples/react-enhanced-page-properties/package.json index ecfb37bc59..4e7fb5c2eb 100644 --- a/samples/react-enhanced-page-properties/package.json +++ b/samples/react-enhanced-page-properties/package.json @@ -21,6 +21,7 @@ "@microsoft/sp-property-pane": "1.17.4", "@microsoft/sp-webpart-base": "1.17.4", "@pnp/sp": "^3.17.0", + "date-fns": "^2.30.0", "office-ui-fabric-react": "^7.199.1", "react": "17.0.1", "react-dom": "17.0.1", diff --git a/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/EnhancedPagePropertiesWebPart.ts b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/EnhancedPagePropertiesWebPart.ts index d7222fe12b..9bb4bfdf38 100644 --- a/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/EnhancedPagePropertiesWebPart.ts +++ b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/EnhancedPagePropertiesWebPart.ts @@ -16,6 +16,7 @@ import { SPFI, spfi, SPFx } from "@pnp/sp"; import EnhancedPageProperties from "./components/EnhancedPageProperties"; import { IEnhancedPagePropertiesProps } from "./components/IEnhancedPagePropertiesProps"; +import { IFieldInfo } from "@pnp/sp/fields"; export interface IEnhancedPagePropertiesWebPartProps { title: string; @@ -23,14 +24,13 @@ export interface IEnhancedPagePropertiesWebPartProps { } export interface propertyItem { + field?: IFieldInfo; + value: string | string[]; label: string; - field: string; - value: string; - isAvailable: boolean; } export default class EnhancedPagePropertiesWebPart extends BaseClientSideWebPart { - private readonly docLibTitle = 'Site Pages'; + private readonly docLibTitle = "Site Pages"; private _sp: SPFI; public async render(): Promise { @@ -59,11 +59,11 @@ export default class EnhancedPagePropertiesWebPart extends BaseClientSideWebPart .getByTitle(this.docLibTitle) .fields(); // Filter to only non hidden fields - const filteredAvailableFields: Map = new Map(); + const filteredAvailableFields: Map = new Map(); for (let i = 0; i < availableFields.length; i++) { const field = availableFields[i]; if (field.Hidden) continue; - filteredAvailableFields.set(field.InternalName, field.Title); + filteredAvailableFields.set(field.InternalName, field); } const selectedFields = this.convertSelectedFieldsString(); @@ -76,13 +76,12 @@ export default class EnhancedPagePropertiesWebPart extends BaseClientSideWebPart ...selectedFields.filter((field) => filteredAvailableFields.has(field)) )(); for (let i = 0; i < selectedFields.length; i++) { - const field = selectedFields[i]; - const isAvailable = filteredAvailableFields.has(field); + const internalName = selectedFields[i]; + const field = filteredAvailableFields.get(internalName); propertyItems.push({ field, - isAvailable, - label: isAvailable ? (filteredAvailableFields.get(field) || '') : field, - value: currentPageProperties[field], + label: field ? field.Title : internalName, + value: currentPageProperties[internalName], }); } return propertyItems; diff --git a/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.module.scss b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.module.scss index d86e1fa052..7e8c4d3e49 100644 --- a/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.module.scss +++ b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.module.scss @@ -18,6 +18,11 @@ margin-bottom: 10px; } + .choice { + display: flex; + gap: 5px; + } + span { background-color: #fafafa; padding: 8px 13px; @@ -36,7 +41,6 @@ background-color: #fce100; } } - } } } \ No newline at end of file diff --git a/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.tsx b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.tsx index 4f8a4eef23..15525bd2da 100644 --- a/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.tsx +++ b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/EnhancedPageProperties.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import styles from './EnhancedPageProperties.module.scss'; import { IEnhancedPagePropertiesProps } from './IEnhancedPagePropertiesProps'; +import Value from './Value/Value'; export default function EnhancedPageProperties( props: IEnhancedPagePropertiesProps @@ -11,10 +12,10 @@ export default function EnhancedPageProperties(

{props.title}

{props.items.map((item) => ( -
+

{item.label}

- {item.isAvailable ? ( - {item.value || "-"} + {item.field ? ( + ) : ( Field not available in the Library metadata. Please check again the diff --git a/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/Value/Value.tsx b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/Value/Value.tsx new file mode 100644 index 0000000000..40580b4f8d --- /dev/null +++ b/samples/react-enhanced-page-properties/src/webparts/enhancedPageProperties/components/Value/Value.tsx @@ -0,0 +1,34 @@ +import { IFieldInfo } from "@pnp/sp/fields"; +import { format } from "date-fns"; +import * as React from "react"; +import styles from "../EnhancedPageProperties.module.scss"; + +export interface IValueProps { + field: IFieldInfo; + value: string | string[]; +} + +export default function Value(props: IValueProps): JSX.Element { + if (!props.value) return -; + + switch (props.field.TypeDisplayName) { + case "Choice": { + const value = props.value as string[]; + return ( +
+ {value.map((item: string) => ( + {item} + ))} +
+ ); + } + case "Date and Time": { + return ( + {format(new Date(props.value as string), "dd MMMM yyyy")} + ); + } + default: { + return {props.value}; + } + } +}