[MAJOR] Added tab bar, fixed bugs
This commit is contained in:
515
package-lock.json
generated
515
package-lock.json
generated
@@ -19,7 +19,9 @@
|
||||
"react-bootstrap": "^2.7.4",
|
||||
"react-dev-utils": "^12.0.1",
|
||||
"react-redux": "^8.0.1",
|
||||
"react-router-dom": "^6.13.0"
|
||||
"react-router-dom": "^6.13.0",
|
||||
"uuid": "^9.0.0",
|
||||
"vite-plugin-svgr": "^3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@storybook/addon-essentials": "^7.0.23",
|
||||
@@ -37,6 +39,7 @@
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/testing-library__jest-dom": "^5.14.5",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
@@ -9478,6 +9481,247 @@
|
||||
"url": "https://opencollective.com/storybook"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-7.0.0.tgz",
|
||||
"integrity": "sha512-khWbXesWIP9v8HuKCl2NU2HNAyqpSQ/vkIl36Nbn4HIwEYSRWL0H7Gs6idJdha2DkpFDWlsqMELvoCE8lfFY6Q==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-7.0.0.tgz",
|
||||
"integrity": "sha512-iiZaIvb3H/c7d3TH2HBeK91uI2rMhZNwnsIrvd7ZwGLkFw6mmunOCoVnjdYua662MqGFxlN9xTq4fv9hgR4VXQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-7.0.0.tgz",
|
||||
"integrity": "sha512-sQQmyo+qegBx8DfFc04PFmIO1FP1MHI1/QEpzcIcclo5OAISsOJPW76ZIs0bDyO/DBSJEa/tDa1W26pVtt0FRw==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-7.0.0.tgz",
|
||||
"integrity": "sha512-i6MaAqIZXDOJeikJuzocByBf8zO+meLwfQ/qMHIjCcvpnfvWf82PFvredEZElErB5glQFJa2KVKk8N2xV6tRRA==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-svg-dynamic-title": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-7.0.0.tgz",
|
||||
"integrity": "sha512-BoVSh6ge3SLLpKC0pmmN9DFlqgFy4NxNgdZNLPNJWBUU7TQpDWeBuyVuDW88iXydb5Cv0ReC+ffa5h3VrKfk1w==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-svg-em-dimensions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-7.0.0.tgz",
|
||||
"integrity": "sha512-tNDcBa+hYn0gO+GkP/AuNKdVtMufVhU9fdzu+vUQsR18RIJ9RWe7h/pSBY338RO08wArntwbDk5WhQBmhf2PaA==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-transform-react-native-svg": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-7.0.0.tgz",
|
||||
"integrity": "sha512-qw54u8ljCJYL2KtBOjI5z7Nzg8LnSvQOP5hPKj77H4VQL4+HdKbAT5pnkkZLmHKYwzsIHSYKXxHouD8zZamCFQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-transform-svg-component": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-7.0.0.tgz",
|
||||
"integrity": "sha512-CcFECkDj98daOg9jE3Bh3uyD9kzevCAnZ+UtzG6+BQG/jOQ2OA3jHnX6iG4G1MCJkUQFnUvEv33NvQfqrb/F3A==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-preset": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-7.0.0.tgz",
|
||||
"integrity": "sha512-EX/NHeFa30j5UjldQGVQikuuQNHUdGmbh9kEpBKofGUtF0GUPJ4T4rhoYiqDAOmBOxojyot36JIFiDUHUK1ilQ==",
|
||||
"dependencies": {
|
||||
"@svgr/babel-plugin-add-jsx-attribute": "^7.0.0",
|
||||
"@svgr/babel-plugin-remove-jsx-attribute": "^7.0.0",
|
||||
"@svgr/babel-plugin-remove-jsx-empty-expression": "^7.0.0",
|
||||
"@svgr/babel-plugin-replace-jsx-attribute-value": "^7.0.0",
|
||||
"@svgr/babel-plugin-svg-dynamic-title": "^7.0.0",
|
||||
"@svgr/babel-plugin-svg-em-dimensions": "^7.0.0",
|
||||
"@svgr/babel-plugin-transform-react-native-svg": "^7.0.0",
|
||||
"@svgr/babel-plugin-transform-svg-component": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/core": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-7.0.0.tgz",
|
||||
"integrity": "sha512-ztAoxkaKhRVloa3XydohgQQCb0/8x9T63yXovpmHzKMkHO6pkjdsIAWKOS4bE95P/2quVh1NtjSKlMRNzSBffw==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@svgr/babel-preset": "^7.0.0",
|
||||
"camelcase": "^6.2.0",
|
||||
"cosmiconfig": "^8.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/core/node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/@svgr/core/node_modules/camelcase": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/core/node_modules/cosmiconfig": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz",
|
||||
"integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==",
|
||||
"dependencies": {
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"parse-json": "^5.0.0",
|
||||
"path-type": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/d-fischer"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/core/node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/hast-util-to-babel-ast": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-7.0.0.tgz",
|
||||
"integrity": "sha512-42Ej9sDDEmsJKjrfQ1PHmiDiHagh/u9AHO9QWbeNx4KmD9yS5d1XHmXUNINfUcykAU+4431Cn+k6Vn5mWBYimQ==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.21.3",
|
||||
"entities": "^4.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/plugin-jsx": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-7.0.0.tgz",
|
||||
"integrity": "sha512-SWlTpPQmBUtLKxXWgpv8syzqIU8XgFRvyhfkam2So8b3BE0OS0HPe5UfmlJ2KIC+a7dpuuYovPR2WAQuSyMoPw==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@svgr/babel-preset": "^7.0.0",
|
||||
"@svgr/hast-util-to-babel-ast": "^7.0.0",
|
||||
"svg-parser": "^2.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
|
||||
@@ -9833,8 +10077,7 @@
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
||||
"peer": true
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA=="
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "4.17.17",
|
||||
@@ -10140,6 +10383,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz",
|
||||
"integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
|
||||
@@ -12644,6 +12893,17 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/envinfo": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.9.0.tgz",
|
||||
@@ -13573,8 +13833,7 @@
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"node_modules/esutils": {
|
||||
"version": "2.0.3",
|
||||
@@ -15031,7 +15290,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||
"integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
@@ -18047,18 +18306,6 @@
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
@@ -18355,7 +18602,6 @@
|
||||
"version": "8.4.24",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
|
||||
"integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -19587,7 +19833,6 @@
|
||||
"version": "3.25.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz",
|
||||
"integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
@@ -19763,7 +20008,7 @@
|
||||
"version": "1.63.4",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.63.4.tgz",
|
||||
"integrity": "sha512-Sx/+weUmK+oiIlI+9sdD0wZHsqpbgQg8wSwSnGBjwb5GwqFhYNwwnI+UWZtLjKvKyFlKkatRK235qQ3mokyPoQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
@@ -20115,7 +20360,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -20420,6 +20664,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/svg-parser": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
|
||||
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ=="
|
||||
},
|
||||
"node_modules/symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||
@@ -21345,7 +21594,6 @@
|
||||
"version": "4.3.9",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz",
|
||||
"integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.17.5",
|
||||
"postcss": "^8.4.23",
|
||||
@@ -21412,6 +21660,40 @@
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-svgr": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-3.2.0.tgz",
|
||||
"integrity": "sha512-Uvq6niTvhqJU6ga78qLKBFJSDvxWhOnyfQSoKpDPMAGxJPo5S3+9hyjExE5YDj6Lpa4uaLkGc1cBgxXov+LjSw==",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.2",
|
||||
"@svgr/core": "^7.0.0",
|
||||
"@svgr/plugin-jsx": "^7.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^2.6.0 || 3 || 4"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-svgr/node_modules/@rollup/pluginutils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vitest": {
|
||||
"version": "0.30.1",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.30.1.tgz",
|
||||
@@ -28605,6 +28887,131 @@
|
||||
"file-system-cache": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@svgr/babel-plugin-add-jsx-attribute": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-7.0.0.tgz",
|
||||
"integrity": "sha512-khWbXesWIP9v8HuKCl2NU2HNAyqpSQ/vkIl36Nbn4HIwEYSRWL0H7Gs6idJdha2DkpFDWlsqMELvoCE8lfFY6Q==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-remove-jsx-attribute": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-7.0.0.tgz",
|
||||
"integrity": "sha512-iiZaIvb3H/c7d3TH2HBeK91uI2rMhZNwnsIrvd7ZwGLkFw6mmunOCoVnjdYua662MqGFxlN9xTq4fv9hgR4VXQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-remove-jsx-empty-expression": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-7.0.0.tgz",
|
||||
"integrity": "sha512-sQQmyo+qegBx8DfFc04PFmIO1FP1MHI1/QEpzcIcclo5OAISsOJPW76ZIs0bDyO/DBSJEa/tDa1W26pVtt0FRw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-replace-jsx-attribute-value": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-7.0.0.tgz",
|
||||
"integrity": "sha512-i6MaAqIZXDOJeikJuzocByBf8zO+meLwfQ/qMHIjCcvpnfvWf82PFvredEZElErB5glQFJa2KVKk8N2xV6tRRA==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-svg-dynamic-title": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-7.0.0.tgz",
|
||||
"integrity": "sha512-BoVSh6ge3SLLpKC0pmmN9DFlqgFy4NxNgdZNLPNJWBUU7TQpDWeBuyVuDW88iXydb5Cv0ReC+ffa5h3VrKfk1w==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-svg-em-dimensions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-7.0.0.tgz",
|
||||
"integrity": "sha512-tNDcBa+hYn0gO+GkP/AuNKdVtMufVhU9fdzu+vUQsR18RIJ9RWe7h/pSBY338RO08wArntwbDk5WhQBmhf2PaA==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-transform-react-native-svg": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-7.0.0.tgz",
|
||||
"integrity": "sha512-qw54u8ljCJYL2KtBOjI5z7Nzg8LnSvQOP5hPKj77H4VQL4+HdKbAT5pnkkZLmHKYwzsIHSYKXxHouD8zZamCFQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-plugin-transform-svg-component": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-7.0.0.tgz",
|
||||
"integrity": "sha512-CcFECkDj98daOg9jE3Bh3uyD9kzevCAnZ+UtzG6+BQG/jOQ2OA3jHnX6iG4G1MCJkUQFnUvEv33NvQfqrb/F3A==",
|
||||
"requires": {}
|
||||
},
|
||||
"@svgr/babel-preset": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-7.0.0.tgz",
|
||||
"integrity": "sha512-EX/NHeFa30j5UjldQGVQikuuQNHUdGmbh9kEpBKofGUtF0GUPJ4T4rhoYiqDAOmBOxojyot36JIFiDUHUK1ilQ==",
|
||||
"requires": {
|
||||
"@svgr/babel-plugin-add-jsx-attribute": "^7.0.0",
|
||||
"@svgr/babel-plugin-remove-jsx-attribute": "^7.0.0",
|
||||
"@svgr/babel-plugin-remove-jsx-empty-expression": "^7.0.0",
|
||||
"@svgr/babel-plugin-replace-jsx-attribute-value": "^7.0.0",
|
||||
"@svgr/babel-plugin-svg-dynamic-title": "^7.0.0",
|
||||
"@svgr/babel-plugin-svg-em-dimensions": "^7.0.0",
|
||||
"@svgr/babel-plugin-transform-react-native-svg": "^7.0.0",
|
||||
"@svgr/babel-plugin-transform-svg-component": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@svgr/core": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-7.0.0.tgz",
|
||||
"integrity": "sha512-ztAoxkaKhRVloa3XydohgQQCb0/8x9T63yXovpmHzKMkHO6pkjdsIAWKOS4bE95P/2quVh1NtjSKlMRNzSBffw==",
|
||||
"requires": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@svgr/babel-preset": "^7.0.0",
|
||||
"camelcase": "^6.2.0",
|
||||
"cosmiconfig": "^8.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
|
||||
},
|
||||
"cosmiconfig": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz",
|
||||
"integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==",
|
||||
"requires": {
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"parse-json": "^5.0.0",
|
||||
"path-type": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"requires": {
|
||||
"argparse": "^2.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@svgr/hast-util-to-babel-ast": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-7.0.0.tgz",
|
||||
"integrity": "sha512-42Ej9sDDEmsJKjrfQ1PHmiDiHagh/u9AHO9QWbeNx4KmD9yS5d1XHmXUNINfUcykAU+4431Cn+k6Vn5mWBYimQ==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.21.3",
|
||||
"entities": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"@svgr/plugin-jsx": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-7.0.0.tgz",
|
||||
"integrity": "sha512-SWlTpPQmBUtLKxXWgpv8syzqIU8XgFRvyhfkam2So8b3BE0OS0HPe5UfmlJ2KIC+a7dpuuYovPR2WAQuSyMoPw==",
|
||||
"requires": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@svgr/babel-preset": "^7.0.0",
|
||||
"@svgr/hast-util-to-babel-ast": "^7.0.0",
|
||||
"svg-parser": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"@swc/helpers": {
|
||||
"version": "0.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
|
||||
@@ -28901,8 +29308,7 @@
|
||||
"@types/estree": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
||||
"peer": true
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA=="
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.17",
|
||||
@@ -29207,6 +29613,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz",
|
||||
"integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
|
||||
@@ -31116,6 +31528,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
|
||||
},
|
||||
"envinfo": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.9.0.tgz",
|
||||
@@ -31806,8 +32223,7 @@
|
||||
"estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.3",
|
||||
@@ -32908,7 +33324,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||
"integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
@@ -35094,14 +35510,6 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"entities": "^4.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"parseurl": {
|
||||
@@ -35329,7 +35737,6 @@
|
||||
"version": "8.4.24",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
|
||||
"integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
@@ -36240,7 +36647,6 @@
|
||||
"version": "3.25.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz",
|
||||
"integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
@@ -36351,7 +36757,7 @@
|
||||
"version": "1.63.4",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.63.4.tgz",
|
||||
"integrity": "sha512-Sx/+weUmK+oiIlI+9sdD0wZHsqpbgQg8wSwSnGBjwb5GwqFhYNwwnI+UWZtLjKvKyFlKkatRK235qQ3mokyPoQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"requires": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
@@ -36635,8 +37041,7 @@
|
||||
"source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.21",
|
||||
@@ -36871,6 +37276,11 @@
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||
},
|
||||
"svg-parser": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
|
||||
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ=="
|
||||
},
|
||||
"symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||
@@ -37575,7 +37985,6 @@
|
||||
"version": "4.3.9",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz",
|
||||
"integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esbuild": "^0.17.5",
|
||||
"fsevents": "~2.3.2",
|
||||
@@ -37597,6 +38006,28 @@
|
||||
"vite": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"vite-plugin-svgr": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-3.2.0.tgz",
|
||||
"integrity": "sha512-Uvq6niTvhqJU6ga78qLKBFJSDvxWhOnyfQSoKpDPMAGxJPo5S3+9hyjExE5YDj6Lpa4uaLkGc1cBgxXov+LjSw==",
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "^5.0.2",
|
||||
"@svgr/core": "^7.0.0",
|
||||
"@svgr/plugin-jsx": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
||||
"requires": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vitest": {
|
||||
"version": "0.30.1",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.30.1.tgz",
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
"react-bootstrap": "^2.7.4",
|
||||
"react-dev-utils": "^12.0.1",
|
||||
"react-redux": "^8.0.1",
|
||||
"react-router-dom": "^6.13.0"
|
||||
"react-router-dom": "^6.13.0",
|
||||
"uuid": "^9.0.0",
|
||||
"vite-plugin-svgr": "^3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@storybook/addon-essentials": "^7.0.23",
|
||||
@@ -56,6 +58,7 @@
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/testing-library__jest-dom": "^5.14.5",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import "./{{pascalCase name}}.component.scss"
|
||||
|
||||
interface {{pascalCase name}}Props {}
|
||||
import { {{pascalCase name}}Props } from "../../../types/components.interface"
|
||||
|
||||
const {{pascalCase name}} = (props: {{pascalCase name}}Props): JSX.Element => {
|
||||
return <div className="ar-{{pascalCase name}}">In Component {{pascalCase name}}</div>
|
||||
|
||||
2
plop-templates/components.interface.ts.hbs
Normal file
2
plop-templates/components.interface.ts.hbs
Normal file
@@ -0,0 +1,2 @@
|
||||
/* PLOP_INJECT_INTERFACE */
|
||||
|
||||
18
plopfile.cjs
18
plopfile.cjs
@@ -47,6 +47,12 @@ module.exports = (plop) => {
|
||||
pattern: `/* PLOP_INJECT_EXPORT */`,
|
||||
template: `\t{{pascalCase name}},`,
|
||||
},
|
||||
{
|
||||
type: "append",
|
||||
path: "src/app/types/components.interface.ts",
|
||||
pattern: `/* PLOP_INJECT_INTERFACE */`,
|
||||
template: `export interface {{pascalCase name}}Props extends BaseProps {\n}\n`,
|
||||
},
|
||||
],
|
||||
})
|
||||
plop.setGenerator("atom", {
|
||||
@@ -97,6 +103,12 @@ module.exports = (plop) => {
|
||||
pattern: `/* PLOP_INJECT_EXPORT */`,
|
||||
template: `\t{{pascalCase name}},`,
|
||||
},
|
||||
{
|
||||
type: "append",
|
||||
path: "src/app/types/components.interface.ts",
|
||||
pattern: `/* PLOP_INJECT_INTERFACE */`,
|
||||
template: `export interface {{pascalCase name}}Props extends BaseProps {\n}\n`,
|
||||
},
|
||||
],
|
||||
})
|
||||
plop.setGenerator("molecule", {
|
||||
@@ -147,6 +159,12 @@ module.exports = (plop) => {
|
||||
pattern: `/* PLOP_INJECT_EXPORT */`,
|
||||
template: `\t{{pascalCase name}},`,
|
||||
},
|
||||
{
|
||||
type: "append",
|
||||
path: "src/app/types/components.interface.ts",
|
||||
pattern: `/* PLOP_INJECT_INTERFACE */`,
|
||||
template: `export interface {{pascalCase name}}Props extends BaseProps {\n}\n`,
|
||||
},
|
||||
],
|
||||
})
|
||||
plop.setGenerator("page", {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Suspense, useEffect } from "react"
|
||||
import { useRoutes } from "react-router-dom"
|
||||
import { AlertProps } from "./components/atoms/Alert/Alert"
|
||||
import { AlertProps } from "./types/components.interface"
|
||||
import Header from "./components/Header"
|
||||
import { useAppSelector } from "./hooks"
|
||||
import { notification } from "./store"
|
||||
import { Alert } from "./components"
|
||||
@@ -22,6 +23,7 @@ const Router = (props: RouterProps) => {
|
||||
|
||||
return (
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<Header />
|
||||
{useRoutes(ROUTES)}
|
||||
<Alert {...alertInfo} />
|
||||
</Suspense>
|
||||
|
||||
@@ -14,7 +14,7 @@ const ComponentList = (props: ComponentListProps): JSX.Element => {
|
||||
const params = treeNode.data?.props
|
||||
treeNode.data?.component &&
|
||||
navigate(
|
||||
Network.stringifyUrl(`/component/${treeNode.data?.component}`, params),
|
||||
Network.stringifyUrl(`/components/${treeNode.data?.component}`, params),
|
||||
)
|
||||
}
|
||||
return (
|
||||
|
||||
@@ -1,31 +1,14 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { ReactNode, useEffect, useState } from "react"
|
||||
import { useLocation } from "react-router-dom"
|
||||
import { createPortal } from "react-dom"
|
||||
import { Alert, Toggle } from ".."
|
||||
import { FrameContentDefinition } from "../../types/entity.interface"
|
||||
import { FrameContentProps } from "../../types/components.interface"
|
||||
import Helper from "../../utils/helper"
|
||||
import COMPONENTS from "../../config/components"
|
||||
import * as images from "../../static/images"
|
||||
import "./Editor.component.scss"
|
||||
|
||||
interface FrameContentDefinition {
|
||||
componentName: string
|
||||
component: JSX.ElementType
|
||||
props?: {
|
||||
[key: string]:
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| { [key: string]: any }
|
||||
| undefined
|
||||
}
|
||||
data: { [key: string]: any }
|
||||
hierarchy: string
|
||||
}
|
||||
interface FrameContentProps {
|
||||
contentDefinition: FrameContentDefinition | null
|
||||
notificationProps?: any
|
||||
}
|
||||
|
||||
const FrameContent = (
|
||||
props: FrameContentProps,
|
||||
): JSX.Element | string | null => {
|
||||
@@ -66,6 +49,7 @@ const Editor = (): JSX.Element | string => {
|
||||
const [selectedComponentDefinition, setSelectedComponentDefinition] =
|
||||
useState<FrameContentDefinition | null>(null)
|
||||
const [theme, setTheme] = useState<string>("th-light-1")
|
||||
const [portal, setPortal] = useState<ReactNode>()
|
||||
const location = useLocation()
|
||||
|
||||
useEffect(() => {
|
||||
@@ -79,12 +63,20 @@ const Editor = (): JSX.Element | string => {
|
||||
const iframeHtml =
|
||||
contentRef?.contentWindow?.document?.getElementsByTagName("html")[0]
|
||||
iframeHtml && iframeHtml.setAttribute("ar-theme", theme)
|
||||
const iframeBody = iframeHtml?.getElementsByTagName("body")[0]
|
||||
iframeBody && (iframeBody.style.backgroundColor = "var(--ar-bg)")
|
||||
if (selectedComponentDefinition && selectedComponentDefinition.props) {
|
||||
selectedComponentDefinition.props.theme = theme
|
||||
}
|
||||
}
|
||||
}, [contentRef, theme])
|
||||
|
||||
useEffect(() => {
|
||||
const locationPathArr = location.pathname.split("/")
|
||||
const componentName = locationPathArr[locationPathArr.length - 1]
|
||||
const locationPathArr = location.pathname
|
||||
.split("/")
|
||||
.filter((p: string) => p)
|
||||
const componentName =
|
||||
locationPathArr.length > 1 && locationPathArr[locationPathArr.length - 1]
|
||||
if (componentName) {
|
||||
const { selectedItem, hierarchy } = Helper.findComponentDescription(
|
||||
componentName,
|
||||
@@ -180,6 +172,19 @@ const Editor = (): JSX.Element | string => {
|
||||
|
||||
const mountNode = contentRef?.contentWindow?.document?.body
|
||||
|
||||
useEffect(() => {
|
||||
mountNode &&
|
||||
setPortal(
|
||||
createPortal(
|
||||
<FrameContent
|
||||
contentDefinition={selectedComponentDefinition}
|
||||
notificationProps={notificationProps}
|
||||
/>,
|
||||
mountNode,
|
||||
),
|
||||
)
|
||||
}, [selectedComponentDefinition, mountNode, notificationProps, theme])
|
||||
|
||||
return (
|
||||
<div className="ar-Editor w-100 h-100 d-flex flex-column">
|
||||
<div className="ar-Editor__tools px-3 py-2">
|
||||
@@ -198,16 +203,9 @@ const Editor = (): JSX.Element | string => {
|
||||
ref={setContentRef}
|
||||
title="Armco form-componentComponent Viewer"
|
||||
>
|
||||
{mountNode &&
|
||||
createPortal(
|
||||
<FrameContent
|
||||
contentDefinition={selectedComponentDefinition}
|
||||
notificationProps={notificationProps}
|
||||
/>,
|
||||
mountNode,
|
||||
)}
|
||||
{/* <div className="ar-Editor__props-container d-inline-block h-100"></div> */}
|
||||
{portal}
|
||||
</iframe>
|
||||
{/* <div className="ar-Editor__props-container d-inline-block h-100"></div> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
.ar-Header {
|
||||
background-color: var(--ar-bg-base);
|
||||
border-bottom: 1px solid var(--ar-color-layout-border);
|
||||
|
||||
.ar-Header__app-logo {
|
||||
cursor: pointer;
|
||||
.ar-Header__brand {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,74 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { useLocation, useNavigate } from "react-router-dom"
|
||||
import { v4 as uuid } from "uuid"
|
||||
import { TabBar } from ".."
|
||||
import { ArTabType } from "../../types/enums"
|
||||
import { TabProps } from "../../types/entity.interface"
|
||||
import { AppLogo } from "../../static/images"
|
||||
import { ReactComponent as AppName } from "../../static/images/Omnia Alkatra.svg"
|
||||
import "./Header.component.scss"
|
||||
|
||||
interface HeaderProps {}
|
||||
const tabs = [
|
||||
{
|
||||
label: "Components",
|
||||
id: uuid(),
|
||||
isActive: true,
|
||||
route: "/components",
|
||||
icon: "cg.CgComponents",
|
||||
},
|
||||
{
|
||||
label: "Icons",
|
||||
id: uuid(),
|
||||
isActive: false,
|
||||
route: "/icons",
|
||||
icon: "md.MdOutlineInsertEmoticon",
|
||||
},
|
||||
{
|
||||
label: "Fonts",
|
||||
id: uuid(),
|
||||
isActive: false,
|
||||
route: "/fonts",
|
||||
icon: "bi.BiFontFamily",
|
||||
},
|
||||
]
|
||||
|
||||
const Header = (props: HeaderProps): JSX.Element => {
|
||||
return <header className="ar-Header w-100"></header>
|
||||
const Header = (): JSX.Element => {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const [activeTabId, setActiveTabId] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
const matchedTab =
|
||||
tabs && tabs.find((tab) => location.pathname.startsWith(tab.route))
|
||||
if (matchedTab) {
|
||||
setActiveTabId(matchedTab.id)
|
||||
}
|
||||
}, [location])
|
||||
return (
|
||||
<header className="ar-Header w-100 flex-v-center px-2">
|
||||
<div className="ar-Header__app-logo" onClick={() => navigate("/")}>
|
||||
<img
|
||||
src={AppLogo}
|
||||
alt="App Logo"
|
||||
className="ar-Header__brand mx-2"
|
||||
width="32"
|
||||
height="32"
|
||||
/>
|
||||
<AppName className="ar-Header__app-name" width="50" />
|
||||
</div>
|
||||
<TabBar
|
||||
classes="ms-auto"
|
||||
data={tabs.map((tab: TabProps) => {
|
||||
tab.isActive = activeTabId === tab.id
|
||||
return tab
|
||||
})}
|
||||
variant={ArTabType.MODERN}
|
||||
onTabSelected={(id: string, data: TabProps) => {
|
||||
data?.data?.route && navigate(data.data.route)
|
||||
}}
|
||||
/>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { ChangeEvent } from "react"
|
||||
import { useAppDispatch } from "../../hooks"
|
||||
import { notify } from "../../store"
|
||||
import { Pagination, Search } from ".."
|
||||
import { Loader, Pagination, Search } from ".."
|
||||
import { ArLoaderTypes } from "../../types/enums"
|
||||
import Helper from "../../utils/helper"
|
||||
import { ICON_ROOT } from "../../config/constants"
|
||||
import "./IconsList.component.scss"
|
||||
@@ -58,7 +59,10 @@ const IconsList = (props: IconsListProps): JSX.Element => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ar-IconsList h-100 w-100 overflow-auto p-3">
|
||||
<div className="ar-IconsList h-100 w-100 overflow-auto position-relative">
|
||||
{!icons && (
|
||||
<Loader label="Loading Icons..." type={ArLoaderTypes.CUSTOM} />
|
||||
)}
|
||||
<div className="ar-IconsList__header-pagination-search py-2 px-3 mb-3 border">
|
||||
<div className="row">
|
||||
<div className="col-2 d-flex align-items-center">
|
||||
@@ -88,14 +92,13 @@ const IconsList = (props: IconsListProps): JSX.Element => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ar-IconsList__icon-tile-container py-2 px-3 border d-flex justify-content-between flex-wrap">
|
||||
{icons &&
|
||||
icons
|
||||
.slice(0, 100)
|
||||
.map((icon, index) => (
|
||||
<IconTile key={index} icon={icon} onClick={onIconTileClick} />
|
||||
))}
|
||||
</div>
|
||||
{icons && (
|
||||
<div className="ar-IconsList__icon-tile-container py-2 px-3 border d-flex justify-content-between flex-wrap">
|
||||
{icons.slice(0, 100).map((icon, index) => (
|
||||
<IconTile key={index} icon={icon} onClick={onIconTileClick} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,9 @@ const Main = (props: MainProps): JSX.Element => {
|
||||
<main className="ar-Main d-flex flex-grow-1 w-100">
|
||||
<Drawer classes="d-flex h-100">{drawerContent}</Drawer>
|
||||
<ErrorBoundary>
|
||||
<Content classes="flex-center p-3">{mainContent}</Content>
|
||||
<Content classes="flex-center p-3 position-relative">
|
||||
{mainContent}
|
||||
</Content>
|
||||
</ErrorBoundary>
|
||||
</main>
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
transition: all 0.3s;
|
||||
border-radius: 0.2rem;
|
||||
opacity: 0;
|
||||
color: white;
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
@@ -67,7 +68,7 @@
|
||||
}
|
||||
&.success {
|
||||
background-color: var(--ar-color-success);
|
||||
color: var(--ar-bg);
|
||||
color: var(--ar-white);
|
||||
}
|
||||
|
||||
.ar-Alert__icon {
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import Icon from "../Icon"
|
||||
import API_CONFIG from "../../../config/api-config"
|
||||
import "./Alert.component.scss"
|
||||
import { AlertProps } from "../../../types/components.interface"
|
||||
import { ICON_ROOT } from "../../../config/constants"
|
||||
|
||||
type AlertType = "success" | "warning" | "error" | "information"
|
||||
export interface AlertProps {
|
||||
classes?: string
|
||||
closeable?: boolean
|
||||
demo?: boolean
|
||||
position?: string
|
||||
show?: boolean
|
||||
type?: AlertType
|
||||
message: string
|
||||
timeout?: number
|
||||
}
|
||||
import "./Alert.component.scss"
|
||||
|
||||
let timeoutRef: any
|
||||
const Alert = (props: AlertProps): JSX.Element => {
|
||||
@@ -35,7 +23,10 @@ const Alert = (props: AlertProps): JSX.Element => {
|
||||
setTimeout(() => show("show"), 0)
|
||||
if (!demo || timeout) {
|
||||
clearTimeout(timeoutRef)
|
||||
timeoutRef = setTimeout(() => show(""), timeout || 5000)
|
||||
timeoutRef = setTimeout(() => {
|
||||
show("")
|
||||
window.top?.postMessage({ ar: null }, "*")
|
||||
}, timeout || 5000)
|
||||
}
|
||||
}
|
||||
}, [position, type, timeout, externalShow, message, demo])
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
import { Alert, Icon } from "../.."
|
||||
import { Alert, Link, LoadableIcon } from "../.."
|
||||
import { BrowserIncompatibilityProps } from "../../../types/components.interface"
|
||||
import Helper from "../../../utils/helper"
|
||||
import { ICON_ROOT } from "../../../config/constants"
|
||||
import "./BrowserIncompatibility.component.scss"
|
||||
|
||||
interface BrowserIncompatibilityProps {
|
||||
applicationName?: string
|
||||
moreLink?: string
|
||||
}
|
||||
|
||||
const BrowserIncompatibility = (
|
||||
props: BrowserIncompatibilityProps,
|
||||
): JSX.Element => {
|
||||
const { applicationName, moreLink } = props
|
||||
const demoDummyLink = "http://notabuck.com/armco-design-system/docs/devices"
|
||||
const { applicationName, moreLink, theme } = props
|
||||
const demoDummyLink = "https://notabuck.com/armco-design-system/docs/devices"
|
||||
const demoAppName = '"My Awesome App"'
|
||||
const helpLink = moreLink || demoDummyLink
|
||||
const app = applicationName || demoAppName
|
||||
const heroIconSize = "8rem"
|
||||
|
||||
return (
|
||||
<div className="ar-BrowserIncompatibility p-3 flex-center flex-column">
|
||||
<Icon
|
||||
src={`${ICON_ROOT}/vsc/VscRunErrors/black/10rem${heroIconSize}`}
|
||||
<LoadableIcon
|
||||
icon="vsc.VscRunErrors"
|
||||
size={heroIconSize}
|
||||
containerClasses="mb-3"
|
||||
color={theme && theme === "th-dark-1" ? "white" : "black"}
|
||||
classes="mb-3"
|
||||
theme={theme}
|
||||
/>
|
||||
<h5 className="mb-3">{app} can not run on this browser</h5>
|
||||
<p className="mb-2">
|
||||
Supported browsers are Google Chrome v51+ & Microsoft's Edge v32+
|
||||
</p>
|
||||
<p>For More details you can also check the below link</p>
|
||||
<div
|
||||
className="ar-BrowserIncompatibility__help-link px-3 py-2"
|
||||
<Link
|
||||
to={helpLink}
|
||||
label={helpLink}
|
||||
classes="ar-BrowserIncompatibility__help-link px-3 py-2"
|
||||
onClick={() => {
|
||||
Helper.copyToClipboard(helpLink)
|
||||
window.top?.postMessage(
|
||||
@@ -40,15 +40,15 @@ const BrowserIncompatibility = (
|
||||
type: "success",
|
||||
closeable: true,
|
||||
message: "Link Copied!",
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
"*",
|
||||
)
|
||||
}}
|
||||
>
|
||||
{helpLink}
|
||||
<Alert message="Link Copied!" />
|
||||
</div>
|
||||
preemptNavigation
|
||||
/>
|
||||
<Alert message="Link Copied!" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,22 +1,7 @@
|
||||
import { MouseEventHandler } from "react"
|
||||
import { ICON_ROOT } from "../../../config/constants"
|
||||
import { IconProps } from "../../../types/components.interface"
|
||||
import "./Icon.component.scss"
|
||||
|
||||
interface IconProps {
|
||||
alt?: string
|
||||
classes?: string
|
||||
color?: string
|
||||
containerClasses?: string
|
||||
demo?: boolean
|
||||
height?: string
|
||||
onClick?: MouseEventHandler
|
||||
onMouseEnter?: MouseEventHandler
|
||||
onMouseLeave?: MouseEventHandler
|
||||
size?: string
|
||||
src: string
|
||||
width?: string
|
||||
}
|
||||
|
||||
const Icon = (props: IconProps): JSX.Element | null => {
|
||||
const {
|
||||
alt,
|
||||
|
||||
@@ -1,10 +1,41 @@
|
||||
import React from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { LinkProps } from "../../../types/components.interface"
|
||||
import "./Link.component.scss"
|
||||
|
||||
interface LinkProps {}
|
||||
|
||||
const Link = (props: any): JSX.Element => {
|
||||
return <div className="ar-Link">In Component Link</div>
|
||||
const Link = (props: LinkProps): JSX.Element => {
|
||||
const {
|
||||
classes,
|
||||
label,
|
||||
to,
|
||||
children,
|
||||
onClick,
|
||||
openInNew,
|
||||
preemptNavigation,
|
||||
} = props
|
||||
const navigate = useNavigate()
|
||||
return (
|
||||
<div
|
||||
className={`ar-Link btn btn-link${classes ? " " + classes : ""}`}
|
||||
onClick={(e) => {
|
||||
if (!preemptNavigation) {
|
||||
if (to) {
|
||||
if (
|
||||
to.startsWith("http://") ||
|
||||
to.startsWith("https://") ||
|
||||
openInNew
|
||||
) {
|
||||
!openInNew ? window.open(to) : window.open(to, "_blank")
|
||||
} else {
|
||||
navigate(to)
|
||||
}
|
||||
}
|
||||
}
|
||||
onClick && onClick(e)
|
||||
}}
|
||||
>
|
||||
{label || children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Link
|
||||
|
||||
3
src/app/components/atoms/LoadableIcon/LoadableIcon.component.scss
Executable file
3
src/app/components/atoms/LoadableIcon/LoadableIcon.component.scss
Executable file
@@ -0,0 +1,3 @@
|
||||
.ar-LoadableIcon {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
6
src/app/components/atoms/LoadableIcon/LoadableIcon.test.ts
Executable file
6
src/app/components/atoms/LoadableIcon/LoadableIcon.test.ts
Executable file
@@ -0,0 +1,6 @@
|
||||
import React from "react"
|
||||
import LoadableIcon from "./LoadableIcon"
|
||||
|
||||
describe("LoadableIcon", () => {
|
||||
it("renders without error", () => {})
|
||||
})
|
||||
113
src/app/components/atoms/LoadableIcon/LoadableIcon.tsx
Executable file
113
src/app/components/atoms/LoadableIcon/LoadableIcon.tsx
Executable file
@@ -0,0 +1,113 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { Network, DomHelper } from "../../../utils"
|
||||
import { LoadableIconProps } from "../../../types/components.interface"
|
||||
import { GenericObject, ObjectType } from "../../../types/types"
|
||||
import "./LoadableIcon.component.scss"
|
||||
|
||||
const parser = new DOMParser()
|
||||
|
||||
// Add below string to prevent API calls for same iconKey,
|
||||
// This value is overriden in promise resolution below
|
||||
const ongoingApiCalls: ObjectType = {}
|
||||
|
||||
const iconsFactory: GenericObject<SVGSVGElement> = {}
|
||||
|
||||
const placeholder = parser
|
||||
.parseFromString(
|
||||
'<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><rect width="20" height="20" x="2" y="2" fill="none" stroke="#000" stroke-width="2"rx="2"></rect></svg>',
|
||||
"image/svg+xml",
|
||||
)
|
||||
.querySelector("svg")
|
||||
|
||||
const LoadableIcon = (props: LoadableIconProps) => {
|
||||
const { classes, color, height, isLocal, size, width } = props
|
||||
let { icon } = props
|
||||
const [b64, setB64] = useState<string>()
|
||||
const [iconContent, setIconContent] = useState<SVGSVGElement | null>(
|
||||
placeholder,
|
||||
)
|
||||
|
||||
icon = !icon || icon.indexOf(".") < 0 ? "gr.GrStatusPlaceholder" : icon
|
||||
const iconParts = icon.split(".")
|
||||
const iconCategory = iconParts[0] ? iconParts[0].toLowerCase() : ""
|
||||
const iconName = iconParts[1]
|
||||
const iconKey = `${iconCategory}_${iconName}`
|
||||
|
||||
const iData = iconsFactory[iconKey]
|
||||
|
||||
const getIcon = () => {
|
||||
if (!ongoingApiCalls[iconKey]) {
|
||||
// console.log("Requesting Icon from Server for the icon: ", iconKey)
|
||||
ongoingApiCalls[iconKey] = true
|
||||
Network.getStatic(`/icon/${iconCategory}/${iconName}`)
|
||||
.then((res) => {
|
||||
const parsedSvg = parser
|
||||
.parseFromString(res.body, "image/svg+xml")
|
||||
.querySelector("svg")
|
||||
if (parsedSvg) {
|
||||
iconsFactory[iconKey] = parsedSvg
|
||||
setIconContent(parsedSvg)
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
ongoingApiCalls[iconKey] = false
|
||||
})
|
||||
.finally(() => (ongoingApiCalls[iconKey] = false))
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
useEffect(() => {
|
||||
if (!isLocal) {
|
||||
if (iconName && iconCategory) {
|
||||
!iData && getIcon()
|
||||
} else {
|
||||
console.log("Icon name and category is required, received: ", icon)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
iconContent && !isLocal && setB64(DomHelper.svgToBase64(iconContent))
|
||||
}, [iconContent])
|
||||
|
||||
useEffect(() => {
|
||||
iData &&
|
||||
!isLocal &&
|
||||
setB64(DomHelper.svgToBase64(iData, { size, classes, color }))
|
||||
}, [size, classes, color])
|
||||
|
||||
if (isLocal) {
|
||||
return (
|
||||
<img
|
||||
className={`ar-LoadableIcon${classes ? " " + classes : ""}`}
|
||||
src={icon}
|
||||
style={{
|
||||
width: width || size || "1rem",
|
||||
height: height || size || "1rem",
|
||||
}}
|
||||
alt="Icon"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
// Below is only for property changes after first render like on hover, click etc
|
||||
if (iData && !b64) {
|
||||
setB64(DomHelper.svgToBase64(iData, { size, classes, color }))
|
||||
}
|
||||
|
||||
return b64 ? (
|
||||
<img
|
||||
className={`ar-LoadableIcon${classes ? " " + classes : ""}`}
|
||||
src={`data:image/svg+xml;base64,${b64}`}
|
||||
style={{
|
||||
width: width || size || "1rem",
|
||||
height: height || size || "1rem",
|
||||
}}
|
||||
alt="Icon"
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
|
||||
export default LoadableIcon
|
||||
3
src/app/components/atoms/LoadableIcon/index.ts
Executable file
3
src/app/components/atoms/LoadableIcon/index.ts
Executable file
@@ -0,0 +1,3 @@
|
||||
import LoadableIcon from "./LoadableIcon"
|
||||
|
||||
export default LoadableIcon
|
||||
74
src/app/components/atoms/Loader/Loader.component.scss
Executable file
74
src/app/components/atoms/Loader/Loader.component.scss
Executable file
@@ -0,0 +1,74 @@
|
||||
.ar-Loader {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
z-index: 1001;
|
||||
.ar-Loader-content {
|
||||
position: absolute;
|
||||
|
||||
&.custom {
|
||||
top: calc(50% - 25px);
|
||||
left: calc(50% - 25px);
|
||||
.loader {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
animation: rotating 5s infinite;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&.circle {
|
||||
top: calc(50% - 25px);
|
||||
left: calc(50% - 25px);
|
||||
.loader {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
animation: effect 1s linear infinite;
|
||||
border-radius: 50%;
|
||||
border: 6px solid #a3bdda;
|
||||
border-top-color: #3B77BC;
|
||||
}
|
||||
}
|
||||
|
||||
&.small .loader {
|
||||
top: calc(50% - 12.5px);
|
||||
left: calc(50% - 12.5px);
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
&.large .loader {
|
||||
top: calc(50% - 50px);
|
||||
left: calc(50% - 50px);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes effect {
|
||||
0% {transform: rotate(0deg);}
|
||||
100% {transform: rotate(360deg);}
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
animation-timing-function: linear; /* Constant speed for the first 4s */
|
||||
}
|
||||
25% {
|
||||
transform: rotate(1800deg); /* 10 rotations (10 x 360 degrees) */
|
||||
animation-timing-function: linear; /* Constant speed for the next 1s */
|
||||
}
|
||||
50% {
|
||||
transform: rotate(3600deg); /* 6 rotations (6 x 360 degrees) */
|
||||
animation-timing-function: cubic-bezier(0, -200, 1, -200); /* Slow down for the next 4s */
|
||||
}
|
||||
75% {
|
||||
transform: rotate(4320deg); /* 10 rotations (10 x 360 degrees) */
|
||||
animation-timing-function: cubic-bezier(0, -200, 1, -200); /* Constant speed for the next 1s */
|
||||
}
|
||||
100% {
|
||||
transform: rotate(5040deg); /* 12 rotations (12 x 360 degrees) */
|
||||
animation-timing-function: linear; /* Constant speed for the last 4s */
|
||||
}
|
||||
}
|
||||
}
|
||||
8
src/app/components/atoms/Loader/Loader.test.ts
Executable file
8
src/app/components/atoms/Loader/Loader.test.ts
Executable file
@@ -0,0 +1,8 @@
|
||||
import React from "react"
|
||||
import Loader from "./Loader"
|
||||
|
||||
describe("Loader", () => {
|
||||
it("renders without error", () => {
|
||||
|
||||
})
|
||||
})
|
||||
48
src/app/components/atoms/Loader/Loader.tsx
Executable file
48
src/app/components/atoms/Loader/Loader.tsx
Executable file
@@ -0,0 +1,48 @@
|
||||
import { LoaderProps } from "../../../types/components.interface"
|
||||
import { ArLoaderTypes } from "../../../types/enums"
|
||||
import { LoadableIcon, ProgressIndicator } from "../.."
|
||||
import { AppLogo } from "../../../static/images"
|
||||
import "./Loader.component.scss"
|
||||
|
||||
// Add ability to provide custom loader: an icon or image that rotates
|
||||
const Loader = (props: LoaderProps): JSX.Element => {
|
||||
const { type = ArLoaderTypes.CIRCLE, size, label, icon, progress } = props
|
||||
let loaderContent
|
||||
switch (type) {
|
||||
case ArLoaderTypes.BAR:
|
||||
loaderContent = <ProgressIndicator progress={progress} />
|
||||
break
|
||||
case ArLoaderTypes.CUSTOM:
|
||||
loaderContent = (
|
||||
<>
|
||||
<span className="loader">
|
||||
<LoadableIcon icon={icon || AppLogo} size="50px" isLocal />
|
||||
</span>
|
||||
{label ? <span className="mt-3">{label}</span> : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
case ArLoaderTypes.CIRCLE:
|
||||
default:
|
||||
loaderContent = (
|
||||
<>
|
||||
<span className="loader" />
|
||||
{label ? <span className="mt-3">{label}</span> : ""}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="position-absolute ar-Loader h-100 w-100">
|
||||
<div
|
||||
className={`ar-Loader-content flex-column flex-center${
|
||||
type ? " " + type : ""
|
||||
}${size ? " " + size : ""}`}
|
||||
>
|
||||
{loaderContent}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Loader
|
||||
3
src/app/components/atoms/Loader/index.ts
Executable file
3
src/app/components/atoms/Loader/index.ts
Executable file
@@ -0,0 +1,3 @@
|
||||
import Loader from "./Loader"
|
||||
|
||||
export default Loader
|
||||
@@ -1,14 +1,11 @@
|
||||
import React from "react"
|
||||
import "./ProgressIndicator.component.scss"
|
||||
|
||||
interface ProgressIndicatorProps {}
|
||||
|
||||
const ProgressIndicator = (props: any): JSX.Element => {
|
||||
return (
|
||||
<div className="ar-ProgressIndicator">
|
||||
In Component ProgressIndicator
|
||||
</div>
|
||||
<div className="ar-ProgressIndicator">In Component ProgressIndicator</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ProgressIndicator
|
||||
export default ProgressIndicator
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
.ar-Tab {
|
||||
width: 5rem;
|
||||
height: 2rem;
|
||||
max-width: 10rem;
|
||||
max-height: 3rem;
|
||||
line-height: 1;
|
||||
border: var(--ar-border);
|
||||
border-radius: 6px 6px 0 0;
|
||||
padding: 0.4rem 1rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
|
||||
&:hover {
|
||||
&:hover:not(.active) {
|
||||
background-color: var(--ar-bg-hover);
|
||||
}
|
||||
|
||||
.active {
|
||||
|
||||
&.active {
|
||||
// background-color: var(--ar-bg-selected);
|
||||
}
|
||||
|
||||
.compact {
|
||||
&.compact {
|
||||
|
||||
}
|
||||
|
||||
.comfortable {
|
||||
&.comfortable {
|
||||
|
||||
}
|
||||
|
||||
.modern {
|
||||
&.modern {
|
||||
|
||||
}
|
||||
|
||||
.classic {
|
||||
|
||||
&.classic {
|
||||
border: var(--ar-border);
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
|
||||
.ar-Tab__delete-icon {
|
||||
|
||||
@@ -1,55 +1,78 @@
|
||||
import Icon from "../Icon"
|
||||
import { memo, useEffect, useRef } from "react"
|
||||
import { TabProps } from "../../../types/components.interface"
|
||||
import { LoadableIcon, Icon } from "../.."
|
||||
import "./Tab.component.scss"
|
||||
|
||||
export interface TabProps {
|
||||
label: string
|
||||
data?: any
|
||||
demo?: boolean
|
||||
deletable?: boolean
|
||||
id?: string
|
||||
isActive?: boolean
|
||||
onSelect?: Function
|
||||
size?: string
|
||||
variant?: string
|
||||
}
|
||||
|
||||
const dummyData = {
|
||||
label: "Tab 1",
|
||||
id: "23jhrfl2l3lkj2lk3jlkjlsd",
|
||||
isActive: false,
|
||||
}
|
||||
|
||||
const Tab = (props: TabProps): JSX.Element => {
|
||||
const {
|
||||
label,
|
||||
data,
|
||||
demo,
|
||||
deletable,
|
||||
id,
|
||||
isActive,
|
||||
onSelect,
|
||||
size,
|
||||
variant,
|
||||
} = props
|
||||
const useLabel = label ? label : demo ? dummyData.label : label
|
||||
return (
|
||||
<div
|
||||
className={`ar-Tab position-relative${isActive ? " active" : ""}${
|
||||
size ? " " + size : ""
|
||||
}${variant ? " " + variant : ""}${deletable ? " pe-3" : ""}`}
|
||||
id={id || useLabel}
|
||||
onClick={() => onSelect && onSelect(id, data)}
|
||||
>
|
||||
{deletable && (
|
||||
<Icon
|
||||
containerClasses="ar-Tab__delete-icon position-absolute"
|
||||
src="rx/RxCross2"
|
||||
size="0.8rem"
|
||||
/>
|
||||
)}
|
||||
{useLabel}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const Tab = memo(
|
||||
(props: TabProps): JSX.Element => {
|
||||
const {
|
||||
bubbleDimensions,
|
||||
data,
|
||||
demo,
|
||||
deletable,
|
||||
icon,
|
||||
id,
|
||||
isActive,
|
||||
label,
|
||||
onSelect,
|
||||
size,
|
||||
variant,
|
||||
} = props
|
||||
const tabRef = useRef<HTMLDivElement>(null)
|
||||
let useLabel = label ? label : demo ? dummyData.label : label
|
||||
|
||||
useEffect(() => {
|
||||
if (isActive && bubbleDimensions) {
|
||||
const selectedTabDimensions =
|
||||
tabRef.current && tabRef.current.getBoundingClientRect()
|
||||
let selectedWidth, selectedLeft
|
||||
if (selectedTabDimensions) {
|
||||
selectedWidth = selectedTabDimensions.width
|
||||
selectedLeft = tabRef.current.offsetLeft
|
||||
}
|
||||
bubbleDimensions(selectedWidth, selectedLeft)
|
||||
}
|
||||
}, [isActive, bubbleDimensions])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ar-Tab position-relative h-100 flex-center px-2 fw-bold${
|
||||
isActive ? " active" : ""
|
||||
}${size ? " " + size : ""}${variant ? " " + variant : ""}${
|
||||
deletable ? " pe-3" : ""
|
||||
}`}
|
||||
id={id || useLabel}
|
||||
onClick={() => onSelect && onSelect(id, props)}
|
||||
ref={tabRef}
|
||||
>
|
||||
{deletable && (
|
||||
<Icon
|
||||
containerClasses="ar-Tab__delete-icon position-absolute"
|
||||
src="rx/RxCross2"
|
||||
size="0.8rem"
|
||||
/>
|
||||
)}
|
||||
{useLabel}
|
||||
{icon && <LoadableIcon classes="ms-1" icon={icon} />}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
(prevProps, props) => {
|
||||
return (
|
||||
prevProps.isActive === props.isActive &&
|
||||
JSON.stringify(prevProps.data) === JSON.stringify(props.data) &&
|
||||
prevProps.icon === props.icon &&
|
||||
prevProps.label === props.label &&
|
||||
prevProps.size === props.size &&
|
||||
prevProps.variant === props.variant
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
export default Tab
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
.ar-TabBar {
|
||||
height: 3.1rem;
|
||||
font-size: 0.8rem;
|
||||
|
||||
.slider {
|
||||
height: 100%;
|
||||
border-bottom: 3px solid blue; /* Change to your desired border color */
|
||||
bottom: 0;
|
||||
background-color: var(--ar-bg-selected);
|
||||
}
|
||||
|
||||
&.modern {
|
||||
.slider {
|
||||
transition: left 0.3s, width 0.3s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { TabProps } from "../Tab/Tab"
|
||||
import { Tab } from "../.."
|
||||
import { TabBarProps, TabProps } from "../../../types/components.interface"
|
||||
import { ObjectType } from "../../../types/types"
|
||||
import "./TabBar.component.scss"
|
||||
|
||||
interface TabBarProps {
|
||||
activeId?: string
|
||||
data: TabProps[]
|
||||
demo?: boolean
|
||||
onTabChanged?: (id: string, data: any) => void
|
||||
size?: string
|
||||
variant?: string
|
||||
}
|
||||
|
||||
const dummyData = [
|
||||
{
|
||||
label: "Tab 1",
|
||||
@@ -31,39 +23,93 @@ const dummyData = [
|
||||
]
|
||||
|
||||
const TabBar = (props: TabBarProps): JSX.Element => {
|
||||
const { data, demo, onTabChanged, size, variant, activeId } = props
|
||||
const [activeTab, setActiveTab] = useState<string>()
|
||||
const {
|
||||
classes,
|
||||
data,
|
||||
demo,
|
||||
onTabSelected,
|
||||
size,
|
||||
variant,
|
||||
activeId,
|
||||
...rest
|
||||
} = props
|
||||
const [activeTab, setActiveTab] = useState<ObjectType>()
|
||||
const useData = data || (demo && dummyData)
|
||||
|
||||
useEffect(() => {
|
||||
demo && !activeId && setActiveTab({ id: "23jhrfl2l3lkj2lk3jlkjlsd" })
|
||||
if (activeId !== undefined) {
|
||||
setActiveTab(activeId)
|
||||
setActiveTab({ id: activeId })
|
||||
} else {
|
||||
const activeTab = data && data.find((t) => t.isActive)
|
||||
if (activeTab && activeTab.id) {
|
||||
setActiveTab({ id: activeTab.id })
|
||||
}
|
||||
}
|
||||
}, [activeId])
|
||||
const onLocalTabChanged = (id: string, data: any) => {
|
||||
if (activeId === undefined) {
|
||||
setActiveTab(id)
|
||||
}
|
||||
onTabChanged && onTabChanged(id, data)
|
||||
}, [activeId, data, demo])
|
||||
|
||||
const receiveDimensionsOfSelectedTab = (
|
||||
selectedWidth?: number,
|
||||
selectedLeft?: number,
|
||||
) => {
|
||||
setActiveTab({ ...activeTab, selectedWidth, selectedLeft })
|
||||
}
|
||||
|
||||
const onLocalTabSelected = (id: string, data: any) => {
|
||||
if (activeTab) {
|
||||
if (id !== activeTab.id) {
|
||||
setActiveTab({ ...activeTab, id })
|
||||
onTabSelected && onTabSelected(id, data)
|
||||
}
|
||||
} else {
|
||||
setActiveTab({ id })
|
||||
onTabSelected && onTabSelected(id, data)
|
||||
}
|
||||
}
|
||||
|
||||
const tabRenders = useData
|
||||
?.filter((t) => t)
|
||||
.map((tab: TabProps) => {
|
||||
return (
|
||||
<Tab
|
||||
label={tab.label}
|
||||
bubbleDimensions={receiveDimensionsOfSelectedTab}
|
||||
data={tab}
|
||||
icon={tab.icon}
|
||||
id={tab.id}
|
||||
isActive={activeTab === tab.id}
|
||||
onSelect={onLocalTabChanged}
|
||||
variant={variant}
|
||||
size={size}
|
||||
isActive={activeTab && activeTab.id === tab.id}
|
||||
label={tab.label}
|
||||
onSelect={onLocalTabSelected}
|
||||
/>
|
||||
)
|
||||
})
|
||||
return (
|
||||
<div
|
||||
className={`ar-TabBar d-flex${variant ? " " + variant : ""}${
|
||||
size ? " " + size : ""
|
||||
}`}
|
||||
className={`ar-TabBar d-flex position-relative${
|
||||
variant ? " " + variant : ""
|
||||
}${size ? " " + size : ""}${classes ? " " + classes : ""}`}
|
||||
{...rest}
|
||||
>
|
||||
{tabRenders}
|
||||
{activeTab &&
|
||||
activeTab.selectedLeft !== undefined &&
|
||||
activeTab.selectedWidth !== undefined && (
|
||||
<div
|
||||
className="position-absolute slider"
|
||||
role="presentation"
|
||||
style={{
|
||||
left:
|
||||
typeof activeTab.selectedLeft === "number"
|
||||
? activeTab.selectedLeft
|
||||
: 0,
|
||||
width:
|
||||
typeof activeTab.selectedWidth === "number"
|
||||
? activeTab.selectedWidth
|
||||
: 0,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* PLOP_INJECT_IMPORT */
|
||||
import Loader from "./atoms/Loader"
|
||||
import LoadableIcon from "./atoms/LoadableIcon"
|
||||
import ErrorBoundary from "./molecules/ErrorBoundary"
|
||||
import Component_404 from "./molecules/Component_404"
|
||||
import AlertStackManager from "./molecules/AlertStackManager"
|
||||
@@ -114,6 +116,8 @@ import Alert from "./atoms/Alert"
|
||||
|
||||
export {
|
||||
/* PLOP_INJECT_EXPORT */
|
||||
Loader,
|
||||
LoadableIcon,
|
||||
ErrorBoundary,
|
||||
Component_404,
|
||||
AlertStackManager,
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
.ar-Component_404 {
|
||||
|
||||
.ar-Component_404-content {
|
||||
height: 30rem;
|
||||
min-width: 30rem;
|
||||
font-size: 0.8rem;
|
||||
border: var(--ar-border);
|
||||
background-color: var(--ar-bg-base);
|
||||
transition: box-shadow 0.3s;
|
||||
&:hover {
|
||||
box-shadow: 0px 4px 8px var(--ar-shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
import { Component_404Props } from "../../../types/components.interface"
|
||||
import { Icon } from "../.."
|
||||
import "./Component_404.component.scss"
|
||||
|
||||
interface Component_404Props {}
|
||||
|
||||
const Component_404 = (props: Component_404Props): JSX.Element => {
|
||||
return <div className="ar-Component_404">In Component Component_404</div>
|
||||
const { iconSize } = props
|
||||
return (
|
||||
<div className="ar-Component_404 flex-center h-100">
|
||||
<div className="ar-Component_404-content border flex-v-center flex-column p-3">
|
||||
<Icon src="gi/GiDigHole" size={iconSize || "20rem"} />
|
||||
<h5 className="mb-4">Could not dig what you asked for</h5>
|
||||
<p className="mb-2">Please check the URL and try again.</p>
|
||||
<p className="mb-1">
|
||||
You may also use the tabs (right-top) to navigate if you're not sure
|
||||
about the URL
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Component_404
|
||||
|
||||
@@ -4,7 +4,7 @@ const API_CONFIG: ApiConfig = {
|
||||
production: "https://armco.tech/api",
|
||||
},
|
||||
STATIC_HOST: {
|
||||
development: "http://localhost:8080",
|
||||
development: "https://static.armco.tech",
|
||||
production: "https://static.armco.tech",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -209,6 +209,15 @@ const COMPONENTS: ComponentList = {
|
||||
props: [],
|
||||
variants: {},
|
||||
},
|
||||
{
|
||||
name: "Loader",
|
||||
props: ["type", "label", "size"],
|
||||
variants: {
|
||||
size: ["small", "regular", "large"],
|
||||
label: ["Loading Users...", "Submitting Report..."],
|
||||
type: ["bar", "circle", "custom"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ProgressIndicator",
|
||||
props: [],
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Main from "../../components/Main"
|
||||
import Header from "../../components/Header"
|
||||
import Footer from "../../components/Footer"
|
||||
import ComponentList from "../../components/ComponentList"
|
||||
import Editor from "../../components/Editor"
|
||||
@@ -12,8 +11,7 @@ const ComponentsViewerPage = (
|
||||
props: ComponentsViewerPageProps,
|
||||
): JSX.Element => {
|
||||
return (
|
||||
<div className="ar-ComponentsViewerPage vh-100 d-flex flex-column">
|
||||
<Header />
|
||||
<div className="ar-ComponentsViewerPage d-flex flex-column">
|
||||
<Main
|
||||
drawerContent={<ComponentList />}
|
||||
mainContent={
|
||||
|
||||
3
src/app/pages/FontsPage/FontsPage.page.scss
Executable file
3
src/app/pages/FontsPage/FontsPage.page.scss
Executable file
@@ -0,0 +1,3 @@
|
||||
.ar-FontsPage {
|
||||
|
||||
}
|
||||
18
src/app/pages/FontsPage/FontsPage.slice.ts
Normal file
18
src/app/pages/FontsPage/FontsPage.slice.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { createSlice } from "@reduxjs/toolkit"
|
||||
|
||||
export interface FontsPageState {}
|
||||
|
||||
const initialState: FontsPageState = {}
|
||||
|
||||
export const fontsPageSlice = createSlice({
|
||||
name: "fontsPage",
|
||||
initialState,
|
||||
reducers: {
|
||||
increment: (state) => {},
|
||||
},
|
||||
extraReducers: (builder) => {},
|
||||
})
|
||||
|
||||
export const { increment } = fontsPageSlice.actions
|
||||
|
||||
export default fontsPageSlice.reducer
|
||||
8
src/app/pages/FontsPage/FontsPage.test.ts
Executable file
8
src/app/pages/FontsPage/FontsPage.test.ts
Executable file
@@ -0,0 +1,8 @@
|
||||
import React from "react"
|
||||
import FontsPage from "./FontsPage"
|
||||
|
||||
describe("FontsPage", () => {
|
||||
it("renders without error", () => {
|
||||
|
||||
})
|
||||
})
|
||||
9
src/app/pages/FontsPage/FontsPage.tsx
Executable file
9
src/app/pages/FontsPage/FontsPage.tsx
Executable file
@@ -0,0 +1,9 @@
|
||||
import "./FontsPage.page.scss"
|
||||
|
||||
interface FontsPageProps {}
|
||||
|
||||
const FontsPage = (props: FontsPageProps): JSX.Element => {
|
||||
return <div className="ar-FontsPage">Be Here Soon</div>
|
||||
}
|
||||
|
||||
export default FontsPage
|
||||
3
src/app/pages/FontsPage/index.ts
Executable file
3
src/app/pages/FontsPage/index.ts
Executable file
@@ -0,0 +1,3 @@
|
||||
import FontsPage from "./FontsPage"
|
||||
|
||||
export default FontsPage
|
||||
@@ -2,8 +2,8 @@ import { useEffect, useState } from "react"
|
||||
import { Filters } from "../../components"
|
||||
import Footer from "../../components/Footer"
|
||||
import Main from "../../components/Main"
|
||||
import Header from "../../components/Header"
|
||||
import IconsList from "../../components/IconsList"
|
||||
import { ObjectType } from "../../types/types"
|
||||
import Network from "../../utils/network"
|
||||
import Helper from "../../utils/helper"
|
||||
import "./IconsPage.page.scss"
|
||||
@@ -51,7 +51,7 @@ const IconsPage = (props: IconsPageProps): JSX.Element => {
|
||||
(filters.alphabet as Array<BasicFilterConfig>).map(
|
||||
(al: BasicFilterConfig) => al.value,
|
||||
)
|
||||
Helper.matchArrayFilters(
|
||||
finalFilteredIconList = Helper.matchArrayFilters(
|
||||
finalFilteredIconList,
|
||||
alphabet,
|
||||
"name",
|
||||
@@ -63,18 +63,20 @@ const IconsPage = (props: IconsPageProps): JSX.Element => {
|
||||
if (categories) {
|
||||
Object.keys(categories).forEach((category) => {
|
||||
const categoryValue = categories[category as keyof BasicFilterType]
|
||||
Helper.matchArrayFilters(
|
||||
finalFilteredIconList,
|
||||
categoryValue,
|
||||
"group",
|
||||
)
|
||||
if ((categoryValue as Array<ObjectType>).length > 0) {
|
||||
finalFilteredIconList = Helper.matchArrayFilters(
|
||||
finalFilteredIconList,
|
||||
categoryValue,
|
||||
"group",
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const countFilter =
|
||||
filters.count && "data" in filters.count && filters.count.data
|
||||
if (countFilter) {
|
||||
finalFilteredIconList = finalFilteredIconList.slice(
|
||||
finalFilteredIconList = finalFilteredIconList?.slice(
|
||||
"startIndex" in countFilter ? +countFilter.startIndex : 0,
|
||||
"endIndex" in countFilter ? +countFilter.endIndex : 0,
|
||||
)
|
||||
@@ -85,8 +87,7 @@ const IconsPage = (props: IconsPageProps): JSX.Element => {
|
||||
}, [filters, icons, searchText])
|
||||
|
||||
return (
|
||||
<div className="ar-IconsPage vh-100 d-flex flex-column">
|
||||
<Header />
|
||||
<div className="ar-IconsPage d-flex flex-column">
|
||||
<Main
|
||||
drawerContent={
|
||||
<Filters
|
||||
@@ -97,7 +98,6 @@ const IconsPage = (props: IconsPageProps): JSX.Element => {
|
||||
onFilterChange={setFilters}
|
||||
/>
|
||||
}
|
||||
// mainContent={<IconsList icons={filteredIcons || icons} />}
|
||||
mainContent={
|
||||
<IconsList icons={filteredIcons} onSearchChanged={setSearchText} />
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* PLOP_INJECT_IMPORT */
|
||||
import FontsPage from "./FontsPage"
|
||||
import DocsPage from "./DocsPage"
|
||||
import IconsPage from "./IconsPage"
|
||||
import ComponentsViewerPage from "./ComponentsViewerPage"
|
||||
@@ -6,6 +7,7 @@ import PlaygroundPage from "./PlaygroundPage"
|
||||
|
||||
export {
|
||||
/* PLOP_INJECT_EXPORT */
|
||||
FontsPage,
|
||||
DocsPage,
|
||||
IconsPage,
|
||||
ComponentsViewerPage,
|
||||
|
||||
@@ -15,7 +15,17 @@ const ROUTES = [
|
||||
element: "IconsPage",
|
||||
},
|
||||
{
|
||||
path: "/component/:name",
|
||||
path: "/fonts",
|
||||
class: "fonts",
|
||||
element: "FontsPage",
|
||||
},
|
||||
{
|
||||
path: "/components",
|
||||
class: "component-viewer",
|
||||
element: "ComponentsViewerPage",
|
||||
},
|
||||
{
|
||||
path: "/components/:name",
|
||||
class: "component-viewer",
|
||||
element: "ComponentsViewerPage",
|
||||
},
|
||||
@@ -24,6 +34,11 @@ const ROUTES = [
|
||||
class: "docs",
|
||||
element: "DocsPage",
|
||||
},
|
||||
{
|
||||
path: "*",
|
||||
class: "not-a-route",
|
||||
element: "Component_404",
|
||||
},
|
||||
]
|
||||
|
||||
export default ROUTES
|
||||
|
||||
BIN
src/app/static/images/ARC_logo.jpeg
Normal file
BIN
src/app/static/images/ARC_logo.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
BIN
src/app/static/images/ARC_logo1.jpeg
Normal file
BIN
src/app/static/images/ARC_logo1.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
1
src/app/static/images/Omnia Alkatra.svg
Normal file
1
src/app/static/images/Omnia Alkatra.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 12 KiB |
1
src/app/static/images/Omnia.svg
Normal file
1
src/app/static/images/Omnia.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 12 KiB |
@@ -1,3 +1,4 @@
|
||||
import AppLogo from "./ARC_logo.jpeg"
|
||||
import Balloon from "./balloon.jpg"
|
||||
|
||||
export { Balloon }
|
||||
export { AppLogo, Balloon }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@use "./variables";
|
||||
@use "bootstrap/scss/bootstrap.scss";
|
||||
@import "../../static/styles/mixins";
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
@@ -12,12 +13,14 @@ html, body, #root {
|
||||
}
|
||||
|
||||
body {
|
||||
@include drawer-header-footer-layout;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen'
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: var(--ar-color-font);
|
||||
}
|
||||
|
||||
code {
|
||||
@@ -60,6 +63,11 @@ code {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-h-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.h-0 {
|
||||
height: 0 !important;
|
||||
min-height: 0 !important;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// heights and layout
|
||||
--ar-height-header: 3rem;
|
||||
--ar-height-footer: 1.5rem;
|
||||
--ar-white: rgba(250, 250, 240);
|
||||
--ar-color-font-danger-faded: rgba(243, 32, 19, 0.7);
|
||||
--ar-color-font-success-faded: rgba(92, 184, 92, 0.7);
|
||||
--ar-color-font-info-faded: rgba(13, 202, 240, 0.7);
|
||||
@@ -52,7 +53,7 @@
|
||||
--ar-color-primary: #3232d8;
|
||||
--ar-color-primary-faded: rgba(50, 50, 216, 0.7);
|
||||
--ar-color-secondary: #525252;
|
||||
--ar-bg-base: #030307;
|
||||
--ar-bg-base: #101010;
|
||||
--ar-bg: black;
|
||||
--ar-bg-hover: #0a0700;
|
||||
--ar-bg-hover-2: #1f1c15;
|
||||
|
||||
110
src/app/types/components.interface.ts
Normal file
110
src/app/types/components.interface.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { MouseEventHandler, ReactNode } from "react"
|
||||
import { ArAlertType, ArLoaderTypes, ArSizes } from "./enums"
|
||||
import { FrameContentDefinition } from "./entity.interface"
|
||||
|
||||
export interface BaseProps {
|
||||
classes?: string
|
||||
containerClasses?: string
|
||||
childClasses?: string
|
||||
theme?: string
|
||||
}
|
||||
|
||||
/* PLOP_INJECT_INTERFACE */
|
||||
export interface LoaderProps extends BaseProps {
|
||||
type?: ArLoaderTypes
|
||||
size?: ArSizes
|
||||
label?: string
|
||||
icon?: string
|
||||
progress?: number
|
||||
}
|
||||
|
||||
export interface LoadableIconProps extends BaseProps {
|
||||
color?: string
|
||||
icon?: string
|
||||
height?: string
|
||||
isLocal?: boolean
|
||||
size?: string
|
||||
width?: string
|
||||
}
|
||||
|
||||
export interface IconProps extends BaseProps {
|
||||
alt?: string
|
||||
color?: string
|
||||
demo?: boolean
|
||||
height?: string
|
||||
onClick?: MouseEventHandler
|
||||
onMouseEnter?: MouseEventHandler
|
||||
onMouseLeave?: MouseEventHandler
|
||||
size?: string
|
||||
src: string
|
||||
width?: string
|
||||
}
|
||||
|
||||
export interface TabProps extends BaseProps {
|
||||
bubbleDimensions?: Function
|
||||
data?: any
|
||||
demo?: boolean
|
||||
deletable?: boolean
|
||||
icon?: string
|
||||
id?: string
|
||||
isActive?: boolean
|
||||
label: string
|
||||
onSelect?: Function
|
||||
size?: string
|
||||
variant?: string
|
||||
}
|
||||
|
||||
export interface TabBarProps extends BaseProps {
|
||||
activeId?: string
|
||||
data: TabProps[]
|
||||
demo?: boolean
|
||||
onTabSelected?: (id: string, data: any) => void
|
||||
size?: string
|
||||
variant?: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface AlertProps extends BaseProps {
|
||||
closeable?: boolean
|
||||
demo?: boolean
|
||||
position?: string
|
||||
show?: boolean
|
||||
type?: ArAlertType
|
||||
message: string
|
||||
timeout?: number
|
||||
}
|
||||
|
||||
export interface BrowserIncompatibilityProps extends BaseProps {
|
||||
applicationName?: string
|
||||
moreLink?: string
|
||||
}
|
||||
|
||||
interface LinkBaseProps extends BaseProps {
|
||||
to: string
|
||||
onClick?: MouseEventHandler
|
||||
openInNew?: boolean
|
||||
preemptNavigation?: boolean
|
||||
}
|
||||
interface LinkLabelProps extends LinkBaseProps {
|
||||
label: string
|
||||
}
|
||||
|
||||
interface LinkChildrenProps extends LinkBaseProps {
|
||||
children: ReactNode
|
||||
}
|
||||
export type LinkProps =
|
||||
| (LinkLabelProps & Partial<LinkChildrenProps>)
|
||||
| (Partial<LinkLabelProps> & LinkChildrenProps)
|
||||
|
||||
export interface Component_404Props extends BaseProps {
|
||||
iconSize?: string
|
||||
}
|
||||
|
||||
export interface FrameContentProps extends BaseProps {
|
||||
contentDefinition: FrameContentDefinition | null
|
||||
notificationProps?: any
|
||||
}
|
||||
|
||||
// export interface LoaderProps extends BaseProps {
|
||||
|
||||
// }
|
||||
15
src/app/types/entity.interface.ts
Normal file
15
src/app/types/entity.interface.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export interface FrameContentDefinition {
|
||||
componentName: string
|
||||
component: JSX.ElementType
|
||||
props?: {
|
||||
theme?: string
|
||||
[key: string]:
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| { [key: string]: any }
|
||||
| undefined
|
||||
}
|
||||
data: { [key: string]: any }
|
||||
hierarchy: string
|
||||
}
|
||||
29
src/app/types/enums.ts
Normal file
29
src/app/types/enums.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export enum ArTabType {
|
||||
CLASSIC = "classic",
|
||||
MODERN = "modern",
|
||||
}
|
||||
|
||||
export enum ArAriaRoles {
|
||||
TAB = "tab",
|
||||
}
|
||||
|
||||
export enum ArAlertType {
|
||||
SUCCESS = "success",
|
||||
WARNING = "warning",
|
||||
ERROR = "error",
|
||||
INFORMATION = "information",
|
||||
}
|
||||
|
||||
export enum ArSizes {
|
||||
XSMALL = "xsmall",
|
||||
SMALL = "small",
|
||||
REGULAR = "regular",
|
||||
LARGE = "large",
|
||||
XLARGE = "xlarge",
|
||||
}
|
||||
|
||||
export enum ArLoaderTypes {
|
||||
BAR = "bar",
|
||||
CIRCLE = "circle",
|
||||
CUSTOM = "custom",
|
||||
}
|
||||
14
src/app/types/types.ts
Normal file
14
src/app/types/types.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export type ObjectType = {
|
||||
[key: string]:
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| undefined
|
||||
| ObjectType
|
||||
| ArrayType
|
||||
}
|
||||
|
||||
export type ArrayType = Array<string | number | boolean | ObjectType>
|
||||
|
||||
export type GenericObject<T> = { [key: string]: T }
|
||||
23
src/app/utils/domHelper.ts
Normal file
23
src/app/utils/domHelper.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { LoadableIconProps } from "../types/entity.interface"
|
||||
|
||||
class DOMHelper {
|
||||
static svgToBase64(svg: SVGSVGElement, svgProps?: LoadableIconProps) {
|
||||
const { size, classes, color } = svgProps || {}
|
||||
svg.setAttribute("height", size || "1rem")
|
||||
svg.setAttribute("width", size || "1rem")
|
||||
svg.setAttribute("class", classes || "")
|
||||
svg.setAttribute("stroke", color || "black")
|
||||
const path = svg.querySelector("path")
|
||||
// Override stroke and color of "path" node inside SVG at below line.
|
||||
path &&
|
||||
color &&
|
||||
!!path.getAttribute("stroke") &&
|
||||
path.setAttribute("stroke", color)
|
||||
// path && color && !!path.getAttribute("fill") && path.setAttribute("fill", color);
|
||||
svg.style.color = color || "black"
|
||||
const serializedSvg = new XMLSerializer().serializeToString(svg)
|
||||
return btoa(serializedSvg)
|
||||
}
|
||||
}
|
||||
|
||||
export default DOMHelper
|
||||
@@ -202,7 +202,7 @@ class Helper {
|
||||
: searchList.filter(
|
||||
(item) =>
|
||||
filters.findIndex(
|
||||
(al) => item[match].toLowerCase() === al.toLowerCase(),
|
||||
(al) => item[match].toLowerCase() === al.value.toLowerCase(),
|
||||
) > -1,
|
||||
)
|
||||
}
|
||||
|
||||
6
src/app/utils/index.ts
Normal file
6
src/app/utils/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import DomHelper from "./domHelper"
|
||||
import Adapter from "./adapters"
|
||||
import Helper from "./helper"
|
||||
import Network from "./network"
|
||||
|
||||
export { DomHelper, Adapter, Helper, Network }
|
||||
@@ -27,8 +27,8 @@ export default class Network {
|
||||
|
||||
static async getStatic(
|
||||
url: string,
|
||||
queryParams: object | null,
|
||||
options: Options | null,
|
||||
queryParams?: object | null,
|
||||
options?: Options | null,
|
||||
) {
|
||||
let urlString = Network.stringifyUrl(url, queryParams)
|
||||
const environment = process.env.NODE_ENV || "development"
|
||||
@@ -119,7 +119,7 @@ export default class Network {
|
||||
throw new Error(err.message, err.error)
|
||||
}
|
||||
|
||||
static stringifyUrl(url: string, queryParams: any) {
|
||||
static stringifyUrl(url: string, queryParams?: any) {
|
||||
return url
|
||||
? queryParams
|
||||
? Object.keys(queryParams).reduce(
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { defineConfig } from "vitest/config"
|
||||
import react from "@vitejs/plugin-react"
|
||||
import path from "path"
|
||||
import svgr from "vite-plugin-svgr"
|
||||
import { visualizer } from "rollup-plugin-visualizer"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
svgr(),
|
||||
react(),
|
||||
// visualizer({
|
||||
// template: "treemap", // or sunburst
|
||||
@@ -26,7 +28,7 @@ export default defineConfig({
|
||||
},
|
||||
build: {
|
||||
outDir: "build",
|
||||
// sourcemap: true,
|
||||
sourcemap: true,
|
||||
rollupOptions: {
|
||||
treeshake: true,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user