Skip to content

Commit

Permalink
Merge branch 'main' into dev-new
Browse files Browse the repository at this point in the history
  • Loading branch information
hugoabernier authored Jan 13, 2025
2 parents 7735057 + 4f2eded commit eed28bb
Show file tree
Hide file tree
Showing 62 changed files with 30,645 additions and 31 deletions.
4 changes: 2 additions & 2 deletions .metadata/extension-samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -6916,7 +6916,7 @@
"This sample shows site mega menu. Application customizer is used along with SharePoint List to store the menu items."
],
"creationDateTime": "2018-12-10",
"updateDateTime": "2018-12-10",
"updateDateTime": "2024-10-31",
"products": [
"SharePoint"
],
Expand All @@ -6927,7 +6927,7 @@
},
{
"key": "SPFX-VERSION",
"value": "1.7.0"
"value": "1.20.0"
}
],
"tags": [],
Expand Down
81 changes: 79 additions & 2 deletions .metadata/samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -6916,7 +6916,7 @@
"This sample shows site mega menu. Application customizer is used along with SharePoint List to store the menu items."
],
"creationDateTime": "2018-12-10",
"updateDateTime": "2018-12-10",
"updateDateTime": "2024-10-31",
"products": [
"SharePoint"
],
Expand All @@ -6927,7 +6927,7 @@
},
{
"key": "SPFX-VERSION",
"value": "1.7.0"
"value": "1.20.0"
}
],
"tags": [],
Expand Down Expand Up @@ -27685,6 +27685,83 @@
}
]
},
{
"name": "pnp-sp-dev-spfx-web-parts-react-svg-to-json-converter",
"source": "pnp",
"title": "SVG to JSON Converter",
"shortDescription": "Allows users to read SVGs from a SharePoint library, select one of them and have the code converted into a JSON format that is ready to be used in a SharePoint List in advanced formatting.",
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-svg-to-json-converter",
"downloadUrl": "https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-svg-to-json-converter",
"longDescription": [
"This web part allows users to read SVGs from a SharePoint library, select one of them and have the code converted into a JSON format that is ready to be used in a SharePoint List in advanced formatting. Users can both copy the JSON format to their clipboard (for further manipulation) or select a site, a list, and a column and then directly apply the format to this column."
],
"creationDateTime": "2024-11-01",
"updateDateTime": "2024-11-01",
"products": [
"SharePoint"
],
"metadata": [
{
"key": "CLIENT-SIDE-DEV",
"value": "React"
},
{
"key": "SPFX-VERSION",
"value": "1.20.0"
}
],
"thumbnails": [
{
"name": "webpart-german.png",
"type": "image",
"order": 100,
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-svg-to-json-converter/assets/webpart-german.png",
"alt": "Web Part Preview"
},
{
"name": "webpart-sp.png",
"type": "image",
"order": 101,
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-svg-to-json-converter/assets/webpart-sp.png",
"alt": "Web Part Preview"
},
{
"name": "webpart-with-reset.png",
"type": "image",
"order": 102,
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-svg-to-json-converter/assets/webpart-with-reset.png",
"alt": "Web Part Preview"
},
{
"name": "webpart-with-site-selector.png",
"type": "image",
"order": 103,
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-svg-to-json-converter/assets/webpart-with-site-selector.png",
"alt": "Web Part Preview"
},
{
"name": "webpart.png",
"type": "image",
"order": 104,
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-svg-to-json-converter/assets/webpart.png",
"alt": "Web Part Preview"
}
],
"authors": [
{
"gitHubAccount": "LuiseFreese",
"pictureUrl": "https://github.com/LuiseFreese.png",
"name": "Luise Freese"
}
],
"references": [
{
"name": "Build your first SharePoint client-side web part",
"description": "Client-side web parts are client-side components that run in the context of a SharePoint page. Client-side web parts can be deployed to SharePoint environments that support the SharePoint Framework. You can also use modern JavaScript web frameworks, tools, and libraries to build them.",
"url": "https://learn.microsoft.com/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part"
}
]
},
{
"name": "pnp-sp-dev-spfx-web-parts-react-tabacordion",
"source": "pnp",
Expand Down
1 change: 1 addition & 0 deletions samples/react-securitygrid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ This is a port of an Angular 1.3 SharePoint hosted App at https://github.com/rus

Version|Date|Comments
-------|----|--------
1.0.7.0|Nov 28, 2024 | Property pane didn't refresh fixed, added multiple permissions display
1.0.6.0|Oct 20, 2024 | Upgrade to SPFx 1.20
1.0.5.0|March 6, 2021 | Added webApiPermission request
1.0.0.4|February 22, 2021 | Added support for AD groups
Expand Down
2 changes: 1 addition & 1 deletion samples/react-securitygrid/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"main": "lib/index.js",
"name": "spsecurity-webpart-3",
"version": "1.0.5",
"version": "1.0.7",
"private": true,
"engines": {
"node": ">=16.13.0 <17.0.0 || >=18.17.1 <19.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as ReactDom from "react-dom";
import { ISpSecurityProps } from "./components/ISpSecurityProps";
import SpSecurity from "./components/SpSecurity";
import { PropertyFieldSelectedPermissions } from "./containers/PropertyFieldSelectedPermissions";
import { ISpSecurityWebPartProps } from "./ISpSecurityWebPartProps";
import { ISelectedPermission, ISpSecurityWebPartProps } from "./ISpSecurityWebPartProps";

export default class SpSecurityWebPart extends BaseClientSideWebPart<ISpSecurityWebPartProps> {
private _sp: SPFI = null;
Expand Down Expand Up @@ -70,18 +70,22 @@ export default class SpSecurityWebPart extends BaseClientSideWebPart<ISpSecurity
return perms;
}

private onPropertyChange(propertyPath: string, newValue: unknown): void {
private onPropertyChange(propertyPath: string, oldValue: ISelectedPermission[], newValue: ISelectedPermission[]): void {
switch (propertyPath) {
case "SelectedPermissions":
this.properties.selectedPermissions = newValue as ISpSecurityWebPartProps['selectedPermissions'];
case "SelectedPermissions": {
const updatedPermissions = newValue.map(newPerm => {
const existingPermission = this.properties.selectedPermissions.find(permission => permission.permission === newPerm.permission);
return existingPermission ? { ...existingPermission, ...newPerm } : newPerm;
});
this.properties.selectedPermissions = updatedPermissions;
this.context.propertyPane.refresh();
this.render();
break;
}
default:
break;
}
}

protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ const SpSecurity: React.FC<ISpSecurityProps> = (props) => {
setState({ ...state });
};

const expandCollapseList = (item: SPList | SPListItem): void => {
const expandCollapseList = (item: SPList | SPListItem, event: React.MouseEvent): void => {
event.stopPropagation();
if (item.itemCount === 0) return;

if (item.isExpanded) {
Expand All @@ -130,7 +131,7 @@ const SpSecurity: React.FC<ISpSecurityProps> = (props) => {
const renderListTitle = (item: SPList): JSX.Element => {
const iconName = item.itemCount > 0 ? 'FabricFormLibrary' : 'FabricFolder';
return (
<div className={styles.itemTitle} onClick={() => expandCollapseList(item)}>
<div className={styles.itemTitle} onClick={(event) => expandCollapseList(item, event)}>
<Icon iconName={iconName} className={styles.themecolor} />
<span>&nbsp;{item.title}</span>
</div>
Expand All @@ -141,7 +142,7 @@ const SpSecurity: React.FC<ISpSecurityProps> = (props) => {
const style = { marginLeft: `${item.level * 20}px` };
const iconName = item.itemCount > 0 ? 'FabricFormLibrary' : 'FabricFolder';
return (
<div className={styles.itemTitle} onClick={() => expandCollapseList(item)}>
<div className={styles.itemTitle} onClick={(event) => expandCollapseList(item, event)}>
<Icon iconName={iconName} style={style} className={styles.themecolor} />
<span>&nbsp;{item.title}</span>
</div>
Expand All @@ -160,8 +161,8 @@ const SpSecurity: React.FC<ISpSecurityProps> = (props) => {
};

const addUserColumns = (
columns: IColumn[],
users: SPSiteUser[],
columns: IColumn[],
users: SPSiteUser[],
effectivePermissions: ISelectedPermission[]
): IColumn[] => {
for (const user of users) {
Expand Down Expand Up @@ -252,11 +253,12 @@ const SpSecurity: React.FC<ISpSecurityProps> = (props) => {
column: IColumn,
effectivePermissions: ISelectedPermission[]
): JSX.Element => {

const user = find(state.securityInfo.siteUsers, (su) => su.upn.toString() === column.key);

for (const selectedPermission of effectivePermissions) {
const icons = effectivePermissions.map((selectedPermission) => {
const permissionKey = selectedPermission.permission as keyof typeof SPPermission;

if (user && Helpers.doesUserHavePermission(
item,
user,
Expand All @@ -266,20 +268,36 @@ const SpSecurity: React.FC<ISpSecurityProps> = (props) => {
state.securityInfo.adGroups
)) {
return (
<Icon
iconName={selectedPermission.iconName}
style={{ color: selectedPermission.color }}
onClick={() => expandCollapseList(item)}
/>
<div key={selectedPermission.permission} style={{ display: 'block' }} onClick={(event) => expandCollapseList(item, event)}>
{icons}
<Icon
iconName={selectedPermission.iconName}
style={{ color: selectedPermission.color}}
/>
</div>
);
}
}


return null;
});

return (
<Icon iconName={item.iconName} onClick={() => expandCollapseList(item)} />
<div style={{ display: 'block' } } onClick={(event) => expandCollapseList(item, event)}>
{icons}
<div style={{ display: 'block' }}>
<Icon iconName={item.iconName}/>
</div>
</div>
);
};


if (!state.securityInfoLoaded) {
return (
<div>
<Spinner label={'Fetching security information, please wait...'} />
</div>
);
}
if (!state.securityInfoLoaded) {
return (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,16 @@ export default class PropertyFieldSelectedPermissionsHost extends React.Componen
<SelectedPermissionsPanel
isOpen={this.state.openPanel}
onPropertyChange={(prop: string, oldval: ISelectedPermission[], newval: ISelectedPermission[]) => {
this.setState({ SelectedPermissions: [...newval] });
this.props.onPropertyChange("SelectedPermissions", this.props.SelectedPermissions, newval);
const updatedPermissions = newval.map(newPerm => {
const existingPermission = this.state.SelectedPermissions.find(permission => permission.permission === newPerm.permission);
return existingPermission ? { ...existingPermission, ...newPerm } : newPerm;
});
this.setState({ SelectedPermissions: updatedPermissions });
this.props.onPropertyChange("SelectedPermissions", this.props.SelectedPermissions, updatedPermissions);
}}
closePanel={() => { this.onClosePanel(); }}
SelectedPermissions={this.props.SelectedPermissions}
/>
</div>
/> </div>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "SPFx 1.20.0",
"image": "docker.io/m365pnp/spfx:1.20.0",
"customizations": {
"vscode": {
"extensions": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint"
]
}
},
"forwardPorts": [
4321,
35729,
5432
],
"portsAttributes": {
"4321": {
"protocol": "https",
"label": "Manifest",
"onAutoForward": "silent",
"requireLocalPort": true
},
"5432": {
"protocol": "https",
"label": "Workbench",
"onAutoForward": "silent"
},
"35729": {
"protocol": "https",
"label": "LiveReload",
"onAutoForward": "silent",
"requireLocalPort": true
}
},
"postCreateCommand": "bash .devcontainer/spfx-startup.sh",
"remoteUser": "node"
}
33 changes: 33 additions & 0 deletions samples/react-svg-to-json-converter/.devcontainer/spfx-startup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
echo
echo -e "\e[1;94mInstalling Node dependencies\e[0m"
npm install

## commands to create dev certificate and copy it to the root folder of the project
echo
echo -e "\e[1;94mGenerating dev certificate\e[0m"
gulp trust-dev-cert

# Convert the generated PEM certificate to a CER certificate
openssl x509 -inform PEM -in ~/.rushstack/rushstack-serve.pem -outform DER -out ./spfx-dev-cert.cer

# Copy the PEM ecrtificate for non-Windows hosts
cp ~/.rushstack/rushstack-serve.pem ./spfx-dev-cert.pem

## add *.cer to .gitignore to prevent certificates from being saved in repo
if ! grep -Fxq '*.cer' ./.gitignore
then
echo "# .CER Certificates" >> .gitignore
echo "*.cer" >> .gitignore
fi

## add *.pem to .gitignore to prevent certificates from being saved in repo
if ! grep -Fxq '*.pem' ./.gitignore
then
echo "# .PEM Certificates" >> .gitignore
echo "*.pem" >> .gitignore
fi

echo
echo -e "\e[1;92mReady!\e[0m"

echo -e "\n\e[1;94m**********\nOptional: if you plan on using gulp serve, don't forget to add the container certificate to your local machine. Please visit https://aka.ms/spfx-devcontainer for more information\n**********"
Loading

0 comments on commit eed28bb

Please sign in to comment.