Skip to content

Commit d08f33a

Browse files
committed
DISPATCH-1914 Update console's schema page to fix formatting issues (using PF4 treeview component)
1 parent a91eee4 commit d08f33a

File tree

1 file changed

+62
-167
lines changed

1 file changed

+62
-167
lines changed

console/react/src/details/schema/schemaPage.js

Lines changed: 62 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -18,191 +18,86 @@ under the License.
1818
*/
1919

2020
import React from "react";
21-
import { PageSection, PageSectionVariants } from "@patternfly/react-core";
22-
import { Stack, StackItem, TextContent, Text, TextVariants } from "@patternfly/react-core";
23-
import { Card, CardBody } from "@patternfly/react-core";
21+
import { TreeView, Button } from "@patternfly/react-core";
2422

2523
class SchemaPage extends React.Component {
2624
constructor(props) {
2725
super(props);
28-
29-
this.state = {
30-
root: {
31-
key: "entities",
32-
title: "Schema entities",
33-
description: "List of management entities. Click on an entity to view its attributes.",
34-
hidden: false
35-
}
36-
};
37-
this.initRoot(this.state.root, this.props.schema.entityTypes);
26+
this.state = { activeItems: {}, allExpanded: false };
27+
this.nextId = 0;
3828
}
3929

40-
initRoot = (root, schema) => {
41-
root.attributes = [
42-
{
43-
key: Object.keys(schema).length,
44-
value: "Entities"
45-
}
46-
];
47-
root.children = [];
48-
const entities = Object.keys(schema).sort();
49-
for (let i = 0; i < entities.length; i++) {
50-
const entity = entities[i];
51-
const child = { title: entity, key: entity };
52-
this.initChild(child, schema[entity]);
53-
root.children.push(child);
54-
}
30+
handleTreeClick = (evt, treeViewItem, parentItem) => {
31+
this.setState({
32+
activeItems: [treeViewItem, parentItem],
33+
});
5534
};
5635

57-
initChild = (child, obj) => {
58-
child.hidden = true;
59-
child.description = obj.description;
60-
child.attributes = [];
61-
if (obj.attributes) {
62-
child.hidden = false;
63-
child.attributes.push({
64-
key: Object.keys(obj.attributes).length,
65-
value: "Attributes"
66-
});
67-
child.children = [];
68-
for (const attr in obj.attributes) {
69-
const sub = { title: attr, key: `${child.key}-${attr}` };
70-
this.initChild(sub, obj.attributes[attr]);
71-
child.children.push(sub);
72-
}
73-
}
74-
if (obj.operations) {
75-
child.attributes.push({
76-
key: "Operations",
77-
value: `[${obj.operations.join(", ")}]`
78-
});
79-
}
80-
if (obj.fullyQualifiedType) {
81-
child.fqt = obj.fullyQualifiedType;
82-
}
83-
if (obj.type) {
84-
child.attributes.push({
85-
key: "type",
86-
value: obj.type.constructor === Array ? `[${obj.type.join(", ")}]` : obj.type
87-
});
88-
}
89-
if (obj.default) {
90-
child.attributes.push({ key: "default", value: obj.default });
91-
}
92-
if (obj.required) {
93-
child.attributes.push({ key: "required", value: "" });
94-
}
95-
if (obj.unique) {
96-
child.attributes.push({ key: "unique", value: "" });
97-
}
98-
if (obj.graph) {
99-
child.attributes.push({ key: "statistic", value: "" });
100-
}
36+
onToggle = evt => {
37+
const { allExpanded } = this.state;
38+
this.setState({
39+
allExpanded: allExpanded !== undefined ? !allExpanded : true,
40+
});
10141
};
10242

103-
toggleChildren = (event, parent) => {
104-
event.stopPropagation();
105-
if (parent.children && parent.children.length > 0) {
106-
parent.children.forEach(child => {
107-
child.hidden = !child.hidden;
108-
});
109-
this.setState({ root: this.state.root });
110-
}
43+
handleExpandAllToggle = (evt, treeViewItem, parentItem) => {
44+
this.handleTreeClick(evt, treeViewItem, parentItem);
11145
};
11246

113-
folderIconClass = item => {
114-
if (item.children) {
115-
return item.children.some(child => !child.hidden)
116-
? "pficon-folder-open"
117-
: "pficon-folder-close";
118-
}
119-
return "pficon-catalog";
47+
buildTreeOptions = () => {
48+
const schema = this.props.schema.entityTypes;
49+
const options = [];
50+
const entities = Object.keys(schema).sort();
51+
entities.forEach(entity => {
52+
this.initChild(options, entity, schema);
53+
});
54+
return options;
12055
};
12156

122-
attrIconClass = attr => {
123-
const attrMap = {
124-
type: "pficon-builder-image",
125-
Operations: "pficon-maintenance",
126-
default: "pficon-info",
127-
unique: "pficon-locked",
128-
statistic: "fa fa-icon fa-tachometer"
129-
};
130-
if (attrMap[attr.key]) return `pficon ${attrMap[attr.key]}`;
131-
return "pficon pficon-repository";
57+
initChild = (parent, entity, schema) => {
58+
const child = { name: entity, id: `ID.${this.nextId++}` };
59+
const keys = Object.keys(schema[entity]);
60+
keys.forEach(key => {
61+
console.log(
62+
`processing schema[${entity}][${key}] which is type ${typeof schema[entity][key]}`
63+
);
64+
const isArray = Array.isArray(schema[entity][key]);
65+
if (typeof schema[entity][key] === "object" && !isArray) {
66+
if (!child.children) {
67+
child.children = [];
68+
}
69+
this.initChild(child.children, key, schema[entity]);
70+
} else {
71+
if (!child.children) {
72+
child.children = [];
73+
}
74+
child.children.push({
75+
name: `${key}: ${
76+
isArray ? schema[entity][key].join(", ") : schema[entity][key]
77+
}`,
78+
id: `ID.{this.nextId++}`,
79+
});
80+
}
81+
});
82+
parent.push(child);
13283
};
13384

13485
render() {
135-
const TreeItem = itemInfo => {
136-
return (
137-
!itemInfo.hidden && (
138-
<div
139-
key={itemInfo.key}
140-
data-testid={itemInfo.key}
141-
className={`list-group-item-container container-fluid`}
142-
onClick={event => this.toggleChildren(event, itemInfo)}
143-
>
144-
<div className="list-group-item">
145-
<div className="list-group-item-header">
146-
<div className="list-view-pf-main-info">
147-
<div className="list-view-pf-left">
148-
<span
149-
className={`pficon ${this.folderIconClass(itemInfo)} list-view-pf-icon-sm`}
150-
></span>
151-
</div>
152-
<div className="list-view-pf-body">
153-
<div className="list-view-pf-description">
154-
<div className="list-group-item-heading">{itemInfo.title}</div>
155-
<div className="list-group-item-text">
156-
{itemInfo.description}
157-
{itemInfo.fqt && <div className="list-group-item-fqt">{itemInfo.fqt}</div>}
158-
</div>
159-
</div>
160-
<div className="list-view-pf-additional-info">
161-
{itemInfo.attributes &&
162-
itemInfo.attributes.map((attr, i) => (
163-
<div
164-
className="list-view-pf-additional-info-item"
165-
key={`${itemInfo.key}-${i}`}
166-
>
167-
<span className={this.attrIconClass(attr)}></span>
168-
<strong>{attr.key}</strong>
169-
{attr.value}
170-
</div>
171-
))}
172-
</div>
173-
</div>
174-
</div>
175-
</div>
176-
{itemInfo.children && itemInfo.children.map(childInfo => TreeItem(childInfo))}
177-
</div>
178-
</div>
179-
)
180-
);
181-
};
182-
86+
const { activeItems, allExpanded } = this.state;
87+
const options = this.buildTreeOptions();
18388
return (
184-
<PageSection variant={PageSectionVariants.light} id="schema-page">
185-
<Stack>
186-
<StackItem>
187-
<TextContent>
188-
<Text className="overview-title" component={TextVariants.h1}>
189-
Schema
190-
</Text>
191-
</TextContent>
192-
</StackItem>
193-
<StackItem>
194-
<Card>
195-
<CardBody>
196-
<div className="container-fluid">
197-
<div className="list-group tree-list-view-pf" data-testid="root">
198-
{TreeItem(this.state.root)}
199-
</div>
200-
</div>
201-
</CardBody>
202-
</Card>
203-
</StackItem>
204-
</Stack>
205-
</PageSection>
89+
<React.Fragment>
90+
<Button variant="link" onClick={this.onToggle}>
91+
{allExpanded && "Collapse all"}
92+
{!allExpanded && "Expand all"}
93+
</Button>
94+
<TreeView
95+
data={options}
96+
activeItems={activeItems}
97+
onSelect={this.handleTreeClick}
98+
allExpanded={allExpanded}
99+
/>
100+
</React.Fragment>
206101
);
207102
}
208103
}

0 commit comments

Comments
 (0)