├── .asf.yaml ├── .dockerignore ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── node.js.yml ├── .gitignore ├── DISCLAIMER ├── Dockerfile ├── LICENSE ├── NOTICE ├── README.md ├── backend ├── .babelrc ├── .gitignore ├── README.md ├── misc │ └── graph_kw.csv ├── package.json ├── sql │ ├── 11 │ │ └── meta_data.sql │ ├── 12 │ │ └── meta_data.sql │ ├── 13 │ │ └── meta_data.sql │ ├── 14 │ │ └── meta_data.sql │ ├── 15 │ │ └── meta_data.sql │ ├── analyze_graph.sql │ ├── get_graph_names.sql │ ├── get_role.sql │ ├── graph_labels.sql │ ├── meta_edges.sql │ ├── meta_nodes.sql │ ├── pg_version.sql │ └── property_keys.sql ├── src │ ├── app.js │ ├── bin │ │ └── www.js │ ├── common │ │ └── Routes.js │ ├── config │ │ ├── Flavors.js │ │ ├── Pg.js │ │ └── winston.js │ ├── controllers │ │ ├── cypherController.js │ │ └── databaseController.js │ ├── models │ │ ├── GraphCreator.js │ │ ├── GraphRepository.js │ │ └── QueryBuilder.js │ ├── routes │ │ ├── cypherRouter.js │ │ ├── databaseRouter.js │ │ ├── miscellaneous.js │ │ └── sessionRouter.js │ ├── services │ │ ├── cypherService.js │ │ ├── databaseService.js │ │ ├── queryList.js │ │ └── sessionService.js │ ├── tools │ │ ├── AGEParser.js │ │ ├── Agtype.g4 │ │ ├── AgtypeLexer.js │ │ ├── AgtypeListener.js │ │ ├── AgtypeParser.js │ │ ├── CustomAgTypeListener.js │ │ └── SQLFlavorManager.js │ └── util │ │ ├── JsonBuilder.js │ │ └── ObjectExtras.js └── test │ ├── Dockerfile │ ├── README.md │ ├── ageParsing.test.js │ ├── ageUtil.test.js │ ├── docker-compose.yml │ ├── docker-entrypoint-initdb.d │ ├── 00-create-extension-age.sql │ ├── 01-create-user.sql │ └── 02-create-db.sql │ ├── graphCreate.test.js │ ├── test-data │ ├── has_model.csv │ ├── make.csv │ └── model.csv │ ├── test-queries │ └── queries.js │ └── testDB.js ├── ecosystem.config.js ├── frontend ├── .eslintrc.js ├── .gitignore ├── package.json ├── public │ ├── index.html │ ├── resources │ │ ├── csv │ │ │ └── northwind │ │ │ │ ├── categories.csv.xlsx │ │ │ │ ├── customers.csv.xlsx │ │ │ │ ├── employee_territories.csv.xlsx │ │ │ │ ├── employees.csv.xlsx │ │ │ │ ├── orders.csv.xlsx │ │ │ │ ├── orders_details.csv.xlsx │ │ │ │ ├── products.csv.xlsx │ │ │ │ ├── regions.csv.xlsx │ │ │ │ ├── shippers.csv.xlsx │ │ │ │ ├── suppliers.csv.xlsx │ │ │ │ └── territories.csv.xlsx │ │ └── images │ │ │ ├── agedb-favicon.ico.png │ │ │ └── northwind │ │ │ ├── Entity-Relationship-Diagram.png │ │ │ ├── Graphmodel.png │ │ │ ├── customer-orders.png │ │ │ ├── order-graph.png │ │ │ ├── product-category-supplier.png │ │ │ └── product-graph.png │ ├── robots.txt │ └── site.webmanifest └── src │ ├── App.css │ ├── App.jsx │ ├── app │ ├── reducers.js │ └── store.js │ ├── components │ ├── alert │ │ ├── containers │ │ │ └── AlertContainers.js │ │ └── presentations │ │ │ └── Alert.jsx │ ├── contents │ │ ├── containers │ │ │ ├── Contents.js │ │ │ ├── Editor.js │ │ │ └── Frames.js │ │ └── presentations │ │ │ ├── Contents.jsx │ │ │ ├── Contents.module.scss │ │ │ ├── Editor.jsx │ │ │ └── Frames.jsx │ ├── csv │ │ └── index.jsx │ ├── cypherresult │ │ ├── components │ │ │ ├── EdgeThicknessMenu.jsx │ │ │ ├── GraphFilterModal.jsx │ │ │ └── popover.module.scss │ │ ├── containers │ │ │ ├── CypherResultCytoscapeContainer.js │ │ │ ├── CypherResultMetaContainer.js │ │ │ ├── CypherResultTableContainer.js │ │ │ └── CypherResultTextContainer.js │ │ └── presentations │ │ │ ├── CypherResultCytoscape.jsx │ │ │ ├── CypherResultMeta.jsx │ │ │ ├── CypherResultTable.jsx │ │ │ └── CypherResultText.jsx │ ├── cytoscape │ │ ├── CypherResultCytoscapeChart.jsx │ │ ├── CypherResultCytoscapeFooter.jsx │ │ ├── CypherResultCytoscapeLegend.jsx │ │ ├── CypherResultTab.jsx │ │ ├── CytoscapeConfig.js │ │ ├── CytoscapeLayouts.js │ │ ├── CytoscapeStyleSheet.js │ │ └── MetadataCytoscapeChart.jsx │ ├── editor │ │ ├── containers │ │ │ ├── CodeMirrorWapperContainer.js │ │ │ └── SideBarMenuToggleContainer.js │ │ └── presentations │ │ │ ├── CodeMirror.scss │ │ │ ├── CodeMirrorWrapper.jsx │ │ │ └── SidebarMeunuToggle.jsx │ ├── frame │ │ ├── Frame.jsx │ │ ├── Frame.module.scss │ │ ├── containers │ │ │ ├── ContentsFrameContainer.js │ │ │ ├── CypherGraphResultContainers.js │ │ │ ├── CypherResultContainers.js │ │ │ ├── ServerConnectContainer.js │ │ │ ├── ServerDisconnectContainer.js │ │ │ └── ServerStatusContainer.js │ │ └── presentations │ │ │ ├── ContentsFrame.jsx │ │ │ ├── CypherGraphResultFrame.jsx │ │ │ ├── CypherResultFrame.jsx │ │ │ ├── ServerConnectFrame.jsx │ │ │ ├── ServerConnectFrame.module.scss │ │ │ ├── ServerDisconnectFrame.jsx │ │ │ └── ServerStatusFrame.jsx │ ├── initializer │ │ └── presentation │ │ │ ├── GraphInit.scss │ │ │ └── GraphInitializer.jsx │ ├── modal │ │ ├── containers │ │ │ ├── Modal.js │ │ │ └── Tutorial.js │ │ └── presentations │ │ │ ├── ModalDialog.jsx │ │ │ ├── TutorialBody.jsx │ │ │ ├── TutorialDialog.jsx │ │ │ ├── TutorialFooter.jsx │ │ │ └── TutorialHeader.jsx │ ├── navigator │ │ ├── containers │ │ │ └── Navigator.js │ │ └── presentations │ │ │ ├── Navigator.jsx │ │ │ └── NavigatorItem.jsx │ ├── query_builder │ │ ├── BuilderContainer.jsx │ │ ├── BuilderContainer.scss │ │ └── BuilderSelection.jsx │ ├── sidebar │ │ ├── containers │ │ │ ├── Sidebar.js │ │ │ ├── SidebarHome.js │ │ │ └── SidebarSetting.js │ │ └── presentations │ │ │ ├── Components.scss │ │ │ ├── Sidebar.jsx │ │ │ ├── SidebarComponents.jsx │ │ │ ├── SidebarHome.jsx │ │ │ └── SidebarSetting.jsx │ └── template │ │ ├── DefaultTemplate.js │ │ └── presentations │ │ ├── DefaultTemplate.jsx │ │ └── DefaultTemplate.scss │ ├── conf │ └── config.js │ ├── features │ ├── alert │ │ └── AlertSlice.js │ ├── capture │ │ └── Capture.js │ ├── cookie │ │ └── CookieUtil.js │ ├── cypher │ │ ├── CypherSlice.js │ │ └── CypherUtil.js │ ├── database │ │ ├── DatabaseSlice.js │ │ └── MetadataSlice.js │ ├── editor │ │ └── EditorSlice.js │ ├── frame │ │ └── FrameSlice.js │ ├── layout │ │ └── LayoutSlice.js │ ├── menu │ │ └── MenuSlice.js │ ├── modal │ │ └── ModalSlice.js │ ├── query_builder │ │ └── KeyWordFinder.js │ └── setting │ │ └── SettingSlice.js │ ├── icons │ ├── EdgeWeight.jsx │ ├── IconFilter.jsx │ ├── IconGraph.jsx │ ├── IconPlay.jsx │ └── IconSearchCancel.jsx │ ├── images │ ├── agce.gif │ ├── copy.png │ ├── graphCSV.png │ ├── graphMenu.png │ └── queryEditor.png │ ├── index.css │ ├── index.jsx │ ├── lib │ └── cytoscape-cxtmenu │ │ ├── LICENSE │ │ ├── assign.js │ │ ├── core │ │ └── index.js │ │ ├── cxtmenu.js │ │ ├── defaults.js │ │ ├── dom-util.js │ │ ├── index.js │ │ └── package.json │ ├── pages │ └── Main │ │ └── MainPage.jsx │ └── static │ ├── navbar-fixed-left.css │ └── style.css ├── package-lock.json └── package.json /.asf.yaml: -------------------------------------------------------------------------------- 1 | notifications: 2 | commits: commits@age.apache.org 3 | pullrequests: commits@age.apache.org 4 | 5 | github: 6 | description: "Graph database optimized for fast analysis and real-time data processing. 7 | It is provided as an extension to PostgreSQL." 8 | homepage: https://age.apache.org 9 | labels: 10 | - postgresql 11 | - graph-database 12 | - analytics 13 | - postgresql-extension 14 | - graphdb 15 | - multi-model-dbms 16 | - age-database 17 | features: 18 | wiki: true 19 | issues: true 20 | projects: true 21 | discussions: true 22 | 23 | enabled_merge_buttons: 24 | squash: true 25 | merge: false 26 | rebase: true 27 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | node_modules 20 | **/node_modules 21 | README* 22 | *.md 23 | .git 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | *.scss text eol=lf 20 | *.css text eol=lf 21 | 22 | *.js text eol=lf 23 | *.ts text eol=lf 24 | *.tsx text eol=lf 25 | *.jsx text eol=lf 26 | 27 | *.md text eol=lf 28 | 29 | *.java text eol=lf 30 | *.kt text eol=lf 31 | *.kts text eol=lf 32 | 33 | *.svg text eol=lf 34 | *.sh text eol=lf 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: AGEViewer build 2 | 3 | on: 4 | push: 5 | branches: [ main, develop ] 6 | pull_request: 7 | branches: [ main, develop ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [14.x] 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v2 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - run: npm install --global yarn 24 | - run: cd backend && yarn install --frozen-lockfile && yarn run build 25 | - run: cd frontend && yarn install --frozen-lockfile && yarn run build 26 | env: 27 | CI: false 28 | -------------------------------------------------------------------------------- /DISCLAIMER: -------------------------------------------------------------------------------- 1 | Apache AGE is an effort undergoing incubation at 2 | The Apache Software Foundation (ASF), sponsored by Apache Incubator PMC. 3 | 4 | Incubation is required of all newly accepted projects until a further review 5 | indicates that the infrastructure, communications, and decision making process 6 | have stabilized in a manner consistent with other successful ASF projects. 7 | 8 | While incubation status is not necessarily a reflection of the completeness 9 | or stability of the code, it does indicate that the project has yet to be fully 10 | endorsed by the ASF. 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14-alpine3.16 2 | 3 | RUN npm install pm2 4 | 5 | WORKDIR /src 6 | 7 | COPY . . 8 | 9 | RUN npm run setup 10 | 11 | CMD ["npm", "run", "start"] 12 | 13 | EXPOSE 3000 -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache AGE (incubating) 2 | Copyright 2021 The Apache Software Foundation. 3 | This product includes software developed at 4 | The Apache Software Foundation (http://www.apache.org/). 5 | 6 | 7 | Portions of Apache AGE were originally developed by Bitnine Co., Ltd. and were 8 | donated to the Apache Software Foundation. Copyright 2019-2020 Bitnine Co., Ltd. 9 | -------------------------------------------------------------------------------- /backend/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ], 5 | "plugins": [ 6 | [ 7 | "@babel/transform-runtime" 8 | ], 9 | "@babel/plugin-proposal-class-properties" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | # AGViewer Backend 2 | 3 | ### ENV 4 | - LOG_DIR -------------------------------------------------------------------------------- /backend/misc/graph_kw.csv: -------------------------------------------------------------------------------- 1 | ,MATCH,WITH,DELETE,CREATE,RETURN,ORDER BY,SKIP,LIMIT,SET,REMOVE,MERGE,AS,WHERE,DETACH 2 | MATCH,0,1,1,0,1,0,0,0,0,1,0,0,0,0 3 | WITH,0,0,0,0,0,1,0,0,0,0,0,1,1,0 4 | DELETE,0,0,0,0,0,0,0,0,0,0,0,0,0,0 5 | CREATE,0,0,0,0,1,0,0,0,0,0,0,0,0,0 6 | RETURN,0,0,0,0,1,0,0,0,0,0,0,0,0,0 7 | ORDER BY,0,0,0,0,1,0,1,1,0,0,0,0,0,0 8 | SKIP,0,0,0,0,0,0,0,0,0,0,0,0,0,0 9 | LIMIT,0,0,0,0,0,0,0,0,0,0,0,0,0,0 10 | SET,0,0,0,0,0,0,0,0,0,0,0,0,0,0 11 | REMOVE,0,0,0,0,0,0,0,0,0,0,0,0,0,0 12 | MERGE,0,0,0,0,1,0,0,0,0,0,0,0,0,0 13 | AS,0,0,0,0,0,0,0,0,0,0,0,0,0,0 14 | WHERE,0,0,0,0,0,0,0,0,0,0,0,0,0,0 15 | DETACH,0,0,1,0,0,0,0,0,0,0,0,0,0,0 16 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ag-viewer-backend", 3 | "version": "0.4.0", 4 | "private": true, 5 | "license": "Apache-2.0", 6 | "licenses": [ 7 | { 8 | "type": "Apache-2.0", 9 | "url": "https://www.apache.org/licenses/LICENSE-2.0" 10 | } 11 | ], 12 | "scripts": { 13 | "test": "mocha -r @babel/register --exit --timeout 100000", 14 | "test:ageParsing": "mocha -r @babel/register --exit --timeout 10000 ./test/ageParsing.test.js", 15 | "start": "babel-node src/bin/www", 16 | "start:dev": "nodemon --watch src/app.js --watch src/ --exec 'babel-node' src/bin/www", 17 | "build": "babel -d ./build ./src -s", 18 | "start:production": "node ./build/bin/www.js" 19 | }, 20 | "dependencies": { 21 | "antlr4": "4.9.3", 22 | "chai": "^4.3.7", 23 | "cookie-parser": "~1.4.5", 24 | "cors": "^2.8.5", 25 | "csv": "^5.5.0", 26 | "debug": "~4.3.1", 27 | "ejs": "^3.1.6", 28 | "express": "~4.17.1", 29 | "express-session": "^1.17.1", 30 | "http-status": "^1.5.0", 31 | "morgan": "~1.10.0", 32 | "multer": "^1.4.2", 33 | "npm-run-all": "^4.1.5", 34 | "papaparse": "^5.3.2", 35 | "pegjs": "^0.10.0", 36 | "pg": "^8.5.1", 37 | "pg-types": "^2.2.0", 38 | "uuid": "^8.3.2", 39 | "winston": "^3.3.3", 40 | "winston-daily-rotate-file": "^4.5.0" 41 | }, 42 | "devDependencies": { 43 | "@babel/cli": "^7.12.13", 44 | "@babel/core": "^7.12.13", 45 | "@babel/node": "^7.12.13", 46 | "@babel/plugin-proposal-class-properties": "^7.13.0", 47 | "@babel/plugin-transform-runtime": "^7.12.15", 48 | "@babel/preset-env": "^7.12.13", 49 | "@babel/register": "^7.12.13", 50 | "babel-plugin-polyfill-corejs2": "^0.2.0", 51 | "babel-plugin-polyfill-corejs3": "^0.2.0", 52 | "babel-plugin-polyfill-regenerator": "^0.2.0", 53 | "mocha": "^8.2.1", 54 | "nodemon": "^2.0.7", 55 | "supertest": "^6.0.1", 56 | "supertest-session": "^4.1.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /backend/sql/11/meta_data.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM ( 2 | SELECT c.relname AS label, n.oid as namespace_id, c.reltuples AS cnt 3 | FROM pg_catalog.pg_class c 4 | JOIN pg_catalog.pg_namespace n 5 | ON n.oid = c.relnamespace 6 | WHERE c.relkind = 'r' 7 | AND n.nspname = '%s' 8 | ) as q1 9 | JOIN ag_graph as g ON q1.namespace_id = g.namespace 10 | INNER JOIN ag_label as label 11 | 12 | ON label.name = q1.label 13 | AND label.graph = g.oid; 14 | -------------------------------------------------------------------------------- /backend/sql/12/meta_data.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM ( 2 | SELECT c.relname AS label, n.oid as namespace_id, c.reltuples AS cnt 3 | FROM pg_catalog.pg_class c 4 | JOIN pg_catalog.pg_namespace n 5 | ON n.oid = c.relnamespace 6 | WHERE c.relkind = 'r' 7 | AND n.nspname = '%s' 8 | ) as q1 9 | JOIN ag_graph as g ON q1.namespace_id = g.namespace 10 | INNER JOIN ag_label as label 11 | 12 | ON label.name = q1.label 13 | AND label.graph = g.graphid; 14 | -------------------------------------------------------------------------------- /backend/sql/13/meta_data.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM ( 2 | SELECT c.relname AS label, n.oid as namespace_id, c.reltuples AS cnt 3 | FROM pg_catalog.pg_class c 4 | JOIN pg_catalog.pg_namespace n 5 | ON n.oid = c.relnamespace 6 | WHERE c.relkind = 'r' 7 | AND n.nspname = '%s' 8 | ) as q1 9 | JOIN ag_graph as g ON q1.namespace_id = g.namespace 10 | INNER JOIN ag_label as label 11 | 12 | ON label.name = q1.label 13 | AND label.graph = g.graphid; 14 | -------------------------------------------------------------------------------- /backend/sql/14/meta_data.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM ( 2 | SELECT c.relname AS label, n.oid as namespace_id, c.reltuples AS cnt 3 | FROM pg_catalog.pg_class c 4 | JOIN pg_catalog.pg_namespace n 5 | ON n.oid = c.relnamespace 6 | WHERE c.relkind = 'r' 7 | AND n.nspname = '%s' 8 | ) as q1 9 | JOIN ag_graph as g ON q1.namespace_id = g.namespace 10 | INNER JOIN ag_label as label 11 | 12 | ON label.name = q1.label 13 | AND label.graph = g.graphid; 14 | -------------------------------------------------------------------------------- /backend/sql/15/meta_data.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM ( 2 | SELECT c.relname AS label, n.oid as namespace_id, c.reltuples AS cnt 3 | FROM pg_catalog.pg_class c 4 | JOIN pg_catalog.pg_namespace n 5 | ON n.oid = c.relnamespace 6 | WHERE c.relkind = 'r' 7 | AND n.nspname = '%s' 8 | ) as q1 9 | JOIN ag_graph as g ON q1.namespace_id = g.namespace 10 | INNER JOIN ag_label as label 11 | 12 | ON label.name = q1.label 13 | AND label.graph = g.graphid; 14 | -------------------------------------------------------------------------------- /backend/sql/analyze_graph.sql: -------------------------------------------------------------------------------- 1 | ANALYZE; -------------------------------------------------------------------------------- /backend/sql/get_graph_names.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM ag_catalog.ag_graph; 2 | -------------------------------------------------------------------------------- /backend/sql/get_role.sql: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | SELECT usename as user_name, 21 | CASE 22 | WHEN usesuper THEN 23 | CAST('admin' AS pg_catalog.text) 24 | ELSE 25 | CAST('user' AS pg_catalog.text) 26 | END role_name 27 | FROM pg_catalog.pg_user 28 | WHERE usename = $1 29 | -------------------------------------------------------------------------------- /backend/sql/graph_labels.sql: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | SELECT oid as la_oid, name as la_name, kind as la_kind FROM ag_catalog.ag_label; 21 | -------------------------------------------------------------------------------- /backend/sql/meta_edges.sql: -------------------------------------------------------------------------------- 1 | SELECT label, count(label)::INTEGER as cnt 2 | FROM ( 3 | SELECT ag_catalog._label_name(oid, v)::text as label 4 | from cypher('%s', $$ 5 | MATCH ()-[V]-() 6 | RETURN id(V) 7 | $$) as (V agtype), (SELECT oid FROM ag_catalog.ag_graph where name = '%s') as oid 8 | ) b 9 | GROUP BY b.label; 10 | 11 | /* 12 | * Licensed to the Apache Software Foundation (ASF) under one 13 | * or more contributor license agreements. See the NOTICE file 14 | * distributed with this work for additional information 15 | * regarding copyright ownership. The ASF licenses this file 16 | * to you under the Apache License, Version 2.0 (the 17 | * "License"); you may not use this file except in compliance 18 | * with the License. You may obtain a copy of the License at 19 | * 20 | * http://www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, 23 | * software distributed under the License is distributed on an 24 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 25 | * KIND, either express or implied. See the License for the 26 | * specific language governing permissions and limitations 27 | * under the License. 28 | */ 29 | 30 | -- TODO: COUNT needs AGE supporting or Client-side processing. 31 | -------------------------------------------------------------------------------- /backend/sql/meta_nodes.sql: -------------------------------------------------------------------------------- 1 | SELECT label, count(label)::INTEGER as cnt 2 | FROM ( 3 | SELECT ag_catalog._label_name(oid, v)::text as label 4 | from cypher('%s', $$ 5 | MATCH (V:_ag_label_vertex) 6 | RETURN id(V) 7 | $$) as (V agtype), (SELECT oid FROM ag_catalog.ag_graph where name = '%s') as oid 8 | ) b 9 | GROUP BY b.label; 10 | 11 | /* 12 | * Licensed to the Apache Software Foundation (ASF) under one 13 | * or more contributor license agreements. See the NOTICE file 14 | * distributed with this work for additional information 15 | * regarding copyright ownership. The ASF licenses this file 16 | * to you under the Apache License, Version 2.0 (the 17 | * "License"); you may not use this file except in compliance 18 | * with the License. You may obtain a copy of the License at 19 | * 20 | * http://www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, 23 | * software distributed under the License is distributed on an 24 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 25 | * KIND, either express or implied. See the License for the 26 | * specific language governing permissions and limitations 27 | * under the License. 28 | */ 29 | 30 | -- TODO: COUNT needs AGE supporting or Client-side processing. 31 | -------------------------------------------------------------------------------- /backend/sql/pg_version.sql: -------------------------------------------------------------------------------- 1 | show server_version; 2 | -------------------------------------------------------------------------------- /backend/sql/property_keys.sql: -------------------------------------------------------------------------------- 1 | select * from (SELECT null as key, null as keytype) A limit 0; 2 | 3 | /* 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | -- TODO: need AGE Supporting. 23 | -------------------------------------------------------------------------------- /backend/src/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | const express = require('express'); 20 | const cors = require('cors'); 21 | const session = require('express-session'); 22 | const uuid = require('uuid'); 23 | const path = require('path'); 24 | const cookieParser = require('cookie-parser'); 25 | const logger = require('morgan'); 26 | const {stream} = require('./config/winston'); 27 | const cypherRouter = require('./routes/cypherRouter'); 28 | const databaseRouter = require('./routes/databaseRouter'); 29 | const sessionRouter = require('./routes/sessionRouter'); 30 | const miscellaneousRouter = require('./routes/miscellaneous'); 31 | const app = express(); 32 | 33 | app.use(cors({ 34 | origin: true, 35 | credentials: true 36 | })) 37 | app.use(express.static(path.join(__dirname, '../../frontend/build'))); 38 | app.get('/', function (req, res) { 39 | res.sendFile(path.join(__dirname, '../../frontend/build', 'index.html')); 40 | }); 41 | 42 | app.use( 43 | session({ 44 | secret: 'apache-age-viewer', 45 | secure: true, 46 | resave: false, 47 | saveUninitialized: true, 48 | proxy: true, 49 | genid: (req) => { 50 | return uuid.v4(); 51 | }, 52 | }) 53 | ); 54 | app.use(logger('common', {stream})); 55 | app.use(express.json()); 56 | app.use(express.urlencoded({extended: false})); 57 | app.use(cookieParser()); 58 | 59 | app.use('/api/v1/*', sessionRouter); 60 | app.use('/api/v1/miscellaneous', miscellaneousRouter); 61 | app.use('/api/v1/cypher', cypherRouter); 62 | app.use('/api/v1/db', databaseRouter); 63 | 64 | // Error Handler 65 | app.use(function (err, req, res, next) { 66 | // TODO: logger 67 | console.error(err); 68 | res.status(err.status || 500).json( 69 | { 70 | severity: err.severity || '', 71 | message: err.message || '', 72 | code: err.code || '' 73 | } 74 | ); 75 | }); 76 | 77 | process.on('uncaughtException', function (exception) { 78 | console.log(exception); 79 | }); 80 | 81 | module.exports = app; 82 | -------------------------------------------------------------------------------- /backend/src/bin/www.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | /** 23 | * Module dependencies. 24 | */ 25 | const app = require('../app'); 26 | const debug = require('debug')('ag-viewer:server'); 27 | const http = require('http'); 28 | 29 | /** 30 | * Get port from environment and store in Express. 31 | */ 32 | const port = normalizePort(process.env.PORT || '3001'); 33 | app.set('port', port); 34 | 35 | /** 36 | * Create HTTP server. 37 | */ 38 | const server = http.createServer(app); 39 | 40 | /** 41 | * Listen on provided port, on all network interfaces. 42 | */ 43 | 44 | server.listen(port); 45 | server.on('error', onError); 46 | server.on('listening', onListening); 47 | 48 | /** 49 | * Normalize a port into a number, string, or false. 50 | */ 51 | 52 | function normalizePort(val) { 53 | const port = parseInt(val, 10); 54 | 55 | if (isNaN(port)) { 56 | // named pipe 57 | return val; 58 | } 59 | 60 | if (port >= 0) { 61 | // port number 62 | return port; 63 | } 64 | 65 | return false; 66 | } 67 | 68 | /** 69 | * Event listener for HTTP server "error" event. 70 | */ 71 | 72 | function onError(error) { 73 | if (error.syscall !== 'listen') { 74 | throw error; 75 | } 76 | 77 | const bind = typeof port === 'string' 78 | ? 'Pipe ' + port 79 | : 'Port ' + port; 80 | 81 | // handle specific listen errors with friendly messages 82 | switch (error.code) { 83 | case 'EACCES': 84 | console.error(bind + ' requires elevated privileges'); 85 | process.exit(1); 86 | break; 87 | case 'EADDRINUSE': 88 | console.error(bind + ' is already in use'); 89 | process.exit(1); 90 | break; 91 | default: 92 | throw error; 93 | } 94 | } 95 | 96 | /** 97 | * Event listener for HTTP server "listening" event. 98 | */ 99 | 100 | function onListening() { 101 | const addr = server.address(); 102 | const bind = typeof addr === 'string' 103 | ? 'pipe ' + addr 104 | : 'port ' + addr.port; 105 | debug('Listening on ' + bind); 106 | } 107 | -------------------------------------------------------------------------------- /backend/src/common/Routes.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | export function wrap(asyncFn) { 21 | return (async (req, res, next) => { 22 | try { 23 | return await asyncFn(req, res, next) 24 | } catch (error) { 25 | return next(error) 26 | } 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /backend/src/config/Flavors.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | export default { 21 | AGE: 'AGE' 22 | } 23 | -------------------------------------------------------------------------------- /backend/src/config/Pg.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | export default { 21 | // all valid client config options are also valid here 22 | // in addition here are the pool specific configuration parameters: 23 | // number of milliseconds to wait before timing out when connecting a new client 24 | // by default this is 0 which means no timeout 25 | connectionTimeoutMillis: 2000, 26 | // number of milliseconds a client must sit idle in the pool and not be checked out 27 | // before it is disconnected from the backend and discarded 28 | // default is 10000 (10 seconds) - set to 0 to disable auto-disconnection of idle clients 29 | idleTimeoutMillis: 30000, 30 | // maximum number of clients the pool should contain 31 | // by default this is set to 10. 32 | max: 10, 33 | } 34 | -------------------------------------------------------------------------------- /backend/src/config/winston.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | const fs = require('fs'); 20 | const winston = require('winston'); 21 | const winstonDaily = require('winston-daily-rotate-file'); 22 | 23 | const logDir = process.env.LOG_DIR || 'logs'; 24 | const { combine, timestamp, printf } = winston.format; 25 | 26 | const logFormat = printf((info) => { 27 | return `${info.timestamp} ${info.level}: ${info.message}`; 28 | }); 29 | 30 | if (!fs.existsSync(logDir)) { 31 | fs.mkdirSync(logDir); 32 | } 33 | 34 | const infoTransport = new winstonDaily({ 35 | level: 'info', 36 | datePattern: 'YYYY-MM-DD', 37 | dirname: logDir, 38 | filename: 'info.%DATE%.log', 39 | maxFiles: 15, 40 | zippedArchive: true, 41 | }); 42 | 43 | const errorTransport = new winstonDaily({ 44 | level: 'error', 45 | datePattern: 'YYYY-MM-DD', 46 | dirname: logDir + '/error', 47 | filename: 'error.%DATE%.log', 48 | maxFiles: 15, 49 | zippedArchive: true, 50 | }); 51 | 52 | const logger = winston.createLogger({ 53 | format: combine( 54 | timestamp({ 55 | format: 'YYYY-MM-DD HH:mm:ss', 56 | }), 57 | logFormat 58 | ), 59 | transports: [infoTransport, errorTransport], 60 | }); 61 | 62 | const stream = { 63 | write: (message) => { 64 | logger.info(message); 65 | }, 66 | }; 67 | 68 | if (process.env.NODE_ENV !== 'production') { 69 | logger.add( 70 | new winston.transports.Console({ 71 | format: winston.format.combine(winston.format.colorize(), winston.format.simple()), 72 | }) 73 | ); 74 | } 75 | 76 | module.exports = { logger, stream }; 77 | -------------------------------------------------------------------------------- /backend/src/models/QueryBuilder.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | class QueryBuilder { 4 | 5 | constructor({graphName, returnAs='x'}={}){ 6 | this._graphName = graphName; 7 | this.ends = { 8 | start:`SELECT * FROM cypher('${this._graphName}', $$`, 9 | end:`$$) as (${returnAs} agtype);` 10 | }; 11 | this.clause = ''; 12 | this.middle = []; 13 | } 14 | 15 | startQuery(startQuery){ 16 | this.ends.start = startQuery; 17 | } 18 | 19 | insertQuery(clause){ 20 | this.middle.push(clause); 21 | } 22 | create(){ 23 | this.clause = 'CREATE ' 24 | } 25 | endQuery(endQuery){ 26 | this.ends.end = endQuery; 27 | } 28 | 29 | getGeneratedQuery(){ 30 | return (( 31 | this.ends.start + 32 | this.clause + 33 | this.middle.join(', ')+ 34 | this.ends.end).trim()); 35 | } 36 | } 37 | 38 | module.exports = QueryBuilder; -------------------------------------------------------------------------------- /backend/src/routes/cypherRouter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | const express = require("express"); 21 | const CypherController = require("../controllers/cypherController"); 22 | const multer = require('multer'); 23 | const storage = multer.memoryStorage(); 24 | const upload = multer({storage}); 25 | const router = express.Router(); 26 | const cypherController = new CypherController(); 27 | 28 | const {wrap} = require('../common/Routes'); 29 | 30 | // Execute Cypher Query 31 | router.post("/", wrap(cypherController.executeCypher)); 32 | router.post("/init", upload.fields([{name:"edges"}, {name:"nodes"}]), wrap(cypherController.createGraph)); 33 | 34 | module.exports = router; 35 | -------------------------------------------------------------------------------- /backend/src/routes/databaseRouter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | const express = require("express"); 20 | const DatabaseController = require('../controllers/databaseController') 21 | const router = express.Router(); 22 | const databaseController = new DatabaseController(); 23 | 24 | const {wrap} = require('../common/Routes'); 25 | // Get connection status 26 | router.get("/", wrap(databaseController.getStatus)); 27 | router.post("/connect", wrap(databaseController.connectDatabase)); 28 | router.get("/disconnect", wrap(databaseController.disconnectDatabase)); 29 | router.post("/meta", wrap(databaseController.getMetadata)); 30 | router.get("/metaChart", wrap(databaseController.getMetaChart)); 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /backend/src/routes/miscellaneous.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { wrap } = require('../common/Routes'); 3 | const getQueryList = require('../services/queryList'); 4 | const router = express.Router(); 5 | 6 | 7 | router.get('/', wrap(getQueryList)); 8 | 9 | module.exports = router; -------------------------------------------------------------------------------- /backend/src/routes/sessionRouter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | const DatabaseService = require('../services/databaseService'); 21 | const sessionService = require('../services/sessionService'); 22 | 23 | function sessionRouter(req, res, next) { 24 | if (sessionService.get(req.sessionID) == null) { 25 | sessionService.put(req.sessionID, new DatabaseService()); 26 | } 27 | next(); 28 | } 29 | 30 | module.exports = sessionRouter; 31 | -------------------------------------------------------------------------------- /backend/src/services/queryList.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs').promises; 2 | const papa = require('papaparse'); 3 | const path = require('path'); 4 | 5 | 6 | const readCSV = (file, resolve, reject)=>{ 7 | return papa.parse(file, { 8 | skipEmptyLines:true, 9 | transform:(val, col)=>{ 10 | if (col !== 0) return val; 11 | 12 | }, 13 | complete:(results)=>{ 14 | resolve(results); 15 | }, 16 | error:(err)=>{ 17 | reject(err); 18 | }, 19 | }); 20 | } 21 | const getQueryList = async (req, res, next)=>{ 22 | const p = path.join(__dirname, "../../misc/graph_kw.csv"); 23 | const file = await fs.readFile(p, { 24 | encoding: 'utf-8' 25 | }); 26 | 27 | const results = await new Promise((resolve, reject)=>{ 28 | readCSV(file, resolve, reject); 29 | }); 30 | 31 | const kwResults = { 32 | kw:results.data[0].splice(1), 33 | relationships:results.data.slice(1) 34 | } 35 | res.status(200).json(kwResults).end(); 36 | 37 | } 38 | module.exports = getQueryList; -------------------------------------------------------------------------------- /backend/src/services/sessionService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | class SessionService { 21 | constructor() { 22 | this._sessionMap = new Map(); 23 | } 24 | 25 | put(key, value) { 26 | this._sessionMap.set(key, value); 27 | } 28 | 29 | get(key) { 30 | if(!this._sessionMap.get(key)) { 31 | return null; 32 | } 33 | return this._sessionMap.get(key); 34 | } 35 | } 36 | const sessionService = new SessionService(); 37 | 38 | module.exports = sessionService; 39 | -------------------------------------------------------------------------------- /backend/src/tools/AGEParser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import antlr4 from 'antlr4'; 21 | import { cli } from 'winston/lib/winston/config'; 22 | import AgtypeLexer from './AgtypeLexer'; 23 | import AgtypeParser from './AgtypeParser'; 24 | import CustomAgTypeListener from './CustomAgTypeListener'; 25 | 26 | function AGTypeParse(input) { 27 | const chars = new antlr4.InputStream(input); 28 | const lexer = new AgtypeLexer(chars); 29 | const tokens = new antlr4.CommonTokenStream(lexer); 30 | const parser = new AgtypeParser(tokens); 31 | parser.buildParseTrees = true; 32 | const tree = parser.agType(); 33 | const printer = new CustomAgTypeListener(); 34 | antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree); 35 | return printer.getResult(); 36 | } 37 | 38 | async function setAGETypes(client, types) { 39 | await client.query(` 40 | CREATE EXTENSION IF NOT EXISTS age; 41 | LOAD 'age'; 42 | SET search_path = ag_catalog, "$user", public; 43 | `) 44 | 45 | const oidResults = await client.query(` 46 | select typelem 47 | from pg_type 48 | where typname = '_agtype';`); 49 | 50 | if (oidResults.rows.length < 1) 51 | throw new Error(); 52 | 53 | types.setTypeParser(oidResults.rows[0].typelem, AGTypeParse) 54 | } 55 | 56 | async function onConnectQueries(client){ 57 | const v = await client.query('show server_version;'); 58 | return {server_version: v.rows[0].server_version}; 59 | } 60 | 61 | export {setAGETypes, AGTypeParse, onConnectQueries} 62 | -------------------------------------------------------------------------------- /backend/src/tools/Agtype.g4: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | grammar Agtype; 19 | 20 | agType 21 | : agValue EOF 22 | ; 23 | 24 | agValue 25 | : value typeAnnotation? 26 | ; 27 | 28 | value 29 | : STRING #StringValue 30 | | INTEGER #IntegerValue 31 | | floatLiteral #FloatValue 32 | | 'true' #TrueBoolean 33 | | 'false' #FalseBoolean 34 | | 'null' #NullValue 35 | | obj #ObjectValue 36 | | array #ArrayValue 37 | ; 38 | 39 | obj 40 | : '{' pair (',' pair)* '}' 41 | | '{' '}' 42 | ; 43 | 44 | pair 45 | : STRING ':' agValue 46 | ; 47 | 48 | array 49 | : '[' agValue (',' agValue)* ']' 50 | | '[' ']' 51 | ; 52 | 53 | typeAnnotation 54 | : '::' IDENT 55 | ; 56 | 57 | IDENT 58 | : [A-Z_a-z][$0-9A-Z_a-z]* 59 | ; 60 | 61 | STRING 62 | : '"' (ESC | SAFECODEPOINT)* '"' 63 | ; 64 | 65 | fragment ESC 66 | : '\\' (["\\/bfnrt] | UNICODE) 67 | ; 68 | 69 | fragment UNICODE 70 | : 'u' HEX HEX HEX HEX 71 | ; 72 | 73 | fragment HEX 74 | : [0-9a-fA-F] 75 | ; 76 | 77 | fragment SAFECODEPOINT 78 | : ~ ["\\\u0000-\u001F] 79 | ; 80 | 81 | INTEGER 82 | : '-'? INT 83 | ; 84 | 85 | fragment INT 86 | : '0' | [1-9] [0-9]* 87 | ; 88 | 89 | floatLiteral 90 | : RegularFloat 91 | | ExponentFloat 92 | | '-'? 'Infinity' 93 | | 'NaN' 94 | ; 95 | 96 | RegularFloat 97 | : '-'? INT DECIMAL 98 | ; 99 | 100 | ExponentFloat 101 | : '-'? INT DECIMAL? SCIENTIFIC 102 | ; 103 | 104 | fragment DECIMAL 105 | : '.' [0-9]+ 106 | ; 107 | 108 | fragment SCIENTIFIC 109 | : [Ee][+-]? [0-9]+ 110 | ; 111 | 112 | WS 113 | : [ \t\n\r] + -> skip 114 | ; 115 | -------------------------------------------------------------------------------- /backend/src/tools/SQLFlavorManager.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | import * as path from "path"; 20 | import fs from 'fs' 21 | 22 | const sqlBasePath = path.join(__dirname, '../../sql'); 23 | 24 | // todo: util.format -> ejs 25 | function getQuery(name, version='') { 26 | const sqlPath = path.join(sqlBasePath, version, `${name}.sql`); 27 | if (!fs.existsSync(sqlPath)) { 28 | throw new Error(`SQL does not exist, name = ${name}`); 29 | } 30 | return fs.readFileSync(sqlPath, 'utf8'); 31 | } 32 | 33 | export {getQuery} 34 | -------------------------------------------------------------------------------- /backend/src/util/JsonBuilder.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | export function stringWrap(valstr, flavor) { 21 | return JSON.stringify(valstr); 22 | } 23 | 24 | export function JsonStringify(flavor, record) { 25 | let ageJsonStr = '{'; 26 | let isFirst = true; 27 | for (const [key, value] of Object.entries(record)) { 28 | if (!isFirst) { 29 | ageJsonStr = ageJsonStr + ','; 30 | } 31 | let valueWrapped = stringWrap(value, flavor); 32 | ageJsonStr = ageJsonStr + `${key}:${valueWrapped}`; 33 | isFirst = false; 34 | } 35 | ageJsonStr = ageJsonStr + '}'; 36 | return ageJsonStr; 37 | } 38 | 39 | export async function createVertex(client, graphPathStr, label, record, flavor) { 40 | const createQ = `CREATE (n:${label} ${JsonStringify(flavor, record)})`; 41 | if (flavor === 'AGE') { 42 | return AGECreateVertex(client, graphPathStr, createQ); 43 | } else { 44 | throw new Error(`Unknown flavor ${flavor}`) 45 | } 46 | } 47 | 48 | async function AGECreateVertex(client, graphPathStr, createQ) { 49 | await client.query( 50 | `select * 51 | from cypher('${graphPathStr}', $$ ${createQ} $$) as (a agtype)`); 52 | } 53 | 54 | export async function createEdge(client, label, record, graphPathStr, edgeStartLabel, edgeEndLabel, startNodeName, endNodeName, flavor) { 55 | const createQ = `CREATE (:${edgeStartLabel} {name: ${stringWrap(startNodeName, flavor)}})-[n:${label} ${JsonStringify(flavor, record)}]->(:${edgeEndLabel} {name: ${stringWrap(endNodeName, flavor)}})`; 56 | if (flavor === 'AGE') { 57 | return AGECreateEdge(client, graphPathStr, createQ); 58 | } else { 59 | throw new Error(`Unknown flavor ${flavor}`) 60 | } 61 | } 62 | 63 | async function AGECreateEdge(client, graphPathStr, createQ) { 64 | await client.query( 65 | `select * 66 | from cypher('${graphPathStr}', $$ ${createQ} $$) as (a agtype)`); 67 | } 68 | -------------------------------------------------------------------------------- /backend/src/util/ObjectExtras.js: -------------------------------------------------------------------------------- 1 | const getDelete = (ob, name)=>{ 2 | const val = ob[name]; 3 | delete ob[name]; 4 | return val; 5 | }; 6 | const toAgeProps = (data, empty=false)=>{ 7 | let props = []; 8 | Object.entries(data).forEach(([k, v])=>{ 9 | let val = typeof v === 'string' ? `'${v}'` : v; 10 | props.push(`${k}:${val}`); 11 | }); 12 | if (!empty && Object.keys(data).length === 0) return ''; 13 | return `{${props.join(', ')}}`; 14 | } 15 | 16 | module.exports = { 17 | getDelete, 18 | toAgeProps 19 | } 20 | -------------------------------------------------------------------------------- /backend/test/Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM postgres:11-buster 3 | 4 | RUN apt-get update 5 | RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \ 6 | bison \ 7 | build-essential \ 8 | flex \ 9 | ca-certificates\ 10 | git \ 11 | postgresql-server-dev-11 12 | RUN git clone https://github.com/apache/age.git 13 | RUN cd /age && make install 14 | 15 | COPY docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/ 16 | EXPOSE 5432 17 | CMD ["postgres", "-c", "shared_preload_libraries=age"] -------------------------------------------------------------------------------- /backend/test/README.md: -------------------------------------------------------------------------------- 1 | For integration tests involving db: 2 | docker compose up 3 | -------------------------------------------------------------------------------- /backend/test/ageUtil.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const {toAgeProps} = require('../src/util/ObjectExtras'); 3 | 4 | describe('object serialize', ()=>{ 5 | it('serialize basic', ()=>{ 6 | let serial = toAgeProps({'id':2,'name':'hi'}); 7 | assert.equal(serial, "{id:2, name:'hi'}"); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /backend/test/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | postgres: 3 | build: . 4 | ports: 5 | - 5432:5432 6 | environment: 7 | POSTGRES_USER: 'TEST' 8 | POSTGRES_DB: 'TEST' 9 | POSTGRES_PASSWORD: 'TEST' -------------------------------------------------------------------------------- /backend/test/docker-entrypoint-initdb.d/00-create-extension-age.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | -- 18 | 19 | CREATE EXTENSION age; 20 | 21 | -------------------------------------------------------------------------------- /backend/test/docker-entrypoint-initdb.d/01-create-user.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | -- 18 | 19 | CREATE USER TEST WITH PASSWORD 'TEST' CREATEDB; -------------------------------------------------------------------------------- /backend/test/docker-entrypoint-initdb.d/02-create-db.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, software 13 | -- distributed under the License is distributed on an "AS IS" BASIS, 14 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | -- See the License for the specific language governing permissions and 16 | -- limitations under the License. 17 | -- 18 | 19 | CREATE DATABASE TEST; -------------------------------------------------------------------------------- /backend/test/graphCreate.test.js: -------------------------------------------------------------------------------- 1 | const app = require('../src/app'); 2 | const { queries } = require('./test-queries/queries'); 3 | const { connectionForm } = require('./testDB'); 4 | const pathCreate = require('path'); 5 | const request = require('supertest'); 6 | const expect = require('chai').expect; 7 | const agent = request.agent(app); 8 | request.Test.prototype.attachMultiple = function(files, key){ 9 | files.forEach(([name, path])=>{ 10 | this.attach(key, path, name); 11 | }); 12 | return this; 13 | } 14 | 15 | const START_PATH = '/api/v1' 16 | 17 | describe('Graph Creation', ()=>{ 18 | const path = `${START_PATH}/db/connect` 19 | before((done)=>{ 20 | 21 | agent 22 | .post(path) 23 | .send({...connectionForm}) 24 | .end((err, res)=>{ 25 | expect(err).to.be.null; 26 | expect(res).property('status').to.equal(200) 27 | done(); 28 | }); 29 | 30 | }); 31 | 32 | 33 | 34 | it('creates a graph', (done)=>{ 35 | const urlPath = `${START_PATH}/cypher/init` 36 | const nodesFilePath = [['Make', getPathForFile('make.csv')],['Model', getPathForFile('model.csv')]] 37 | const edgesFilePath = [['has_model', getPathForFile('has_model.csv')]] 38 | const formData = { 39 | nodes:nodesFilePath, 40 | edges:edgesFilePath, 41 | graphName:connectionForm.database, 42 | dropGraph:'true' 43 | } 44 | agent 45 | .post(urlPath) 46 | .field('graphName', formData.graphName) 47 | .field('dropGraph', formData.dropGraph) 48 | .attachMultiple(nodesFilePath, 'nodes') 49 | .attachMultiple(edgesFilePath, 'edges') 50 | .end((err, res)=>{ 51 | expect(err).to.be.null; 52 | expect(res.status).to.equal(204); 53 | 54 | done(); 55 | }); 56 | }); 57 | after((done)=>{ 58 | const urlPath = `${START_PATH}/cypher` 59 | const query = queries.drop_graph(connectionForm.database, true, (s)=>{ 60 | return {cmd: s} 61 | }) 62 | agent 63 | .post(urlPath) 64 | .send(query) 65 | .expect(200) 66 | .end(done) 67 | }) 68 | 69 | }); 70 | 71 | function getPathForFile(fname){ 72 | const dataPath = 'test-data' 73 | return pathCreate.join(__dirname, dataPath, fname); 74 | } -------------------------------------------------------------------------------- /backend/test/test-data/has_model.csv: -------------------------------------------------------------------------------- 1 | start_id,start_vertex_type,end_id,end_vertex_type,type 2 | 1,Make,1,Model,S 3 | 1,Make,2,Model,S 4 | 2,Make,6,Model,S 5 | 3,Make,4,Model,A 6 | 4,Make,3,Model,A 7 | 5,Make,5,Model,A 8 | -------------------------------------------------------------------------------- /backend/test/test-data/make.csv: -------------------------------------------------------------------------------- 1 | id,name 2 | 1,Ferrari 3 | 2,Lamborghini 4 | 3,Toyota 5 | 4,Tesla 6 | 5,Nissan 7 | -------------------------------------------------------------------------------- /backend/test/test-data/model.csv: -------------------------------------------------------------------------------- 1 | id,name,price 2 | 1,488,300000 3 | 2,458,190000 4 | 3,S,100000 5 | 4,Supra,70000 6 | 5,GTR,100000 7 | 6,Aventador,500000 8 | -------------------------------------------------------------------------------- /backend/test/test-queries/queries.js: -------------------------------------------------------------------------------- 1 | export const queries = { 2 | drop_graph:(graph, cascade=false, cb=null)=>{ 3 | const q = `SELECT * FROM drop_graph('${graph}', ${cascade})` 4 | if (cb){ 5 | return cb(q) 6 | } 7 | return q 8 | } 9 | } -------------------------------------------------------------------------------- /backend/test/testDB.js: -------------------------------------------------------------------------------- 1 | const connectionForm = { 2 | 'host':"localhost", 3 | 'port':"5432", 4 | 'database':"TEST", 5 | 'user':"TEST", 6 | 'password':"TEST" 7 | 8 | } 9 | 10 | export {connectionForm}; -------------------------------------------------------------------------------- /ecosystem.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | module.exports = { 21 | apps: [{ 22 | name: "ag-viewer", 23 | namespace: "ag-viewer", 24 | script: "cd backend && node ./build/bin/www", 25 | watch: false, 26 | env: { 27 | name: "ag-viewer-develop", 28 | PORT: 3001, 29 | NODE_ENV: "develop", 30 | }, 31 | env_release: { 32 | name: "ag-viewer-release", 33 | PORT: 4000, 34 | NODE_ENV: "release", 35 | } 36 | }], 37 | deploy: { 38 | staging: { 39 | 'post-deploy': 'npm install && npm run setup && npm run build-front && pm2 reload ecosystem.config.js' 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /frontend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | module.exports = { 21 | env: { 22 | browser: true, 23 | es2021: true, 24 | }, 25 | extends: [ 26 | 'eslint:recommended', 27 | 'plugin:react/recommended', 28 | 'airbnb', 29 | ], 30 | parserOptions: { 31 | ecmaFeatures: { 32 | jsx: true, 33 | }, 34 | ecmaVersion: 12, 35 | sourceType: 'module', 36 | }, 37 | plugins: ['babel', 'react', 'import', 'react-hooks'], 38 | rules: { 39 | 'linebreak-style': 0, // fow winodw user 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | /build 20 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ag-viewer-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "license": "Apache-2.0", 6 | "licenses": [ 7 | { 8 | "type": "Apache-2.0", 9 | "url": "https://www.apache.org/licenses/LICENSE-2.0" 10 | } 11 | ], 12 | "dependencies": { 13 | "@fortawesome/fontawesome-svg-core": "^1.2.34", 14 | "@fortawesome/free-brands-svg-icons": "^5.15.2", 15 | "@fortawesome/free-regular-svg-icons": "^5.15.2", 16 | "@fortawesome/free-solid-svg-icons": "^5.15.2", 17 | "@fortawesome/react-fontawesome": "^0.1.14", 18 | "@reduxjs/toolkit": "^1.5.0", 19 | "@uiw/react-codemirror": "3.0.5", 20 | "antd": "^4.12.3", 21 | "ascii-table": "0.0.9", 22 | "axios": "^0.21.1", 23 | "bootstrap": "^4.6.0", 24 | "codemirror": "5.59.0", 25 | "cytoscape": "^3.18.0", 26 | "cytoscape-avsdf": "^1.0.0", 27 | "cytoscape-cise": "^1.0.0", 28 | "cytoscape-cola": "^2.4.0", 29 | "cytoscape-cose-bilkent": "^4.1.0", 30 | "cytoscape-d3-force": "^1.1.4", 31 | "cytoscape-dagre": "^2.3.2", 32 | "cytoscape-euler": "^1.2.2", 33 | "cytoscape-fcose": "^2.0.0", 34 | "cytoscape-klay": "^3.1.4", 35 | "cytoscape-spread": "^3.0.0", 36 | "file-saver": "^2.0.5", 37 | "json2csv": "^5.0.6", 38 | "papaparse": "^5.3.2", 39 | "prop-types": "^15.7.2", 40 | "react": "^17.0.2", 41 | "react-bootstrap": "^1.4.3", 42 | "react-cookies": "^0.1.1", 43 | "react-cytoscapejs": "^1.2.1", 44 | "react-dom": "^17.0.2", 45 | "react-redux": "^7.2.4", 46 | "react-scripts": "^4.0.3", 47 | "react-uuid": "^1.0.2", 48 | "redux": "^4.0.5", 49 | "redux-thunk": "^2.3.0", 50 | "serve": "^11.3.2" 51 | }, 52 | "scripts": { 53 | "start": "react-scripts start", 54 | "build": "react-scripts build", 55 | "test": "react-scripts test", 56 | "eject": "react-scripts eject" 57 | }, 58 | "proxy": "http://localhost:3001", 59 | "browserslist": { 60 | "production": [ 61 | ">0.2%", 62 | "not dead", 63 | "not op_mini all" 64 | ], 65 | "development": [ 66 | "last 1 chrome version", 67 | "last 1 firefox version", 68 | "last 1 safari version" 69 | ] 70 | }, 71 | "devDependencies": { 72 | "@babel/core": "^7.16.0", 73 | "@testing-library/jest-dom": "^5.14.1", 74 | "@testing-library/react": "^12.0.0", 75 | "@testing-library/user-event": "^13.2.1", 76 | "babel-eslint": "^10.1.0", 77 | "eslint": "^7.32.0", 78 | "eslint-config-airbnb": "^18.2.1", 79 | "eslint-import-resolver-alias": "^1.1.2", 80 | "eslint-plugin-babel": "^5.3.1", 81 | "eslint-plugin-import": "^2.24.2", 82 | "eslint-plugin-prettier": "^4.0.0", 83 | "eslint-plugin-react": "^7.25.1", 84 | "eslint-plugin-react-hooks": "^4.2.0", 85 | "sass": "^1.38.2", 86 | "webpack-dev-server": "3.11.1" 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | AGEViewer 35 | 36 | 37 | 38 | 39 |
40 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/categories.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/categories.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/customers.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/customers.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/employee_territories.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/employee_territories.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/employees.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/employees.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/orders.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/orders.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/orders_details.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/orders_details.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/products.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/products.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/regions.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/regions.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/shippers.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/shippers.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/suppliers.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/suppliers.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/csv/northwind/territories.csv.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/csv/northwind/territories.csv.xlsx -------------------------------------------------------------------------------- /frontend/public/resources/images/agedb-favicon.ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/images/agedb-favicon.ico.png -------------------------------------------------------------------------------- /frontend/public/resources/images/northwind/Entity-Relationship-Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/images/northwind/Entity-Relationship-Diagram.png -------------------------------------------------------------------------------- /frontend/public/resources/images/northwind/Graphmodel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/images/northwind/Graphmodel.png -------------------------------------------------------------------------------- /frontend/public/resources/images/northwind/customer-orders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/images/northwind/customer-orders.png -------------------------------------------------------------------------------- /frontend/public/resources/images/northwind/order-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/images/northwind/order-graph.png -------------------------------------------------------------------------------- /frontend/public/resources/images/northwind/product-category-supplier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/images/northwind/product-category-supplier.png -------------------------------------------------------------------------------- /frontend/public/resources/images/northwind/product-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/age-viewer/8a7f0be2513e2aa4b2caf3d9833f4e2707f0001d/frontend/public/resources/images/northwind/product-graph.png -------------------------------------------------------------------------------- /frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /frontend/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Incubating Apache AGE Viewer", 3 | "short_name": "Incubating AGE Viewer", 4 | "theme_color": "#ffffff", 5 | "background_color": "#ffffff", 6 | "display": "standalone" 7 | } 8 | -------------------------------------------------------------------------------- /frontend/src/App.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | .App { 21 | text-align: center; 22 | } 23 | 24 | .App-logo { 25 | height: 40vmin; 26 | pointer-events: none; 27 | } 28 | 29 | @media (prefers-reduced-motion: no-preference) { 30 | .App-logo { 31 | animation: App-logo-spin infinite 20s linear; 32 | } 33 | } 34 | 35 | .App-header { 36 | background-color: #282c34; 37 | min-height: 100vh; 38 | display: flex; 39 | flex-direction: column; 40 | align-items: center; 41 | justify-content: center; 42 | font-size: calc(10px + 2vmin); 43 | color: white; 44 | } 45 | 46 | .App-link { 47 | color: #61dafb; 48 | } 49 | 50 | @keyframes App-logo-spin { 51 | from { 52 | transform: rotate(0deg); 53 | } 54 | to { 55 | transform: rotate(360deg); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /frontend/src/App.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import React from 'react'; 21 | import 'bootstrap/dist/css/bootstrap.min.css'; 22 | import 'antd/dist/antd.css'; 23 | import './static/style.css'; 24 | import './static/navbar-fixed-left.css'; 25 | import MainPage from './pages/Main/MainPage'; 26 | 27 | const App = () => ( 28 | 29 | 30 | 31 | ); 32 | 33 | export default App; 34 | -------------------------------------------------------------------------------- /frontend/src/app/reducers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { combineReducers } from 'redux'; 21 | import DatabaseReducer from '../features/database/DatabaseSlice'; 22 | import MetadataReducer from '../features/database/MetadataSlice'; 23 | import FrameReducer from '../features/frame/FrameSlice'; 24 | import MenuReducer from '../features/menu/MenuSlice'; 25 | import SettingReducer from '../features/setting/SettingSlice'; 26 | import CypherReducer from '../features/cypher/CypherSlice'; 27 | import AlertReducer from '../features/alert/AlertSlice'; 28 | import EditorSlice from '../features/editor/EditorSlice'; 29 | import ModalSlice from '../features/modal/ModalSlice'; 30 | import LayoutSlice from '../features/layout/LayoutSlice'; 31 | 32 | const rootReducer = combineReducers({ 33 | navigator: MenuReducer, 34 | setting: SettingReducer, 35 | database: DatabaseReducer, 36 | metadata: MetadataReducer, 37 | frames: FrameReducer, 38 | cypher: CypherReducer, 39 | alerts: AlertReducer, 40 | editor: EditorSlice, 41 | modal: ModalSlice, 42 | layout: LayoutSlice, 43 | }); 44 | 45 | export default rootReducer; 46 | -------------------------------------------------------------------------------- /frontend/src/app/store.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { configureStore } from '@reduxjs/toolkit'; 21 | import rootReducer from './reducers'; 22 | 23 | const store = configureStore({ 24 | reducer: rootReducer, 25 | }); 26 | 27 | export default store; 28 | -------------------------------------------------------------------------------- /frontend/src/components/alert/containers/AlertContainers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import Alert from '../presentations/Alert'; 22 | import { setCommand } from '../../../features/editor/EditorSlice'; 23 | import { removeAlert } from '../../../features/alert/AlertSlice'; 24 | 25 | const mapStateToProps = () => ({ 26 | }); 27 | 28 | const mapDispatchToProps = { setCommand, removeAlert }; 29 | 30 | export default connect(mapStateToProps, mapDispatchToProps)(Alert); 31 | -------------------------------------------------------------------------------- /frontend/src/components/contents/containers/Contents.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { getConnectionStatus } from '../../../features/database/DatabaseSlice'; 22 | import { getMetaData/* getMetaChartData */ } from '../../../features/database/MetadataSlice'; 23 | import Contents from '../presentations/Contents'; 24 | 25 | const mapStateToProps = (state) => ({ 26 | database: state.database, 27 | isActive: state.navigator.isActive, 28 | currentGraph: state.metadata.currentGraph, 29 | }); 30 | 31 | const mapDispatchToProps = { getConnectionStatus, getMetaData /* getMetaChartData */ }; 32 | 33 | export default connect(mapStateToProps, mapDispatchToProps)(Contents); 34 | -------------------------------------------------------------------------------- /frontend/src/components/contents/containers/Editor.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { addFrame, trimFrame, removeFrame } from '../../../features/frame/FrameSlice'; 22 | import { addAlert } from '../../../features/alert/AlertSlice'; 23 | import { getConnectionStatus } from '../../../features/database/DatabaseSlice'; 24 | import { executeCypherQuery } from '../../../features/cypher/CypherSlice'; 25 | import { addCommandHistory, addCommandFavorites, setCommand } from '../../../features/editor/EditorSlice'; 26 | import { toggleMenu } from '../../../features/menu/MenuSlice'; 27 | import { getMetaData } from '../../../features/database/MetadataSlice'; 28 | import { setLabel } from '../../../features/layout/LayoutSlice'; 29 | 30 | import Editor from '../presentations/Editor'; 31 | 32 | const mapStateToProps = (state) => ({ 33 | alertList: state.alerts, 34 | database: state.database, 35 | command: state.editor.command, 36 | update: state.editor.updateClause, 37 | isActive: state.navigator.isActive, 38 | activeRequests: state.cypher.activeRequests, 39 | isLabel: state.layout.isLabel, 40 | }); 41 | 42 | const mapDispatchToProps = { 43 | setCommand, 44 | addFrame, 45 | trimFrame, 46 | removeFrame, 47 | addAlert, 48 | getConnectionStatus, 49 | executeCypherQuery, 50 | addCommandHistory, 51 | addCommandFavorites, 52 | toggleMenu, 53 | getMetaData, 54 | setLabel, 55 | }; 56 | 57 | export default connect(mapStateToProps, mapDispatchToProps)(Editor); 58 | -------------------------------------------------------------------------------- /frontend/src/components/contents/containers/Frames.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import Frames from '../presentations/Frames'; 22 | import { addFrame } from '../../../features/frame/FrameSlice'; 23 | 24 | const mapStateToProps = (state) => ({ 25 | frameList: state.frames, 26 | queryResult: state.cypher.queryResult, 27 | database: state.database, 28 | maxNumOfFrames: state.setting.maxNumOfFrames, 29 | }); 30 | 31 | const mapDispatchToProps = { addFrame }; 32 | 33 | export default connect(mapStateToProps, mapDispatchToProps)(Frames); 34 | -------------------------------------------------------------------------------- /frontend/src/components/contents/presentations/Contents.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import React, { useEffect } from 'react'; 21 | import { useDispatch } from 'react-redux'; 22 | import PropTypes from 'prop-types'; 23 | import FramesContainer from '../containers/Frames'; 24 | import styles from './Contents.module.scss'; 25 | 26 | const Contents = ({ 27 | database, isActive, getConnectionStatus, getMetaData, currentGraph, 28 | }) => { 29 | const dispatch = useDispatch(); 30 | 31 | useEffect(() => { 32 | if (database.status === 'init') { 33 | dispatch(() => { 34 | getConnectionStatus().then((response) => { 35 | if (response.type === 'database/getConnectionStatus/fulfilled') { 36 | getMetaData({ currentGraph }); 37 | getMetaData(); 38 | } 39 | }); 40 | }); 41 | } 42 | }, [database.status]); 43 | 44 | return ( 45 |
46 |
47 | 48 |
49 |
50 | ); 51 | }; 52 | 53 | Contents.propTypes = { 54 | database: PropTypes.shape({ 55 | status: PropTypes.string.isRequired, 56 | }).isRequired, 57 | isActive: PropTypes.bool.isRequired, 58 | getConnectionStatus: PropTypes.func.isRequired, 59 | getMetaData: PropTypes.func.isRequired, 60 | currentGraph: PropTypes.string.isRequired, 61 | }; 62 | 63 | export default Contents; 64 | -------------------------------------------------------------------------------- /frontend/src/components/contents/presentations/Contents.module.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | .Content { 21 | width: 100%; 22 | height: 100%; 23 | min-height: 100%; 24 | transition: all 0.3s; 25 | top: 0; 26 | right: 0; 27 | background-color: var(--bg-color); 28 | color: var(--text-color); 29 | } 30 | 31 | .Content.Expanded { 32 | width: 100%; 33 | } 34 | -------------------------------------------------------------------------------- /frontend/src/components/csv/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import React from 'react'; 21 | import PropTypes from 'prop-types'; 22 | import { Button, message, Upload } from 'antd'; 23 | import { useDispatch } from 'react-redux'; 24 | import Frame from '../frame/Frame'; 25 | import { getMetaData } from '../../features/database/MetadataSlice'; 26 | 27 | const CSV = ({ 28 | reqString, refKey, 29 | }) => { 30 | const dispatch = useDispatch(); 31 | 32 | const props = { 33 | name: 'file', 34 | action: '/api/v1/feature/uploadCSV', 35 | headers: { 36 | authorization: 'authorization-text', 37 | }, 38 | onChange(info) { 39 | if (info.file.status === 'done') { 40 | dispatch(getMetaData()); 41 | message.success(`${info.file.name} file uploaded successfully`); 42 | } else if (info.file.status === 'error') { 43 | message.error(`${info.file.name} file upload failed.`); 44 | } 45 | }, 46 | }; 47 | 48 | return ( 49 | 53 | {/* eslint-disable-next-line react/jsx-props-no-spreading */} 54 | 55 | 56 | 57 | 58 | ); 59 | }; 60 | 61 | CSV.propTypes = { 62 | reqString: PropTypes.string.isRequired, 63 | refKey: PropTypes.string.isRequired, 64 | 65 | }; 66 | 67 | export default CSV; 68 | -------------------------------------------------------------------------------- /frontend/src/components/cypherresult/components/popover.module.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | .title { 21 | font-size: 18px; 22 | font-weight: bold; 23 | } 24 | .input { 25 | width: 100%; 26 | height: 48px; 27 | background: #F8F9FA 0% 0% no-repeat padding-box !important; 28 | border-radius: 5px !important; 29 | opacity: 1 !important; 30 | border: none; 31 | margin: 5px 0px 5px 0px; 32 | color: #2756FF; 33 | } 34 | .input:hover { 35 | border: 1px solid #2756FF; 36 | } 37 | .input:focus { 38 | border: 1px solid #2756FF; 39 | } 40 | .select { 41 | width: 100%; 42 | height: 48px; 43 | background: #F8F9FA 0% 0% no-repeat padding-box !important; 44 | border-radius: 5px !important; 45 | opacity: 1 !important; 46 | border: none; 47 | margin: 5px 0px 5px 0px; 48 | color: #2756FF; 49 | } 50 | .default{ 51 | width: 100%; 52 | height: 48px; 53 | background: #F8F9FA 0% 0% no-repeat padding-box !important; 54 | border-radius: 5px !important; 55 | opacity: 1 !important; 56 | border: none; 57 | margin: 5px 0px 5px 0px; 58 | color:#808080; 59 | } 60 | .select select-item { 61 | width: 100%; 62 | height: 48px; 63 | background: #F8F9FA 0% 0% no-repeat padding-box !important; 64 | border-radius: 5px !important; 65 | opacity: 1 !important; 66 | border: none; 67 | color:#808080; 68 | } 69 | .buttons { 70 | margin: 32px 0 32px 0; 71 | text-align: right; 72 | } 73 | 74 | .btn { 75 | width: 100px; 76 | height: 45px; 77 | font-size: 14px; 78 | font-weight: bold; 79 | border: 1px solid #2756FF; 80 | border-radius: 10px; 81 | opacity: 1; 82 | margin-left: 10px; 83 | margin-right: 10px; 84 | color: #2756FF; 85 | background-color: #F8F9FA; 86 | } 87 | 88 | .btn:hover { 89 | color: #F8F9FA; 90 | background-color: #2756FF; 91 | } 92 | -------------------------------------------------------------------------------- /frontend/src/components/cypherresult/containers/CypherResultCytoscapeContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import CypherResultCytoscape from '../presentations/CypherResultCytoscape'; 22 | import { setLabels } from '../../../features/cypher/CypherSlice'; 23 | import { openModal, addGraphHistory, addElementHistory } from '../../../features/modal/ModalSlice'; 24 | import { generateCytoscapeElement } from '../../../features/cypher/CypherUtil'; 25 | 26 | const mapStateToProps = (state, ownProps) => { 27 | const { refKey } = ownProps; 28 | 29 | const generateElements = () => { 30 | try { 31 | return generateCytoscapeElement( 32 | state.cypher.queryResult[refKey].rows, state.setting.maxDataOfGraph, false, 33 | ); 34 | } catch (e) { 35 | // TODO need tracing error 36 | console.error(e); 37 | } 38 | return { 39 | legend: { 40 | nodeLegend: {}, 41 | edgeLegend: {}, 42 | }, 43 | elements: { 44 | nodes: [], 45 | edges: [], 46 | }, 47 | }; 48 | }; 49 | return { 50 | data: generateElements(), 51 | maxDataOfGraph: state.setting.maxDataOfGraph, 52 | maxDataOfTable: state.setting.maxDataOfTable, 53 | setChartLegend: ownProps.setChartLegend, 54 | graph: state.database.graph, 55 | }; 56 | }; 57 | 58 | const mapDispatchToProps = { 59 | setLabels, 60 | openModal, 61 | addGraphHistory, 62 | addElementHistory, 63 | }; 64 | 65 | export default connect( 66 | mapStateToProps, 67 | mapDispatchToProps, 68 | null, 69 | { forwardRef: true }, 70 | )(CypherResultCytoscape); 71 | -------------------------------------------------------------------------------- /frontend/src/components/cypherresult/containers/CypherResultMetaContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import CypherResultMeta from '../presentations/CypherResultMeta'; 22 | 23 | const mapStateToProps = (state, ownProps) => { 24 | const { refKey } = ownProps; 25 | 26 | let database = {}; 27 | let query = ''; 28 | let data = {}; 29 | if (state.cypher.queryResult[refKey]) { 30 | database = state.database; 31 | query = state.cypher.queryResult[refKey].query; 32 | data = { 33 | columns: state.cypher.queryResult[refKey].columns, 34 | command: state.cypher.queryResult[refKey].command, 35 | rowCount: state.cypher.queryResult[refKey].rowCount, 36 | rows: state.cypher.queryResult[refKey].rows, 37 | message: state.cypher.queryResult[refKey].message, 38 | }; 39 | } 40 | 41 | return { 42 | database, 43 | query, 44 | data, 45 | }; 46 | }; 47 | 48 | const mapDispatchToProps = {}; 49 | 50 | export default connect(mapStateToProps, mapDispatchToProps)(CypherResultMeta); 51 | -------------------------------------------------------------------------------- /frontend/src/components/cypherresult/containers/CypherResultTableContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import CypherResultTable from '../presentations/CypherResultTable'; 22 | 23 | const mapStateToProps = (state, ownProps) => { 24 | const { refKey } = ownProps; 25 | const generateTableData = (data) => { 26 | let columns = []; 27 | let rows = []; 28 | let command; 29 | let rowCount = null; 30 | let message = ''; 31 | 32 | if (data && data.command !== 'ERROR' && data.command !== null) { 33 | columns = data.columns; 34 | rows = data.rows.slice(0, (state.setting.maxDataOfTable === 0 35 | ? data.rows.length : state.setting.maxDataOfTable)); 36 | command = data.command; 37 | rowCount = data.rowCount; 38 | } else { 39 | command = data.command; 40 | message = data.message; 41 | } 42 | return { 43 | command, rowCount, columns, rows, message, 44 | }; 45 | }; 46 | return { 47 | data: generateTableData(state.cypher.queryResult[refKey]), 48 | }; 49 | }; 50 | 51 | const mapDispatchToProps = { }; 52 | 53 | export default connect(mapStateToProps, mapDispatchToProps)(CypherResultTable); 54 | -------------------------------------------------------------------------------- /frontend/src/components/cypherresult/containers/CypherResultTextContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import CypherResultText from '../presentations/CypherResultText'; 22 | 23 | const mapStateToProps = (state, ownProps) => { 24 | const { refKey } = ownProps; 25 | const generateTableData = (data) => { 26 | let columns = []; 27 | let rows = []; 28 | if (data) { 29 | columns = data.columns; 30 | rows = data.rows; 31 | } 32 | return { columns, rows }; 33 | }; 34 | return { 35 | data: generateTableData(state.cypher.queryResult[refKey]), 36 | }; 37 | }; 38 | 39 | const mapDispatchToProps = {}; 40 | 41 | export default connect(mapStateToProps, mapDispatchToProps)(CypherResultText); 42 | -------------------------------------------------------------------------------- /frontend/src/components/cypherresult/presentations/CypherResultMeta.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import React from 'react'; 21 | import PropTypes from 'prop-types'; 22 | import { Col, Row } from 'antd'; 23 | 24 | const CypherResultMeta = ({ database, query, data }) => ( 25 | <> 26 | 27 | 28 | Server Version 29 | 30 | TBD 31 | 32 | 33 | Database URI 34 | 35 | {database.host} 36 | : 37 | {database.port} 38 | 39 | 40 | 41 | Executed Query 42 | {query} 43 | 44 | 45 | Data 46 |
{JSON.stringify(data, null, 2)}
47 |
48 | 49 | ); 50 | 51 | CypherResultMeta.propTypes = { 52 | database: PropTypes.shape({ 53 | host: PropTypes.string.isRequired, 54 | port: PropTypes.string.isRequired, 55 | }).isRequired, 56 | query: PropTypes.string.isRequired, 57 | // eslint-disable-next-line react/forbid-prop-types 58 | data: PropTypes.any.isRequired, 59 | }; 60 | 61 | export default CypherResultMeta; 62 | -------------------------------------------------------------------------------- /frontend/src/components/cypherresult/presentations/CypherResultText.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import React from 'react'; 21 | import PropTypes from 'prop-types'; 22 | import AsciiTable from 'ascii-table'; 23 | 24 | const CypherResultText = ({ data }) => { 25 | const extractRows = () => data.rows.map( 26 | (d) => data.columns.map( 27 | (alias) => JSON.stringify(d[alias]), 28 | ), 29 | ); 30 | 31 | const table = AsciiTable.factory({ 32 | heading: data.columns, 33 | rows: extractRows(), 34 | }); 35 | 36 | return ( 37 |
{table.toString()}
38 | ); 39 | }; 40 | 41 | CypherResultText.propTypes = { 42 | data: PropTypes.shape({ 43 | rows: PropTypes.arrayOf(PropTypes.any), 44 | columns: PropTypes.arrayOf(PropTypes.string), 45 | }).isRequired, 46 | }; 47 | 48 | export default CypherResultText; 49 | -------------------------------------------------------------------------------- /frontend/src/components/cytoscape/CytoscapeConfig.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | export default { 21 | // Viewport Options 22 | zoom: 1, 23 | // Interaction Options 24 | minZoom: 0.5, 25 | maxZoom: 2, 26 | zoomingEnabled: false, // true 27 | userZoomingEnabled: false, // true 28 | panningEnabled: true, 29 | userPanningEnabled: true, 30 | boxSelectionEnabled: false, // true 31 | selectionType: 'single', 32 | touchTapThreshold: 8, 33 | desktopTapThreshold: 4, 34 | autolock: false, 35 | autoungrabify: false, 36 | autounselectify: false, 37 | // Rendering Options 38 | headless: false, 39 | styleEnabled: true, 40 | hideEdgesOnViewport: false, 41 | textureOnViewport: false, 42 | motionBlur: false, 43 | motionBlurOpacity: 0.2, 44 | wheelSensitivity: 0.5, 45 | pixelRatio: 'auto', 46 | }; 47 | -------------------------------------------------------------------------------- /frontend/src/components/editor/containers/CodeMirrorWapperContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import CodeMirrorWrapper from '../presentations/CodeMirrorWrapper'; 22 | 23 | const mapStateToProps = (state) => ({ 24 | commandHistory: state.editor.commandHistory.slice( 25 | Math.max((state.editor.commandHistory.length - state.setting.maxNumOfHistories === 0 26 | ? state.editor.commandHistory.length : state.setting.maxNumOfHistories), 0), 27 | ), 28 | commandFavorites: state.editor.commandFavorites.slice(0), 29 | }); 30 | 31 | const mapDispatchToProps = { }; 32 | 33 | export default connect( 34 | mapStateToProps, 35 | mapDispatchToProps, 36 | )(CodeMirrorWrapper); 37 | -------------------------------------------------------------------------------- /frontend/src/components/editor/containers/SideBarMenuToggleContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import SidebarMeunuToggle from '../presentations/SidebarMeunuToggle'; 22 | 23 | const mapStateToProps = (state) => ({ 24 | isActive: state.navigator.isActive, 25 | }); 26 | 27 | const mapDispatchToProps = { }; 28 | 29 | export default connect(mapStateToProps, 30 | mapDispatchToProps)(SidebarMeunuToggle); 31 | -------------------------------------------------------------------------------- /frontend/src/components/editor/presentations/CodeMirror.scss: -------------------------------------------------------------------------------- 1 | pre.CodeMirror-placeholder.CodeMirror-line-like{ 2 | color:grey; 3 | opacity: 90%; 4 | } -------------------------------------------------------------------------------- /frontend/src/components/editor/presentations/SidebarMeunuToggle.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import React from 'react'; 21 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 22 | import { faAngleUp, faAngleDown } from '@fortawesome/free-solid-svg-icons'; 23 | import PropTypes from 'prop-types'; 24 | 25 | const SidebarMeunuToggle = ({ 26 | isActive, 27 | }) => ( 28 |
29 | { 30 | isActive === true 31 | ? ( 32 | 36 | ) 37 | : ( 38 | 42 | ) 43 | } 44 |
45 | ); 46 | 47 | SidebarMeunuToggle.propTypes = { 48 | isActive: PropTypes.bool.isRequired, 49 | }; 50 | 51 | export default SidebarMeunuToggle; 52 | -------------------------------------------------------------------------------- /frontend/src/components/frame/containers/ContentsFrameContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { pinFrame, removeFrame } from '../../../features/frame/FrameSlice'; 22 | import ContentsFrame from '../presentations/ContentsFrame'; 23 | import { addAlert } from '../../../features/alert/AlertSlice'; 24 | 25 | const mapStateToProps = () => ({ 26 | }); 27 | 28 | const mapDispatchToProps = { 29 | removeFrame, pinFrame, addAlert, 30 | }; 31 | 32 | export default connect(mapStateToProps, mapDispatchToProps)(ContentsFrame); 33 | -------------------------------------------------------------------------------- /frontend/src/components/frame/containers/CypherGraphResultContainers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { pinFrame, removeFrame } from '../../../features/frame/FrameSlice'; 22 | import CypherGraphResultFrame from '../presentations/CypherGraphResultFrame'; 23 | 24 | const mapStateToProps = (state, props) => ({ 25 | queryComplete: state.cypher.queryResult[props.refKey], 26 | }); 27 | 28 | const mapDispatchToProps = { removeFrame, pinFrame }; 29 | 30 | export default connect(mapStateToProps, mapDispatchToProps)(CypherGraphResultFrame); 31 | -------------------------------------------------------------------------------- /frontend/src/components/frame/containers/CypherResultContainers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { pinFrame, removeFrame } from '../../../features/frame/FrameSlice'; 22 | import CypherResultFrame from '../presentations/CypherResultFrame'; 23 | 24 | const mapStateToProps = () => ( 25 | {} 26 | ); 27 | 28 | const mapDispatchToProps = { removeFrame, pinFrame }; 29 | 30 | export default connect(mapStateToProps, mapDispatchToProps)(CypherResultFrame); 31 | -------------------------------------------------------------------------------- /frontend/src/components/frame/containers/ServerConnectContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { connectToDatabase } from '../../../features/database/DatabaseSlice'; 22 | import { /* getMetaChartData, */ getMetaData } from '../../../features/database/MetadataSlice'; 23 | import { 24 | addFrame, pinFrame, removeFrame, trimFrame, 25 | } from '../../../features/frame/FrameSlice'; 26 | import { addAlert } from '../../../features/alert/AlertSlice'; 27 | import ServerConnectFrame from '../presentations/ServerConnectFrame'; 28 | 29 | const mapStateToProps = (state) => ({ 30 | currentGraph: state.metadata.currentGraph, 31 | }); 32 | 33 | const mapDispatchToProps = { 34 | connectToDatabase, 35 | addFrame, 36 | trimFrame, 37 | removeFrame, 38 | pinFrame, 39 | addAlert, 40 | getMetaData, 41 | /* getMetaChartData, */ 42 | }; 43 | 44 | export default connect(mapStateToProps, mapDispatchToProps)(ServerConnectFrame); 45 | -------------------------------------------------------------------------------- /frontend/src/components/frame/containers/ServerDisconnectContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { disconnectToDatabase } from '../../../features/database/DatabaseSlice'; 22 | import { resetMetaData } from '../../../features/database/MetadataSlice'; 23 | import { addFrame, pinFrame, removeFrame } from '../../../features/frame/FrameSlice'; 24 | import { addAlert } from '../../../features/alert/AlertSlice'; 25 | import { setCommand } from '../../../features/editor/EditorSlice'; 26 | import ServerDisconnectFrame from '../presentations/ServerDisconnectFrame'; 27 | 28 | const mapStateToProps = () => ({ 29 | }); 30 | 31 | const mapDispatchToProps = { 32 | disconnectToDatabase, addFrame, removeFrame, pinFrame, addAlert, setCommand, resetMetaData, 33 | }; 34 | 35 | export default connect(mapStateToProps, mapDispatchToProps)(ServerDisconnectFrame); 36 | -------------------------------------------------------------------------------- /frontend/src/components/frame/containers/ServerStatusContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { connect } from 'react-redux'; 21 | import { pinFrame, removeFrame } from '../../../features/frame/FrameSlice'; 22 | import { generateCytoscapeMetadataElement } from '../../../features/cypher/CypherUtil'; 23 | import ServerStatusFrame from '../presentations/ServerStatusFrame'; 24 | import { openTutorial } from '../../../features/modal/ModalSlice'; 25 | 26 | const mapStateToProps = (state) => { 27 | const generateElements = () => generateCytoscapeMetadataElement(state.metadata.rows); 28 | 29 | return { 30 | serverInfo: state.database, 31 | isTutorial: state.modal.isTutorial, 32 | data: generateElements(), 33 | }; 34 | }; 35 | 36 | const mapDispatchToProps = { removeFrame, pinFrame, openTutorial }; 37 | 38 | export default connect(mapStateToProps, mapDispatchToProps)(ServerStatusFrame); 39 | -------------------------------------------------------------------------------- /frontend/src/components/frame/presentations/ContentsFrame.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import PropTypes from 'prop-types'; 21 | import React, { useEffect, useState } from 'react'; 22 | import { useDispatch } from 'react-redux'; 23 | import Frame from '../Frame'; 24 | import FrameStyles from '../Frame.module.scss'; 25 | import { removeFrame } from '../../../features/frame/FrameSlice'; 26 | import { addAlert } from '../../../features/alert/AlertSlice'; 27 | 28 | const ContentFrame = ({ 29 | refKey, 30 | isPinned, 31 | reqString, 32 | playTarget, 33 | }) => { 34 | const dispatch = useDispatch(); 35 | const [slides] = useState([]); 36 | const [currentSlide, setCurrentSlide] = useState(0); 37 | 38 | useEffect(() => { 39 | dispatch(addAlert('ErrorPlayLoadFail', playTarget)); 40 | dispatch(removeFrame(refKey)); 41 | }, []); 42 | 43 | const genCarousel = () => { 44 | const slideSize = slides.length; 45 | const carousel = []; 46 | for (let i = 0; i < slideSize; i += 1) { 47 | carousel.push( 48 |