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 { 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<ISpSiteDiagramProps> = (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 (
<div className={styles.spSiteErDiagram} style={{height: "calc(100% - 0px)", padding: "0px"}}>
{
loadingProgress != 100 || nodeDataArray.length == 0 ?
<div style={{ padding: "8%" }}>
<ProgressIndicator label={`Loading Lists and Columns ${loadingProgress.toFixed(0)}%`} percentComplete={loadingProgress/100} />
</div> :
<ReactDiagram //ref={diagramRef}
divClassName='diagram-component'
style={{ backgroundColor: '#eee' }}
initDiagram={initDiagram}
nodeDataArray={nodeDataArray}
linkDataArray={linkDataArray}
/>}
<div style={{height: "100%", padding: "0px"}}>
<CommandBar items={[
{key: '1', text: 'Refresh', iconProps: { iconName: 'Refresh' }, onClick: () => { loadDiagram(true); }},
{key: '2', text: 'Only Lists with Relations', iconProps: { iconName: optionRelationOnly ? 'CheckboxComposite' : 'Checkbox' }, onClick: () => { setOptionRelationOnly(!optionRelationOnly); }}
]} />
<div className={styles.spSiteErDiagram} style={{height: "calc(100% - 44px)", padding: "0px"}}>
{ loadingProgress != 100 && nodeDataArray.length == 0 ?
<div style={{ padding: "8%" }}>
<ProgressIndicator label={`Loading Lists and Columns ${loadingProgress.toFixed(0)}%`} percentComplete={loadingProgress/100} />
</div> :
<ReactDiagram //ref={diagramRef}
divClassName='diagram-component'
style={{ backgroundColor: '#eee' }}
initDiagram={initDiagram}
nodeDataArray={nodeDataArray}
linkDataArray={linkDataArray}
/>
}
</div>
</div>
);
}

View File

@ -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<SPRelation>(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];
}

View File

@ -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;