diff --git a/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/SpSiteErDiagram.tsx b/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/SpSiteErDiagram.tsx index 9607e3e30..2c7b7d668 100644 --- a/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/SpSiteErDiagram.tsx +++ b/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/SpSiteErDiagram.tsx @@ -4,7 +4,7 @@ import { ReactDiagram } from 'gojs-react'; import getSPSiteData from './helpers/SPSiteData'; import { initDiagram } from './helpers/GoJSHelper'; import getGoJSNodesFromSPSiteData from './helpers/SPSiteDataToGoJSER'; -import { ProgressIndicator } from 'office-ui-fabric-react'; +import { CommandBar, ProgressIndicator } from 'office-ui-fabric-react'; export interface ISpSiteDiagramProps { context: any @@ -17,37 +17,46 @@ const SpSiteErDiagram: React.FC = (props: ISpSiteDiagramPro // State: Options const [optionRelationOnly, setOptionRelationOnly] = React.useState(false); - const loadDiagram = async () => { + const loadDiagram = async (refresh: boolean) => { + if(refresh) { setLoadingProgress(0); setNodeDataArray([]); } // Get SP SiteData for ER Diagram - let spSiteData = await getSPSiteData(props.context, true, (progress) => {setLoadingProgress(progress);}); + let spSiteData = await getSPSiteData(props.context, refresh, (progress) => {setLoadingProgress(progress);}); console.log("SPSiteData", spSiteData); // Transform to GoJS Model let goJSNodes = getGoJSNodesFromSPSiteData(spSiteData); // Set State - setNodeDataArray(goJSNodes.nodeDataArray); + setNodeDataArray(goJSNodes.nodeDataArray.filter((n) => + optionRelationOnly && goJSNodes.linkDataArray.some(l => l.from == n.key || l.to == n.key) || !optionRelationOnly // Filter optionRelationOnly + )); setLinkDataArray(goJSNodes.linkDataArray); } // "ComponentDitMount" React.useEffect(() => { - loadDiagram(); + loadDiagram(false); }, [optionRelationOnly]); return ( -
- { - loadingProgress != 100 || nodeDataArray.length == 0 ? -
- -
: - } +
+ { loadDiagram(true); }}, + {key: '2', text: 'Only Lists with Relations', iconProps: { iconName: optionRelationOnly ? 'CheckboxComposite' : 'Checkbox' }, onClick: () => { setOptionRelationOnly(!optionRelationOnly); }} + ]} /> +
+ { loadingProgress != 100 && nodeDataArray.length == 0 ? +
+ +
: + + } +
); } diff --git a/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteData.ts b/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteData.ts index bae1f2ca3..dabc2e169 100644 --- a/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteData.ts +++ b/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteData.ts @@ -11,6 +11,7 @@ export interface SPSiteData { relations: SPRelation[] } export interface SPTable { + id: string, title: string, fields: SPTableField[], alerts: SPTableAlert[] @@ -63,7 +64,7 @@ const getSPSiteData = async (spfxContext: any, force?: boolean, progress?: (numb tmp_listNames[`{${list.Id.toLocaleLowerCase()}}`] = list.Title; // Tables/Lists - let table: SPTable = { title: list.Title, fields: [], alerts: [] }; + let table: SPTable = { id: list.Id, title: list.Title, fields: [], alerts: [] }; // Fields let fields = (await sp.web.lists.getById(list.Id).fields.filter("Hidden ne 1")()) .filter(f => !f.Hidden).sort((a,b) => a.TypeDisplayName.charCodeAt(0) - b.TypeDisplayName.charCodeAt(0) ); @@ -71,7 +72,7 @@ const getSPSiteData = async (spfxContext: any, force?: boolean, progress?: (numb return { name: f.InternalName, displayName: f.Title, - iskey: (f as any).TypeDisplayName == "Lookup" && (f as any).IsRelationship, + iskey: (f as any).TypeDisplayName == "Lookup" && (f as any).IsRelationship && (f as any).LookupList != '' && (f as any).LookupList != "AppPrincipals", type: f.TypeDisplayName } }); @@ -87,15 +88,16 @@ const getSPSiteData = async (spfxContext: any, force?: boolean, progress?: (numb // Links/Lookups let relations: SPRelation[] = fields.filter(f => f.TypeDisplayName == "Lookup" && (f as any).IsRelationship && - (f as any).LookupList != '' && - (f as any).LookupList != "AppPrincipals" + (f as any).LookupList != '' && (f as any).LookupList != "AppPrincipals" ).map(f => - {return { - fromTableTitle: list.Title, - toTableTitle: (f as any).LookupList!, - fromX: "n", - toX: 1 - }}); + { + return { + fromTableTitle: list.Title, + toTableTitle: (f as any).LookupList!, + fromX: "n", + toX: 1 + } + }); spSiteData.relations = [...spSiteData.relations, ...relations]; } diff --git a/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteDataToGoJSER.ts b/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteDataToGoJSER.ts index c33391803..0ebbcd8e5 100644 --- a/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteDataToGoJSER.ts +++ b/samples/react-pnpjs-spsite-er-diagram/src/webparts/spSiteErDiagram/components/helpers/SPSiteDataToGoJSER.ts @@ -27,7 +27,7 @@ const configByFieldType: any = { "Choice": { color: colors.blue, figure: "Ellipse" }, "Hyperlink or Picture": { color: colors.blue, figure: "Ellipse" } } -const getNodeFromField = (f: SPTableField) => { +const getNodeItemFromField = (f: SPTableField) : GoJSNodeItem => { let c = configByFieldType[f.type] || configByFieldType['default']; let prefix = f.type == "Counter" ? "PK | " : (f.iskey && f.type == "Lookup" ? "FK | " : ""); return { @@ -42,7 +42,7 @@ const configByAlert: any = { 'Warning': { color: colors.orange, figure: "LineRight" }, 'Error': { color: colors.red, figure: "LineRight" }, } -const getNodeFromAlert = (a: SPTableAlert) => { +const getNodeItemFromAlert = (a: SPTableAlert) : GoJSNodeItem => { let c = configByAlert[a.type]; return { name: "#" + a.type + " | " + a.title, @@ -52,16 +52,32 @@ const getNodeFromAlert = (a: SPTableAlert) => { }; } -const getGoJSNodesFromSPSiteData = (spSiteData: SPSiteData) : { nodeDataArray: [], linkDataArray: [] } => { +export interface GoJSNode { + key: string, + items: GoJSNodeItem[] +} +export interface GoJSNodeItem { + name: string, + iskey: boolean, + figure: string, + color: string +} +export interface GoJSLink { + from: string, + to: string, + text: string, + toText: string +} +const getGoJSNodesFromSPSiteData = (spSiteData: SPSiteData) : { nodeDataArray: GoJSNode[], linkDataArray: GoJSLink[] } => { - let nodeDataArray: any = []; - let linkDataArray: any = []; + let nodeDataArray: GoJSNode[] = []; + let linkDataArray: GoJSLink[] = []; nodeDataArray = spSiteData.tables.map(t => { return { key: t.title, items: [ - ...t.alerts.map(a => getNodeFromAlert(a)), - ...t.fields.map(f => getNodeFromField(f)) + ...t.alerts.map(a => getNodeItemFromAlert(a)), + ...t.fields.map(f => getNodeItemFromField(f)) ] }}) @@ -72,6 +88,6 @@ const getGoJSNodesFromSPSiteData = (spSiteData: SPSiteData) : { nodeDataArray: [ toText: "1" }}) - return { nodeDataArray, linkDataArray} + return { nodeDataArray, linkDataArray } } export default getGoJSNodesFromSPSiteData; \ No newline at end of file