interfaces + optionRelationOnly

This commit is contained in:
NiklasWilhelm 2022-10-05 23:03:53 +02:00
parent 157db93bf5
commit 3ff4d771b3
3 changed files with 63 additions and 36 deletions

View File

@ -4,7 +4,7 @@ import { ReactDiagram } from 'gojs-react';
import getSPSiteData from './helpers/SPSiteData'; import getSPSiteData from './helpers/SPSiteData';
import { initDiagram } from './helpers/GoJSHelper'; import { initDiagram } from './helpers/GoJSHelper';
import getGoJSNodesFromSPSiteData from './helpers/SPSiteDataToGoJSER'; import getGoJSNodesFromSPSiteData from './helpers/SPSiteDataToGoJSER';
import { ProgressIndicator } from 'office-ui-fabric-react'; import { CommandBar, ProgressIndicator } from 'office-ui-fabric-react';
export interface ISpSiteDiagramProps { export interface ISpSiteDiagramProps {
context: any context: any
@ -17,37 +17,46 @@ const SpSiteErDiagram: React.FC<ISpSiteDiagramProps> = (props: ISpSiteDiagramPro
// State: Options // State: Options
const [optionRelationOnly, setOptionRelationOnly] = React.useState(false); 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 // 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); console.log("SPSiteData", spSiteData);
// Transform to GoJS Model // Transform to GoJS Model
let goJSNodes = getGoJSNodesFromSPSiteData(spSiteData); let goJSNodes = getGoJSNodesFromSPSiteData(spSiteData);
// Set State // 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); setLinkDataArray(goJSNodes.linkDataArray);
} }
// "ComponentDitMount" // "ComponentDitMount"
React.useEffect(() => { React.useEffect(() => {
loadDiagram(); loadDiagram(false);
}, [optionRelationOnly]); }, [optionRelationOnly]);
return ( return (
<div className={styles.spSiteErDiagram} style={{height: "calc(100% - 0px)", padding: "0px"}}> <div style={{height: "100%", padding: "0px"}}>
{ <CommandBar items={[
loadingProgress != 100 || nodeDataArray.length == 0 ? {key: '1', text: 'Refresh', iconProps: { iconName: 'Refresh' }, onClick: () => { loadDiagram(true); }},
<div style={{ padding: "8%" }}> {key: '2', text: 'Only Lists with Relations', iconProps: { iconName: optionRelationOnly ? 'CheckboxComposite' : 'Checkbox' }, onClick: () => { setOptionRelationOnly(!optionRelationOnly); }}
<ProgressIndicator label={`Loading Lists and Columns ${loadingProgress.toFixed(0)}%`} percentComplete={loadingProgress/100} /> ]} />
</div> : <div className={styles.spSiteErDiagram} style={{height: "calc(100% - 44px)", padding: "0px"}}>
<ReactDiagram //ref={diagramRef} { loadingProgress != 100 && nodeDataArray.length == 0 ?
divClassName='diagram-component' <div style={{ padding: "8%" }}>
style={{ backgroundColor: '#eee' }} <ProgressIndicator label={`Loading Lists and Columns ${loadingProgress.toFixed(0)}%`} percentComplete={loadingProgress/100} />
initDiagram={initDiagram} </div> :
nodeDataArray={nodeDataArray} <ReactDiagram //ref={diagramRef}
linkDataArray={linkDataArray} divClassName='diagram-component'
/>} style={{ backgroundColor: '#eee' }}
initDiagram={initDiagram}
nodeDataArray={nodeDataArray}
linkDataArray={linkDataArray}
/>
}
</div>
</div> </div>
); );
} }

View File

