You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by hb...@apache.org on 2022/12/29 05:33:26 UTC
[age-viewer] branch main updated: filter/search table (#85)
This is an automated email from the ASF dual-hosted git repository.
hbshin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/age-viewer.git
The following commit(s) were added to refs/heads/main by this push:
new b2bacc7 filter/search table (#85)
b2bacc7 is described below
commit b2bacc78cd374a175c43f5f2a45121613721cb76
Author: MJinH <97...@users.noreply.github.com>
AuthorDate: Wed Dec 28 21:33:20 2022 -0800
filter/search table (#85)
Co-authored-by: moon19960501@gmail.com <we...@gmail.com>
---
.../cypherresult/components/GraphFilterModal.jsx | 4 +-
.../presentations/CypherResultCytoscape.jsx | 3 +-
.../presentations/CypherResultTable.jsx | 58 ++++++++++++++++------
.../src/components/cytoscape/CypherResultTab.jsx | 6 ++-
frontend/src/components/frame/Frame.jsx | 7 +--
.../frame/presentations/CypherGraphResultFrame.jsx | 12 ++++-
frontend/src/static/style.css | 2 +-
7 files changed, 69 insertions(+), 23 deletions(-)
diff --git a/frontend/src/components/cypherresult/components/GraphFilterModal.jsx b/frontend/src/components/cypherresult/components/GraphFilterModal.jsx
index bb0b916..bee47d7 100644
--- a/frontend/src/components/cypherresult/components/GraphFilterModal.jsx
+++ b/frontend/src/components/cypherresult/components/GraphFilterModal.jsx
@@ -38,6 +38,7 @@ const GraphFilterModal = ({
onSubmit,
properties,
globalFilter,
+ isTable,
}) => {
const [propertyElements, setPropertyElements] = useState([]);
const [filterList, setFilterList] = useState([
@@ -154,7 +155,7 @@ const GraphFilterModal = ({
);
}, [propertyElements, filterList]);
return (
- <Modal title="Filter on Graph" visible={visible} onOk={onOk} onCancel={() => setVisible(false)} width={800}>
+ <Modal title={isTable ? 'Filter Data in Table' : 'Filter on Graph'} visible={visible} onOk={onOk} onCancel={() => setVisible(false)} width={800}>
{
filterElements
}
@@ -171,6 +172,7 @@ GraphFilterModal.propTypes = {
property: PropTypes.string,
})).isRequired,
globalFilter: PropTypes.bool.isRequired,
+ isTable: PropTypes.bool.isRequired,
};
export default GraphFilterModal;
diff --git a/frontend/src/components/cypherresult/presentations/CypherResultCytoscape.jsx b/frontend/src/components/cypherresult/presentations/CypherResultCytoscape.jsx
index 7799276..049a86e 100644
--- a/frontend/src/components/cypherresult/presentations/CypherResultCytoscape.jsx
+++ b/frontend/src/components/cypherresult/presentations/CypherResultCytoscape.jsx
@@ -368,7 +368,7 @@ const CypherResultCytoscape = forwardRef((props, ref) => {
isReloading={isReloading}
legendData={legendData}
/>
- <CypherResultTab refKey={props.refKey} currentTab="graph" />
+ <CypherResultTab refKey={props.refKey} setIsTable={props.setIsTable} currentTab="graph" />
</div>
<CypherResultCytoscapeChart
onElementsMouseover={getFooterData}
@@ -421,6 +421,7 @@ CypherResultCytoscape.propTypes = {
refKey: PropTypes.string.isRequired,
setChartLegend: PropTypes.func.isRequired,
graph: PropTypes.string.isRequired,
+ setIsTable: PropTypes.func.isRequired,
};
export default CypherResultCytoscape;
diff --git a/frontend/src/components/cypherresult/presentations/CypherResultTable.jsx b/frontend/src/components/cypherresult/presentations/CypherResultTable.jsx
index 6014ab7..f687ff7 100644
--- a/frontend/src/components/cypherresult/presentations/CypherResultTable.jsx
+++ b/frontend/src/components/cypherresult/presentations/CypherResultTable.jsx
@@ -46,18 +46,45 @@ const CypherResultTable = ({ data, ...props }) => {
});
setLocalColumns(columnsForFTable);
- setLocalRows(data.rows.map((item) => {
- const newItem = {
- ...item,
- };
- if (hasKey) {
- newItem[randKeyName] = newItem.key;
- delete newItem.key;
- }
- newItem.key = uuid();
- return newItem;
- }));
- }, []);
+ if (props.filterTable?.length > 0) {
+ const newItem = [];
+ data.rows.forEach((item) => {
+ props.filterTable.forEach((filter) => {
+ if ((filter.property.label === item.r.label
+ && item.r.properties[filter.property.property].includes(filter.keyword))
+ || (filter.property.label === item.v.label
+ && item.v.properties[filter.property.property].includes(filter.keyword))
+ || (filter.property.label === item.v2.label
+ && item.v2.properties[filter.property.property].includes(filter.keyword))) {
+ newItem.push(item);
+ }
+ });
+ });
+ setLocalRows(newItem.map((item) => {
+ const filteredItem = {
+ ...item,
+ };
+ if (hasKey) {
+ newItem[randKeyName] = newItem.key;
+ delete newItem.key;
+ }
+ filteredItem.key = uuid();
+ return filteredItem;
+ }));
+ } else {
+ setLocalRows(data.rows.map((item) => {
+ const newItem = {
+ ...item,
+ };
+ if (hasKey) {
+ newItem[randKeyName] = newItem.key;
+ delete newItem.key;
+ }
+ newItem.key = uuid();
+ return newItem;
+ }));
+ }
+ }, [props.filterTable]);
if (data.command && data.command.toUpperCase().match('(GRAPH|COPY|UPDATE).*')) {
return (
@@ -75,7 +102,7 @@ const CypherResultTable = ({ data, ...props }) => {
return <div style={{ margin: '25px' }}><span style={{ whiteSpace: 'pre-line' }}>Query not entered!</span></div>;
}
- const { refKey } = props;
+ const { refKey, setIsTable } = props;
return (
<div className="legend-area">
<div className="contianer-frame-tab">
@@ -83,7 +110,7 @@ const CypherResultTable = ({ data, ...props }) => {
<div className="d-flex nodeLegend">Node:</div>
<div className="d-flex edgeLegend">Edge:</div>
</div>
- <CypherResultTab refKey={refKey} currentTab="table" />
+ <CypherResultTab refKey={refKey} setIsTable={setIsTable} currentTab="table" />
</div>
<Table columns={localColumns} dataSource={localRows} />
</div>
@@ -102,6 +129,9 @@ CypherResultTable.propTypes = {
statusText: PropTypes.string,
}).isRequired,
refKey: PropTypes.string.isRequired,
+ setIsTable: PropTypes.func.isRequired,
+ // eslint-disable-next-line react/forbid-prop-types
+ filterTable: PropTypes.any.isRequired,
};
export default CypherResultTable;
diff --git a/frontend/src/components/cytoscape/CypherResultTab.jsx b/frontend/src/components/cytoscape/CypherResultTab.jsx
index 5c2a142..6c2eda0 100644
--- a/frontend/src/components/cytoscape/CypherResultTab.jsx
+++ b/frontend/src/components/cytoscape/CypherResultTab.jsx
@@ -30,6 +30,7 @@ class CypherResultTab extends Component {
this.state = {};
this.refKey = props.refKey;
this.currentTab = props.currentTab;
+ this.setIsTable = props.setIsTable;
}
render() {
@@ -52,7 +53,7 @@ class CypherResultTab extends Component {
className="btn"
type="button"
style={{ width: '50%', fontSize: '14px', color: this.currentTab === 'graph' ? '#142B80' : '#495057' }}
- onClick={() => activeTab(this.refKey, 'graph')}
+ onClick={() => { activeTab(this.refKey, 'graph'); this.setIsTable(false); }}
>
<IconGraph />
<br />
@@ -70,7 +71,7 @@ class CypherResultTab extends Component {
className="btn"
type="button"
style={{ width: '50%', fontSize: '14px', color: this.currentTab === 'table' ? '#142B80' : '#495057' }}
- onClick={() => activeTab(this.refKey, 'table')}
+ onClick={() => { activeTab(this.refKey, 'table'); this.setIsTable(true); }}
>
<FontAwesomeIcon icon={faTable} style={{ fontSize: '25px' }} />
<br />
@@ -84,6 +85,7 @@ class CypherResultTab extends Component {
CypherResultTab.propTypes = {
refKey: PropTypes.string.isRequired,
currentTab: PropTypes.string.isRequired,
+ setIsTable: PropTypes.func.isRequired,
};
export default CypherResultTab;
diff --git a/frontend/src/components/frame/Frame.jsx b/frontend/src/components/frame/Frame.jsx
index 969c2fd..fab3b99 100644
--- a/frontend/src/components/frame/Frame.jsx
+++ b/frontend/src/components/frame/Frame.jsx
@@ -37,7 +37,7 @@ const Frame = ({
reqString, children, refKey,
onSearch, onSearchCancel, onRefresh,
onThick, thicnessMenu,
- bodyNoPadding,
+ bodyNoPadding, isTable,
}) => {
const dispatch = useDispatch();
const [isFullScreen, setFullScreen] = useState(false);
@@ -78,7 +78,7 @@ const Frame = ({
</div>
<div className={styles.ButtonArea}>
- {onThick ? (
+ {!isTable && onThick ? (
<Popover placement="bottomLeft" content={thicnessMenu} trigger="click">
<Button
size="large"
@@ -146,7 +146,7 @@ const Frame = ({
/>
</Button>
{
- onRefresh ? (
+ !isTable && onRefresh ? (
<Button
size="large"
type="link"
@@ -228,6 +228,7 @@ Frame.propTypes = {
onSearchCancel: PropTypes.func,
onRefresh: PropTypes.func,
bodyNoPadding: PropTypes.bool,
+ isTable: PropTypes.bool.isRequired,
};
export default Frame;
diff --git a/frontend/src/components/frame/presentations/CypherGraphResultFrame.jsx b/frontend/src/components/frame/presentations/CypherGraphResultFrame.jsx
index 93cf0ac..7d3c783 100644
--- a/frontend/src/components/frame/presentations/CypherGraphResultFrame.jsx
+++ b/frontend/src/components/frame/presentations/CypherGraphResultFrame.jsx
@@ -42,11 +42,13 @@ const CypherResultFrame = ({
const [thicknessModalVisible, setThicknessModalVisible] = useState(false);
const [filterProperties, setFilterProperties] = useState([]);
+ const [filterTable, setFilterTable] = useState(null);
const [edgeProperties, setEdgeProperties] = useState([]);
const [globalFilter, setGlobalFilter] = useState(null);
const [globalThickness, setGlobalThickness] = useState(null);
const [chartLegend, setChartLegend] = useState({ edgeLegend: {}, nodeLegend: {} });
+ const [isTable, setIsTable] = useState(false);
useEffect(() => {
if (chartAreaRef.current && filterModalVisible) {
@@ -77,10 +79,13 @@ const CypherResultFrame = ({
useEffect(() => {
if (!chartAreaRef.current) return;
- if (globalFilter) {
+ if (globalFilter && !isTable) {
chartAreaRef.current.applyFilterOnCytoscapeElements(globalFilter);
+ } else if (globalFilter && isTable) {
+ setFilterTable(globalFilter);
} else {
chartAreaRef.current.resetFilterOnCytoscapeElements();
+ setFilterTable();
}
}, [globalFilter]);
@@ -177,6 +182,7 @@ const CypherResultFrame = ({
reqString={reqString}
isPinned={isPinned}
refKey={refKey}
+ isTable={isTable}
>
{
queryComplete?.complete
@@ -188,11 +194,14 @@ const CypherResultFrame = ({
ref={chartAreaRef}
refKey={refKey}
setChartLegend={setChartLegend}
+ setIsTable={setIsTable}
/>
</div>
<div style={{ height: '100%', width: '100%' }} id={`${refKey}-table`} className="deselected-frame-tab">
<CypherResultTableContainer
refKey={refKey}
+ filterTable={filterTable}
+ setIsTable={setIsTable}
/>
</div>
</div>
@@ -214,6 +223,7 @@ const CypherResultFrame = ({
setVisible={setFilterModalVisible}
properties={filterProperties}
globalFilter={globalFilter}
+ isTable={isTable}
/>
</>
diff --git a/frontend/src/static/style.css b/frontend/src/static/style.css
index 41e61e5..8d5ad43 100644
--- a/frontend/src/static/style.css
+++ b/frontend/src/static/style.css
@@ -277,7 +277,7 @@ a[data-toggle="collapse"] {
}
.legend-area {
- width: 80%;
+ width: 100%;
}
.legend-button-area {