├── .babelrc
├── .browserslistrc
├── .eslintrc
├── .gitignore
├── LICENSE
├── README.md
├── config
├── postcss.config.js
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js
├── docs
└── img
│ ├── example-entity-referencing.gif
│ ├── example-json-document.gif
│ ├── example-json-schema.gif
│ ├── example-user-entity.gif
│ ├── example-zoom-in-out.gif
│ ├── migcast-db-schema.png
│ ├── movie-lens-db-schema.png
│ └── schema-visualizer-social-banner-cut.png
├── package.json
├── src
├── css
│ ├── custom-jointjs.css
│ ├── custom.css
│ ├── schema-diagram.css
│ └── schema-editor.css
├── favicon.ico
├── index.html
└── js
│ ├── font-awesome-custom.js
│ ├── index.js
│ ├── jointjs-helper
│ ├── cell-collapse-example.js
│ ├── diagram-generator.js
│ ├── jointjs-helper.js
│ ├── schema-examples.js
│ └── template-generator.js
│ ├── json-editor
│ ├── json-editor.js
│ └── schema-validators.js
│ ├── modal-template.html
│ ├── schema-diagram
│ ├── common
│ │ ├── hierarchy-base-view.js
│ │ ├── hierarchy-base.js
│ │ └── html-element.js
│ ├── diagram-root
│ │ ├── diagram-root-view.js
│ │ ├── diagram-root.html
│ │ ├── diagram-root.js
│ │ └── index.js
│ ├── diagram-title
│ │ ├── diagram-title.html
│ │ ├── diagram-title.js
│ │ └── index.js
│ ├── object-row-header
│ │ ├── object-row-header.html
│ │ └── object-row-header.js
│ ├── object-row
│ │ ├── object-row.html
│ │ └── object-row.js
│ ├── simple-row
│ │ ├── simple-row.html
│ │ └── simple-row.js
│ ├── supertype
│ │ ├── supertype-view.js
│ │ └── supertype.js
│ └── utils
│ │ ├── append-values.js
│ │ ├── index.js
│ │ ├── initialize-box.js
│ │ ├── remove-box.js
│ │ ├── render-box.js
│ │ └── update-box.js
│ ├── ui-script.js
│ └── visual-schema-editor
│ ├── html-to-json-schema
│ └── index.js
│ ├── index.js
│ ├── object-row
│ ├── index.js
│ └── template.html
│ └── simple-row
│ ├── index.js
│ └── template.html
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "useBuiltIns": "usage",
7 | "corejs": "3.0.0"
8 | }
9 | ]
10 | ],
11 | "plugins": [
12 | "@babel/plugin-syntax-dynamic-import",
13 | "@babel/plugin-proposal-class-properties"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | [production staging]
2 | >5%
3 | last 2 versions
4 | Firefox ESR
5 | not ie < 11
6 |
7 | [development]
8 | last 1 chrome version
9 | last 1 firefox version
10 | last 1 edge version
11 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "node": true
5 | },
6 | "parserOptions": {
7 | "ecmaVersion": 6,
8 | "sourceType": "module"
9 | },
10 | "rules": {
11 | "semi": 2
12 | }
13 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 |
4 | # production
5 | build
6 | public
7 |
8 | # misc
9 | .DS_Store
10 |
11 | npm-debug.log
12 | yarn-error.log
13 | yarn.lock
14 | .yarnclean
15 | .vscode
16 | .idea
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Shamil Nabiyev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # Schema Visualizer
6 |
7 | Schema Visualizer is an online data modeling tool for JSON and document based databases (document stores). It also can be used to visualize JSON data and JSON-Schema.
8 |
9 | ## Installation
10 |
11 | ```yarn install```
12 |
13 | ## Development
14 |
15 | ```yarn run dev```
16 |
17 | ## Production build
18 |
19 | ```yarn run build```
20 |
21 | ## Used libraries
22 |
23 | * Bootstrap: https://github.com/twbs/bootstrap
24 | * JointJS: https://github.com/clientIO/joint
25 | * JSON Editor: https://github.com/josdejong/jsoneditor
26 | * JSON Schema Generator: https://github.com/mowgliLab/json-s-gen
27 | * Webpack: https://github.com/webpack/webpack
28 |
29 | ## Examples
30 |
31 | ### How to create a new entity type
32 |
33 |
34 |
35 | ---
36 |
37 | ### How to reference an entity
38 |
39 |
40 |
41 | ---
42 |
43 | ### How to zoom in/out
44 |
45 |
46 |
47 | ---
48 |
49 | ### How to import a JSON document
50 |
51 |
52 |
53 | ---
54 |
55 | ### How to import a JSON-Schema
56 |
57 |
58 |
59 | ---
60 |
61 | ### MovieLens Database Schema Diagrams
62 |
63 |
64 |
65 | ---
66 |
67 | ### MigCast Database Schema Diagrams
68 |
69 |
70 |
71 | ---
72 |
--------------------------------------------------------------------------------
/config/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | require('autoprefixer')
4 | ]
5 | }
--------------------------------------------------------------------------------
/config/webpack.common.js:
--------------------------------------------------------------------------------
1 | const Path = require('path');
2 | const CleanWebpackPlugin = require('clean-webpack-plugin');
3 | const CopyWebpackPlugin = require('copy-webpack-plugin');
4 | const HtmlWebpackPlugin = require('html-webpack-plugin');
5 |
6 | module.exports = {
7 | entry: {
8 | app: Path.resolve(__dirname, '../src/js/index.js')
9 | },
10 | output: {
11 | path: Path.join(__dirname, '../public'),
12 | filename: 'js/[name].js'
13 | },
14 | optimization: {
15 | splitChunks: {
16 | chunks: 'all',
17 | name: false
18 | }
19 | },
20 | plugins: [
21 | new CleanWebpackPlugin(),
22 | new CopyWebpackPlugin([
23 | { from: Path.resolve(__dirname, '../public'), to: 'public' }
24 | ]),
25 | new HtmlWebpackPlugin({
26 | template: Path.resolve(__dirname, '../src/', 'index.html'),
27 | favicon: Path.join(__dirname, '../src/', 'favicon.ico'),
28 | }),
29 | ],
30 | resolve: {
31 | modules: ['node_modules', 'src'],
32 | alias: {
33 | '~': Path.resolve(__dirname, '../src'),
34 | normalize_css: Path.join(__dirname, '../node_modules/normalize.css'),
35 | fontawesome_min_css: Path.join(__dirname, '../node_modules/@fortawesome/fontawesome-free/css/fontawesome.min.css'),
36 | fontawesome_solid_min_css: Path.join(__dirname, '../node_modules/@fortawesome/fontawesome-free/css/solid.min.css'),
37 | }
38 | },
39 | module: {
40 | rules: [
41 | {
42 | test: /\.html$/,
43 | loader: "html-loader"
44 | },
45 | {
46 | test: /\.mjs$/,
47 | include: /node_modules/,
48 | type: 'javascript/auto'
49 | },
50 | {
51 | test: /\.(ico|jpg|jpeg|png|gif|webp)(\?.*)?$/,
52 | use: {
53 | loader: 'file-loader',
54 | options: {
55 | name: '[path][name].[ext]'
56 | }
57 | }
58 | },
59 | {
60 | test: /\.(woff(2)?|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
61 | use: [
62 | {
63 | loader: 'file-loader',
64 | options: {
65 | name: '[name].[ext]',
66 | outputPath: 'fonts/'
67 | }
68 | }
69 | ]
70 | }
71 | ]
72 | }
73 | };
74 |
--------------------------------------------------------------------------------
/config/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const Path = require('path');
2 | const Webpack = require('webpack');
3 | const merge = require('webpack-merge');
4 | const common = require('./webpack.common.js');
5 |
6 | module.exports = merge(common, {
7 | mode: 'development',
8 | devtool: 'cheap-eval-source-map',
9 | output: {
10 | chunkFilename: 'js/[name].chunk.js'
11 | },
12 | devServer: {
13 | inline: true
14 | },
15 | plugins: [
16 | new Webpack.DefinePlugin({
17 | 'process.env.NODE_ENV': JSON.stringify('development')
18 | })
19 | ],
20 | module: {
21 | rules: [
22 | {
23 | test: /\.(js)$/,
24 | include: Path.resolve(__dirname, '../src'),
25 | enforce: 'pre',
26 | loader: 'eslint-loader',
27 | options: {
28 | emitWarning: true,
29 | }
30 | },
31 | {
32 | test: /\.(js)$/,
33 | include: Path.resolve(__dirname, '../src'),
34 | loader: 'babel-loader'
35 | },
36 | {
37 | test: /\.(css)$/,
38 | use: ['style-loader', 'css-loader?sourceMap=true', 'sass-loader']
39 | },
40 | {
41 | test: /\.(scss)$/,
42 | use: [{
43 | loader: 'style-loader', // inject CSS to page
44 | }, {
45 | loader: 'css-loader', // translates CSS into CommonJS modules
46 | }, {
47 | loader: 'postcss-loader', // Run post css actions
48 | options: {
49 | plugins: function () { // post css plugins, can be exported to postcss.config.js
50 | return [
51 | require('precss'),
52 | require('autoprefixer')
53 | ];
54 | }
55 | }
56 | }, {
57 | loader: 'sass-loader' // compiles Sass to CSS
58 | }]
59 | }
60 | ]
61 | }
62 | });
63 |
--------------------------------------------------------------------------------
/config/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const Path = require('path');
2 | const Webpack = require('webpack');
3 | const merge = require('webpack-merge');
4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5 | const common = require('./webpack.common.js');
6 |
7 | module.exports = merge(common, {
8 | mode: 'production',
9 | devtool: 'source-map',
10 | stats: 'errors-only',
11 | bail: true,
12 | output: {
13 | filename: 'js/[name].[chunkhash:8].js',
14 | chunkFilename: 'js/[name].[chunkhash:8].chunk.js'
15 | },
16 | plugins: [
17 | new Webpack.DefinePlugin({
18 | 'process.env.NODE_ENV': JSON.stringify('production')
19 | }),
20 | new Webpack.optimize.ModuleConcatenationPlugin(),
21 | new MiniCssExtractPlugin({
22 | filename: 'bundle.css'
23 | })
24 | ],
25 | module: {
26 | rules: [
27 | {
28 | test: /\.(js)$/,
29 | exclude: /node_modules/,
30 | use: 'babel-loader'
31 | },
32 | {
33 | test: /\.s?css/i,
34 | use : [
35 | MiniCssExtractPlugin.loader,
36 | 'css-loader',
37 | 'sass-loader'
38 | ]
39 | }
40 | ]
41 | }
42 | });
43 |
--------------------------------------------------------------------------------
/docs/img/example-entity-referencing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/example-entity-referencing.gif
--------------------------------------------------------------------------------
/docs/img/example-json-document.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/example-json-document.gif
--------------------------------------------------------------------------------
/docs/img/example-json-schema.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/example-json-schema.gif
--------------------------------------------------------------------------------
/docs/img/example-user-entity.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/example-user-entity.gif
--------------------------------------------------------------------------------
/docs/img/example-zoom-in-out.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/example-zoom-in-out.gif
--------------------------------------------------------------------------------
/docs/img/migcast-db-schema.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/migcast-db-schema.png
--------------------------------------------------------------------------------
/docs/img/movie-lens-db-schema.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/movie-lens-db-schema.png
--------------------------------------------------------------------------------
/docs/img/schema-visualizer-social-banner-cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/docs/img/schema-visualizer-social-banner-cut.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Schema Visualizer v2.0 for NoSQL DBMS",
3 | "name": "schema-visualizer-v2",
4 | "version": "2.0.0",
5 | "scripts": {
6 | "build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js --colors",
7 | "dev": "webpack-dev-server --config config/webpack.dev.js"
8 | },
9 | "license": "MIT",
10 | "private": true,
11 | "keywords": [
12 | "JSON",
13 | "JSON-Schema",
14 | "NoSQL",
15 | "database Modeling",
16 | "Schema Visualisation"
17 | ],
18 | "devDependencies": {
19 | "@babel/core": "^7.4.0",
20 | "@babel/plugin-proposal-class-properties": "^7.4.0",
21 | "@babel/plugin-syntax-dynamic-import": "^7.2.0",
22 | "@babel/preset-env": "^7.6.2",
23 | "@fortawesome/fontawesome-svg-core": "^1.2.25",
24 | "@fortawesome/free-brands-svg-icons": "^5.11.2",
25 | "@fortawesome/free-regular-svg-icons": "^5.11.2",
26 | "@fortawesome/free-solid-svg-icons": "^5.11.2",
27 | "babel-loader": "^8.0.6",
28 | "clean-webpack-plugin": "^2.0.2",
29 | "copy-webpack-plugin": "^5.0.3",
30 | "cross-env": "^6.0.0",
31 | "css-loader": "^3.0.0",
32 | "eslint": "^6.0.0",
33 | "eslint-loader": "^3.0.1",
34 | "file-loader": "^4.0.0",
35 | "html-loader": "^0.5.5",
36 | "html-webpack-plugin": "^4.0.0-beta.5",
37 | "mini-css-extract-plugin": "^0.8.0",
38 | "node-sass": "^4.12.0",
39 | "postcss-loader": "^3.0.0",
40 | "precss": "^4.0.0",
41 | "sass-loader": "^8.0.0",
42 | "style-loader": "^1.0.0",
43 | "webpack": "^4.29.6",
44 | "webpack-cli": "^3.3.9",
45 | "webpack-dev-server": "^3.8.1",
46 | "webpack-merge": "^4.2.1"
47 | },
48 | "dependencies": {
49 | "@fortawesome/fontawesome-free": "^5.11.2",
50 | "@jdw/jst": "^2.0.0-beta.15",
51 | "backbone": "^1.4.0",
52 | "bootstrap": "^4.3.1",
53 | "core-js": "^3.2.1",
54 | "generate-schema": "^2.6.0",
55 | "himalaya": "^1.1.0",
56 | "jointjs": "^3.0.4",
57 | "jquery": "^3.4.1",
58 | "json-s-generator": "^0.0.4",
59 | "json-schema-ref-parser": "^7.1.1",
60 | "json-schema-traverse": "^0.4.1",
61 | "jsoneditor": "^7.2.0",
62 | "lodash": "^4.17.15",
63 | "uuid": "^3.3.3"
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/css/custom-jointjs.css:
--------------------------------------------------------------------------------
1 | .joint-paper {
2 | border: 1px solid lightgray;
3 | display: inline-block;
4 | overflow: hidden;
5 | }
6 |
7 | #paper-multiple-papers-small {
8 | width: 300px;
9 | }
10 |
11 | #paper-html-elements {
12 | position: relative;
13 | border: 1px solid #cccccc;
14 | display: inline-block;
15 | background: transparent;
16 | overflow: hidden;
17 | margin-bottom: 1rem;
18 | }
19 |
20 | #paper-html-elements svg {
21 | background: transparent;
22 | }
23 |
24 | #paper-html-elements svg .link {
25 | z-index: 2;
26 | }
27 |
28 | .html-element {
29 | position: absolute;
30 | pointer-events: none;
31 | -webkit-user-select: none;
32 | z-index: 2;
33 | }
34 |
35 |
36 | circle.port-body,
37 | circle.joint-port-body {
38 | opacity: 0;
39 | fill: yellow;
40 | stroke: #424242;
41 | }
42 |
43 |
44 | circle.port-body:hover,
45 | circle.joint-port-body:hover {
46 | opacity: 1;
47 | }
48 |
49 |
50 | /* port styling */
51 | .available-magnet {
52 | fill: yellow;
53 | }
54 |
55 | /* element styling */
56 | .available-cell rect {
57 | stroke-dasharray: 5, 2;
58 | }
59 |
60 | #paper-holder {
61 | height: 65vh !important;
62 | flex-grow: 1;
63 | }
--------------------------------------------------------------------------------
/src/css/custom.css:
--------------------------------------------------------------------------------
1 | .vertical-divider {
2 | display: inline;
3 | border-right: 1px solid #aaaaaa;
4 | }
5 |
6 | .modal-body {
7 | height: 70vh;
8 | display: flex;
9 | flex-direction: column;
10 | }
11 | .jsoneditor-wrapper {
12 | flex-grow: 1;
13 | /* height: 40vh; */
14 | }
15 |
16 | .jsoneditor-menu {
17 | background-color: #0099ee;
18 | border-bottom: 1px solid #0068a2;
19 | }
20 |
21 | .jsoneditor {
22 | border: thin solid #0099ee;
23 | }
24 |
25 | .joint-tool {
26 | opacity: 0.01;
27 | transition: opacity 0.5s;
28 | }
29 |
30 | .joint-layers:hover .joint-tool {
31 | transition: opacity 0.5s;
32 | opacity: 1;
33 | }
34 |
35 | #schema-editor-modal .modal-content {
36 | /*height: 80vh;*/
37 | }
38 |
39 | #entity-type-name-form {
40 | border: 1px solid #cccccc;
41 | }
--------------------------------------------------------------------------------
/src/css/schema-diagram.css:
--------------------------------------------------------------------------------
1 | .flex-container {
2 | height: 100%;
3 | display: flex;
4 | flex-wrap: nowrap;
5 | justify-content: space-between;
6 | background-color: #ffffff;
7 | border-bottom: 1px solid #7d7d7d;
8 | border-left: 1px solid #7d7d7d;
9 | border-right: 1px solid #7d7d7d;
10 | }
11 |
12 | .in_port {
13 | padding: 0.5em 0.5em;
14 | }
15 |
16 | .out_port {
17 | display: flex;
18 | flex-wrap: nowrap;
19 | }
20 |
21 | .field_constraints {
22 | font-style: italic;
23 | color: #aaa;
24 | padding: 0.5em 0.5em;
25 | }
26 |
27 | .field_date_type {
28 | min-width: 5em;
29 | text-align: right;
30 | padding: 0.5em 0.5em;
31 | }
32 |
33 | .header {
34 | height: 100%;
35 | width: 100%;
36 | padding: 0.2em 0.5em;
37 | text-align: center;
38 | background-color: #0099ee;
39 | color: #fff;
40 | border: 1px solid #00598a;
41 | }
42 |
43 | .row-placeholder {
44 | padding: 0 0.25rem;
45 | color: #cccccc;
46 | }
47 |
48 | .row-expander {
49 | cursor: pointer;
50 | }
51 |
52 |
53 | .fa-caret-right {
54 | -moz-transition: all 200ms linear;
55 | -webkit-transition: all 200ms linear;
56 | transition: all 200ms linear;
57 | }
58 |
59 | .fa-caret-right.down {
60 | -moz-transform: rotate(90deg);
61 | -webkit-transform: rotate(90deg);
62 | transform: rotate(90deg);
63 | }
64 |
65 | .html-element .flex-container {
66 | /* Enable interacting with inputs only. */
67 | pointer-events: auto;
68 | }
69 |
--------------------------------------------------------------------------------
/src/css/schema-editor.css:
--------------------------------------------------------------------------------
1 | #editor, #test {
2 | margin: 1em auto;
3 | width: 800px;
4 | padding: 1em;
5 | }
6 |
7 | #schema-editor {
8 | border: 1px solid #cccccc;
9 | overflow-y: auto;
10 | flex-grow: 1;
11 | }
12 |
13 | .new-prop-block,
14 | .new-field-elements {
15 | margin-top: -1px;
16 | padding: 0.5em 0.5em 0.5em 1em;
17 | }
18 |
19 | .properties {
20 | padding-left: 1em;
21 | }
22 |
23 | .object-row {
24 | margin-bottom: -1px;
25 | border-left: 1px solid #cccccc;
26 | border-bottom: 1px solid #cccccc;
27 | }
28 |
29 | #schema-editor > .object-row {
30 | border-left: none;
31 | }
32 |
33 | .simple-row {
34 | padding: 0.3em 0 0.3em 1em;
35 | border-left: 1px solid #cccccc;
36 | border-bottom: 1px solid #cccccc;
37 | display: flex;
38 | justify-content: space-between;
39 | }
40 |
41 | .object-row > .simple-row {
42 | border-left: none;
43 | border-right: none;
44 | margin-bottom: -1px;
45 | }
46 |
47 | .empty-placeholder {
48 | font-style: italic;
49 | }
50 |
51 | .new-field-elements {
52 | border-top: 1px solid #cccccc;
53 | }
54 |
55 | .add-btn,
56 | .cancel-btn {
57 | cursor: pointer;
58 | }
59 |
60 | .add-btn:disabled {
61 | cursor: not-allowed;
62 | }
63 |
64 | .remove-btn:disabled {
65 | cursor: not-allowed;
66 | }
67 |
68 | .field-type {
69 | font-style: italic;
70 | }
71 |
72 |
73 | .simple-row .remove-btn-block {
74 | width: 25%;
75 | }
76 |
77 | .remove-btn-block {
78 | display: flex;
79 | justify-content: flex-end;
80 | }
81 |
82 | .property-info {
83 | width: 75%;
84 | display: flex;
85 | justify-content: space-between;
86 | }
87 |
88 | #parser-btn {
89 | float: right;
90 | }
91 |
92 | #form-schema-editor-title {
93 | border: 1px solid #cccccc;
94 | }
--------------------------------------------------------------------------------
/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamilnabiyev/schema-visualizer/7e14552ec83d8c9978e1fe7feda8ac2b9a7de54e/src/favicon.ico
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Schema Visualizer
11 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
158 |
167 |
168 |
169 |
170 |
171 |
176 |
187 |
188 |
189 |
190 |
191 |
196 |
209 |
210 |
211 |
212 |
213 |
230 |
231 |
232 |
233 |
238 |
253 |
254 |
255 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
298 |
299 |
300 |
301 |
341 |
342 |
383 |
384 |
416 |
417 |
418 |
419 |
420 |
421 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/src/js/font-awesome-custom.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileoverview Font Awesome 5
3 | * @link https://fontawesome.com/how-to-use/with-the-api/
4 | */
5 |
6 | import { library, dom } from '@fortawesome/fontawesome-svg-core';
7 |
8 | // Solid
9 | // https://fontawesome.com/icons?d=gallery&s=solid&m=free
10 | import {
11 | faBars,
12 | faBorderStyle,
13 | faCheck,
14 | faFlag,
15 | faInfoCircle,
16 | faExclamationTriangle,
17 | faTrash,
18 | faSearchPlus,
19 | faSearchMinus,
20 | faFolder,
21 | faGripHorizontal,
22 | faExpand,
23 | faArrowsAltH,
24 | faPrint,
25 | faCaretRight,
26 | faFileCode,
27 | faBan,
28 | faPencilAlt,
29 | faChevronDown,
30 | faChevronRight,
31 | faPlus,
32 | faCheckCircle,
33 | faTrashAlt,
34 | faTimesCircle,
35 | faFileImport,
36 | faEdit,
37 | faStream,
38 | faSave,
39 | faFolderOpen
40 | } from '@fortawesome/free-solid-svg-icons';
41 |
42 | import {
43 | faFile,
44 | faFilePdf,
45 | faImage,
46 | faCaretSquareRight,
47 | } from '@fortawesome/free-regular-svg-icons';
48 |
49 |
50 | library.add(faBars, faBorderStyle, faCheck, faFlag, faInfoCircle, faExclamationTriangle,
51 | faTrash, faSearchPlus, faSearchMinus, faFolder, faGripHorizontal, faExpand,
52 | faArrowsAltH, faFile, faSave, faPrint, faFilePdf, faImage, faCaretRight,
53 | faCaretSquareRight, faFileCode, faCheckCircle, faBan, faPencilAlt, faTrashAlt, faChevronDown,
54 | faChevronRight, faPlus, faTimesCircle, faFileImport, faEdit, faStream, faFolderOpen);
55 |
56 |
57 | // automatically find any tags in the page and replace those with