@ -11,6 +11,7 @@ export interface SPSiteData {
relations: SPRelation[] relations: SPRelation[]
} }
export interface SPTable { export interface SPTable {
id: string,
title: string, title: string,
fields: SPTableField[], fields: SPTableField[],
alerts: SPTableAlert[] alerts: SPTableAlert[]
@ -63,7 +64,7 @@ const getSPSiteData = async (spfxContext: any, force?: boolean, progress?: (numb
tmp_listNames[`{${list.Id.toLocaleLowerCase()}}`] = list.Title; tmp_listNames[`{${list.Id.toLocaleLowerCase()}}`] = list.Title;
// Tables/Lists // Tables/Lists
let table: SPTable = { title: list.Title, fields: [], alerts: [] }; let table: SPTable = { id: list.Id, title: list.Title, fields: [], alerts: [] };
// Fields // Fields
let fields = (await sp.web.lists.getById(list.Id).fields.filter("Hidden ne 1")()) 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) ); .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 { return {
name: f.InternalName, name: f.InternalName,
displayName: f.Title, 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 type: f.TypeDisplayName
} }
}); });
@ -87,15 +88,16 @@ const getSPSiteData = async (spfxContext: any, force?: boolean, progress?: (numb
// Links/Lookups // Links/Lookups
let relations: SPRelation[] = fields.filter(f => f.TypeDisplayName == "Lookup" && let relations: SPRelation[] = fields.filter(f => f.TypeDisplayName == "Lookup" &&
(f as any).IsRelationship && (f as any).IsRelationship &&
(f as any).LookupList != '' && (f as any).LookupList != '' && (f as any).LookupList != "AppPrincipals"
(f as any).LookupList != "AppPrincipals"
).map<SPRelation>(f => ).map<SPRelation>(f =>
{return { {
fromTableTitle: list.Title, return {
toTableTitle: (f as any).LookupList!, fromTableTitle: list.Title,
fromX: "n", toTableTitle: (f as any).LookupList!,
toX: 1 fromX: "n",
}}); toX: 1
}
});
spSiteData.relations = [...spSiteData.relations, ...relations]; spSiteData.relations = [...spSiteData.relations, ...relations];
} }

View File

@ -27,7 +27,7 @@ const configByFieldType: any = {
"Choice": { color: colors.blue, figure: "Ellipse" }, "Choice": { color: colors.blue, figure: "Ellipse" },
"Hyperlink or Picture": { 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 c = configByFieldType[f.type] || configByFieldType['default'];
let prefix = f.type == "Counter" ? "PK | " : (f.iskey && f.type == "Lookup" ? "FK | " : ""); let prefix = f.type == "Counter" ? "PK | " : (f.iskey && f.type == "Lookup" ? "FK | " : "");
return { return {
@ -42,7 +42,7 @@ const configByAlert: any = {
'Warning': { color: colors.orange, figure: "LineRight" }, 'Warning': { color: colors.orange, figure: "LineRight" },
'Error': { color: colors.red, figure: "LineRight" }, 'Error': { color: colors.red, figure: "LineRight" },
} }
const getNodeFromAlert = (a: SPTableAlert) => { const getNodeItemFromAlert = (a: SPTableAlert) : GoJSNodeItem => {
let c = configByAlert[a.type]; let c = configByAlert[a.type];
return { return {
name: "#" + a.type + " | " + a.title, 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 nodeDataArray: GoJSNode[] = [];
let linkDataArray: any = []; let linkDataArray: GoJSLink[] = [];
nodeDataArray = spSiteData.tables.map(t => { return { nodeDataArray = spSiteData.tables.map(t => { return {
key: t.title, key: t.title,
items: [ items: [
...t.alerts.map(a => getNodeFromAlert(a)), ...t.alerts.map(a => getNodeItemFromAlert(a)),
...t.fields.map(f => getNodeFromField(f)) ...t.fields.map(f => getNodeItemFromField(f))
] ]
}}) }})
@ -72,6 +88,6 @@ const getGoJSNodesFromSPSiteData = (spSiteData: SPSiteData) : { nodeDataArray: [
toText: "1" toText: "1"
}}) }})
return { nodeDataArray, linkDataArray} return { nodeDataArray, linkDataArray }
} }
export default getGoJSNodesFromSPSiteData; export default getGoJSNodesFromSPSiteData;