diff --git a/package-lock.json b/package-lock.json index e748f456..53c541f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,8 +25,11 @@ "next": "^14.0.4", "next-redux-wrapper": "^8.1.0", "react": "^18", + "react-csv": "^2.2.2", "react-date-range": "^2.0.0-alpha.4", "react-dom": "^18", + "react-drag-drop-files": "^2.3.10", + "react-json-tree": "^0.18.0", "react-redux": "^9.0.4", "react-router-dom": "^6.21.2" }, @@ -62,10 +65,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" @@ -138,6 +154,168 @@ "node": ">=4" } }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "peer": true + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", @@ -149,6 +327,56 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "peer": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", @@ -165,6 +393,29 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", + "peer": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/highlight": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", @@ -242,6 +493,31 @@ "node": ">=4" } }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.23.8", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", @@ -265,10 +541,51 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", - "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -388,6 +705,11 @@ } } }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, "node_modules/@emotion/unitless": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", @@ -1065,7 +1387,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1079,7 +1400,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1088,7 +1408,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1096,14 +1415,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2029,6 +2346,11 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/base16": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.5.tgz", + "integrity": "sha512-OzOWrTluG9cwqidEzC/Q6FAmIPcnZfm8BFRlIx0+UIUqnuAmi5OS88O0RpT3Yz6qdmqObvUhasrbNsCofE4W9A==" + }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", @@ -2044,6 +2366,11 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==" + }, "node_modules/@types/node": { "version": "20.10.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", @@ -2553,12 +2880,32 @@ "npm": ">=6" } }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base16": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", + "integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==" + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2594,7 +2941,6 @@ "version": "4.22.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "dev": true, "funding": [ { "type": "opencollective", @@ -2664,6 +3010,14 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001565", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", @@ -2769,6 +3123,15 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2785,6 +3148,28 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2861,6 +3246,24 @@ "node": ">= 8" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-vendor": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", @@ -2906,7 +3309,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3039,8 +3441,7 @@ "node_modules/electron-to-chromium": { "version": "1.4.605", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.605.tgz", - "integrity": "sha512-V52j+P5z6cdRqTjPR/bYNxx7ETCHIkm5VIGuyCy3CMrfSnbEpIlLnk5oHmZo7gYvDfh2TfHeanB6rawyQ23ktg==", - "dev": true + "integrity": "sha512-V52j+P5z6cdRqTjPR/bYNxx7ETCHIkm5VIGuyCy3CMrfSnbEpIlLnk5oHmZo7gYvDfh2TfHeanB6rawyQ23ktg==" }, "node_modules/email-addresses": { "version": "5.0.0", @@ -3984,6 +4385,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -4764,6 +5174,17 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -4977,6 +5398,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.assignwith": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", @@ -4992,6 +5418,11 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, + "node_modules/lodash.curry": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", + "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -5149,8 +5580,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mui-datatables": { "version": "4.3.0", @@ -5312,8 +5742,7 @@ "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5606,7 +6035,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -5874,8 +6302,7 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -5996,6 +6423,25 @@ "node": ">=0.10.0" } }, + "node_modules/react-base16-styling": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.9.1.tgz", + "integrity": "sha512-1s0CY1zRBOQ5M3T61wetEpvQmsYSNtWEcdYzyZNxKa8t7oDvaOn9d21xrGezGAHFWLM7SHcktPuPTrvoqxSfKw==", + "dependencies": { + "@babel/runtime": "^7.16.7", + "@types/base16": "^1.0.2", + "@types/lodash": "^4.14.178", + "base16": "^1.0.0", + "color": "^3.2.1", + "csstype": "^3.0.10", + "lodash.curry": "^4.1.1" + } + }, + "node_modules/react-csv": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz", + "integrity": "sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw==" + }, "node_modules/react-date-range": { "version": "2.0.0-alpha.4", "resolved": "https://registry.npmjs.org/react-date-range/-/react-date-range-2.0.0-alpha.4.tgz", @@ -6051,11 +6497,38 @@ "react": "^18.2.0" } }, + "node_modules/react-drag-drop-files": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/react-drag-drop-files/-/react-drag-drop-files-2.3.10.tgz", + "integrity": "sha512-Fv614W9+OtXFB5O+gjompTxQZLYGO7wJeT4paETGiXtiADB9yPOMGYD4A3PMCTY9Be874/wcpl+2dm3MvCIRzg==", + "dependencies": { + "prop-types": "^15.7.2", + "styled-components": "^5.3.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-json-tree": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.18.0.tgz", + "integrity": "sha512-Qe6HKSXrr++n9Y31nkRJ3XvQMATISpqigH1vEKhLwB56+nk5thTP0ITThpjxY6ZG/ubpVq/aEHIcyLP/OPHxeA==", + "dependencies": { + "@babel/runtime": "^7.20.6", + "@types/lodash": "^4.14.191", + "react-base16-styling": "^0.9.1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", @@ -6527,6 +7000,11 @@ "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6562,6 +7040,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6731,6 +7222,59 @@ "node": ">=0.8.0" } }, + "node_modules/styled-components": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "node_modules/styled-components/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/styled-components/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -7153,7 +7697,6 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index 704c15fa..0d6af1b8 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,11 @@ "next": "^14.0.4", "next-redux-wrapper": "^8.1.0", "react": "^18", + "react-csv": "^2.2.2", "react-date-range": "^2.0.0-alpha.4", "react-dom": "^18", + "react-drag-drop-files": "^2.3.10", + "react-json-tree": "^0.18.0", "react-redux": "^9.0.4", "react-router-dom": "^6.21.2" }, diff --git a/src/Lib/Features/actions/getDatasetsByType.js b/src/Lib/Features/actions/getDatasetsByType.js new file mode 100644 index 00000000..55dabb54 --- /dev/null +++ b/src/Lib/Features/actions/getDatasetsByType.js @@ -0,0 +1,39 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetsByType = createAsyncThunk( + 'getDatasetsByType/fetchDatasetsByType', + async (datasetType, { dispatch }) => { + const params = fetchParams(`${ENDPOINTS.getDatasets}instances/?dataset_type=${datasetType}`,"POST"); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const getDatasetsByType = createSlice({ + name: 'getDatasetsByType', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetsByType.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetsByType.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetsByType.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default getDatasetsByType.reducer; diff --git a/src/Lib/Features/datasets/DatasetSearchPopup.js b/src/Lib/Features/datasets/DatasetSearchPopup.js new file mode 100644 index 00000000..8c2190c5 --- /dev/null +++ b/src/Lib/Features/datasets/DatasetSearchPopup.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetSearchPopup = createAsyncThunk( + 'DatasetSearchPopup/fetchDatasetSearchPopup', + async (taskObj, { dispatch }) => { + const body ={taskObj} + const params = fetchParams(`${ENDPOINTS.getDatasets}dataitems/get_data_items/`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const DatasetSearchPopup = createSlice({ + name: 'DatasetSearchPopup', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetSearchPopup.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetSearchPopup.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetSearchPopup.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default DatasetSearchPopup.reducer; diff --git a/src/Lib/Features/datasets/GetDataitemsById.js b/src/Lib/Features/datasets/GetDataitemsById.js new file mode 100644 index 00000000..e599978e --- /dev/null +++ b/src/Lib/Features/datasets/GetDataitemsById.js @@ -0,0 +1,46 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDataitemsById = createAsyncThunk( + 'GetDataitemsById/fetchDataitemsById', + async (instanceIds, datasetType,selectedFilters,pageNo, countPerPage, { dispatch }) => { + const body ={ + instance_ids: instanceIds, + dataset_type: datasetType, + search_keys:selectedFilters + } + const queryString = `?${pageNo ? "&page="+pageNo : ""}${countPerPage ?"&records="+countPerPage : ""}` + + const params = fetchParams(`${ENDPOINTS.getDatasets}dataitems/get_data_items/${queryString}`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDataitemsById = createSlice({ + name: 'GetDataitemsById', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDataitemsById.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDataitemsById.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDataitemsById.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDataitemsById.reducer; diff --git a/src/Lib/Features/datasets/GetDatasetDetailedReports.js b/src/Lib/Features/datasets/GetDatasetDetailedReports.js new file mode 100644 index 00000000..a410455e --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasetDetailedReports.js @@ -0,0 +1,52 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetDetailedReports = createAsyncThunk( + 'GetDatasetDetailedReports/fetchDatasetDetailedReports', + async (dataId, projectType, userId, statistics, { dispatch }) => { + const body={ + dataset_id: dataId, + user_id: userId, + project_type: projectType, + } + + if(statistics === 1){ + body.annotation_statistics = true; + }else if(statistics === 2){ + body["meta-info_statistics"] = true; + }else if(statistics === 3){ + body.complete_statistics = true; + }; + const params = fetchParams(`/functions/schedule_project_reports_email`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDatasetDetailedReports = createSlice({ + name: 'GetDatasetDetailedReports', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetDetailedReports.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetDetailedReports.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetDetailedReports.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasetDetailedReports.reducer; diff --git a/src/Lib/Features/datasets/GetDatasetDownloadCSV.js b/src/Lib/Features/datasets/GetDatasetDownloadCSV.js new file mode 100644 index 00000000..ee1745f0 --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasetDownloadCSV.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetDownloadCSV = createAsyncThunk( + 'GetDatasetDownloadCSV/fetchDatasetDownloadCSV', + async (datasetId, { dispatch }) => { + + const params = fetchParams(`}${ENDPOINTS.getDatasets}instances/${datasetId}/download/?export_type=CSV`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDatasetDownloadCSV = createSlice({ + name: 'GetDatasetDownloadCSV', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetDownloadCSV.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetDownloadCSV.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetDownloadCSV.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasetDownloadCSV.reducer; diff --git a/src/Lib/Features/datasets/GetDatasetDownloadJSON.js b/src/Lib/Features/datasets/GetDatasetDownloadJSON.js new file mode 100644 index 00000000..17320eef --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasetDownloadJSON.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetDownloadJSON = createAsyncThunk( + 'GetDatasetDownloadJSON/fetchDatasetDownloadJSON', + async (datasetId, { dispatch }) => { + + const params = fetchParams(`}${ENDPOINTS.getDatasets}instances/${datasetId}/download/?export_type=JSON`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDatasetDownloadJSON = createSlice({ + name: 'GetDatasetDownloadJSON', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetDownloadJSON.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetDownloadJSON.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetDownloadJSON.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasetDownloadJSON.reducer; diff --git a/src/Lib/Features/datasets/GetDatasetDownloadTSV.js b/src/Lib/Features/datasets/GetDatasetDownloadTSV.js new file mode 100644 index 00000000..d8662c40 --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasetDownloadTSV.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetDownloadTSV = createAsyncThunk( + 'GetDatasetDownloadTSV/fetchDatasetDownloadTSV', + async (datasetId, { dispatch }) => { + + const params = fetchParams(`}${ENDPOINTS.getDatasets}instances/${datasetId}/download/?export_type=TSV`); + return fetch(params.url, params.options) + .then(response => response.TSV()) + } +); + +const GetDatasetDownloadTSV = createSlice({ + name: 'GetDatasetDownloadTSV', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetDownloadTSV.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetDownloadTSV.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetDownloadTSV.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasetDownloadTSV.reducer; diff --git a/src/Lib/Features/datasets/GetDatasetLogs.js b/src/Lib/Features/datasets/GetDatasetLogs.js new file mode 100644 index 00000000..1b69c8b6 --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasetLogs.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetLogs = createAsyncThunk( + 'GetDatasetLogs/fetchDatasetLogs', + async (instanceId, taskName, { dispatch }) => { + + const params = fetchParams(`${ENDPOINTS.getDatasets}instances/${instanceId}/get_async_task_results/?task_name=${taskName}`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDatasetLogs = createSlice({ + name: 'GetDatasetLogs', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetLogs.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetLogs.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetLogs.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasetLogs.reducer; diff --git a/src/Lib/Features/datasets/GetDatasetProjects.js b/src/Lib/Features/datasets/GetDatasetProjects.js new file mode 100644 index 00000000..83b3ebcb --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasetProjects.js @@ -0,0 +1,42 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetProjects = createAsyncThunk( + 'GetDatasetProjects/fetchDatasetProjects', + async (datasetId, { dispatch }) => { + + const params = fetchParams(`${ + ENDPOINTS.getDatasets + }instances/${datasetId}/projects/`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDatasetProjects = createSlice({ + name: 'GetDatasetProjects', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetProjects.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetProjects.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetProjects.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasetProjects.reducer; diff --git a/src/Lib/Features/datasets/GetDatasetType.js b/src/Lib/Features/datasets/GetDatasetType.js new file mode 100644 index 00000000..2f8bee03 --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasetType.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, + }; + + export const fetchDatasetType = createAsyncThunk( + 'GetDatasetType/fetchDatasetType', + async (datasetType,{ dispatch }) => { + const params = fetchParams(`${ENDPOINTS.getDatasets}instances/dataset_types/`); + return fetch(params.url, params.options) + .then(response => response.json()) + } + ); + + const GetDatasetType = createSlice({ + name: 'GetDatasetType', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetType.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetType.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetType.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, + }); + + export default GetDatasetType.reducer; + \ No newline at end of file diff --git a/src/Lib/Features/datasets/GetDatasets.js b/src/Lib/Features/datasets/GetDatasets.js new file mode 100644 index 00000000..01ba41c5 --- /dev/null +++ b/src/Lib/Features/datasets/GetDatasets.js @@ -0,0 +1,57 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasets = createAsyncThunk( + 'GetDatasets/fetchDatasets', + async (selectedFilters, { dispatch }) => { + let queryString = ""; + + for (let key in selectedFilters) { + if (selectedFilters[key] && selectedFilters[key] !== "") { + switch (key) { + case 'dataset_visibility': + queryString += `${key}=${selectedFilters[key]}` + break; + case 'dataset_type': + queryString += `&${key}=${selectedFilters[key]}` + break; + + default: + queryString += `` + + } + } + } + const params = fetchParams(`${ENDPOINTS.getDatasets}instances/?${queryString}`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDatasets = createSlice({ + name: 'GetDatasets', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasets.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasets.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasets.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasets.reducer; diff --git a/src/Lib/Features/datasets/GetFileTypes.js b/src/Lib/Features/datasets/GetFileTypes.js new file mode 100644 index 00000000..3e94f54c --- /dev/null +++ b/src/Lib/Features/datasets/GetFileTypes.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchFileTypes = createAsyncThunk( + 'GetFileTypes/fetchFileTypes', + async ( { dispatch }) => { + + const params = fetchParams(`${ENDPOINTS.getDatasets}instances/accepted_filetypes/`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetFileTypes = createSlice({ + name: 'GetFileTypes', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchFileTypes.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchFileTypes.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchFileTypes.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetFileTypes.reducer; diff --git a/src/Lib/Features/datasets/GetIndicTransLanguages.js b/src/Lib/Features/datasets/GetIndicTransLanguages.js new file mode 100644 index 00000000..f52cb774 --- /dev/null +++ b/src/Lib/Features/datasets/GetIndicTransLanguages.js @@ -0,0 +1,39 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchIndicTransLanguages = createAsyncThunk( + 'GetIndicTransLanguages/fetchIndicTransLanguages', + async ( { dispatch }) => { + const params = fetchParams(`${ENDPOINTS.functions}get_indic_trans_supported_languages`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetIndicTransLanguages = createSlice({ + name: 'GetIndicTransLanguages', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchIndicTransLanguages.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchIndicTransLanguages.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchIndicTransLanguages.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetIndicTransLanguages.reducer; diff --git a/src/Lib/Features/datasets/getDatasetDetails.js b/src/Lib/Features/datasets/getDatasetDetails.js new file mode 100644 index 00000000..3ebcbc2f --- /dev/null +++ b/src/Lib/Features/datasets/getDatasetDetails.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetDetails = createAsyncThunk( + 'GetDatasetDetails/fetchDatasetDetails', + async (datasetId, { dispatch }) => { + + const params = fetchParams(`${ENDPOINTS.getDatasets}instances/${datasetId}`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetDatasetDetails = createSlice({ + name: 'GetDatasetDetails', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetDetails.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetDetails.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetDetails.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetDatasetDetails.reducer; diff --git a/src/Lib/Features/datasets/getDatasetMembers.js b/src/Lib/Features/datasets/getDatasetMembers.js new file mode 100644 index 00000000..cd3354f4 --- /dev/null +++ b/src/Lib/Features/datasets/getDatasetMembers.js @@ -0,0 +1,42 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetMembers = createAsyncThunk( + 'getDatasetMembers/fetchDatasetMembers', + async (datasetId, { dispatch }) => { + + const params = fetchParams(`${ + ENDPOINTS.getDatasets + }instances/${datasetId}/users/`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const getDatasetMembers = createSlice({ + name: 'getDatasetMembers', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetMembers.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetMembers.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetMembers.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default getDatasetMembers.reducer; diff --git a/src/Lib/Features/datasets/getDatasetProjectReports.js b/src/Lib/Features/datasets/getDatasetProjectReports.js new file mode 100644 index 00000000..de114a68 --- /dev/null +++ b/src/Lib/Features/datasets/getDatasetProjectReports.js @@ -0,0 +1,45 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDatasetProjectReports = createAsyncThunk( + 'getDatasetProjectReports/fetchDatasetProjectReports', + async (datasetId, projectType, language, { dispatch }) => { + const body=language === "all" ? { + project_type: projectType + } : { + project_type: projectType, + tgt_language: language, + } + const params = fetchParams(`${ENDPOINTS.getDatasets}instances/${datasetId}/project_analytics/`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const getDatasetProjectReports = createSlice({ + name: 'getDatasetProjectReports', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDatasetProjectReports.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDatasetProjectReports.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDatasetProjectReports.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default getDatasetProjectReports.reducer; diff --git a/src/Lib/Features/getProjectReport.js b/src/Lib/Features/getProjectReport.js new file mode 100644 index 00000000..cf740f12 --- /dev/null +++ b/src/Lib/Features/getProjectReport.js @@ -0,0 +1,44 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../fetchParams'; +import ENDPOINTS from "../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchProjectReport = createAsyncThunk( + 'getProjectReport/fetchProjectReport', + async (projectId, startDate, endDate,reports_type, { dispatch }) => { + const body ={ + from_date: startDate, + to_date: endDate, + reports_type: reports_type, + }; + const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/get_analytics/`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const getProjectReport = createSlice({ + name: 'getProjectReport', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchProjectReport.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchProjectReport.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchProjectReport.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default getProjectReport.reducer; diff --git a/src/Lib/Features/projects/DownloadJSONProject.js b/src/Lib/Features/projects/DownloadJSONProject.js new file mode 100644 index 00000000..71204829 --- /dev/null +++ b/src/Lib/Features/projects/DownloadJSONProject.js @@ -0,0 +1,46 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" + + +const initialState = { + data: [], + status: 'idle', + error: null, + }; + + export const fetchDownloadJSONProject = createAsyncThunk( + 'DownloadJSONProject/fetchDownloadJSONProject', + async (projectId, taskStatus ,downloadMetadataToggle,{ dispatch }) => { + const projectBody={} + const body = { + projectBody + } + const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/download/?export_type=JSON&task_status=${taskStatus}&include_input_data_metadata_json=${downloadMetadataToggle}`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } + ); + + const DownloadJSONProject = createSlice({ + name: 'DownloadJSONProject', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDownloadJSONProject.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDownloadJSONProject.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDownloadJSONProject.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, + }); + + export default DownloadJSONProject.reducer; + \ No newline at end of file diff --git a/src/Lib/Features/projects/DownloadProjectCsv.js b/src/Lib/Features/projects/DownloadProjectCsv.js new file mode 100644 index 00000000..71d1e54f --- /dev/null +++ b/src/Lib/Features/projects/DownloadProjectCsv.js @@ -0,0 +1,46 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" + + +const initialState = { + data: [], + status: 'idle', + error: null, + }; + + export const fetchDownloadCSVProject = createAsyncThunk( + 'DownloadCSVProject/fetchDownloadCSVProject', + async (projectId, taskStatus ,downloadMetadataToggle,{ dispatch }) => { + const projectBody={} + const body = { + projectBody + } + const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/download/?export_type=CSV&task_status=${taskStatus}&include_input_data_metadata_json=${downloadMetadataToggle}`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } + ); + + const DownloadCSVProject = createSlice({ + name: 'DownloadCSVProject', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDownloadCSVProject.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDownloadCSVProject.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDownloadCSVProject.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, + }); + + export default DownloadCSVProject.reducer; + \ No newline at end of file diff --git a/src/Lib/Features/projects/DownloadProjectTsv.js b/src/Lib/Features/projects/DownloadProjectTsv.js new file mode 100644 index 00000000..5a10165a --- /dev/null +++ b/src/Lib/Features/projects/DownloadProjectTsv.js @@ -0,0 +1,46 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" + + +const initialState = { + data: [], + status: 'idle', + error: null, + }; + + export const fetchDownloadTSVProject = createAsyncThunk( + 'DownloadTSVProject/fetchDownloadTSVProject', + async (projectId, taskStatus ,downloadMetadataToggle,{ dispatch }) => { + const projectBody={} + const body = { + projectBody + } + const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/download/?export_type=CSV&task_status=${taskStatus}&include_input_data_metadata_json=${downloadMetadataToggle}`,"POST",body); + return fetch(params.url, params.options) + .then(response => response.json()) + } + ); + + const DownloadTSVProject = createSlice({ + name: 'DownloadTSVProject', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDownloadTSVProject.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDownloadTSVProject.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDownloadTSVProject.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, + }); + + export default DownloadTSVProject.reducer; + \ No newline at end of file diff --git a/src/Lib/Features/projects/ResendUserInvite.js b/src/Lib/Features/projects/GetArchiveProject.js similarity index 53% rename from src/Lib/Features/projects/ResendUserInvite.js rename to src/Lib/Features/projects/GetArchiveProject.js index 27a17885..367ccf47 100644 --- a/src/Lib/Features/projects/ResendUserInvite.js +++ b/src/Lib/Features/projects/GetArchiveProject.js @@ -7,34 +7,33 @@ const initialState = { error: null, }; -export const fetchResendUserInvite = createAsyncThunk( - 'ResendUserInvite/fetchResendUserInvite', - async (projectId,projectObj,type, { dispatch }) => { - let queryStr = type == "PROJECT_SUPERCHECKER" ? "remove_superchecker" : "remove_reviewer"; - const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/${queryStr}/`,method='POST',projectObj); +export const fetchArchiveProject = createAsyncThunk( + 'getArchiveProject/fetchArchiveProject', + async (projectId, { dispatch }) => { + const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/archive/`,"POST"); return fetch(params.url, params.options) .then(response => response.json()) } ); -const ResendUserInvite = createSlice({ - name: 'ResendUserInvite', +const getArchiveProject = createSlice({ + name: 'getArchiveProject', initialState, reducers: {}, extraReducers: (builder) => { builder - .addCase(fetchResendUserInvite.pending, (state) => { + .addCase(fetchArchiveProject.pending, (state) => { state.status = 'loading'; }) - .addCase(fetchResendUserInvite.fulfilled, (state, action) => { + .addCase(fetchArchiveProject.fulfilled, (state, action) => { state.status = 'succeeded'; state.data = action.payload; }) - .addCase(fetchResendUserInvite.rejected, (state, action) => { + .addCase(fetchArchiveProject.rejected, (state, action) => { state.status = 'failed'; state.error = action.error.message; }); }, }); -export default ResendUserInvite.reducer; +export default getArchiveProject.reducer; diff --git a/src/Lib/Features/projects/GetProjectTypeDetails.js b/src/Lib/Features/projects/GetProjectTypeDetails.js new file mode 100644 index 00000000..d7e57e98 --- /dev/null +++ b/src/Lib/Features/projects/GetProjectTypeDetails.js @@ -0,0 +1,39 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchProjectTypeDetails = createAsyncThunk( + 'GetProjectTypeDetails/fetchProjectTypeDetails', + async (projecType, { dispatch }) => { + const params = fetchParams(`${ENDPOINTS.getProjects}types/?project_type=${projecType}`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetProjectTypeDetails = createSlice({ + name: 'GetProjectTypeDetails', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchProjectTypeDetails.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchProjectTypeDetails.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchProjectTypeDetails.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetProjectTypeDetails.reducer; diff --git a/src/Lib/Features/projects/getAllTaskData.js b/src/Lib/Features/projects/getAllTaskData.js index b87b501c..4f0c571a 100644 --- a/src/Lib/Features/projects/getAllTaskData.js +++ b/src/Lib/Features/projects/getAllTaskData.js @@ -1,6 +1,7 @@ import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import fetchParams from '../../fetchParams'; import ENDPOINTS from "../../../config/apiendpoint" + const initialState = { data: [], status: 'idle', diff --git a/src/Lib/Features/searchProjectCard.js b/src/Lib/Features/searchProjectCard.js new file mode 100644 index 00000000..762b9c79 --- /dev/null +++ b/src/Lib/Features/searchProjectCard.js @@ -0,0 +1,18 @@ +import { createSlice } from '@reduxjs/toolkit'; + +const initialState = { + searchValue: "", +}; + +const searchProjectCard = createSlice({ + name: 'searchProjectCard', + initialState, + reducers: { + setSearchProjectCard: (state, action) => { + state.searchValue = action.payload; + }, + }, +}); + +export const { setSearchProjectCard } = searchProjectCard.actions; +export default searchProjectCard.reducer; diff --git a/src/Lib/Features/user/FetchLoggedInUserData.js b/src/Lib/Features/user/FetchLoggedInUserData.js deleted file mode 100644 index e9370940..00000000 --- a/src/Lib/Features/user/FetchLoggedInUserData.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * FetchLoggedInUserData - */ - - import API from "@/Constants/api"; -import ENDPOINTS from "../../../config/apiendpoint" -import constants from "@/Constants/constants"; - - export default class FetchLoggedInUserDataAPI extends API { - constructor(timeout = 2000) { - super("GET", timeout, false); - this.type = constants.GET_LOGGED_IN_USER_DATA; - this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.fetch}me/fetch/`; - } - - processResponse(res) { - super.processResponse(res); - if (res) { - this.UserData = res; - } - } - - apiEndPoint() { - return this.endpoint; - } - - getBody() {} - - getHeaders() { - this.headers = { - headers: { - "Content-Type": "application/json", - "Authorization": `JWT ${localStorage.getItem("anudesh_access_token")}` - }, - }; - return this.headers; - } - - getPayload() { - return this.UserData - } - } - \ No newline at end of file diff --git a/src/Lib/Features/user/GetProjectLogs.js b/src/Lib/Features/user/GetProjectLogs.js new file mode 100644 index 00000000..cbae4f50 --- /dev/null +++ b/src/Lib/Features/user/GetProjectLogs.js @@ -0,0 +1,41 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" + +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchProjectLogs = createAsyncThunk( + 'GetProjectLogs/fetchProjectLogs', + async (projectId,taskName, { dispatch }) => { + + const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/get_async_task_results/?task_name=${taskName}`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const GetProjectLogs = createSlice({ + name: 'GetProjectLogs', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchProjectLogs.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchProjectLogs.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchProjectLogs.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default GetProjectLogs.reducer; diff --git a/src/Lib/Features/user/GetScheduledMails.js b/src/Lib/Features/user/GetScheduledMails.js index 26e8158e..129bdc10 100644 --- a/src/Lib/Features/user/GetScheduledMails.js +++ b/src/Lib/Features/user/GetScheduledMails.js @@ -9,8 +9,8 @@ const initialState = { export const fetchScheduledMails = createAsyncThunk( 'GetScheduledMails/fetchScheduledMails', - async (userId, { dispatch }) => { - const params = fetchParams(`${ENDPOINTS.getUsers}${userId}/get_scheduled_mails/`); + async (projectId, { dispatch }) => { + const params = fetchParams(`${ENDPOINTS.getProjects}${projectId}/export_project_tasks/`); return fetch(params.url, params.options) .then(response => response.json()) } diff --git a/src/Lib/Features/user/UpdateUIPrefs.js b/src/Lib/Features/user/UpdateUIPrefs.js index 24e80216..56c1f7b6 100644 --- a/src/Lib/Features/user/UpdateUIPrefs.js +++ b/src/Lib/Features/user/UpdateUIPrefs.js @@ -29,7 +29,7 @@ export default class UpdateUIPrefsAPI extends API { this.headers = { headers: { "Content-Type": "application/json", - "Authorization": `JWT ${localStorage.getItem('shoonya_access_token')}` + "Authorization": `JWT ${localStorage.getItem('anudesh_access_token')}` }, }; return this.headers; diff --git a/src/Lib/Features/user/getDownloadProjectAnnotations.js b/src/Lib/Features/user/getDownloadProjectAnnotations.js new file mode 100644 index 00000000..011a993e --- /dev/null +++ b/src/Lib/Features/user/getDownloadProjectAnnotations.js @@ -0,0 +1,41 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchDownloadProjectAnnotations = createAsyncThunk( + 'getDownloadProjectAnnotations/fetchDownloadProjectAnnotations', + async (userId, { dispatch }) => { + const params = fetchParams(`${ENDPOINTS.getUsers}${userId}/get_scheduled_mails/`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const getDownloadProjectAnnotations = createSlice({ + name: 'getDownloadProjectAnnotations', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchDownloadProjectAnnotations.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchDownloadProjectAnnotations.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchDownloadProjectAnnotations.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default getDownloadProjectAnnotations.reducer; + + diff --git a/src/Lib/Features/user/getUserById.js b/src/Lib/Features/user/getUserById.js index 5baf3f1c..03aa66c2 100644 --- a/src/Lib/Features/user/getUserById.js +++ b/src/Lib/Features/user/getUserById.js @@ -9,8 +9,8 @@ const initialState = { export const fetchUserById = createAsyncThunk( 'getUserById/fetchUserById', - async (workspaceId, { dispatch }) => { - const params = fetchParams(`${ENDPOINTS.fetch}me/fetch/`); + async (userId, { dispatch }) => { + const params = fetchParams(`${ENDPOINTS.getUsers}account/${userId}/fetch/`); return fetch(params.url, params.options) .then(response => response.json()) } diff --git a/src/Lib/Features/user/getUserDetails.js b/src/Lib/Features/user/getUserDetails.js new file mode 100644 index 00000000..b4613b2e --- /dev/null +++ b/src/Lib/Features/user/getUserDetails.js @@ -0,0 +1,40 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; +import fetchParams from '../../fetchParams'; +import ENDPOINTS from "../../../config/apiendpoint" +const initialState = { + data: [], + status: 'idle', + error: null, +}; + +export const fetchUserDetails = createAsyncThunk( + 'getUserDetails/fetchUserDetails', + async ( { dispatch }) => { + + const params = fetchParams(`${ENDPOINTS.fetch}user_details`); + return fetch(params.url, params.options) + .then(response => response.json()) + } +); + +const getUserDetails = createSlice({ + name: 'getUserDetails', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchUserDetails.pending, (state) => { + state.status = 'loading'; + }) + .addCase(fetchUserDetails.fulfilled, (state, action) => { + state.status = 'succeeded'; + state.data = action.payload; + }) + .addCase(fetchUserDetails.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error.message; + }); + }, +}); + +export default getUserDetails.reducer; diff --git a/src/Lib/Store.js b/src/Lib/Store.js index 2d8209ec..d157b64e 100644 --- a/src/Lib/Store.js +++ b/src/Lib/Store.js @@ -21,7 +21,6 @@ import getNextTask from './Features/projects/getNextTask'; import getFindAndReplaceWordsInAnnotation from './Features/projects/getFindAndReplaceWordsInAnnotation'; import getTaskFilter from './Features/projects/getTaskFilter'; import RemoveProjectMember from './Features/projects/RemoveProjectMember'; -import ResendUserInvite from './Features/projects/ResendUserInvite'; import GetOrganizationUserReports from './Features/projects/GetOrganizationUserReports'; import GetOrganizationDetailedProjectReports from './Features/projects/GetOrganizationDetailedProjectReports'; import GetOrganizationProjectReports from './Features/projects/GetOrganizationProjectReports'; @@ -33,10 +32,58 @@ import getAllTaskData from './Features/projects/getAllTaskData'; import GetScheduledMails from './Features/user/GetScheduledMails'; import getUserAnalytics from './Features/user/getUserAnalytics'; import getRecentTasks from './Features/user/getRecentTasks'; +import getUserDetails from './Features/user/getUserDetails'; +import getProjectReport from './Features/getProjectReport'; +import GetProjectTypeDetails from './Features/projects/GetProjectTypeDetails'; +import getDownloadProjectAnnotations from './Features/user/getDownloadProjectAnnotations'; +import GetArchiveProject from './Features/projects/GetArchiveProject'; +import DownloadJSONProject from './Features/projects/DownloadJSONProject'; +import DownloadProjectCsv from './Features/projects/DownloadProjectCsv'; +import DownloadProjectTsv from './Features/projects/DownloadProjectTsv'; +import GetDatasets from './Features/datasets/GetDatasets'; +import GetDatasetType from './Features/datasets/GetDatasetType'; +import GetDataitemsById from './Features/datasets/GetDataitemsById'; +import getDatasetDetails from './Features/datasets/getDatasetDetails'; +import GetDatasetProjects from './Features/datasets/GetDatasetProjects'; +import GetDatasetLogs from './Features/datasets/GetDatasetLogs'; +import getDatasetProjectReports from './Features/datasets/getDatasetProjectReports'; +import GetDatasetDetailedReports from './Features/datasets/GetDatasetDetailedReports'; +import getDatasetMembers from './Features/datasets/getDatasetMembers'; +import GetIndicTransLanguages from './Features/datasets/GetIndicTransLanguages'; +import GetDatasetDownloadCSV from './Features/datasets/GetDatasetDownloadCSV'; +import GetDatasetDownloadTSV from './Features/datasets/GetDatasetDownloadTSV'; +import GetDatasetDownloadJSON from './Features/datasets/GetDatasetDownloadJSON'; +import GetFileTypes from './Features/datasets/GetFileTypes'; +import DatasetSearchPopup from './Features/datasets/DatasetSearchPopup'; +import searchProjectCard from './Features/searchProjectCard'; const makeStore = () => { return configureStore({ reducer: { apiStatus:apiStatus, + searchProjectCard:searchProjectCard, + DatasetSearchPopup:DatasetSearchPopup, + GetFileTypes:GetFileTypes, + GetIndicTransLanguages:GetIndicTransLanguages, + GetDatasetDownloadJSON:GetDatasetDownloadJSON, + GetDatasetDownloadCSV:GetDatasetDownloadCSV, + GetDatasetDownloadTSV:GetDatasetDownloadTSV, + getDatasetMembers:getDatasetMembers, + GetDatasetDetailedReports:GetDatasetDetailedReports, + getDatasetProjectReports:getDatasetProjectReports, + GetDatasetProjects:GetDatasetProjects, + GetDatasetLogs:GetDatasetLogs, + getDatasetDetails:getDatasetDetails, + GetDataitemsById:GetDataitemsById, + GetDatasetType:GetDatasetType, + GetDatasets:GetDatasets, + DownloadJSONProject:DownloadJSONProject, + DownloadProjectCsv:DownloadProjectCsv, + DownloadProjectTsv:DownloadProjectTsv, + GetArchiveProject:GetArchiveProject, + getDownloadProjectAnnotations:getDownloadProjectAnnotations, + GetProjectTypeDetails:GetProjectTypeDetails, + getProjectReport:getProjectReport, + getUserDetails:getUserDetails, getAllTaskData:getAllTaskData, getRecentTasks:getRecentTasks, getUserAnalytics:getUserAnalytics, @@ -50,7 +97,6 @@ const makeStore = () => { GetOrganizationProjectReports:GetOrganizationProjectReports, getProjects:getProjects, getTaskFilter:getTaskFilter, - ResendUserInvite:ResendUserInvite, getNextTask:getNextTask, RemoveProjectMember:RemoveProjectMember, getFindAndReplaceWordsInAnnotation:getFindAndReplaceWordsInAnnotation, diff --git a/src/app/actions/api/Dashboard/DeallocationAnnotatorsAndReviewers.js b/src/app/actions/api/Dashboard/DeallocationAnnotatorsAndReviewers.js new file mode 100644 index 00000000..03663879 --- /dev/null +++ b/src/app/actions/api/Dashboard/DeallocationAnnotatorsAndReviewers.js @@ -0,0 +1,46 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class DeallocationAnnotatorsAndReviewersAPI extends API { + constructor(projectId,radiobutton,annotatorsUser,reviewerssUser,annotationStatus,reviewStatus,superCheckUser,SuperCheckStatus,projectObj, timeout = 2000) { + super("GET", timeout, false); + this.projectObj = projectObj; + const queryString = radiobutton === "annotation" ? `unassign_tasks/?annotator_id=${annotatorsUser}&annotation_status=["${annotationStatus}"]` : radiobutton === "review"? `unassign_review_tasks/?reviewer_id=${reviewerssUser}&review_status=["${reviewStatus}"]`:`unassign_supercheck_tasks/?superchecker_id=${superCheckUser}&supercheck_status=["${SuperCheckStatus}"]`; + console.log(queryString,"queryStringqueryString") + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/${queryString}`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.deallocationAnnotatorsAndReviewers= res; + } + } + + apiEndPoint() { + return this.endpoint; + } + getBody() { + return this.projectObj; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.deallocationAnnotatorsAndReviewers + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Dashboard/DeleteAnnotationAPI.js b/src/app/actions/api/Dashboard/DeleteAnnotationAPI.js new file mode 100644 index 00000000..94eb2513 --- /dev/null +++ b/src/app/actions/api/Dashboard/DeleteAnnotationAPI.js @@ -0,0 +1,43 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class DeleteAnnotationAPI extends API { + constructor(annotationId, timeout = 2000) { + super("DELETE", timeout, false); + this.type = constant.DELETE_ANNOTATION; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.annotations}${annotationId}/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.deletedAnnotation = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() {} + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.deletedAnnotation; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Dashboard/GetTaskAnnotationsAPI.js b/src/app/actions/api/Dashboard/GetTaskAnnotationsAPI.js new file mode 100644 index 00000000..fc574c17 --- /dev/null +++ b/src/app/actions/api/Dashboard/GetTaskAnnotationsAPI.js @@ -0,0 +1,43 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constants from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class GetTaskAnnotationsAPI extends API { + constructor(taskId, timeout = 2000) { + super("GET", timeout, false); + this.type = constants.GET_TASK_ANNOTATIONS; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getTasks}${taskId}/annotations/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.taskAnnotations = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() {} + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.taskAnnotations; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Dashboard/GetUserDetailUpdateAPI.js b/src/app/actions/api/Dashboard/GetUserDetailUpdateAPI.js new file mode 100644 index 00000000..95ca7c92 --- /dev/null +++ b/src/app/actions/api/Dashboard/GetUserDetailUpdateAPI.js @@ -0,0 +1,45 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constants from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + +export default class GetUserDetailUpdateAPI extends API { + constructor(Id,projectObj,timeout = 2000) { + super("PATCH", timeout, false); + this.projectObj = projectObj; + // this.type = constants.GET_USER_DETAILS; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.fetch}${Id}/edit_user_details/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.userDetailUpdate = res; + } +} + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return this.projectObj; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.userDetailUpdate + } +} diff --git a/src/app/actions/api/Dashboard/SuperCheckerSettingsAPI.js b/src/app/actions/api/Dashboard/SuperCheckerSettingsAPI.js new file mode 100644 index 00000000..a3529e3a --- /dev/null +++ b/src/app/actions/api/Dashboard/SuperCheckerSettingsAPI.js @@ -0,0 +1,47 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + +export default class SuperCheckSettingsAPI extends API { + constructor(projectId,projectObj, timeout = 2000) { + super("PATCH", timeout, false); + this.projectObj = projectObj; + // this.type = constants.REMOVE_PROJECT_MEMBER; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.superCheckSettings = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return this.projectObj; + } + + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.superCheckSettings; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Dashboard/getTaskDetails.js b/src/app/actions/api/Dashboard/getTaskDetails.js new file mode 100644 index 00000000..af9441c2 --- /dev/null +++ b/src/app/actions/api/Dashboard/getTaskDetails.js @@ -0,0 +1,43 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class GetTaskDetailsAPI extends API { + constructor(taskId, timeout = 2000) { + super("GET", timeout, false); + this.type = constants.GET_TASK_DETAILS; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getTasks}${taskId}/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.taskDetails = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() {} + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.taskDetails + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/DeallocateReviewTasksAPI.js b/src/app/actions/api/Projects/DeallocateReviewTasksAPI.js index 295ad9dd..63f14df8 100644 --- a/src/app/actions/api/Projects/DeallocateReviewTasksAPI.js +++ b/src/app/actions/api/Projects/DeallocateReviewTasksAPI.js @@ -10,7 +10,7 @@ constructor(projectId,selectedFilters, timeout = 2000) { super("GET", timeout, false); this.projectId = projectId; - this.type = constants.DE_ALLOCATE_REVIEW_TASKS; + this.type = constant.DE_ALLOCATE_REVIEW_TASKS; this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/unassign_review_tasks/?review_status=['${selectedFilters}']`; } diff --git a/src/app/actions/api/Projects/DeallocateSuperCheckerTasksAPI.js b/src/app/actions/api/Projects/DeallocateSuperCheckerTasksAPI.js index 413540ff..90b7c71b 100644 --- a/src/app/actions/api/Projects/DeallocateSuperCheckerTasksAPI.js +++ b/src/app/actions/api/Projects/DeallocateSuperCheckerTasksAPI.js @@ -11,7 +11,7 @@ constructor(projectId,selectedFilters, timeout = 2000) { super("GET", timeout, false); this.projectId = projectId; - this.type = constants.DE_ALLOCATE_SUPERCHECKER_TASKS; + this.type = constant.DE_ALLOCATE_SUPERCHECKER_TASKS; this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/unassign_supercheck_tasks/?supercheck_status=['${selectedFilters}']`; } processResponse(res) { diff --git a/src/app/actions/api/Projects/DeallocateTasksAPI.js b/src/app/actions/api/Projects/DeallocateTasksAPI.js index fb1227f9..9d8a685b 100644 --- a/src/app/actions/api/Projects/DeallocateTasksAPI.js +++ b/src/app/actions/api/Projects/DeallocateTasksAPI.js @@ -9,7 +9,7 @@ constructor(projectId,selectedFilters, timeout = 2000) { super("GET", timeout, false); this.projectId = projectId; - this.type = constants.DE_ALLOCATE_TASKS; + this.type = constant.DE_ALLOCATE_TASKS; this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/unassign_tasks/?annotation_status=['${selectedFilters}']`; } diff --git a/src/app/actions/api/Projects/DeleteProjectTasksAPI.js b/src/app/actions/api/Projects/DeleteProjectTasksAPI.js new file mode 100644 index 00000000..b01f5159 --- /dev/null +++ b/src/app/actions/api/Projects/DeleteProjectTasksAPI.js @@ -0,0 +1,45 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class DeleteProjectTasksAPI extends API { + constructor(projectId,projectObj, timeout = 2000) { + super("PUT", timeout, false); + this.projectObj = projectObj; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getTasks}${projectId}/delete_project_tasks/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.deleteProjectTasks= res; + } + } + + apiEndPoint() { + return this.endpoint; + } + getBody() { + return this.projectObj; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.deleteProjectTasks + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/DownloadAllProjects.js b/src/app/actions/api/Projects/DownloadAllProjects.js new file mode 100644 index 00000000..06679aa1 --- /dev/null +++ b/src/app/actions/api/Projects/DownloadAllProjects.js @@ -0,0 +1,51 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class DownloadAllProjects extends API { + constructor(id,userid,timeout = 2000) { + super("POST", timeout, false); + // this.projectBody={}//object with key-value pair + // this.type = constants.DOWNLOAD_PROJECT_CSV; + this.userid=userid + this.endpoint = `${super.apiEndPointAuto()}/functions/download_all_projects?workspace_id=${id}`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.downloadProject = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + user_id: this.userid, + }; + } + + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.downloadProjectCsv; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/GetExportProjectButtonAPI.js b/src/app/actions/api/Projects/GetExportProjectButtonAPI.js new file mode 100644 index 00000000..685dc278 --- /dev/null +++ b/src/app/actions/api/Projects/GetExportProjectButtonAPI.js @@ -0,0 +1,49 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + +export default class GetExportProjectButtonAPI extends API { + constructor(projectId,instanceId = -1,datasetId ,save_type , timeout = 2000) { + super("POST", timeout, false); + this.type = constant.GET_EXPORT_PROJECT_BUTTON; + this.export_dataset_instance_id = save_type==="new_record"?datasetId:instanceId; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/project_export/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.exportProjectButton = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return this.export_dataset_instance_id !== -1 ? { + export_dataset_instance_id: this.export_dataset_instance_id + + } : {} + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.exportProjectButton; + } +} + \ No newline at end of file diff --git a/src/app/actions/api/Projects/GetProjectReportAPI.js b/src/app/actions/api/Projects/GetProjectReportAPI.js new file mode 100644 index 00000000..99ab212c --- /dev/null +++ b/src/app/actions/api/Projects/GetProjectReportAPI.js @@ -0,0 +1,52 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class GetProjectReportAPI extends API { + constructor(projectId, startDate, endDate,reports_type, timeout = 2000) { + super("POST", timeout, false); + this.startDate = startDate; + this.endDate = endDate; + this. reports_type= reports_type; + this.type = constant.GET_PROJECT_REPORT; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/get_analytics/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.projectReport = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + from_date: this.startDate, + to_date: this.endDate, + reports_type:this. reports_type, + }; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.projectReport; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/GetPublishProjectButtonAPI.js b/src/app/actions/api/Projects/GetPublishProjectButtonAPI.js new file mode 100644 index 00000000..0c74255a --- /dev/null +++ b/src/app/actions/api/Projects/GetPublishProjectButtonAPI.js @@ -0,0 +1,44 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class GetPublishProjectButtonAPI extends API { + constructor(projectId, timeout = 2000) { + super("POST", timeout, false); + this.type = constant.GET_PUBLISH_PROJECT_BUTTON; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/project_publish/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.publishProjectButton = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() {} + + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.publishProjectButton; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/GetPullNewDataAPI.js b/src/app/actions/api/Projects/GetPullNewDataAPI.js new file mode 100644 index 00000000..b1774b73 --- /dev/null +++ b/src/app/actions/api/Projects/GetPullNewDataAPI.js @@ -0,0 +1,44 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class GetPullNewDataAPI extends API { + constructor(projectId, timeout = 2000) { + super("POST", timeout, false); + this.type = constant.GET_PULL_NEW_ITEMS; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/pull_new_items/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.pullNewData = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() {} + + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.pullNewData; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/GetWorkspaceSaveButton.js b/src/app/actions/api/Projects/GetWorkspaceSaveButton.js new file mode 100644 index 00000000..f9e6177c --- /dev/null +++ b/src/app/actions/api/Projects/GetWorkspaceSaveButton.js @@ -0,0 +1,46 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class GetWorkspaceSaveButtonAPI extends API { + constructor(id,workspaceObj, timeout = 2000) { + super("PUT", timeout, false); + this.workspaceObj = workspaceObj; + console.log(workspaceObj) + // this.type = constants.GET_SAVE_BUTTON; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getWorkspaces}${id}/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.saveButton= res; + } + } + + apiEndPoint() { + return this.endpoint; + } + getBody() { + return this.workspaceObj; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.saveButton + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/PullNewBatchAPI.js b/src/app/actions/api/Projects/PullNewBatchAPI.js index 246ebc7e..54df62be 100644 --- a/src/app/actions/api/Projects/PullNewBatchAPI.js +++ b/src/app/actions/api/Projects/PullNewBatchAPI.js @@ -10,7 +10,7 @@ super("POST", timeout, false); this.projectId = projectId; this.numsTasks = numsTasks; - this.type = constants.PULL_NEW_BATCH; + this.type = constant.PULL_NEW_BATCH; this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/assign_new_tasks/`; } diff --git a/src/app/actions/api/Projects/PullNewReviewBatchAPI.js b/src/app/actions/api/Projects/PullNewReviewBatchAPI.js index 89d018b0..e354502c 100644 --- a/src/app/actions/api/Projects/PullNewReviewBatchAPI.js +++ b/src/app/actions/api/Projects/PullNewReviewBatchAPI.js @@ -10,7 +10,7 @@ super("POST", timeout, false); this.projectId = projectId; this.numsTasks = numsTasks; - this.type = constants.PULL_NEW_REVIEW_BATCH; + this.type = constant.PULL_NEW_REVIEW_BATCH; this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/assign_new_review_tasks/`; } diff --git a/src/app/actions/api/Projects/PullNewSuperCheckerBatchAPI.js b/src/app/actions/api/Projects/PullNewSuperCheckerBatchAPI.js index 53e5258e..d514667f 100644 --- a/src/app/actions/api/Projects/PullNewSuperCheckerBatchAPI.js +++ b/src/app/actions/api/Projects/PullNewSuperCheckerBatchAPI.js @@ -10,7 +10,7 @@ export default class PullNewSuperCheckerBatchAPI extends API { super("POST", timeout, false); this.projectId = projectId; this.numsTasks = numsTasks; - this.type = constants.PULL_NEW_SUPER_CHECKER_BATCH; + this.type = constant.PULL_NEW_SUPER_CHECKER_BATCH; this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/assign_new_supercheck_tasks/`; } diff --git a/src/app/actions/api/Projects/RemoveProjectReviewerAPI.js b/src/app/actions/api/Projects/RemoveProjectReviewerAPI.js index 79affd0c..93f1a054 100644 --- a/src/app/actions/api/Projects/RemoveProjectReviewerAPI.js +++ b/src/app/actions/api/Projects/RemoveProjectReviewerAPI.js @@ -9,7 +9,7 @@ constructor(projectId,projectObj,type, timeout = 2000) { super("POST", timeout, false); this.projectObj = projectObj; - this.type = constants.REMOVE_PROJECT_REVIEWER; + this.type = constant.REMOVE_PROJECT_REVIEWER; let queryStr = type == "PROJECT_SUPERCHECKER" ? "remove_superchecker" : "remove_reviewer"; this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/${queryStr}/`; } diff --git a/src/app/actions/api/Projects/ResendUserInvite.js b/src/app/actions/api/Projects/ResendUserInvite.js new file mode 100644 index 00000000..b2e33862 --- /dev/null +++ b/src/app/actions/api/Projects/ResendUserInvite.js @@ -0,0 +1,48 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + +export default class ResendUserInviteAPI extends API { + constructor(email, timeout = 2000) { + super("POST", timeout, false); + this.email = email + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getUsers}invite/regenerate/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.resendinviteRes = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + emails : this.email + } +} + + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.resendinviteRes; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/TaskReviewsAPI.js b/src/app/actions/api/Projects/TaskReviewsAPI.js new file mode 100644 index 00000000..3c63420c --- /dev/null +++ b/src/app/actions/api/Projects/TaskReviewsAPI.js @@ -0,0 +1,48 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class TaskReviewsAPI extends API { + constructor(id,taskReviews, timeout = 2000) { + super("POST", timeout, false); + this.taskReviews = taskReviews; + this.type = constant.TASK_REVIEWS; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${id}/change_project_stage/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.reviewRes = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + getBody() { + return { + project_stage: this.taskReviews, + }; + } + + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization": `JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.reviewRes; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/getProjectLogsAPI.js b/src/app/actions/api/Projects/getProjectLogsAPI.js new file mode 100644 index 00000000..07990dec --- /dev/null +++ b/src/app/actions/api/Projects/getProjectLogsAPI.js @@ -0,0 +1,44 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + + export default class GetProjectLogsAPI extends API { + constructor(projectId, taskName, timeout = 2000) { + super("GET", timeout, false); + this.type = constant.GET_PROJECT_LOGS; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/get_async_task_results/?task_name=${taskName}`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.projectLogs = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() {} + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.projectLogs; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/Projects/getSaveButtonAPI.js b/src/app/actions/api/Projects/getSaveButtonAPI.js new file mode 100644 index 00000000..df552d5a --- /dev/null +++ b/src/app/actions/api/Projects/getSaveButtonAPI.js @@ -0,0 +1,45 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class GetSaveButtonAPI extends API { + constructor(projectId,projectObj, timeout = 2000) { + super("PUT", timeout, false); + this.projectObj = projectObj; + // this.type = constants.GET_SAVE_BUTTON; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getProjects}${projectId}/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.saveButton= res; + } + } + + apiEndPoint() { + return this.endpoint; + } + getBody() { + return this.projectObj; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.saveButton + } + } + \ No newline at end of file diff --git a/src/app/actions/api/dataset/AutomateDatasetsAPI.js b/src/app/actions/api/dataset/AutomateDatasetsAPI.js new file mode 100644 index 00000000..70ab6b0c --- /dev/null +++ b/src/app/actions/api/dataset/AutomateDatasetsAPI.js @@ -0,0 +1,63 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constants from "../../constants"; + + + export default class AutomateDatasetsAPI extends API { + constructor(srcInstanceId, tgtInstanceId, languages, organizationId,checks,api_type,checked, timeout = 2000) { + super("POST", timeout, false); + this.type = constants.AUTOMATE_DATASETS; + this.input_dataset_instance_id = srcInstanceId; + this.languages = languages && languages.length > 0 && languages.map((element,index)=>{ + return element + }); + this.output_dataset_instance_id = tgtInstanceId; + this.organization_id = organizationId; + this.checks_for_particular_languages = checks; + this.api_type = api_type; + this.automate_missing_data_items = `${checked}` + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.functions}automated_sentence_text_translation_job`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.res = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + input_dataset_instance_id: this.input_dataset_instance_id, + // languages:`"[`+ this.languages + `]"`, + languages: JSON.stringify(this.languages) , + output_dataset_instance_id: this.output_dataset_instance_id, + organization_id: this.organization_id, + checks_for_particular_languages: this.checks_for_particular_languages, + api_type:this.api_type, + automate_missing_data_items : this.automate_missing_data_items + } + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.res; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/dataset/CreateNewDatasetInstance.js b/src/app/actions/api/dataset/CreateNewDatasetInstance.js new file mode 100644 index 00000000..1b4b9fa0 --- /dev/null +++ b/src/app/actions/api/dataset/CreateNewDatasetInstance.js @@ -0,0 +1,44 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + + export default class CreateNewDatasetInstanceAPI extends API { + constructor(projectObj,timeout = 2000) { + super("POST", timeout, false); + this.projectObj = projectObj; + this.type = constant.CREATE_NEW_DATASET_INSTANCE; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getDatasets}instances/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.createNewDatasetInstance = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return this.projectObj; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.createNewDatasetInstance; + } + } \ No newline at end of file diff --git a/src/app/actions/api/dataset/DeleteDataItemsAPI.js b/src/app/actions/api/dataset/DeleteDataItemsAPI.js new file mode 100644 index 00000000..101fdbc8 --- /dev/null +++ b/src/app/actions/api/dataset/DeleteDataItemsAPI.js @@ -0,0 +1,45 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + + + export default class DeleteDataItemsAPI extends API { + constructor(instanceIds,datasetObj, timeout = 2000) { + super("POST", timeout, false); + this.datasetObj = datasetObj; + //this.type = constants.DELETE_DATAITEMS; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getDatasets}dataitems/${instanceIds}/delete_data_items/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.deleteDataItems= res; + } + } + + apiEndPoint() { + return this.endpoint; + } + getBody() { + return this.datasetObj; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.deleteDataItems + } + } + \ No newline at end of file diff --git a/src/app/actions/api/dataset/UploaddataAPI.js b/src/app/actions/api/dataset/UploaddataAPI.js new file mode 100644 index 00000000..f6d41027 --- /dev/null +++ b/src/app/actions/api/dataset/UploaddataAPI.js @@ -0,0 +1,45 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constants from "../../constants"; + + + export default class UploaddataAPI extends API { + constructor(datasetId,projectObj, timeout = 2000) { + super("POST", false); + this.projectObj = projectObj; + this.type = constants.UPLOAD_DATA; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getDatasets}instances/${datasetId}/upload/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.uploaddata = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return this.projectObj; + } + + getHeaders() { + this.headers = { + headers: { + // "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.uploaddata; + } + } \ No newline at end of file diff --git a/src/app/actions/api/dataset/aiModel.js b/src/app/actions/api/dataset/aiModel.js new file mode 100644 index 00000000..78d51473 --- /dev/null +++ b/src/app/actions/api/dataset/aiModel.js @@ -0,0 +1,54 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constants from "../../constants"; + + export default class aiModel extends API { + constructor(srcInstanceId,translationmodel,org_id,checked,srcDatasetType, timeout = 2000) { + super("POST", timeout, false); + // this.type = constants.AUTOMATE_DATASETS; + this.input_dataset_instance_id = srcInstanceId; + this.api_type = translationmodel; + this.org = org_id; + this.automate_missing_data_items= checked; + const queryString = srcDatasetType === "OCRDocument" ? "schedule_ocr_prediction_json_population" : "schedule_asr_prediction_json_population"; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.functions}${queryString}`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.res = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + dataset_instance_id: this.input_dataset_instance_id, + api_type: this.api_type, + organization_id: this.org, + automate_missing_data_items:this.automate_missing_data_items + } + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.res; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/dataset/intraAutomateDatasetsAPI.js b/src/app/actions/api/dataset/intraAutomateDatasetsAPI.js new file mode 100644 index 00000000..4fa3fa7b --- /dev/null +++ b/src/app/actions/api/dataset/intraAutomateDatasetsAPI.js @@ -0,0 +1,55 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constants from "../../constants"; + + + export default class intraAutomateDatasetsAPI extends API { + constructor(srcInstanceId,org_id,field, timeout = 2000) { + super("POST", timeout, false); + // this.type = constants.AUTOMATE_DATASETS; + this.input_dataset_instance_id = srcInstanceId; + this.org = org_id; + this.field = field.map((element,index)=>{ + return element + }); + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.functions}schedule_draft_data_json_population`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.res = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + dataset_instance_id: this.input_dataset_instance_id, + fields_list: this.field.toString().trim(), + organization_id: this.org + + } + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.res; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/dataset/removeDuplicatesDatasetInstanceAPI.js b/src/app/actions/api/dataset/removeDuplicatesDatasetInstanceAPI.js new file mode 100644 index 00000000..f273654e --- /dev/null +++ b/src/app/actions/api/dataset/removeDuplicatesDatasetInstanceAPI.js @@ -0,0 +1,41 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constant from "../../constants"; + + export default class removeDuplicatesDatasetInstanceAPI extends API { + constructor( datasetId,dataitemsvalues,timeout = 2000) { + super("GET", timeout, false); + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.getDatasets}instances/${datasetId}/remove_duplicates_from_dataset_instance/?deduplicate_fields_list=${dataitemsvalues}`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.removeDuplicatesDatasetInstance = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() {} + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.removeDuplicatesDatasetInstance; + } + } + \ No newline at end of file diff --git a/src/app/actions/api/user/InviteUsersToOrgAPI.js b/src/app/actions/api/user/InviteUsersToOrgAPI.js index b9eaf5b3..f90adfce 100644 --- a/src/app/actions/api/user/InviteUsersToOrgAPI.js +++ b/src/app/actions/api/user/InviteUsersToOrgAPI.js @@ -38,7 +38,7 @@ this.headers = { headers: { "Content-Type": "application/json", - "Authorization":`JWT ${localStorage.getItem('shoonya_access_token')}` + "Authorization":`JWT ${localStorage.getItem('anudesh_access_token')}` }, }; return this.headers; diff --git a/src/app/actions/api/user/UpdateProfileAPI.js b/src/app/actions/api/user/UpdateProfileAPI.js index f50d106f..e6905aca 100644 --- a/src/app/actions/api/user/UpdateProfileAPI.js +++ b/src/app/actions/api/user/UpdateProfileAPI.js @@ -1,3 +1,57 @@ import API from "../../api"; import ENDPOINTS from "../../../../config/apiendpoint" -import constants from "../../constants"; \ No newline at end of file +import constants from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + +export default class UpdateProfileAPI extends API { + constructor(username, first_name, last_name, languages, phone,availability_status, participation_type, timeout = 2000) { + super("POST", timeout, false); + this.username = username; + this.first_name = first_name; + this.last_name = last_name; + this.languages = languages; + this.phone = phone; + this.availability_status = availability_status; + this.participation_type = participation_type; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.fetch}update/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.report = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + username: this.username, + first_name: this.first_name, + last_name: this.last_name, + languages: this.languages, + phone: this.phone, + availability_status:this.availability_status, + participation_type :this.participation_type + }; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization": `JWT ${localStorage.getItem("anudesh_access_token")}` + }, + }; + return this.headers; + } + + getPayload() { + return this.report + } + } + \ No newline at end of file diff --git a/src/app/actions/api/user/VerifyEmailAPI.js b/src/app/actions/api/user/VerifyEmailAPI.js new file mode 100644 index 00000000..5abec51c --- /dev/null +++ b/src/app/actions/api/user/VerifyEmailAPI.js @@ -0,0 +1,50 @@ +/** + * Login API + */ + import API from "../../api"; + import ENDPOINTS from "../../../../config/apiendpoint" + import constants from "../../constants"; + /* eslint-disable react-hooks/exhaustive-deps */ + + export default class VerifyEmailAPI extends API { + constructor(oldEmailCode, newEmailCode, timeout = 2000) { + super("POST", timeout, false); + this.oldEmailCode = oldEmailCode; + this.newEmailCode = newEmailCode; + this.type = constants.VERIFY_EMAIL; + this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.fetch}verify_email_updation/`; + } + + processResponse(res) { + super.processResponse(res); + if (res) { + this.verifyEmail = res; + } + } + + apiEndPoint() { + return this.endpoint; + } + + getBody() { + return { + old_email_update_code: this.oldEmailCode, + new_email_verification_code: this.newEmailCode, + }; + } + + getHeaders() { + this.headers = { + headers: { + "Content-Type": "application/json", + "Authorization": `JWT ${localStorage.getItem('anudesh_access_token')}` + }, + }; + return this.headers; + } + + getPayload() { + return this.verifyEmail; + } + } + \ No newline at end of file diff --git a/src/app/layout.js b/src/app/layout.js index a4276962..ff1b60ec 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -28,4 +28,4 @@ export default function RootLayout({ children }) { ); -} +} \ No newline at end of file diff --git a/src/app/page.js b/src/app/page.js index 45cabc21..0182e30a 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -7,12 +7,22 @@ import Login from "./ui/pages/login/login"; import Layout from "./ui/Layout"; import MyOrganization from "./ui/pages/organizations/organizations"; import ProjectList from "./ui/pages/projects/project"; -import Projects from "./ui/pages/projects/projectDetails"; +import Projects from "./ui/pages/projects/projectDetails" import Dataset from "./ui/pages/dataset/dataset"; import Workspace from "./ui/pages/workspace/workspace"; import WorkspaceSettingTabs from "./ui/pages/workspace/workspacesetting/setting"; import SignUp from "./ui/pages/invite/invite"; import ForgotPassword from "./ui/pages/forgot-password/forgot-password"; +import Dashboard from "./ui/pages/admin/Dashboard" +import ProgressPage from "./progress/progress"; +import ProfilePage from "./profile/profile"; +import EditProfile from "./ui/pages/edit-profile/edit-profile" +import ChangePassword from "./ui/pages/change-password/change-password" +import ProjectSetting from "@/components/Project/ProjectSettings"; +import DatasetDetails from "@/components/datasets/DatasetDetails"; +import DatasetSettingTabs from "@/components/datasets/DatasetSettingTab"; +import AutomateDatasets from "@/components/datasets/AutomateDatasets"; +import CreateNewDatasetInstanceAPI from "@/components/datasets/CreateNewDatasetInstance"; export default function Root() { if (typeof window !== 'undefined') { @@ -36,6 +46,10 @@ export default function Root() { } /> } /> } /> + } />)} + /> } />)} @@ -50,12 +64,50 @@ export default function Root() { } Backbutton={true} backPressNavigationPath={"/projects"} /> )} /> + } Backbutton={true} /> + )} + /> + } Backbutton={true} /> + )} + /> + } Backbutton={true} /> + )} + /> + } Backbutton={true} /> + )} + /> + } Backbutton={true} />)} + /> + } Backbutton={true} />)} + /> } /> )} /> + } Backbutton={true} /> + )} + /> } Backbutton={true} /> )} /> + + } Backbutton={true} />)} + /> + } Backbutton={true} />)} + /> diff --git a/src/app/profile/profile.js b/src/app/profile/profile.js index d5952d0b..e05bf5de 100644 --- a/src/app/profile/profile.js +++ b/src/app/profile/profile.js @@ -14,7 +14,7 @@ import CustomizedSnackbars from "../../components/common/Snackbar"; import userRole from "../../utils/Role"; import ProfileDetails from "../../components/UserManagement/ProfileDetails" import ScheduleMails from '@/components/UserManagement/ScheduleMails'; - +import { useNavigate,useParams } from 'react-router-dom'; // import { useRouter } from 'next/navigation'; import ToggleMailsAPI from '../actions/api/user/ToggleMailsAPI'; import UpdateProfileImageAPI from '../actions/api/user/UpdateProfileImageAPI' @@ -23,10 +23,11 @@ import APITransport from '@/Lib/apiTransport/apitransport'; import { fetchUserById } from '@/Lib/Features/user/getUserById'; export default function ProfilePage () { - - const id=2; + /* eslint-disable react-hooks/exhaustive-deps */ + + const {id} = useParams(); const dispatch = useDispatch(); - // const navigate = useNavigate(); + const navigate = useNavigate(); const [userDetails, setUserDetails] = useState(null); const [loading, setLoading] = useState(false); const [snackbar, setSnackbarInfo] = useState({ @@ -195,7 +196,7 @@ export default function ProfilePage () { navigate(`/progress/${UserDetails.id}`)} + onClick={() => navigate(`/progress/${UserDetails.id}`)} /> } @@ -227,4 +228,4 @@ export default function ProfilePage () { ) -} +} \ No newline at end of file diff --git a/src/app/progress/progress.js b/src/app/progress/progress.js index d10cf896..6953b256 100644 --- a/src/app/progress/progress.js +++ b/src/app/progress/progress.js @@ -7,19 +7,18 @@ import RecentTasks from '../../components/Tabs/RecentTasks'; import Spinner from "../../components/common/Spinner"; import userRole from "../../utils/Role"; import { useDispatch, useSelector } from "react-redux"; -import APITransport from '@/Lib/apiTransport/apitransport'; -import FetchUserByIdAPI from '../actions/api/user/FetchUserByIDAPI'; +import {useNavigate, useParams} from "react-router-dom" import ToggleMailsAPI from '../actions/api/user/ToggleMailsAPI'; import { fetchUserById } from '@/Lib/Features/user/getUserById'; import CustomizedSnackbars from '../../components/common/Snackbar'; export default function ProgressPage () { - // const { id } = useParams(); - const id = 1; + const { id } = useParams(); + // const id = 1; const dispatch = useDispatch(); /* eslint-disable react-hooks/exhaustive-deps */ - // const navigate = useNavigate(); + const navigate = useNavigate(); const [userDetails, setUserDetails] = useState(null); const [loading, setLoading] = useState(false); const [snackbar, setSnackbarInfo] = useState({ @@ -87,7 +86,7 @@ export default function ProgressPage () { return ( - {/* {loading && } */} + {loading && } {renderSnackBar()} {/* {userDetails && ( */} <> diff --git a/src/app/ui/pages/admin/AnnotationDetails.jsx b/src/app/ui/pages/admin/AnnotationDetails.jsx new file mode 100644 index 00000000..f034ea7b --- /dev/null +++ b/src/app/ui/pages/admin/AnnotationDetails.jsx @@ -0,0 +1,190 @@ + +import React, { useState, useEffect } from 'react'; +import { Grid, TextField, Button, Box, CircularProgress } from '@mui/material'; +import { JSONTree } from 'react-json-tree'; +import { snakeToTitleCase } from '../../../../utils/utils.js'; +import CustomizedSnackbars from '@/components/common/Snackbar.jsx'; +import FetchUserByIdAPI from '../../../actions/api/user/FetchUserByIDAPI.js'; +import DeleteAnnotationAPI from '../../../actions/api/Dashboard/DeleteAnnotationAPI.js'; +import GetTaskDetailsAPI from '../../../actions/api/Dashboard/getTaskDetails.js'; + + + +function AnnotationDetails() { + /* eslint-disable react-hooks/exhaustive-deps */ + + const [annotationId, setAnnotationId] = useState(''); + const [annotationDetails, setAnnotationDetails] = useState(null); + const [loading, setLoading] = useState(false); + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + const fetchAnnotationDetails = async () => { + setLoading(true); + setAnnotationDetails(null); + //not actually deleting the annotation, just fetching the details + const apiObj = new DeleteAnnotationAPI(annotationId); + fetch(apiObj.apiEndPoint(), apiObj.getHeaders()) + .then(async (res) => { + if(res.status === 200) { + const data = await res.json(); + return data; + } + else if(res.status === 404){ + + setSnackbarInfo({ + open: true, + message: "Annotation Not Found", + variant: "error", + }) + setLoading(false) + } + else { + setSnackbarInfo({ + open: true, + message: "Something Went Wrong", + variant: "error", + }) + setLoading(false) + } + }) + .then(async (data) => { + if(data?.error) { + setLoading(false); + setAnnotationDetails(data); + } + else { + if(data){ + const projectId = await getProjectId(data['task']); + data['project_id'] = projectId; + if(data['completed_by']) { + const userEmail = await getUserEmail(data['completed_by']); + data['completed_by'] = `${data['completed_by']} (${userEmail})`; + setLoading(false); + setAnnotationDetails(data); + } + else { + setLoading(false); + setAnnotationDetails(data); + } + } + } + }); + }; + + const getUserEmail = async (userId) => { + const apiObj = new FetchUserByIdAPI(userId); + return fetch(apiObj.apiEndPoint(), apiObj.getHeaders()) + .then(res => res.json()) + .then(res => res?.email); + }; + + const getProjectId = async (taskId) => { + const apiObj = new GetTaskDetailsAPI(taskId); + return fetch(apiObj.apiEndPoint(), apiObj.getHeaders()) + .then(res => res.json()) + .then(res => res?.project_id); + }; + + const theme = { + extend: { + base00: '#000', + base01: '#383830', + base02: '#49483e', + base03: '#75715e', + base04: '#a59f85', + base05: '#f8f8f2', + base06: '#f5f4f1', + base07: '#f9f8f5', + base08: '#f92672', + base09: '#fd971f', //orange + base0A: '#f4bf75', + base0B: '#a6e22e', //green + base0C: '#a1efe4', + base0D: '#66d9ef', + base0E: '#ae81ff', + base0F: '#cc6633', + }, + value: ({ style }, nodeType, keyPath) => ({ + style: { + ...style, + borderLeft: '2px solid #ccc', + marginLeft: '1.375em', + paddingLeft: '2em', + }, + }), + nestedNode: ({ style }, nodeType, keyPath) => ({ + style: { + ...style, + borderLeft: '2px solid #ccc', + marginLeft: keyPath.length > 1 ? '1.375em' : 0, + textIndent: '-0.375em', + }, + + }), + arrowContainer: ({ style }, arrowStyle) => ({ + style: { + ...style, + paddingRight: '1.375rem', + textIndent: '0rem', + backgroundColor: 'white', + }, + }), + }; + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + + return ( + + {renderSnackBar()} + + + setAnnotationId(event.target.value)} + /> + + + + {loading && ( + + + + )} + {annotationDetails && + + {typeof key === "string" ? snakeToTitleCase(key) : key}} + valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}} + theme={theme} + /> + + } + + ); +} + +export default AnnotationDetails; diff --git a/src/app/ui/pages/admin/Dashboard.jsx b/src/app/ui/pages/admin/Dashboard.jsx new file mode 100644 index 00000000..17388d6e --- /dev/null +++ b/src/app/ui/pages/admin/Dashboard.jsx @@ -0,0 +1,67 @@ +"use client" +import { Box, Tab, Tabs, Typography, Paper } from '@mui/material' +import React from 'react' +import { useState } from 'react' +import AnnotationDetails from './AnnotationDetails'; +import TaskDetails from './TaskDetails'; +import UserDetail from './UserDetails'; + +function TabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +const Admin = () => { + const [tabValue, setTabValue] = useState(0); + /* eslint-disable react-hooks/exhaustive-deps */ + + const handleTabChange = (e, v) => { + setTabValue(v) + } + + return ( + + < > + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default Admin diff --git a/src/app/ui/pages/admin/TaskDetails.jsx b/src/app/ui/pages/admin/TaskDetails.jsx new file mode 100644 index 00000000..57c64339 --- /dev/null +++ b/src/app/ui/pages/admin/TaskDetails.jsx @@ -0,0 +1,296 @@ +import React, { useState, useEffect } from 'react'; +import { Grid, TextField, Button, Tab, Tabs, Box, Typography } from '@mui/material'; +import { JSONTree } from 'react-json-tree'; +import { snakeToTitleCase } from '../../../../utils/utils'; +import {CircularProgress} from '@mui/material'; +import CustomizedSnackbars from '@/components/common/Snackbar'; +import FetchUserByIdAPI from '../../../actions/api/user/FetchUserByIDAPI.js'; +import GetTaskAnnotationsAPI from '../../../actions/api/Dashboard/GetTaskAnnotationsAPI.js'; +import GetTaskDetailsAPI from '../../../actions/api/Dashboard/getTaskDetails.js'; + +function TaskDetails() { + /* eslint-disable react-hooks/exhaustive-deps */ + + const [taskId, setTaskId] = useState(''); + const [tabValue, setTabValue] = useState(0); + const [taskDetails, setTaskDetails] = useState(null); + const [annotations, setAnnotations] = useState(null); + const [usersDetails, setUsersDetails] = useState(null); + const [loading, setLoading] = useState(false); + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + const fetchTaskDetails = async () => { + setLoading(true); + setTaskDetails(null); + setAnnotations(null); + fetchTaskAnnotations(); + const apiObj = new GetTaskDetailsAPI(taskId); + fetch(apiObj.apiEndPoint(), apiObj.getHeaders()) + .then(async (res) => { + if(res.status === 200) { + const data = await res.json(); + return data; + } + else if(res.status === 404){ + // const resp = await res.json(); + setSnackbarInfo({ + open: true, + message: "Task Not Found", + variant: "error", + }) + setLoading(false); + } + else { + const resp = await res.json(); + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + setLoading(false); + } + }) + .then(async (data) => { + if(data?.error) { + setLoading(false); + setTaskDetails(data); + } + else { + const users = await getTaskAssignedUsers(data); + setUsersDetails(users); + if(data && data['review_user']) + data['review_user'] = `${data['review_user']} (${users[1]?.email})`; + if(data && data['super_check_user']) + data['super_check_user'] = `${data['super_check_user']} (${users[2]?.email})`; + if(data && data['annotation_users']?.length) + data['annotation_users'][0] = `${data['annotation_users'][0]} (${users[0]?.email})`; + setLoading(false); + setTaskDetails(data); + } + }) + }; + + const fetchTaskAnnotations = async () => { + const apiObj = new GetTaskAnnotationsAPI(taskId); + fetch(apiObj.apiEndPoint(), apiObj.getHeaders()) + .then(async (res) => { + if(res.status === 200) { + const data = await res.json(); + return data; + } + else if(res.status === 404){ + setSnackbarInfo({ + open: true, + message: "Task Not Found", + variant: "error", + }) + setLoading(false) + } + else { + setSnackbarInfo({ + open: true, + message: "Something Went Wrong", + variant: "error", + }); + setLoading(false) + } + }) + .then(data => { + if(data?.error) { + setLoading(false); + setAnnotations(data); + } + else { + let displayData = {}; + data?.forEach((annotation) => { + annotation.annotation_type === 1 && (displayData['annotator'] = annotation); + annotation.annotation_type === 2 && (displayData['reviewer'] = annotation); + annotation.annotation_type === 3 && (displayData['super_checker'] = annotation); + }); + setAnnotations(displayData); + } + }); + }; + + useEffect(() => { + if(usersDetails?.length && annotations) { + if(annotations['annotator'] && annotations['annotator']['completed_by'] === usersDetails[0]?.id) + annotations['annotator']['completed_by'] = `${annotations['annotator']['completed_by']} (${usersDetails[0]?.email})`; + if(annotations['reviewer'] && annotations['reviewer']['completed_by'] === usersDetails[1]?.id) + annotations['reviewer']['completed_by'] = `${annotations['reviewer']['completed_by']} (${usersDetails[1]?.email})`; + if(annotations['super_checker'] && annotations['super_checker']['completed_by'] === usersDetails[2]?.id) + annotations['super_checker']['completed_by'] = `${annotations['super_checker']['completed_by']} (${usersDetails[2]?.email})`; + }; + }, [usersDetails, annotations]); + + const getTaskAssignedUsers = async (data) => { + const getAnnotator = async () => { + if(!(data?.annotation_users?.length)) + return Promise.resolve(null); + + const annotatorObj = new FetchUserByIdAPI(data?.annotation_users[0]); + return fetch(annotatorObj.apiEndPoint(), annotatorObj.getHeaders()) + .then(res => res.json()); + }; + + const getReviewer = async () => { + if(!(data?.review_user)) + return Promise.resolve(null); + + const reviewerObj = new FetchUserByIdAPI(data?.review_user); + return fetch(reviewerObj.apiEndPoint(), reviewerObj.getHeaders()) + .then(res => res.json()); + } + + const getSuperChecker = async () => { + if(!(data?.super_check_user)) + return Promise.resolve(null); + + const superCheckerObj = new FetchUserByIdAPI(data?.super_check_user); + return fetch(superCheckerObj.apiEndPoint(), superCheckerObj.getHeaders()) + .then(res => res.json()); + }; + + return Promise.all([getAnnotator(), getReviewer(), getSuperChecker()]); + }; + + const theme = { + extend: { + base00: '#000', + base01: '#383830', + base02: '#49483e', + base03: '#75715e', + base04: '#a59f85', + base05: '#f8f8f2', + base06: '#f5f4f1', + base07: '#f9f8f5', + base08: '#f92672', + base09: '#fd971f', //orange + base0A: '#f4bf75', + base0B: '#a6e22e', //green + base0C: '#a1efe4', + base0D: '#66d9ef', + base0E: '#ae81ff', + base0F: '#cc6633', + }, + value: ({ style }, nodeType, keyPath) => ({ + style: { + ...style, + borderLeft: '2px solid #ccc', + marginLeft: '1.375em', + paddingLeft: '2em', + }, + }), + nestedNode: ({ style }, nodeType, keyPath) => ({ + style: { + ...style, + borderLeft: '2px solid #ccc', + marginLeft: keyPath.length > 1 ? '1.375em' : 0, + textIndent: '-0.375em', + }, + + }), + arrowContainer: ({ style }, arrowStyle) => ({ + style: { + ...style, + paddingRight: '1.375rem', + textIndent: '0rem', + backgroundColor: 'white', + }, + }), + }; + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + function TabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + + ); + } + + return ( + + {renderSnackBar()} + + + setTaskId(event.target.value)} + /> + + + + {loading && ( + + + + )} + {taskDetails && <> + + setTabValue(v)} aria-label="task-details-tabs"> + + + + + + + + {typeof key === "string" ? snakeToTitleCase(key) : key}} + valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}} + theme={theme} + /> + + + {typeof key === "string" ? snakeToTitleCase(key) : key}} + valueRenderer={(raw) => {typeof raw === "string" && raw.match(/^"(.*)"$/) ? raw.slice(1, -1) : raw}} + theme={theme} + /> + + + } + + ); +} + +export default TaskDetails; diff --git a/src/app/ui/pages/admin/UserDetails.jsx b/src/app/ui/pages/admin/UserDetails.jsx new file mode 100644 index 00000000..85422596 --- /dev/null +++ b/src/app/ui/pages/admin/UserDetails.jsx @@ -0,0 +1,399 @@ +import React, { useState, useEffect } from "react"; +import MUIDataTable from "mui-datatables"; +import { useNavigate } from "react-router-dom"; +import { useDispatch, useSelector } from "react-redux"; +import { ThemeProvider, Grid, IconButton } from "@mui/material"; +import tableTheme from "../../../../themes/tableTheme"; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import Search from "../../../../components/common/Search"; +import UserMappedByRole from "../../../../utils/UserMappedByRole"; +import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; +import { useRouter } from "next/navigation"; +import VisibilityIcon from '@mui/icons-material/Visibility'; +import UserInfo from "./UserInfo"; +import Spinner from "../../../../components/common/Spinner"; +import { el } from "date-fns/locale"; +import GetUserDetailUpdateAPI from "../../../actions/api/Dashboard/GetUserDetailUpdateAPI"; +import { fetchUserDetails } from "@/Lib/Features/user/getUserDetails"; + +const UserDetail = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const dispatch = useDispatch(); + const router = useRouter(); + const [loading, setLoading] = useState(false); + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + const [openDialog, setOpenDialog] = useState(false); + const [id, setId] = useState(""); + const [userName,setUserName] = useState(""); + const [email, setEmail] = useState(""); + const [active, setActive] = useState(); + const [firstName, setFirstName] = useState(""); + const [lastName, setLastName] = useState(""); + const [language, setLanguage] = useState([]); + const [participationType, setParticipationType] = useState(""); + const [Role, setRole] = useState(""); + + const UserDetail = useSelector((state) => state.getUserDetails.data); + console.log(UserDetail); + const apiLoading = useSelector((state) => state.apiStatus.loading); + const SearchUserDetail = useSelector( + (state) => state.searchProjectCard?.searchValue + ); + const getUserDetail = () => { + setLoading(true); + dispatch(fetchUserDetails()); + }; + + useEffect(() => { + getUserDetail(); + }, []); + + useEffect(() => { + if (UserDetail.length > 0) { + setLoading(false); + } + }, [UserDetail]); + + const handleEditChange = ( + id, + email, + username, + first_name, + last_name, + languages, + participation_type, + role, + is_active, + ) => { + setOpenDialog(true); + setId(id); + setEmail(email); + setUserName(username); + setFirstName(first_name); + setLastName(last_name); + setLanguage(languages); + setParticipationType(participation_type); + setRole(role); + setActive(is_active); + }; + + const handleCloseDialog = () => { + setOpenDialog(false); + }; + + const handleUpdateEditProfile = async () => { + const data = { + email:email, + username: userName, + first_name: firstName, + last_name: lastName, + languages: language, + participation_type: participationType, + role: Role, + is_active: active, + }; + + const UserObj = new GetUserDetailUpdateAPI(id, data); + // dispatch(APITransport(UserObj)); + const res = await fetch(UserObj.apiEndPoint(), { + method: "PATCH", + body: JSON.stringify(UserObj.getBody()), + headers: UserObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }); + getUserDetail(); + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }); + } + handleCloseDialog(); + }; + + const pageSearch = () => { + return UserDetail.filter((el) => { + if (SearchUserDetail == "") { + return el; + } else if ( + el.email?.toLowerCase().includes(SearchUserDetail?.toLowerCase()) + ) { + return el; + }else if( + el.username?.toLowerCase().includes(SearchUserDetail?.toLowerCase()) + ){ + return el; + } else if ( + el.first_name?.toLowerCase().includes(SearchUserDetail?.toLowerCase()) + ) { + return el; + }else if( + el.is_active?.toString() + ?.toLowerCase() + .includes(SearchUserDetail?.toLowerCase()) + ){ + return el; + } else if ( + el.last_name?.toLowerCase().includes(SearchUserDetail?.toLowerCase()) + ) { + return el; + } else if ( + el.participation_type + .toString() + ?.toLowerCase() + .includes(SearchUserDetail?.toLowerCase()) + ) { + return el; + } else if ( + el.languages?.some((val) => + val?.toLowerCase().includes(SearchUserDetail?.toLowerCase()) + ) + ) { + return el; + } + }); + }; + + const columns = [ + { + name: "id", + label: "Id", + options: { + display: false, + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "email", + label: "Email", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "username", + label: "UserName", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "first_name", + label: "First Name", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "last_name", + label: "Last Name", + options: { + filter: false, + sort: false, + align: "center", + setCellProps: () => ({ style: { paddingLeft: "30px" } }), + }, + }, + { + name: "languages", + label: "Languages", + options: { + filter: false, + sort: false, + align: "center", + setCellProps: () => ({ style: { paddingLeft: "30px" } }), + }, + }, + { + name: "participation_type", + label: "Participation Type", + options: { + filter: false, + sort: false, + align: "center", + setCellProps: () => ({ style: { paddingLeft: "40px" , paddingRight: "30px" } }), + }, + }, + { + name: "role", + label: "Role", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "is_active", + label: "Active Status", + options: { + filter: false, + sort: false, + align: "center", + setCellProps: () => ({ style: { paddingLeft: "30px" , paddingRight: "30px"} }), + }, + }, + { + name: "Actions", + label: "Actions", + options: { + filter: false, + sort: false, + align: "center", + setCellProps: () => ({ style: {paddingLeft: "10px" , paddingRight: "20px"}} ), + }, + }, + ]; + + const data = + UserDetail && UserDetail.length > 0 + ? pageSearch().map((el, i) => { + const userRoleFromList = + el.role && UserMappedByRole(el.role)?.element; + + return [ + el.id, + el.email, + el.username, + el.first_name, + el.last_name, + el.languages.join(", "), + el.participation_type, + userRoleFromList ? userRoleFromList : el.role, + el.is_active==true?"Active":"Not Active", + <> +
+ + router.push(`/profile/${el.id}`)} /> + + + + handleEditChange( + el.id, + el.email, + el.username, + el.first_name, + el.last_name, + el.languages, + el.participation_type, + el.role, + el.is_active, + ) + } + /> + +
+ , + ]; + }) + : []; + + + + + const options = { + textLabels: { + body: { + noMatch: "No records", + }, + toolbar: { + search: "Search", + viewColumns: "View Column", + }, + pagination: { rowsPerPage: "Rows per page" }, + options: { sortDirection: "desc" }, + }, + // customToolbar: fetchHeaderButton, + displaySelectToolbar: false, + fixedHeader: false, + filterType: "checkbox", + download: false, + print: false, + rowsPerPageOptions: [10, 25, 50, 100], + // rowsPerPage: PageInfo.count, + filter: false, + // page: PageInfo.page, + viewColumns: false, + selectableRows: "none", + search: false, + jumpToPage: true, + }; + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + return ( +
+ {renderSnackBar()} + {loading && } + + + + + + + + {openDialog && ( + handleCloseDialog()} + submit={() => handleUpdateEditProfile()} + Email={email} + FirstName={firstName} + userName = {userName} + setUserName={setUserName} + active={active} + setActive={setActive} + setFirstName={setFirstName} + LastName={lastName} + setLastName={setLastName} + Language={language} + setLanguage={setLanguage} + ParticipationType={participationType} + setParticipationType={setParticipationType} + Role={Role} + setRole={setRole} + /> + )} +
+ ); +}; + +export default UserDetail; diff --git a/src/app/ui/pages/admin/UserInfo.jsx b/src/app/ui/pages/admin/UserInfo.jsx new file mode 100644 index 00000000..affc62df --- /dev/null +++ b/src/app/ui/pages/admin/UserInfo.jsx @@ -0,0 +1,130 @@ +import { + Grid, + FormControl, + InputLabel, + Select, + Card, + MenuItem, + DialogContent, + Dialog, + DialogContentText, + Typography, + Box, + Tab, + Tabs, + } from "@mui/material"; + import React from "react"; + import { useState } from "react"; + import { useSelector } from "react-redux"; + // import EditProfile from "./EditProfile"; + + function TabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + + ); + } + + const UserInfo = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const { + openDialog, + handleCloseDialog, + submit, + Email, + FirstName, + LastName, + Language, + ParticipationType, + Role, + setRole, + setUserName, + userName, + setActive, + active, + setFirstName, + setLastName, + setLanguage, + setParticipationType, + } = props; + const [tabValue, setTabValue] = useState(0); + + const handleTabChange = (e, v) => { + setTabValue(v); + }; + + return ( + <> + + + + + {/* {renderSnackBar()} */} + + + + + + + + {/* */} + + + + + + + + ); + }; + + export default UserInfo; + \ No newline at end of file diff --git a/src/app/ui/pages/change-password/change-password.js b/src/app/ui/pages/change-password/change-password.js new file mode 100644 index 00000000..0291f8e9 --- /dev/null +++ b/src/app/ui/pages/change-password/change-password.js @@ -0,0 +1,303 @@ +import { + Card, + Grid, + ThemeProvider, + Typography, + InputAdornment, + } from "@mui/material"; + import React, { useEffect, useState } from "react"; + import themeDefault from "@/themes/theme"; + import { translate } from "@/config/localisation"; + import { useNavigate, useParams } from "react-router-dom"; + import Button from "@/components/common/Button"; + import OutlinedTextField from "@/components/common/OutlinedTextField"; + import DatasetStyle from "@/styles/dataset"; + import { useDispatch, useSelector } from "react-redux"; + import Spinner from "@/components/common/Spinner"; + import CustomizedSnackbars from "@/components/common/Snackbar"; + import VpnKeyOutlinedIcon from '@mui/icons-material/VpnKeyOutlined'; + import IconButton from "@material-ui/core/IconButton"; + import Visibility from "@material-ui/icons/Visibility"; + import VisibilityOff from "@material-ui/icons/VisibilityOff"; +import ChangePasswordAPI from "@/app/actions/api/user/ChangePasswordAPI"; + + + const ChangePassword = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const navigate = useNavigate(); + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const [newPassword, setNewPassword] = useState("") + const [currentPassword, setCurrentPassword] = useState("") + const [confirmPassword, setConfirmPassword] = useState("") + const [loading, setLoading] = useState(false); + const [values, setValues] = useState({ + password: "", + showPassword: false, + }); + const [newvalues, setNewValues] = useState({ + newpassword: "", + showNewPassword: false, + }); + const [confirmvalues, setConfirmValues] = useState({ + confirmpassword: "", + showConfirmPassword: false, + }); + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + const apiLoading = useSelector(state => state.apiStatus.loading); + const apiMessage = useSelector(state => state.apiStatus.message); + const apiError = useSelector(state => state.apiStatus.error); + useEffect(() => { + setSnackbarInfo({ + open: apiMessage ? true : false, + variant: apiError ? "error" : "success", + message: apiMessage , + }); + }, [apiMessage, apiError]) + + useEffect(() => { + setLoading(apiLoading); + }, [apiLoading]) + + const handleClickShowPassword = () => { + setValues({ ...values, showPassword: !values.showPassword }); + }; + const handleClickShowNewPassword = () => { + setNewValues({ ...newvalues, showNewPassword: !newvalues.showNewPassword }); + }; + const handleClickShowConfirmPassword = () => { + setConfirmValues({ ...confirmvalues, showConfirmPassword: !confirmvalues.showConfirmPassword }); + }; + + + const handleMouseDownPassword = (event) => { + event.preventDefault(); + }; + const loggedInUserData = useSelector( + (state) => state.getLoggedInData.data + ); + + const handleChangePassword = async () => { + setNewPassword("") + setCurrentPassword("") + setConfirmPassword("") + const ChangePassword = { + new_password: newPassword, + current_password: currentPassword, + confirm_password: confirmPassword + } + if(newPassword!==confirmPassword){ + setSnackbarInfo({ + ...snackbar, + open: true, + message: "New Password and Confirm Password must match", + variant: 'error' + }) + } + else{ + const userObj = new ChangePasswordAPI(loggedInUserData.id,ChangePassword); + const res = await fetch(userObj.apiEndPoint(), { + method: "PATCH", + body: JSON.stringify(userObj.getBody()), + headers: userObj.getHeaders().headers, + }); + const resp = await res.json(); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + } + + } + + + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={[snackbar.message]} + /> + ); + }; + + + return ( + + {loading && } + {renderSnackBar()} + + + + + + + Change Password + + + + {/* + + */} + + + + Current Password + + + + setCurrentPassword(e.target.value)} + InputProps={{ + endAdornment: ( + + + {values.showPassword ? : } + + + + ), + }} + + /> + + + + + New Password + + + + setNewPassword(e.target.value)} + InputProps={{ + endAdornment: ( + + + {newvalues.showNewPassword ? : } + + + + ), + }} + /> + + + + + Confirm Password + + + + setConfirmPassword(e.target.value)} + InputProps={{ + endAdornment: ( + + + {confirmvalues.showConfirmPassword ? : } + + + + ), + }} + /> + + + + + ) + }} + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* + Availability Status + + */} + + Languages + + + + + + + Participation Type + + + + + + + + + setSnackbarState({...snackbarState, open: false})} + anchorOrigin={{vertical: 'top', horizontal: 'right'}} + hide={2000} + /> + + ); +}; + +export default MyProfile; diff --git a/src/app/ui/pages/forgot-password/forgot-password.js b/src/app/ui/pages/forgot-password/forgot-password.js index 748828cd..c411ba44 100644 --- a/src/app/ui/pages/forgot-password/forgot-password.js +++ b/src/app/ui/pages/forgot-password/forgot-password.js @@ -7,7 +7,7 @@ import OutlinedTextField from "@/components/common/OutlinedTextField"; // import { translate } from "@/config/localisation"; import LoginStyle from "@/styles/loginStyle"; import themeDefault from "@/themes/theme"; -// import { useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import AppInfo from "@/components/user/AppInfo"; import ForgotPasswordAPI from "../../../actions/api/user/ForgotPasswordAPI"; // import APITransport from "@/redux/actions/apitransport/apitransport"; @@ -15,6 +15,8 @@ import { useDispatch } from "react-redux"; import CustomizedSnackbars from "@/components/common/Snackbar"; const ForgotPassword = () => { + /* eslint-disable react-hooks/exhaustive-deps */ + const classes = LoginStyle(); const dispatch = useDispatch(); const navigate = useNavigate(); @@ -54,7 +56,7 @@ const ForgotPassword = () => { message: resp?.message, variant: "success", }) - // navigate("/login"); + navigate("/login"); } else { setSnackbarInfo({ open: true, diff --git a/src/app/ui/pages/login/login.js b/src/app/ui/pages/login/login.js index b356c660..2640e03c 100644 --- a/src/app/ui/pages/login/login.js +++ b/src/app/ui/pages/login/login.js @@ -22,9 +22,11 @@ import { auth, googleAuthProvider } from "@/firebase"; import { signInWithPopup } from "firebase/auth"; import GoogleLoginAPI from "../../../actions/api/user/GoogleLogin"; import { authenticateUser } from "@/utils/utils"; -import FetchLoggedInUserDataAPI from "@/Lib/Features/user/FetchLoggedInUserData"; +import { FetchLoggedInUserData } from "@/Lib/Features/getLoggedInData"; export default function Login() { + /* eslint-disable react-hooks/exhaustive-deps */ + const navigate = useNavigate(); const dispatch=useDispatch() @@ -57,8 +59,7 @@ export default function Login() { })); }; const getLoggedInUserData = () => { - const loggedInUserObj = new FetchLoggedInUserDataAPI("me"); - dispatch(APITransport(loggedInUserObj)); + dispatch(FetchLoggedInUserData("me")); }; diff --git a/src/app/ui/pages/projects/project.js b/src/app/ui/pages/projects/project.js index 6a8107c6..f83c8341 100644 --- a/src/app/ui/pages/projects/project.js +++ b/src/app/ui/pages/projects/project.js @@ -106,4 +106,4 @@ const [radiobutton, setRadiobutton] = useState(true); ); -} \ No newline at end of file +} diff --git a/src/app/ui/pages/projects/projectDetails.js b/src/app/ui/pages/projects/projectDetails.js index fd7e82d7..4c29e788 100644 --- a/src/app/ui/pages/projects/projectDetails.js +++ b/src/app/ui/pages/projects/projectDetails.js @@ -12,28 +12,27 @@ import { Tooltip, } from "@mui/material"; import React, { useEffect, useState } from "react"; - import themeDefault from "@/themes/theme"; - import Link from "next/link"; - import TaskTable from "@/components/Project/TaskTable"; - import MembersTable from "@/components/Project/MembersTable"; - import ReportsTable from "@/components/Project/ReportsTable"; - import { translate } from "@/config/localisation"; - import addUserTypes from "@/Constants/addUserTypes"; - import Spinner from "@/components/common/Spinner"; + import themeDefault from "../../../../themes/theme"; + // import Link from "next/link"; + import { Link, useNavigate, useParams, useHistory } from "react-router-dom"; + import TaskTable from "../../../../components/Project/TaskTable"; + import MembersTable from "../../../../components/Project/MembersTable"; + import ReportsTable from "../../../../components/Project/ReportsTable"; + import { translate } from "../../../../config/localisation"; + import addUserTypes from "../../../../Constants/addUserTypes"; + import Spinner from "../../../../components/common/Spinner"; import Menu from "@mui/material/Menu"; - import { useDispatch, useSelector } from "react-redux"; import { styled, alpha } from "@mui/material/styles"; + import { useDispatch ,useSelector } from "react-redux"; + import SuperCheckerTasks from "@/components/Project/SuperCheckerTasks"; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; - import DatasetStyle from "@/styles/dataset"; - import ProjectDescription from "@/components/Tabs/ProjectDescription"; + import DatasetStyle from "../../../../styles/dataset"; + import ProjectDescription from "../../../../components/Tabs/ProjectDescription"; import SettingsOutlinedIcon from "@mui/icons-material/SettingsOutlined"; - import userRole from "@/utils/UsersRolesList"; - import SuperChecker from "@/components/Project/SuperChecker"; -import { fetchProjectDetails } from "@/Lib/Features/projects/getProjectDetails"; -import SuperCheckerTasks from "@/components/Project/SuperCheckerTasks"; + import userRole from "../../../../utils/UsersRolesList"; + import { fetchProjectDetails } from "@/Lib/Features/projects/getProjectDetails"; + import SuperChecker from "../../../../components/Project/SuperChecker"; import AllTaskTable from "@/components/Project/AllTaskTable"; - /* eslint-disable react-hooks/exhaustive-deps */ - const menuOptions = [ { name: "Tasks", isChecked: false, component: () => null }, @@ -105,8 +104,8 @@ import AllTaskTable from "@/components/Project/AllTaskTable"; })); const Projects = () => { // console.log("props", props) - // const { id } = useParams(); - const id = 1 + const { id } = useParams(); + // const id = 1 const classes = DatasetStyle(); const [projectData, setProjectData] = useState([ { name: "Project ID", value: null }, @@ -117,7 +116,7 @@ import AllTaskTable from "@/components/Project/AllTaskTable"; { name: "Total Labeled Task", value: null }, { name: "Reviewed Task Count", value: null }, ]); - // let navigate = useNavigate(); + let navigate = useNavigate(); const [anchorEl, setAnchorEl] = React.useState(null); const open = Boolean(anchorEl); const handleClick = (event) => { @@ -246,9 +245,9 @@ import AllTaskTable from "@/components/Project/AllTaskTable"; } }, [annotationdata, reviewerdata,dispatch]); - // const handleOpenSettings = () => { - // navigate(`/projects/${id}/projectsetting`); - // }; + const handleOpenSettings = () => { + navigate(`/projects/${id}/projectsetting`); + }; let projectValue = "Unassigned Super Check Tasks" @@ -435,12 +434,13 @@ import AllTaskTable from "@/components/Project/AllTaskTable"; {ProjectDetails.title}
- {(userRole.WorkspaceManager === loggedInUserData?.role || + {/* {(userRole.WorkspaceManager === loggedInUserData?.role || userRole.OrganizationOwner === loggedInUserData?.role || - userRole.Admin === loggedInUserData?.role) && ( + userRole.Admin === loggedInUserData?.role) && ( */} - )} + {/* )} */} diff --git a/src/app/ui/pages/workspace/BasicWorkspaceSettings.jsx b/src/app/ui/pages/workspace/BasicWorkspaceSettings.jsx index 561dc7ba..13f77529 100644 --- a/src/app/ui/pages/workspace/BasicWorkspaceSettings.jsx +++ b/src/app/ui/pages/workspace/BasicWorkspaceSettings.jsx @@ -3,7 +3,7 @@ import { Grid, ThemeProvider, Typography, Autocomplete, TextField, FormControlLa import React, { useEffect, useState } from "react"; import themeDefault from '../../../../themes/theme' import OutlinedTextField from "../../../../components/common/OutlinedTextField"; -import "@/styles/Dataset.css"; +import "../../../../styles/Dataset.css"; import CustomButton from "../../../../components/common/Button"; import CustomizedSnackbars from "../../../../components/common/Snackbar"; import Spinner from "../../../../components/common/Spinner"; @@ -11,6 +11,8 @@ import Spinner from "../../../../components/common/Spinner"; const BasicWorkspaceSettings = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + const [snackbar, setSnackbarInfo] = useState({ open: false, message: "", @@ -168,4 +170,4 @@ const BasicWorkspaceSettings = (props) => { ) } -export default BasicWorkspaceSettings; +export default BasicWorkspaceSettings; \ No newline at end of file diff --git a/src/app/ui/pages/workspace/DetailsViewPage.js b/src/app/ui/pages/workspace/DetailsViewPage.js index 8e6d8e9f..de6da8d6 100644 --- a/src/app/ui/pages/workspace/DetailsViewPage.js +++ b/src/app/ui/pages/workspace/DetailsViewPage.js @@ -13,7 +13,7 @@ import { Menu, MenuItem, } from "@mui/material"; -import { Link, useNavigate } from "react-router-dom"; + import { Link, useNavigate, useParams } from "react-router-dom"; import { useDispatch, useSelector } from 'react-redux'; import axios from 'axios'; import React, { useState, useEffect } from "react"; @@ -68,9 +68,9 @@ import { fetchWorkspaceDetails } from "@/Lib/Features/getWorkspaceDetails"; ); const { pageType, title, createdBy, onArchiveWorkspace,initialUserData } = props; - // const { id, orgId } = useParams(); - const id = 1; - const orgId = 1; + const { id, orgId } = useParams(); + // const id = 1; + // const orgId = 1; const classes = DatasetStyle(); // const userDetails = useSelector((state) => state.fetchLoggedInUserData.data); const dispatch = useDispatch(); @@ -98,7 +98,7 @@ import { fetchWorkspaceDetails } from "@/Lib/Features/getWorkspaceDetails"; }; const getWorkspaceDetails = () => { - dispatch(fetchWorkspaceDetails(1)); + dispatch(fetchWorkspaceDetails(orgId)); }; @@ -128,7 +128,7 @@ import { fetchWorkspaceDetails } from "@/Lib/Features/getWorkspaceDetails"; const handleOpenSettings = () => { - navigate(`/workspace/workspacesetting`); + navigate(`/workspaces/${id}/workspacesetting`); }; const handleClickMenu = (data) =>{ @@ -147,7 +147,7 @@ import { fetchWorkspaceDetails } from "@/Lib/Features/getWorkspaceDetails"; {/* {pageType === componentType.Type_Organization && ( */} - title + { title} {/* )} */} {/* {pageType === componentType.Type_Workspace && ( */} @@ -159,7 +159,7 @@ import { fetchWorkspaceDetails } from "@/Lib/Features/getWorkspaceDetails"; sx={{ mb: 3 }} > - title + {title} {/* {(userRole.Annotator !== userDetails?.role || @@ -283,7 +283,7 @@ import { fetchWorkspaceDetails } from "@/Lib/Features/getWorkspaceDetails"; <> {/* */} - + { + /* eslint-disable react-hooks/exhaustive-deps */ const CustomButton = ({ label, buttonVariant, color, disabled = false, ...rest }) => ( + + + + {OpenExportProjectDialog && ( + + )} + + + ); + }; + + export default AdvancedOperation; + \ No newline at end of file diff --git a/src/components/Project/BasicSettings.jsx b/src/components/Project/BasicSettings.jsx new file mode 100644 index 00000000..cf13b1bd --- /dev/null +++ b/src/components/Project/BasicSettings.jsx @@ -0,0 +1,449 @@ + +import { Grid, ThemeProvider, Typography, Autocomplete, TextField } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import themeDefault from '@/themes/theme' +import { useNavigate, useParams } from 'react-router-dom'; +import OutlinedTextField from "../common/OutlinedTextField"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import CustomButton from "../common/Button"; +import CustomizedSnackbars from "../common/Snackbar"; +import Spinner from "../common/Spinner"; +import fetchLanguages from "@/Lib/Features/fetchLanguages"; +import GetSaveButtonAPI from "@/app/actions/api/Projects/getSaveButtonAPI"; + + + +const BasicSettings = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const {ProjectDetails } = props; + + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + const [value, setValue] = useState(); + const [showLanguage, setShowLanguage] = useState(false); + const [sourceLanguage, setSourceLanguage] = useState(""); + const [targetLanguage, setTargetLanguage] = useState(""); + const [languageOptions, setLanguageOptions] = useState([]); + const [loading, setLoading] = useState(false); + const [newDetails, setNewDetails] = useState(); + const { id } = useParams(); + const navigate = useNavigate(); + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const apiLoading = useSelector(state => state.apiStatus.loading); + + + useEffect(() => { + if (ProjectDetails.project_type === "MonolingualTranslation" ||ProjectDetails.project_type === "SemanticTextualSimilarity" || ProjectDetails.project_type === "TranslationEditing" || ProjectDetails.project_type === "ContextualTranslationEditing"|| ProjectDetails.project_type==="SingleSpeakerAudioTranscriptionEditing") { + getLanguageChoices(); + setShowLanguage(true); + } + + }, [ProjectDetails]); + + + + useEffect(() => { + setNewDetails({ + title: ProjectDetails.title, + description: ProjectDetails.description, + max_pending_tasks_per_user: ProjectDetails.max_pending_tasks_per_user, + tasks_pull_count_per_batch: ProjectDetails.tasks_pull_count_per_batch, + }); + setTargetLanguage(ProjectDetails?.tgt_language) + setSourceLanguage(ProjectDetails?.src_language) + }, [ProjectDetails]); + + const LanguageChoices = useSelector((state) => state.getLanguages.data); + + const getLanguageChoices = () => { + dispatch(fetchLanguages()); + }; + + useEffect(() => { + if (LanguageChoices && LanguageChoices.length > 0) { + let temp = []; + console.log(LanguageChoices); + LanguageChoices.forEach((element) => { + temp.push(element[0] + // { + // name: element[0], + // value: element[0], + // } + ); + }); + setLanguageOptions(temp); + } + }, [LanguageChoices]); + + + + const handleSave = async () => { + + const sendData = { + title: newDetails.title, + description: newDetails.description, + tgt_language: targetLanguage, + src_language: sourceLanguage, + project_type: ProjectDetails.project_type, + project_mode: ProjectDetails.project_mode, + users: ProjectDetails.users, + annotation_reviewers: ProjectDetails.annotation_reviewers, + max_pending_tasks_per_user: newDetails.max_pending_tasks_per_user, + tasks_pull_count_per_batch: newDetails.tasks_pull_count_per_batch, + } + const projectObj = new GetSaveButtonAPI(id, sendData); + const res = await fetch(projectObj.apiEndPoint(), { + method: "PUT", + body: JSON.stringify(projectObj.getBody()), + headers: projectObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: "success", + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + + } + + function snakeToTitleCase(str) { + return str.split("_").map((word) => { + return word.charAt(0).toUpperCase() + word.slice(1); + }).join(" "); + } + useEffect(() => { + setLoading(apiLoading); + }, [apiLoading]) + + const handleProjectName = (event) => { + + event.preventDefault(); + setNewDetails((prev) => ({ + ...prev, + [event.target.name]: event.target.value, + })); + } + + // const handleCancel = ()=>{ + // // setSourceLanguage(ProjectDetails?.tgt_language) + // // setTargetLanguage(ProjectDetails?.src_language) + // } + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + return ( + + + {/*
*/} + {loading && } + + {renderSnackBar()} + + + + + + + + Project Name + + + + + + + + + + + Project Description + + + + + + + + <> + + {ProjectDetails.project_type !== "ContextualSentenceVerification"||ProjectDetails.project_type==="SingleSpeakerAudioTranscriptionEditing" && + <> + + + Source Language + + + + setSourceLanguage(newVal)} + options={languageOptions} + value={sourceLanguage} + style={{ fontSize: "14px", width: "500px" }} + renderInput={(params) => ( + + )} + /> + + + } + + + + + {ProjectDetails.project_type==="SingleSpeakerAudioTranscriptionEditing"? "Language" :"Target Language"} + + + + setTargetLanguage(newVal)} + options={languageOptions} + value={targetLanguage} + style={{ fontSize: "14px", width: "500px" }} + renderInput={(params) => ( + + )} + /> + + + + + + + Max Pending Tasks Per User + + + + + + + + + + Tasks Pull Count Per Batch + + + + + + + + + navigate(`/projects/:id/`)} + // onClick={handleCancel} + label="Cancel" /> + + + + + ) +} + +export default BasicSettings; \ No newline at end of file diff --git a/src/components/Project/DeallocationAnnotatorsAndReviewers.jsx b/src/components/Project/DeallocationAnnotatorsAndReviewers.jsx new file mode 100644 index 00000000..aa136cd1 --- /dev/null +++ b/src/components/Project/DeallocationAnnotatorsAndReviewers.jsx @@ -0,0 +1,588 @@ +import React, { useState } from "react"; +import CustomButton from "@/components/common/Button"; +import { + Button, Popover,Box,Grid,Typography,Radio,Select,MenuItem,Dialog, DialogActions, DialogContent, DialogContentText, Checkbox, + ListItemText, + ListItemIcon, +} from "@mui/material"; +import RadioGroup from "@mui/material/RadioGroup"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import FormControl from "@mui/material/FormControl"; +import DatasetStyle from "@/styles/dataset"; +import { translate } from "@/config/localisation"; +import { useDispatch, useSelector } from "react-redux"; +import {useParams } from 'react-router-dom'; +import { snakeToTitleCase } from "@/utils/utils"; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import TextField from '@mui/material/TextField'; +import LoginAPI from "@/app/actions/api/user/Login"; +import DeallocationAnnotatorsAndReviewersAPI from "@/app/actions/api/Dashboard/DeallocationAnnotatorsAndReviewers"; + + +let AnnotationStatus = [ + "unlabeled", + "skipped", + "draft", + "labeled", + "to_be_revised", +]; + +let ReviewStatus = [ + "unreviewed", + "accepted", + "accepted_with_minor_changes", + "accepted_with_major_changes", + "to_be_revised", + "draft", + "skipped", + ]; + + let SuperChecker = ["unvalidated","validated","validated_with_changes","skipped","draft","rejected"]; + const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, + getContentAnchorEl: null, + anchorOrigin: { + vertical: "bottom", + horizontal: "center", + }, + transformOrigin: { + vertical: "top", + horizontal: "center", + }, + variant: "menu", +}; +export default function DeallocationAnnotatorsAndReviewers() { + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const {id} = useParams(); + const [anchorEl, setAnchorEl] = useState(null); + const [radiobutton, setRadiobutton] = useState("annotation"); + const [openDialog, setOpenDialog] = useState(false); + const[annotatorsUser,setAnnotatorsUser] = useState("") + const[annotationStatus,setAnnotationStatus] = useState([]) + const[reviewerssUser,setReviewersUser] = useState("") + const[superCheckersUser,setSuperCheckersUser] = useState("") + const[reviewStatus,setReviewStatus] = useState([]) + const[superCheckStatus,setSuperCheckStatus] = useState([]) + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", +}); + + + + + const open = Boolean(anchorEl); + const Id = open ? "simple-popover" : undefined; + + const ProjectDetails = useSelector(state => state.getProjectDetails.data); + const handleClickOpen = (event) => { + setAnchorEl(event.currentTarget); + }; + + + const handleClose = () => { + setAnchorEl(null); + setAnnotatorsUser("") + setAnnotationStatus([]) + setReviewersUser("") + setReviewStatus([]) + setSuperCheckersUser("") + setSuperCheckStatus([]) + }; + + const handleAnnotation = () => { + setRadiobutton("annotation"); + }; + const handleReview = () => { + setRadiobutton("review"); + }; + const handlesuperChecker = () => { + setRadiobutton("superChecker"); + }; + + const handleSubmit = () => { + setAnchorEl(null); + setOpenDialog(true); +} + +const handleCloseDialog = () => { + setOpenDialog(false); + setAnnotatorsUser("") + setAnnotationStatus([]) + setReviewersUser("") + setReviewStatus([]) + setSuperCheckersUser("") + setSuperCheckStatus([]) +}; + +const handleChangeAnnotationStatus = (event) => { + const value = event.target.value; + setAnnotationStatus(value); + }; + + const handleChangeReviewStatus = (event) =>{ + const value = event.target.value; + setReviewStatus(value); + } + const handleChangeSuperCheckerStatus = (event) =>{ + const value = event.target.value; + setSuperCheckStatus(value); + } + + + +const handleok = async() => { + setAnchorEl(null); + setOpenDialog(false); + setAnnotatorsUser("") + setAnnotationStatus([]) + setReviewersUser("") + setReviewStatus([]) + setSuperCheckersUser("") + setSuperCheckStatus([]) + const projectObj = new DeallocationAnnotatorsAndReviewersAPI(id,radiobutton,annotatorsUser,reviewerssUser,annotationStatus,reviewStatus,superCheckersUser,superCheckStatus); + // dispatch(APITransport(projectObj)); + const res = await fetch(projectObj.apiEndPoint(), { + method: "GET", + body: JSON.stringify(projectObj.getBody()), + headers: projectObj.getHeaders().headers, + }); + const resp = await res.json(); + // setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } +} + + +const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + const emailId = localStorage.getItem("email_id"); + const [password, setPassword] = useState(""); + const [pin, setPin] = useState(""); + const handleConfirm = async () => { + if(radiobutton === "annotation" || radiobutton === "review"){ + const apiObj = new LoginAPI(emailId, password); + const res = await fetch(apiObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(apiObj.getBody()), + headers: apiObj.getHeaders().headers, + }); + const rsp_data = await res.json(); + if (res.ok) { + handleok(); + }else{ + window.alert("Invalid credentials, please try again"); + console.log(rsp_data); + } + }else if(radiobutton === "superChecker"){ + if(pin === "9327"){ + handleok(); + }else{ + window.alert("Incorrect pin entered"); + } + } + }; + + return ( +
+ {renderSnackBar()} + + + + + + + + } + label="Annotators" + onClick={handleAnnotation} + /> + } + label="Reviewers" + onClick={handleReview} + /> + } + label="Super Check" + onClick={handlesuperChecker} + /> + + + + + {radiobutton === "annotation" && ( + <> + + + + Select User: + + + + + + + + + + + + Select Annotation Status : + + + + + + + + + + + + )} + {radiobutton === "review" && ( + <> + + + + Select User: + + + + + + + + + + + + Select Review Status : + + + + + + + + + + )} + + {radiobutton === "superChecker" && ( + <> + + + + Select User: + + + + + + + + + + + + Select Super Check Status : + + + + + + + + + + )} + + + + + + + + + + + + + Are you sure want to Deallocate User Tasks ? + + {(radiobutton === "annotation" || radiobutton === "review") && setPassword(e.target.value)} + />} + {radiobutton === "superChecker" && setPin(e.target.value)} + />} + + + + + + + +
+ ); +} diff --git a/src/components/Project/DeleteProjectTasks.jsx b/src/components/Project/DeleteProjectTasks.jsx new file mode 100644 index 00000000..c9977018 --- /dev/null +++ b/src/components/Project/DeleteProjectTasks.jsx @@ -0,0 +1,405 @@ +import React, { useState } from "react"; +import { + Button, + Popover, + Box, + TextField, + Grid, Typography,Radio, Dialog, DialogActions, DialogContent, DialogContentText, +} from "@mui/material"; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import { translate } from "@/config/localisation"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from 'react-router-dom'; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import userRole from "@/utils/UserMappedByRole/Roles"; +import DeleteProjectTasksAPI from "@/app/actions/api/Projects/DeleteProjectTasksAPI"; + +export default function DeleteProjectTasks() { + const classes = DatasetStyle(); + const { id } = useParams(); + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [projectTaskStartId, setProjectTaskStartId] = useState(""); + const [projectTaskEndId, setProjectTaskEndId] = useState(""); + const [loading, setLoading] = useState(false); + const [openDialog, setOpenDialog] = useState(false); + const [radiobutton, setRadiobutton] = useState(true) + const [dataIds, setDataIds] = useState("") + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + const loggedInUserData = useSelector( + (state) => state.getLoggedInData?.data + ); + + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + const handleCloseDialog = () => { + setOpenDialog(false); + }; + const handleClearSearch = () => { + setAnchorEl(null); + setProjectTaskStartId(); + setProjectTaskEndId(); + }; + + const handleDeletebyids = () => { + setRadiobutton(true) + + } + const handleDeletebyrange = () => { + setRadiobutton(false) + } + const handledataIds = (e,) => { + setDataIds(e.target.value); + + + } + + let datasetitem = dataIds.split(",") + var value = datasetitem.map(function (str) { + return parseInt(str); + }); + + const handleok = async() => { + setOpenDialog(false); + setAnchorEl(null); + setProjectTaskStartId(); + setProjectTaskEndId(); + let projectObj + const ProjectTaskStartAndEndID = { + project_task_start_id: parseInt(projectTaskStartId), + project_task_end_id: parseInt(projectTaskEndId) + } + + + const ProjectTaskIDs = { + project_task_ids: value + } + + if (radiobutton === true) { + projectObj = new DeleteProjectTasksAPI(id, ProjectTaskStartAndEndID) + + + } else { + projectObj = new DeleteProjectTasksAPI(id, ProjectTaskIDs) + } + const res = await fetch(projectObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(projectObj.getBody()), + headers: projectObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + } + + const handleSearchSubmit = () => { + setOpenDialog(true); + + } + + + const open = Boolean(anchorEl); + const Id = open ? 'simple-popover' : undefined; + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + const emailId = localStorage.getItem("email_id"); + const [password, setPassword] = useState(""); + const handleConfirm = async () => { + const apiObj = new LoginAPI(emailId, password); + const res = await fetch(apiObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(apiObj.getBody()), + headers: apiObj.getHeaders().headers, + }); + const rsp_data = await res.json(); + if (res.ok) { + handleok(); + }else{ + window.alert("Invalid credentials, please try again"); + console.log(rsp_data); + } + }; + + return ( +
+ {renderSnackBar()} + + + + + + + + + + } label="Delete by Range" onClick={handleDeletebyids} /> + } label="Delete by IDs" onClick={handleDeletebyrange} /> + + + + + + {radiobutton === true && + <> + + + + + Project Task Start ID: + + + + setProjectTaskStartId(e.target.value)} + inputProps={{ + style: { + fontSize: "16px" + } + }} + /> + + + + + + + Project Task End ID: + + + + setProjectTaskEndId(e.target.value)} + inputProps={{ + style: { + fontSize: "16px" + } + }} + /> + + + + } + {radiobutton === false && + + + + Project Task IDs: + + + + + + + + } + + + + + + + + + + + Are you sure want to delete these tasks? Please note this action cannot be undone. + + setPassword(e.target.value)} + /> + + + + + + +
+ ); +} diff --git a/src/components/Project/DownloadProjectButton.jsx b/src/components/Project/DownloadProjectButton.jsx new file mode 100644 index 00000000..5a93ac61 --- /dev/null +++ b/src/components/Project/DownloadProjectButton.jsx @@ -0,0 +1,227 @@ +import React, { useState, useEffect } from "react"; +import { styled } from '@mui/material/styles'; +import Button from '@mui/material/Button'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; +import { CSVDownload, CSVLink } from "react-csv"; +import { useDispatch, useSelector } from "react-redux"; +import { Link, useNavigate, useParams } from 'react-router-dom'; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import userRole from "@/utils/UserMappedByRole/Roles"; +import { fetchDownloadCSVProject } from "@/Lib/Features/projects/DownloadProjectCsv"; +import { fetchDownloadTSVProject } from "@/Lib/Features/projects/DownloadProjectTsv"; +import { fetchDownloadJSONProject } from "@/Lib/Features/projects/DownloadJSONProject"; + +const StyledMenu = styled((props) => ( + +))(({ theme }) => ({ + '& .MuiPaper-root': { + borderRadius: 6, + marginTop: theme.spacing(1), + minWidth: 100, + + + }, +})); + + +function DownloadProjectButton(props) { + const { taskStatus,SetTask,downloadMetadataToggle} = props; + const [anchorEl, setAnchorEl] = useState(null); + const [downloadres, setdownloadres] = useState(false); + const [loading, setLoading] = useState(false); + const[taskValue ,setTaskValue]= useState(taskStatus) + const apiLoading = useSelector(state => state.apiStatus.loading); + const open = Boolean(anchorEl); + const { id } = useParams(); + const dispatch = useDispatch(); + let csvLink = React.createRef() + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + const loggedInUserData = useSelector( + (state) => state.getLoggedInData?.data + ); + + + useEffect(() => { + setLoading(apiLoading); + }, [apiLoading]) + + + // const getDownloadProject = async () => { + // const projectObj = new DownloadProjectButtonAPI(id); + + // dispatch(APITransport(projectObj)); + + // } + // let DownloadProject = useSelector(state => state.downloadProjectButton.data); + + + // const DownloadJSONProject = async () => { + // const projectObj = new DownloadJSONProjectAPI(id); + + // dispatch(APITransport(projectObj)); + + // } + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + + }; + const handleDownloadJSONProject = async () => { + // SetTask([]) //used to clear the selected task statuses + const projectObj = (id,taskStatus,downloadMetadataToggle); + dispatch(fetchDownloadJSONProject(projectObj)); + // const res = await fetch(projectObj.apiEndPoint(), { + // method: "POST", + // body: JSON.stringify(projectObj.getBody()), + // headers: projectObj.getHeaders().headers, + // }); + // const resp = await res.json(); + // setLoading(false); + // if (res.ok) { + // setSnackbarInfo({ + // open: true, + // message: "success", + // variant: "success", + // }) + + // } else { + // setSnackbarInfo({ + // open: true, + // message: resp?.message, + // variant: "error", + // }) + // } + + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const handleDownloadCSVProject = async () => { + // SetTask([]) //used to clear the selected task statuses + setLoading(true) + const projectObj = (id,taskStatus,downloadMetadataToggle); + dispatch(fetchDownloadCSVProject(projectObj)); + // const res = await fetch(projectObj.apiEndPoint(), { + // method: "POST", + // body: JSON.stringify(projectObj.getBody()), + // headers: projectObj.getHeaders().headers, + // }); + // const resp = await res.json(); + // setLoading(false); + // if (res.ok) { + // setSnackbarInfo({ + // open: true, + // message: "success", + // variant: "success", + // }) + + // } else { + // setSnackbarInfo({ + // open: true, + // message: resp?.message, + // variant: "error", + // }) + // } + + }; + + const handleDownloadTSVProject = async () => { + // SetTask([]) //used to clear the selected task statuses + setLoading(true) + const projectObj = (id,taskStatus,downloadMetadataToggle); + dispatch(fetchDownloadTSVProject(projectObj)); + // const res = await fetch(projectObj.apiEndPoint(), { + // method: "POST", + // body: JSON.stringify(projectObj.getBody()), + // headers: projectObj.getHeaders().headers, + // }); + // const resp = await res.json(); + // setLoading(false); + // if (res.ok) { + // setSnackbarInfo({ + // open: true, + // message: "success", + // variant: "success", + // }) + + // } else { + // setSnackbarInfo({ + // open: true, + // message: resp?.message, + // variant: "error", + // }) + // } + + }; + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + return ( +
+ {renderSnackBar()} + + + + CSV + + + TSV + + + JSON + + +
+ ); +} +export default DownloadProjectButton; \ No newline at end of file diff --git a/src/components/Project/ExportProjectDialog.jsx b/src/components/Project/ExportProjectDialog.jsx new file mode 100644 index 00000000..e4938efc --- /dev/null +++ b/src/components/Project/ExportProjectDialog.jsx @@ -0,0 +1,120 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + Grid, + Box, + Typography, + ListItemText, + MenuItem, + Select, + FormControl, + InputLabel, + Checkbox, + ListItemIcon, + Chip, + } from "@mui/material"; + import React, { useEffect, useState } from "react"; + import { useDispatch, useSelector } from "react-redux"; + import OutlinedTextField from "../common/OutlinedTextField"; + import { snakeToTitleCase } from "@/utils/utils"; + import DatasetStyle from "@/styles/dataset"; + import CancelIcon from "@mui/icons-material/Cancel"; +import { fetchDatasetsByType } from "@/Lib/Features/actions/getDatasetsByType"; + + const ExportProjectDialog = ({ + OpenExportProjectDialog, + handleClose, + datasetId, + setDatasetId, + datavalue, + projectType, + }) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const dispatch = useDispatch(); + const classes = DatasetStyle(); + const [instanceIds, setInstanceIds] = useState([]); + + + const DatasetInstances = useSelector( + (state) => state.getDatasetsByType?.data + ); + + instanceIds?.map((el) => + console.log(el.instance_id, "instanceIdsinstanceIds") + ); + + useEffect(() => { + dispatch(fetchDatasetsByType(projectType)); + }, []); + + useEffect(() => { + if(!( + DatasetInstances && + Object.keys(DatasetInstances).length === 0 && + Object.getPrototypeOf(DatasetInstances) === Object.prototype + ) ){ setInstanceIds(DatasetInstances);} + + }, [DatasetInstances]); + return ( + + + + + + + + Dataset Instance Id + + + + + + + + + + + + + ); + }; + + export default ExportProjectDialog; + \ No newline at end of file diff --git a/src/components/Project/FilterList.jsx b/src/components/Project/FilterList.jsx index f7a7c777..ab8e1159 100644 --- a/src/components/Project/FilterList.jsx +++ b/src/components/Project/FilterList.jsx @@ -31,7 +31,7 @@ const FilterList = (props) => { const [selectAnnotator, setSelectAnnotator] = useState("All"); const ProjectDetails = useSelector((state) => state.getProjectDetails.data); - const userDetails = useSelector((state) => state.fetchLoggedInUserData.data); + const userDetails = useSelector((state) => state.getLoggedInData.data); // const [selectedType, setSelectedType] = useState(selectedFilter.Annotators); // const [selectedStatus, setSelectedStatus] = useState(selectedFilter.status); // const handleDatasetChange = (e) => { diff --git a/src/components/Project/MembersTable.jsx b/src/components/Project/MembersTable.jsx index ae736935..05a55938 100644 --- a/src/components/Project/MembersTable.jsx +++ b/src/components/Project/MembersTable.jsx @@ -2,8 +2,8 @@ import React, { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import MUIDataTable from "mui-datatables"; -import { useRouter } from "next/navigation"; import CustomButton from "../common/Button"; +import { useNavigate,useParams } from "react-router-dom"; import UserMappedByRole from "../../utils/UserMappedByRole"; import { PersonAddAlt } from "@mui/icons-material"; import addUserTypes from "../../Constants/addUserTypes/index"; @@ -26,7 +26,7 @@ import userRoles from "../../utils/Role"; import TextField from '@mui/material/TextField'; import { fetchRemoveProjectMember } from "@/Lib/Features/projects/RemoveProjectMember"; import RemoveProjectReviewerAPI from "@/app/actions/api/Projects/RemoveProjectReviewerAPI"; -import { fetchResendUserInvite } from "@/Lib/Features/projects/ResendUserInvite"; +import ResendUserInviteAPI, { fetchResendUserInvite } from "@/app/actions/api/Projects/ResendUserInvite"; import InviteUsersToOrgAPI from "@/app/actions/api/user/InviteUsersToOrgAPI"; import { fetchOrganizationUsers } from "@/Lib/Features/getOrganizationUsers"; @@ -90,10 +90,10 @@ const addLabel = { const MembersTable = (props) => { const [addUserDialogOpen, setAddUserDialogOpen] = useState(false); - // const { orgId, id } = useParams(); - const id=1; - const orgId =1; - // const navigate = useNavigate(); + const { orgId, id } = useParams(); + // const id=1; + // const orgId =1; + const navigate = useNavigate(); const dispatch = useDispatch(); const [userRole, setUserRole] = useState(); const [loading, setLoading] = useState(false); @@ -117,27 +117,27 @@ const MembersTable = (props) => { const userDetails = useSelector((state) => state.getLoggedInData.data); const ProjectDetails = useSelector((state) => state.getProjectDetails.data); const apiLoading = useSelector((state) => state.apiStatus.loading); - // const SearchWorkspaceMembers = useSelector( - // (state) => state.SearchProjectCards.data - // ); + const SearchWorkspaceMembers = useSelector( + (state) => state.searchProjectCard?.searchValue + ); const loggedInUserData = useSelector( (state) => state.getLoggedInData.data ); const pageSearch = () => { return dataSource.filter((el) => { - // if (SearchWorkspaceMembers == "") { + if (SearchWorkspaceMembers == "") { + return el; + } else if ( + el.username + ?.toLowerCase() + .includes(SearchWorkspaceMembers?.toLowerCase()) + ) { + return el; + } else if ( + el.email?.toLowerCase().includes(SearchWorkspaceMembers?.toLowerCase()) + ) { return el; - // } else if ( - // el.username - // ?.toLowerCase() - // .includes(SearchWorkspaceMembers?.toLowerCase()) - // ) { - // return el; - // } else if ( - // el.email?.toLowerCase().includes(SearchWorkspaceMembers?.toLowerCase()) - // ) { - // return el; - // } + } }); }; @@ -209,7 +209,8 @@ const MembersTable = (props) => { }; const handleResendUser = async(email) => { - dispatch(fetchResendUserInvite(email=[email])); + const projectObj = new ResendUserInviteAPI(email=[email]); + const res = await fetch(projectObj.apiEndPoint(), { method: "POST", body: JSON.stringify(projectObj.getBody()), @@ -218,7 +219,7 @@ const MembersTable = (props) => { const resp = await res.json(); setLoading(false); if (res.ok) { - setSnackbarInfo({ + setSnackbarInfo({ open: true, message: resp?.message, variant: "success", diff --git a/src/components/Project/ProjectCard.jsx b/src/components/Project/ProjectCard.jsx index a0d03acc..f8061690 100644 --- a/src/components/Project/ProjectCard.jsx +++ b/src/components/Project/ProjectCard.jsx @@ -4,12 +4,12 @@ import ProjectCard from "../common/ProjectCard"; import { Link } from "react-router-dom"; import "../../styles/Dataset.css"; import DatasetStyle from "@/styles/dataset"; -// import { useDispatch, useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import TablePagination from "@mui/material/TablePagination"; import TablePaginationActions from "../common/TablePaginationActions"; import Spinner from "../common/Spinner"; import Search from "../common/Search"; -// import SearchProjectCards from "../../../../redux/actions/api/ProjectDetails/SearchProjectCards"; +// import searchProjectCard from "../../../../redux/actions/api/ProjectDetails/searchProjectCard"; // import Record from "../../../../assets/no-record.svg"; import ProjectFilterList from "../common/ProjectFilterList"; import FilterListIcon from "@mui/icons-material/FilterList"; @@ -21,8 +21,7 @@ const Projectcard = (props) => { const { projectData, selectedFilters, setsSelectedFilters } = props; const classes = DatasetStyle(); -// const SearchProject = useSelector((state) => state.SearchProjectCards.data); - const SearchProject = [] + const SearchProject = useSelector((state) => state.searchProjectCard?.searchValue); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(9); diff --git a/src/components/Project/ProjectCardList.jsx b/src/components/Project/ProjectCardList.jsx index bf411fdf..82fe70e4 100644 --- a/src/components/Project/ProjectCardList.jsx +++ b/src/components/Project/ProjectCardList.jsx @@ -1,22 +1,25 @@ import {React, useState, useEffect } from "react"; -import { Link } from "react-router-dom"; +// import Link from 'next/link'; import MUIDataTable from "mui-datatables"; import CustomButton from "../common/Button"; +import { Link } from "react-router-dom"; import { Grid, ThemeProvider, Tooltip, Button } from "@mui/material"; import tableTheme from "../../themes/tableTheme"; import Search from "../common/Search"; -// import { useDispatch, useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import ProjectFilterList from "../common/ProjectFilterList"; import FilterListIcon from "@mui/icons-material/FilterList"; import UserMappedByProjectStage from "../../utils/UserMappedByProjectStage"; const ProjectCardList = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + const { projectData, selectedFilters, setsSelectedFilters } = props; const [anchorEl, setAnchorEl] = useState(null); const popoverOpen = Boolean(anchorEl); const filterId = popoverOpen ? "simple-popover" : undefined; -// const SearchProject = useSelector((state) => state.SearchProjectCards.data); + const SearchProject = useSelector((state) => state.searchProjectCard?.searchValue); const handleShowFilter = (event) => { setAnchorEl(event.currentTarget); @@ -28,38 +31,38 @@ const ProjectCardList = (props) => { const pageSearch = () => { return projectData.filter((el) => { - // if (SearchProject == "") { - // return el; - // } else if ( - // el.project_type?.toLowerCase().includes(SearchProject?.toLowerCase()) - // ) { - // return el; - // } else if ( - // el.title?.toLowerCase().includes(SearchProject?.toLowerCase()) - // ) { - // return el; - // } else if ( - // el.id.toString()?.toLowerCase()?.includes(SearchProject.toLowerCase()) - // ) { - // return el; - // } else if ( - // el.workspace_id - // .toString() - // ?.toLowerCase() - // .includes(SearchProject?.toLowerCase()) - // ) { - // return el; - // } else if ( - // el.tgt_language?.toLowerCase().includes(SearchProject?.toLowerCase()) - // ) { - // return el; - // } else if ( - // UserMappedByProjectStage(el.project_stage) - // ?.name?.toLowerCase() - // .includes(SearchProject?.toLowerCase()) - // ) { + if (SearchProject == "") { + return el; + } else if ( + el.project_type?.toLowerCase().includes(SearchProject?.toLowerCase()) + ) { + return el; + } else if ( + el.title?.toLowerCase().includes(SearchProject?.toLowerCase()) + ) { + return el; + } else if ( + el.id.toString()?.toLowerCase()?.includes(SearchProject?.toLowerCase()) + ) { + return el; + } else if ( + el.workspace_id + .toString() + ?.toLowerCase() + .includes(SearchProject?.toLowerCase()) + ) { + return el; + } else if ( + el.tgt_language?.toLowerCase().includes(SearchProject?.toLowerCase()) + ) { + return el; + } else if ( + UserMappedByProjectStage(el.project_stage) + ?.name?.toLowerCase() + .includes(SearchProject?.toLowerCase()) + ) { return el; - // } + } }); }; const columns = [ @@ -177,8 +180,9 @@ const ProjectCardList = (props) => { el.tgt_language == null ? "-" : el.tgt_language, el.project_mode, el.workspace_id, - + @@ -255,4 +259,4 @@ const ProjectCardList = (props) => { ); }; -export default ProjectCardList; +export default ProjectCardList; \ No newline at end of file diff --git a/src/components/Project/ProjectLogs.jsx b/src/components/Project/ProjectLogs.jsx new file mode 100644 index 00000000..bf6e4d0a --- /dev/null +++ b/src/components/Project/ProjectLogs.jsx @@ -0,0 +1,167 @@ +import React, { useState, useEffect } from "react"; +import MUIDataTable from "mui-datatables"; +import { Box, Button, Card, FormControl, Grid, InputLabel, MenuItem, Select, ThemeProvider } from "@mui/material"; +import { addMonths, parse } from 'date-fns'; +import { DateRangePicker } from "react-date-range"; +import { useParams } from "react-router-dom"; +import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; +import ArrowRightIcon from "@mui/icons-material/ArrowRight"; +import { snakeToTitleCase } from "@/utils/utils"; +import tableTheme from "@/themes/tableTheme"; +import Spinner from "@/components/common/Spinner"; +import GetProjectLogsAPI from "@/app/actions/api/Projects/getProjectLogsAPI"; + +const ProjectLogs = () => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const { id } = useParams(); + console.log(useParams(),"useParams") + const [taskName, setTaskName] = useState("projects.tasks.export_project_in_place"); + const [columns, setColumns] = useState([]); + const [projectLogs, setProjectLogs] = useState([]); + const [showPicker, setShowPicker] = useState(false); + const [loading, setLoading] = useState(false); + const [selectRange, setSelectRange] = useState([{ + startDate: addMonths(new Date(), -3), + endDate: new Date(), + key: "selection" + }]); + const [allLogs, setAllLogs] = useState([]); + + const handleRangeChange = (ranges) => { + const { selection } = ranges; + if (selection.endDate > new Date()) selection.endDate = new Date(); + setSelectRange([selection]); + if (allLogs.length) { + let tempLogs = JSON.parse(JSON.stringify(allLogs)); + tempLogs = tempLogs.filter((log) => { + const date = parse(log.date, 'dd-MM-yyyy', new Date()); + return date >= selection.startDate && date <= selection.endDate; + }); + setProjectLogs(tempLogs); + } + }; + + useEffect(() => { + getProjectLogs(); + setSelectRange([{ + startDate: addMonths(new Date(), -3), + endDate: new Date(), + key: "selection" + }]); + }, [taskName]); + + const getProjectLogs = () => { + setLoading(true); + const apiObj = new GetProjectLogsAPI(id, taskName); + fetch(apiObj.apiEndPoint(), { + method: "GET", + headers: apiObj.getHeaders().headers, + }).then(async (res) => { + setLoading(false); + if (!res.ok) throw await res.json(); + else return await res.json(); + }).then((res) => { + setAllLogs(res); + }).catch(); + }; + + useEffect(() => { + if (allLogs.length) { + let tempColumns = []; + Object.keys(allLogs[0]).forEach((key) => { + tempColumns.push({ + name: key, + label: snakeToTitleCase(key), + options: { + filter: key === 'status', + sort: false, + align: "center" + }, + }); + }); + setColumns(tempColumns); + setProjectLogs(allLogs); + } else { + setColumns([]); + setProjectLogs([]); + } + }, [allLogs]); + + const options = { + filterType: 'checkbox', + selectableRows: "none", + download: false, + filter: true, + print: false, + search: false, + viewColumns: true, + jumpToPage: true, + }; + + return ( + + + + + + Filter by Task Type + + + + + + + {showPicker && + + + + } + + {loading ? : + + + + } + + ); +}; + +export default ProjectLogs; diff --git a/src/components/Project/ProjectSettings.jsx b/src/components/Project/ProjectSettings.jsx new file mode 100644 index 00000000..181a6899 --- /dev/null +++ b/src/components/Project/ProjectSettings.jsx @@ -0,0 +1,106 @@ +import { Box,Grid,Tab, Card,Tabs, Typography, Divider } from '@mui/material' +import React from 'react' +import { useState ,useEffect} from 'react' +import BasicSettings from './BasicSettings'; +import AdvancedOperation from './AdvancedOperation'; +import ReadonlyConfigurations from './ReadOnlyConfigurations'; +import ProjectLogs from './ProjectLogs'; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from 'react-router-dom'; +import { fetchProjectDetails } from '@/Lib/Features/projects/getProjectDetails'; +// import GetProjectDetailsAPI from "@/redux/actions/api/ProjectDetails/GetProjectDetails"; +// import APITransport from '../../../../redux/actions/apitransport/apitransport'; + + +function TabPanel(props) { + /* eslint-disable react-hooks/exhaustive-deps */ + + const { children, value, index, ...other } = props; + + return ( + + ); +} + +const ProjectSetting = () => { + const dispatch = useDispatch(); + const { id } = useParams(); + const [tabValue, setTabValue] = useState(0); + const handleTabChange = (e, v) => { + setTabValue(v) + } + const ProjectDetails = useSelector((state) => state.getProjectDetails.data); + + const getProjectDetails = () => { + + dispatch(fetchProjectDetails(id)); + } + + useEffect(() => { + getProjectDetails(); + }, []) + return ( + + + + + + Project Settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default ProjectSetting \ No newline at end of file diff --git a/src/components/Project/ReadOnlyConfigurations.jsx b/src/components/Project/ReadOnlyConfigurations.jsx new file mode 100644 index 00000000..09785166 --- /dev/null +++ b/src/components/Project/ReadOnlyConfigurations.jsx @@ -0,0 +1,249 @@ +import { Card, Grid, ThemeProvider, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import themeDefault from "@/themes/theme"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import { Link } from "react-router-dom"; +import CustomButton from "@/components/common/Button"; +import { fetchWorkspaceDetails } from "@/Lib/Features/getWorkspaceDetails"; + +const ReadonlyConfigurations = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const ProjectDetails = useSelector((state) => state.getProjectDetails.data); + const getWorkspaceDetails = () => { + dispatch(fetchWorkspaceDetails(ProjectDetails.workspace_id)); +} + +useEffect(() => { + getWorkspaceDetails(); +}, []); + +const workspaceDetails = useSelector(state => state.getWorkspaceDetails.data); + + return ( + + + {/* + + Read-only Configurations + + */} + {ProjectDetails && ProjectDetails.sampling_mode && ( +
+ + Sampling Parameters + + + + + Sampling Mode : + + + + {ProjectDetails.sampling_mode == "f" && "Full"} + {ProjectDetails.sampling_mode == "b" && "Batch"} + {ProjectDetails.sampling_mode == "r" && "Random"} + + + + {ProjectDetails && ProjectDetails?.sampling_parameters_json?.batch_size && ( + + + Batch Size : + + + + {ProjectDetails.sampling_parameters_json?.batch_size} + + + )} + {ProjectDetails && ProjectDetails?.sampling_parameters_json?.batch_size && ( + + + Batch Number : + + + + {ProjectDetails.sampling_parameters_json?.batch_number} + + )} + + {ProjectDetails.datasets.map((dataset,i) => ( + + + Dataset Instance : + + + + {dataset?.instance_name} + + + + + + ))} + + + + Workspace Name : + + + + {workspaceDetails.workspace_name} + + + + + + + {ProjectDetails.filter_string && ( + + + Filter String : + + + + {ProjectDetails.filter_string} + + + )} +
+ )} +
+ + + {ProjectDetails && ProjectDetails?.variable_parameters?.output_language && ( +
+ + Variable Parameters + + + + + Output Language : + + + {ProjectDetails?.variable_parameters?.output_language} + + +
+ )} +
+
+ ); +}; + +export default ReadonlyConfigurations; diff --git a/src/components/Project/ReportsTable.jsx b/src/components/Project/ReportsTable.jsx index 793b8116..615f1fb0 100644 --- a/src/components/Project/ReportsTable.jsx +++ b/src/components/Project/ReportsTable.jsx @@ -6,10 +6,16 @@ import { Box, Button, Grid, CircularProgress, Card, Radio, Typography, ThemeProv import RadioGroup from '@mui/material/RadioGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormControl from '@mui/material/FormControl'; -// import { useDispatch, useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import "../../styles/Dataset.css"; +import DatasetStyle from '@/styles/dataset'; import ColumnList from '../common/ColumnList'; - +import { isSameDay, format } from 'date-fns'; +import 'react-date-range/dist/styles.css'; +import 'react-date-range/dist/theme/default.css'; +import { useNavigate,useParams } from 'react-router-dom'; +import 'react-date-range/dist/styles.css'; +import 'react-date-range/dist/theme/default.css'; import { DateRangePicker, defaultStaticRanges } from "react-date-range"; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ArrowRightIcon from "@mui/icons-material/ArrowRight"; @@ -17,10 +23,21 @@ import tableTheme from "../../themes/tableTheme"; import themeDefault from "../../themes/theme"; import CustomizedSnackbars from "../common/Snackbar"; import userRole from "../../utils/Role"; +import GetProjectReportAPI from '@/app/actions/api/Projects/GetProjectReportAPI'; +import { fetchProjectReport } from '@/Lib/Features/getProjectReport'; const ReportsTable = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + const {isSuperChecker,isReviewer,isAnnotators}=props + const ProjectDetails = useSelector(state => state.getProjectDetails.data); + const [selectRange, setSelectRange] = useState([{ + startDate: new Date(Date.parse(ProjectDetails?.created_at, 'yyyy-MM-ddTHH:mm:ss.SSSZ')), + endDate: new Date(), + key: "selection" + }]); + // const [rangeValue, setRangeValue] = useState([format(Date.parse(ProjectDetails?.created_at, 'yyyy-MM-ddTHH:mm:ss.SSSZ'), 'yyyy-MM-dd'), Date.now()]); const [showPicker, setShowPicker] = useState(false); const [showSpinner, setShowSpinner] = useState(false); const [selectedColumns, setSelectedColumns] = useState([]); @@ -33,160 +50,40 @@ const ReportsTable = (props) => { }); - - const ProjectReport = []; - + const { id } = useParams(); + const dispatch = useDispatch(); + const ProjectReport = useSelector(state => state.getProjectReport.data); + const classes = DatasetStyle(); const [radiobutton, setRadiobutton] = useState(isAnnotators?"AnnotatationReports":isReviewer?"ReviewerReports":"SuperCheckerReports"); const [submitted, setSubmitted] = useState(false); - const ProjectDetails = { - "id": 2279, - "title": "test ocr ce 2", - "description": "test", - "created_by": null, - "is_archived": false, - "is_published": true, - "annotators": [ - { - "id": 1, - "username": "shoonya", - "email": "shoonya@ai4bharat.org", - "languages": [], - "availability_status": 1, - "enable_mail": false, - "first_name": "Admin", - "last_name": "AI4B", - "phone": "", - "profile_photo": "", - "role": 6, - "organization": { - "id": 1, - "title": "AI4Bharat", - "email_domain_name": "ai4bharat.org", - "created_by": { - "username": "shoonya", - "email": "shoonya@ai4bharat.org", - "first_name": "Admin", - "last_name": "AI4B", - "role": 6 - }, - "created_at": "2022-04-24T13:11:30.339610Z" - }, - "unverified_email": "shoonya@ai4bharat.org", - "date_joined": "2022-04-24T07:40:11Z", - "participation_type": 3, - "prefer_cl_ui": false, - "is_active": true - } - ], - "annotation_reviewers": [], - "review_supercheckers": [], - "frozen_users": [], - "workspace_id": 1, - "organization_id": 1, - "filter_string": null, - "sampling_mode": "f", - "sampling_parameters_json": {}, - "project_type": "OCRSegmentCategorizationEditing", - "label_config": "\n \n \n \n \n \n\n \n \n \n \t\n \n \n \n \n \n \t\n \n \n \n \n \t\n \n \n \n \n \n \n \n \t\n \n \n \n \n \t\n \n \n \n\n\n\n", - "variable_parameters": {}, - "project_mode": "Annotation", - "required_annotators_per_task": 1, - "tasks_pull_count_per_batch": 10, - "max_pending_tasks_per_user": 60, - "src_language": null, - "tgt_language": null, - "created_at": "2023-12-06T06:37:58.364413Z", - "project_stage": 1, - "revision_loop_count": 3, - "k_value": 100, - "metadata_json": null, - "datasets": [ - { - "instance_id": 295, - "instance_name": "Test OCR" - } - ], - "status": "Published", - "task_creation_status": "Tasks Creation Process Successful", - "last_project_export_status": "Success", - "last_project_export_date": "Synchronously Completed. No Date.", - "last_project_export_time": "Synchronously Completed. No Time.", - "last_pull_status": "Success", - "last_pull_date": "Synchronously Completed. No Date.", - "last_pull_time": "Synchronously Completed. No Time.", - "last_pull_result": "No result.", - "unassigned_task_count": 29, - "labeled_task_count": 0, - "reviewed_task_count": 0 - } - const userDetails= { - "id": 1, - "username": "shoonya", - "email": "shoonya@ai4bharat.org", - "languages": [], - "availability_status": 1, - "enable_mail": false, - "first_name": "Admin", - "last_name": "AI4B", - "phone": "", - "profile_photo": "", - "role": 6, - "organization": { - "id": 1, - "title": "AI4Bharat", - "email_domain_name": "ai4bharat.org", - "created_by": { - "username": "shoonya", - "email": "shoonya@ai4bharat.org", - "first_name": "Admin", - "last_name": "AI4B", - "role": 6 - }, - "created_at": "2022-04-24T13:11:30.339610Z" - }, - "unverified_email": "shoonya@ai4bharat.org", - "date_joined": "2022-04-24T07:40:11Z", - "participation_type": 3, - "prefer_cl_ui": false, - "is_active": true - }; - - const loggedInUserData= { - "id": 1, - "username": "shoonya", - "email": "shoonya@ai4bharat.org", - "languages": [], - "availability_status": 1, - "enable_mail": false, - "first_name": "Admin", - "last_name": "AI4B", - "phone": "", - "profile_photo": "", - "role": 2, - "organization": { - "id": 1, - "title": "AI4Bharat", - "email_domain_name": "ai4bharat.org", - "created_by": { - "username": "shoonya", - "email": "shoonya@ai4bharat.org", - "first_name": "Admin", - "last_name": "AI4B", - "role": 6 - }, - "created_at": "2022-04-24T13:11:30.339610Z" - }, - "unverified_email": "shoonya@ai4bharat.org", - "date_joined": "2022-04-24T07:40:11Z", - "participation_type": 3, - "prefer_cl_ui": false, - "is_active": true - } - const [selectRange, setSelectRange] = useState([{ - startDate: new Date(Date.parse(ProjectDetails?.created_at, 'yyyy-MM-ddTHH:mm:ss.SSSZ')), - endDate: new Date(), - key: "selection" - }]); + + const loggedInUserData = useSelector( + (state) => state.getLoggedInData.data + ); + useEffect(() => { + if (reportRequested && ProjectReport?.length > 0) { + let cols = []; + let selected = []; + Object.keys(ProjectReport[0]).forEach((key) => { + cols.push({ + name: key, + label: key, + options: { + filter: false, + sort: false, + } + }) + selected.push(key); + }); + setSelectedColumns(selected); + setColumns(cols); + } else { + setColumns([]); + setSelectedColumns([]); + } + setShowSpinner(false); + }, [ProjectReport]); + const handleChangeReports = (e) => { setRadiobutton(e.target.value) @@ -197,7 +94,7 @@ const ReportsTable = (props) => { const buttonSXStyle = { borderRadius: 2, margin: 2 } return ( - + { setSubmitted(true); if (radiobutton === "AnnotatationReports") { - projectObj = new GetProjectReportAPI(id, format(selectRange[0].startDate, 'yyyy-MM-dd'), format(selectRange[0].endDate, 'yyyy-MM-dd')); + projectObj = (id, format(selectRange[0].startDate, 'yyyy-MM-dd'), format(selectRange[0].endDate, 'yyyy-MM-dd')); } else if (radiobutton === "ReviewerReports") { - projectObj = new GetProjectReportAPI(id, format(selectRange[0].startDate, 'yyyy-MM-dd'), format(selectRange[0].endDate, 'yyyy-MM-dd'), reports_type); + projectObj = (id, format(selectRange[0].startDate, 'yyyy-MM-dd'), format(selectRange[0].endDate, 'yyyy-MM-dd'), reports_type); } else if (radiobutton === "SuperCheckerReports") { - projectObj = new GetProjectReportAPI(id, format(selectRange[0].startDate, 'yyyy-MM-dd'), format(selectRange[0].endDate, 'yyyy-MM-dd'), reports_type); + projectObj = (id, format(selectRange[0].startDate, 'yyyy-MM-dd'), format(selectRange[0].endDate, 'yyyy-MM-dd'), reports_type); } - dispatch(APITransport(projectObj)); + dispatch(fetchProjectReport(projectObj)); const res = await fetch(projectObj.apiEndPoint(), { method: "POST", body: JSON.stringify(projectObj.getBody()), diff --git a/src/components/Project/SuperCheckSettings.jsx b/src/components/Project/SuperCheckSettings.jsx new file mode 100644 index 00000000..b8ba9868 --- /dev/null +++ b/src/components/Project/SuperCheckSettings.jsx @@ -0,0 +1,216 @@ +import React, { useState } from "react"; +import { + Button, + Popover, + Box, + TextField, + Grid, Typography, Radio, Dialog, DialogActions, DialogContent, DialogContentText, +} from "@mui/material"; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import { translate } from "@/config/localisation"; +import DatasetStyle from "@/styles/dataset"; +import SuperCheckSettingsAPI from "@/app/actions/api/Dashboard/SuperCheckerSettingsAPI"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from 'react-router-dom'; +import CustomizedSnackbars from "@/components/common/Snackbar"; + + +export default function SuperCheckSettings(props) { + const{ProjectDetails}=props + const classes = DatasetStyle(); + const { id } = useParams(); + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [supercheckLoopCount, setSupercheckLoopCount] = useState(ProjectDetails.revision_loop_count); + const [supercheckvalue, setSupercheckvalue] = useState(ProjectDetails.k_value); + const [loading, setLoading] = useState(false); + + + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const handleSubmit = async () => { + const data = { + revision_loop_count: supercheckLoopCount, + k_value: supercheckvalue + } + setAnchorEl(null); + setSupercheckLoopCount(); + setSupercheckvalue(); + let projectObj = new SuperCheckSettingsAPI(id, data) + const res = await fetch(projectObj.apiEndPoint(), { + method: "PATCH", + body: JSON.stringify(projectObj.getBody()), + headers: projectObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: "success", + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + } + + + + const open = Boolean(anchorEl); + const Id = open ? 'simple-popover' : undefined; + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + return ( +
+ {renderSnackBar()} + + + + + + + + + Super Checking K% value: + + + + setSupercheckvalue(e.target.value)} + inputProps={{ + style: { + fontSize: "16px" + } + }} + /> + + + + + + + Super Check Revision Loop Count : + + + + setSupercheckLoopCount(e.target.value)} + inputProps={{ + style: { + fontSize: "16px" + + } + }} + /> + + + + + + + + + + + +
+ ); +} diff --git a/src/components/Tabs/AnnotatorTable.jsx b/src/components/Tabs/AnnotatorTable.jsx index b301b9a0..08612f29 100644 --- a/src/components/Tabs/AnnotatorTable.jsx +++ b/src/components/Tabs/AnnotatorTable.jsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from "react"; -// import { Link, useNavigate, useParams } from 'react-router-dom'; +import { Link, useNavigate, useParams } from 'react-router-dom'; import MUIDataTable from "mui-datatables"; -import Link from 'next/link'; +// import Link from 'next/link'; import { useDispatch, useSelector } from 'react-redux'; // import GetWorkspacesAnnotatorsDataAPI from "@/app/actions/api/workspace/GetWorkspacesAnnotatorsDataAPI"; import UserMappedByRole from "../../utils/UserMappedByRole"; @@ -21,7 +21,7 @@ const AnnotatorsTable = (props) => { const { onRemoveSuccessGetUpdatedMembers } = props; const [loading, setLoading] = useState(false); - // const { id } = useParams(); + const { id } = useParams(); const [snackbar, setSnackbarInfo] = useState({ open: false, message: "", @@ -29,7 +29,7 @@ const AnnotatorsTable = (props) => { }); const orgId = useSelector(state => state.getWorkspaceProjectData?.data?.[0]?.organization_id); - // const SearchWorkspaceMembers = useSelector((state) => state.SearchProjectCards.data); + const SearchWorkspaceMembers = useSelector((state) => state.searchProjectCard?.searchValue); const workspaceAnnotators = useSelector(state => state.getWorkspacesAnnotatorsData.data); @@ -38,14 +38,14 @@ const AnnotatorsTable = (props) => { useEffect(() => { - dispatch(fetchWorkspacesAnnotatorsData(1)); + dispatch(fetchWorkspacesAnnotatorsData(id)); }, []); const handleRemoveWorkspaceMember = async (Projectid) => { const workspacedata = { user_id: Projectid, } - const projectObj = new RemoveWorkspaceMemberAPI(1, workspacedata); + const projectObj = new RemoveWorkspaceMemberAPI(id, workspacedata); dispatch(APITransport(projectObj)); const res = await fetch(projectObj.apiEndPoint(), { method: "POST", @@ -97,11 +97,29 @@ const AnnotatorsTable = (props) => { }; - const pageSearch = () => { + const pageSearch = () => { return workspaceAnnotators.filter((el) => { + if (SearchWorkspaceMembers == "") { + + return el; + } else if ( + el.username + ?.toLowerCase() + .includes(SearchWorkspaceMembers?.toLowerCase()) + ) { + return el; + } else if ( + el.email + ?.toLowerCase() + .includes(SearchWorkspaceMembers?.toLowerCase()) + ) { + + return el; + } + }) @@ -169,7 +187,7 @@ const AnnotatorsTable = (props) => { // userRole ? userRole : el.role, // el.role, <> - + { variant: "success", }); const router = useRouter() - const id = 1; + const {id} = useParams(); // const orgId = useSelector(state=>state.getWorkspacesProjectData?.data?.[0]?.organization_id); const getWorkspaceManagersData = ()=>{ - - // const workspaceObjs = new GetWorkspacesManagersDataAPI(1); - + dispatch(fetchWorkspacesManagersData(id)); } /* eslint-disable react-hooks/exhaustive-deps */ @@ -44,11 +42,11 @@ const ManagersTable = (props) => { },[]); const workspaceManagers = useSelector(state=>state.getWorkspacesManagersData.data); - // const SearchWorkspaceManagers = useSelector((state) => state.SearchProjectCards.data); + const SearchWorkspaceManagers = useSelector((state) => state.searchProjectCard?.searchValue); const handleRemoveWorkspaceManager = async(userid)=>{ - const projectObj = new RemoveWorkspaceManagerAPI(1, {ids:[userid]},); + const projectObj = new RemoveWorkspaceManagerAPI(id, {ids:[userid]},); dispatch(APITransport(projectObj)); const res = await fetch(projectObj.apiEndPoint(), { method: "POST", @@ -78,24 +76,24 @@ const handleRemoveWorkspaceManager = async(userid)=>{ return workspaceManagers.filter((el) => { - // if (SearchWorkspaceManagers == "") { + if (SearchWorkspaceManagers == "") { return el; - // } else if ( - // el.username - // ?.toLowerCase() - // .includes(SearchWorkspaceManagers?.toLowerCase()) - // ) { + } else if ( + el.username + ?.toLowerCase() + .includes(SearchWorkspaceManagers?.toLowerCase()) + ) { - // return el; - // } else if ( - // el.email - // ?.toLowerCase() - // .includes(SearchWorkspaceManagers?.toLowerCase()) - // ) { + return el; + } else if ( + el.email + ?.toLowerCase() + .includes(SearchWorkspaceManagers?.toLowerCase()) + ) { - // return el; - // } + return el; + } }) } const columns = [ @@ -138,7 +136,7 @@ const handleRemoveWorkspaceManager = async(userid)=>{ el.username, el.email, <> - + { const OrganizationDetails = useSelector(state => state.getLoggedInData?.data.organization); const UserDetails = useSelector(state => state.getLoggedInData.data); const [selectRange, setSelectRange] = useState([{ - // startDate: new Date(Date.parse(OrganizationDetails?.created_at, 'yyyy-MM-ddTHH:mm:ss.SSSZ')), - // endDate: new Date(), - // key: "selection" - startDate: addDays(new Date(), -9), - endDate: addDays(new Date(), -3), - key: 'selection' + startDate: new Date(Date.parse(UserDetails?.date_joined, 'yyyy-MM-ddTHH:mm:ss.SSSZ')), + endDate: new Date(), + key: "selection" }]); + console.log("Start Date:", selectRange[0].startDate); +console.log("End Date:", selectRange[0].endDate); // const [rangeValue, setRangeValue] = useState([format(Date.parse(OrganizationDetails?.created_at, 'yyyy-MM-ddTHH:mm:ss.SSSZ'), 'yyyy-MM-dd'), Date.now()]); const [showPicker, setShowPicker] = useState(false); const [projectTypes, setProjectTypes] = useState([]); diff --git a/src/components/UserManagement/ProfileDetails.jsx b/src/components/UserManagement/ProfileDetails.jsx index 10601d01..b3bd4a8e 100644 --- a/src/components/UserManagement/ProfileDetails.jsx +++ b/src/components/UserManagement/ProfileDetails.jsx @@ -3,14 +3,14 @@ import { Button, Card, CircularProgress, Grid, ThemeProvider, Typography, Select import OutlinedTextField from "../../components/common/OutlinedTextField"; import themeDefault from "../../themes/theme"; -// import { useNavigate, useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { useSelector, useDispatch } from "react-redux"; import FetchLanguagesAPI from "@/app/actions/api/workspace/FetchLanguagesAPI"; import UpdateProfileAPI from "@/app/actions/api/user/UpdateProfileImageAPI"; import UpdateEmailAPI from "@/app/actions/api/user/UpdateEmailAPI"; import Snackbar from "../../components/common/Snackbar"; import APITransport from "@/Lib/apiTransport/apitransport"; -// import UpdateEmailDialog from "../../component/common/UpdateEmailDialog" +import UpdateEmailDialog from "../../components/common/UpdateEmailDialog" import UserMappedByRole from "../../utils/UserMappedByRole"; import {participationType} from '../../config/dropDownValues'; import { MenuProps } from "../../utils/utils"; @@ -18,7 +18,7 @@ import CustomButton from "../../components/common/Button"; import {fetchLanguages} from "@/Lib/Features/fetchLanguages"; const ProfileDetails = () => { -// const { id } = useParams(); + const { id } = useParams(); const [newDetails, setNewDetails] = useState(); const [initLangs, setInitLangs] = useState([]); const [snackbarState, setSnackbarState] = useState({ open: false, message: '', variant: ''}); @@ -27,7 +27,7 @@ const [originalEmail, setOriginalEmail] = useState(""); const [enableVerifyEmail, setEnableVerifyEmail] = useState(false); const [showEmailDialog, setShowEmailDialog] = useState(false); const [emailVerifyLoading, setEmailVerifyLoading] = useState(false); -// const navigate = useNavigate(); +const navigate = useNavigate(); /* eslint-disable react-hooks/exhaustive-deps */ // const userDetails = useSelector((state) => state.fetchLoggedInUserData.data); @@ -58,6 +58,13 @@ useEffect(() => { username: userDetails?.username, first_name: userDetails?.first_name, last_name: userDetails?.last_name, + age: userDetails?.age, + qualification:userDetails?.qualification, + gender:userDetails?.gender, + pin_code:userDetails?.pin_code, + city:userDetails?.city, + address:userDetails?.address, + state:userDetails?.state, languages: userDetails?.languages, phone: userDetails?.phone, availability_status:userDetails?.availability_status, @@ -98,7 +105,7 @@ return ( fullWidth label="First Name" name="first_name" - value={userDetails?.first_name} + value={newDetails?.first_name} InputLabelProps={{ shrink: true }} > @@ -108,7 +115,7 @@ return ( fullWidth label="Last Name" name="last_name" - value={userDetails?.last_name} + value={newDetails?.last_name} InputLabelProps={{ shrink: true }} > @@ -127,7 +134,79 @@ return ( fullWidth label="Phone" name="phone" - value={userDetails?.phone} + value={newDetails?.phone} + InputLabelProps={{ shrink: true }} + > + + + + + + + + + + + + + + + + + + + + + @@ -136,7 +215,7 @@ return ( disabled fullWidth label="Role" - value={UserMappedByRole(userDetails?.role)?.name} + value={UserMappedByRole(newDetails?.role)?.name} InputLabelProps={{ shrink: true }} > @@ -147,7 +226,7 @@ return ( fullWidth label="Username" name="username" - value={userDetails?.username} + value={newDetails?.username} InputLabelProps={{ shrink: true }} > @@ -156,7 +235,7 @@ return ( disabled fullWidth label="Organization" - value={userDetails?.organization?.title} + value={newDetails?.organization?.title} InputLabelProps={{ shrink: true }} > @@ -182,7 +261,7 @@ return ( fullWidth labelId="lang-label" name="languages" - value={userDetails?.languages? userDetails.languages : []} + value={newDetails?.languages? newDetails.languages : []} style={{zIndex: "0"}} MenuProps={MenuProps} input={} @@ -210,7 +289,7 @@ return ( fullWidth label="Availability Status" name="availability_status" - value={userDetails?.availability_status} + value={newDetails?.availability_status} InputLabelProps={{ shrink: true }} > @@ -221,7 +300,7 @@ return ( fullWidth labelId="lang-label" name="participation_type" - value={userDetails?.participation_type? userDetails.participation_type : []} + value={newDetails?.participation_type? newDetails.participation_type : []} style={{zIndex: "0"}} input={} > @@ -245,7 +324,7 @@ return ( navigate("/edit-profile")} + onClick={() => navigate("/edit-profile")} /> } diff --git a/src/components/UserManagement/ScheduleMails.jsx b/src/components/UserManagement/ScheduleMails.jsx index e5b51fb2..2c440652 100644 --- a/src/components/UserManagement/ScheduleMails.jsx +++ b/src/components/UserManagement/ScheduleMails.jsx @@ -2,6 +2,7 @@ import { Card, CircularProgress, Grid, ThemeProvider, Typography, Select, Box, M import themeDefault from "../../themes/theme"; import React, { useEffect, useState } from "react"; import { useSelector, useDispatch } from "react-redux"; +import { useParams } from 'react-router-dom'; // import APITransport from '../../../../redux/actions/apitransport/apitransport'; // import GetWorkspaceAPI from "../../../../redux/actions/api/Organization/GetWorkspace"; // import CreateScheduledMailsAPI from "../../../../redux/actions/api/UserManagement/CreateScheduledMails"; @@ -25,8 +26,8 @@ import CreateScheduledMailsAPI from "@/app/actions/api/user/CreateScheduledMails import DeleteScheduledMailsAPI from "@/app/actions/api/user/DeleteScheduledMailsAPI"; const ScheduleMails = () => { - // const { id } = useParams(); - const id = 1; + const { id } = useParams(); + // const id = 1; const [snackbarState, setSnackbarState] = useState({ open: false, message: '', variant: '' }); const [reportLevel, setReportLevel] = useState(1); const [selectedProjectType, setSelectedProjectType] = useState("AllAudioProjects"); diff --git a/src/components/common/AddUsersDialog.jsx b/src/components/common/AddUsersDialog.jsx index d6a15c72..b05311db 100644 --- a/src/components/common/AddUsersDialog.jsx +++ b/src/components/common/AddUsersDialog.jsx @@ -275,7 +275,7 @@ const AddUsersDialog = ({ setSelectedUsers(e.target.value)} + onChange={(e, newVal) => setSelectedUsers(Array.isArray(newVal) ? newVal : [])} options={availableUsers} value={selectedUsers} style={{ fontSize: "1rem", paddingTop: 4, paddingBottom: 4 }} diff --git a/src/components/common/DatasetCard.jsx b/src/components/common/DatasetCard.jsx index 24f28d61..3862c020 100644 --- a/src/components/common/DatasetCard.jsx +++ b/src/components/common/DatasetCard.jsx @@ -6,7 +6,6 @@ import Link from 'next/link'; const DatasetCard = (props) => { const { datasetObj } = props - console.log(datasetObj); return ( { + /* eslint-disable react-hooks/exhaustive-deps */ + const [anchorElUser, setAnchorElUser] = useState(null); const [anchorElSettings, setAnchorElSettings] = useState(null); const [anchorElHelp, setAnchorElHelp] = useState(null); @@ -738,6 +741,7 @@ const handleopenproject=(id,type)=>{ > anudesh{ {loggedInUserData?.username} @@ -891,7 +895,7 @@ const handleopenproject=(id,type)=>{ } - onLogoutClick() }> + onLogoutClick() } style={{cursor:"pointer"}}> Logout @@ -943,6 +947,7 @@ const handleopenproject=(id,type)=>{ topTranslate={"40"} leftTranslate={"-50"} isTransliteration={true} + style={{cursor:"pointer"}} // sx={{width: "400px"}} > Transliteration diff --git a/src/components/common/Search.jsx b/src/components/common/Search.jsx index 918bb20e..80bfd220 100644 --- a/src/components/common/Search.jsx +++ b/src/components/common/Search.jsx @@ -3,31 +3,32 @@ import SearchIcon from '@mui/icons-material/Search'; import { useEffect, useRef, useState } from "react"; import themeDefault from '../../themes/theme' import "../../styles/Dataset.css"; -// import { useDispatch, useSelector } from "react-redux"; -// import SearchProjectCards from "../../../../redux/actions/api/ProjectDetails/SearchProjectCards" + import { useDispatch, useSelector } from "react-redux"; +import { setSearchProjectCard } from "@/Lib/Features/searchProjectCard"; const Search = (props) => { const ref = useRef(null); + /* eslint-disable react-hooks/exhaustive-deps */ + -// const dispatch = useDispatch(); + const dispatch = useDispatch(); -// const SearchProject = useSelector((state) => state.SearchProjectCards.data); + const SearchProject = useSelector((state) => state.searchProjectCard?.searchValue); const [searchValue, setSearchValue] = useState(""); -// useEffect(() => { -// if (ref) ref.current.focus(); -// }, [ref]); + useEffect(() => { + if (ref) ref.current.focus(); + }, [ref]); -// useEffect(() => { - -// dispatch(SearchProjectCards("")); -// }, []) + useEffect(() => { + dispatch(setSearchProjectCard("")); +}, []) -// const handleChangeName = (value) => { -// setSearchValue(value); -// dispatch(SearchProjectCards(value)); -// }; + const handleChangeName = (value) => { + setSearchValue(value); + dispatch(setSearchProjectCard(value)); + }; return ( @@ -42,7 +43,7 @@ const Search = (props) => { placeholder="Search..." value={searchValue} onChange={(e) => handleChangeName(e.target.value)} - + inputProps={{ "aria-label": "search" }} /> diff --git a/src/components/common/TabPanel.jsx b/src/components/common/TabPanel.jsx new file mode 100644 index 00000000..be799826 --- /dev/null +++ b/src/components/common/TabPanel.jsx @@ -0,0 +1,43 @@ +import { Box, Typography } from "@mui/material"; + +export default function TabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + + ); + + + /** + * + const { children, value, index, ...other } = props; + + return ( + + ); + */ +} diff --git a/src/components/common/UpdateEmailDialog.jsx b/src/components/common/UpdateEmailDialog.jsx new file mode 100644 index 00000000..60ed5f00 --- /dev/null +++ b/src/components/common/UpdateEmailDialog.jsx @@ -0,0 +1,101 @@ +import VerifyEmailAPI from "@/app/actions/api/user/VerifyEmailAPI"; +import { + Button, + CircularProgress, + Dialog, + DialogActions, + DialogTitle, + Grid, + Typography, + } from "@mui/material"; + import React, { useState } from "react"; + import CustomButton from "../common/Button"; + import OutlinedTextField from "../common/OutlinedTextField"; + import Snackbar from "../common/Snackbar"; + + const UpdateEmailDialog = ({isOpen, handleClose, oldEmail, newEmail, onSuccess}) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const [oldEmailCode, setOldEmailCode] = useState(""); + const [newEmailCode, setNewEmailCode] = useState(""); + const [loading, setLoading] = useState(false); + const [snackbarState, setSnackbarState] = useState({ open: false, message: '', variant: ''}); + + const verifyEmail = async () => { + setLoading(true); + const apiObj = new VerifyEmailAPI(oldEmailCode, newEmailCode); + fetch(apiObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(apiObj.getBody()), + headers: apiObj.getHeaders().headers, + }).then(async (res) => { + if (!res.ok) throw await res.json(); + else return await res.json(); + }).then((res) => { + setSnackbarState({ open: true, message: res.message, variant: "success" }); + onSuccess(); + handleClose(); + }).catch((err) => { + setSnackbarState({ open: true, message: err.message, variant: "error" }); + setLoading(false); + }); + }; + + return ( + + + + Verify Email + + + + + + Code received on {oldEmail}: + + + + setOldEmailCode(e.target.value)} + InputLabelProps={{ shrink: true }} + > + + + + Code received on {newEmail}: + + + + setNewEmailCode(e.target.value)} + InputLabelProps={{ shrink: true }} + > + + + + + } + onClick={verifyEmail} + label="Verify" + disabled={!(oldEmailCode && newEmailCode)} + /> + + setSnackbarState({...snackbarState, open: false})} + anchorOrigin={{vertical: 'top', horizontal: 'right'}} + hide={2000} + /> + + ); + }; + + export default UpdateEmailDialog; + \ No newline at end of file diff --git a/src/components/common/WorkspaceReports.jsx b/src/components/common/WorkspaceReports.jsx index 33c451f7..cb412c4e 100644 --- a/src/components/common/WorkspaceReports.jsx +++ b/src/components/common/WorkspaceReports.jsx @@ -28,6 +28,8 @@ import GetWorkspaceDetailedProjectReportsAPI from "../../app/actions/api/workspa import DatasetStyle from "../../styles/dataset"; import ColumnList from "../common/ColumnList"; import { isSameDay, format } from 'date-fns'; +import 'react-date-range/dist/styles.css'; +import 'react-date-range/dist/theme/default.css'; import { DateRangePicker, defaultStaticRanges } from "react-date-range"; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ArrowRightIcon from "@mui/icons-material/ArrowRight"; @@ -39,11 +41,14 @@ import { fetchProjectDomains } from "@/Lib/Features/getProjectDomains"; const ProgressType = [{ name: "Annotation Stage", value: 1 }, { name: "Review Stage", value: 2 }, { name: "Super Check Stage", value: 3 }, { name: "All Stage", value: "AllStage" }] const WorkspaceReports = () => { + /* eslint-disable react-hooks/exhaustive-deps */ + const WorkspaceDetails = useSelector( (state) => state.getWorkspaceDetails.data ); console.log(WorkspaceDetails,"lll"); const UserDetails = useSelector(state => state.getLoggedInData.data); + console.log(UserDetails); const [selectRange, setSelectRange] = useState([{ startDate: new Date(Date.parse(WorkspaceDetails?.created_at, 'yyyy-MM-ddTHH:mm:ss.SSSZ')), endDate: new Date(), diff --git a/src/components/common/WorkspaceTable.jsx b/src/components/common/WorkspaceTable.jsx index ffef4d56..6153f6d5 100644 --- a/src/components/common/WorkspaceTable.jsx +++ b/src/components/common/WorkspaceTable.jsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from "react"; import { useDispatch, useSelector } from 'react-redux'; import CustomButton from '../common/Button' -// import { Link, useNavigate, useParams } from 'react-router-dom'; +import { Link, useNavigate, useParams } from 'react-router-dom'; import MUIDataTable from "mui-datatables"; import GetWorkspaceAPI from "@/app/actions/api/workspace/GetWorkspaceData"; import { ThemeProvider, Grid } from "@mui/material"; @@ -9,18 +9,20 @@ import APITransport from "@/Lib/apiTransport/apitransport"; import tableTheme from "../../themes/tableTheme"; import DatasetStyle from "../../styles/dataset"; import Search from "../common/Search"; -import Link from 'next/link'; +// import Link from 'next/link'; import { setWorkspace } from "@/Lib/Features/GetWorkspace"; import { fetchWorkspaceData } from "@/Lib/Features/GetWorkspace"; const WorkspaceTable = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + const classes = DatasetStyle(); const dispatch = useDispatch(); const { showManager, showCreatedBy } = props; const workspaceData = useSelector(state => state.GetWorkspace.data); - // const SearchWorkspace = useSelector((state) => state.SearchProjectCards.data); - console.log(workspaceData,"lll"); + const SearchWorkspace = useSelector((state) => state.searchProjectCard?.searchValue); + console.log(SearchWorkspace); const [currentPageNumber, setCurrentPageNumber] = useState(1); @@ -30,34 +32,45 @@ const WorkspaceTable = (props) => { const totalWorkspaceCount = useSelector(state => state.GetWorkspace.data.count); - // const getWorkspaceData = async () => { - // const workspaceObj = new GetWorkspaceAPI(currentPageNumber); - // dispatch(APITransport(workspaceObj)); - // // const response = await dispatch(APITransport(workspaceObj)); - // // console.log('Response from API:', response); - // dispatch(setWorkspace(workspaceObj)) - // } + useEffect(() => { dispatch(fetchWorkspaceData(currentPageNumber)); // console.log("fired now") }, [currentPageNumber,dispatch]); - // useEffect(() => { - // dispatch(fetchWorkspaceData(currentRowPerPage)); - // }, [currentRowPerPage]); - useEffect(() => { - dispatch(fetchWorkspaceData(1)); - }, [dispatch]) + dispatch(fetchWorkspaceData(currentPageNumber)); + }, []) - const pageSearch = () => { + const pageSearch = () => { return workspaceData.filter((el) => { + + if (SearchWorkspace == "" ) { + return el; + } else if ( + el.workspace_name + ?.toLowerCase() + .includes(SearchWorkspace?.toLowerCase()) + ) { + console.log(el); + return el; + } + else if ( + el.managers?.some(val => val.username + ?.toLowerCase().includes(SearchWorkspace?.toLowerCase()) )) + + { + console.log(el); + return el; + } }) } + + const columns = [ { @@ -119,7 +132,7 @@ const WorkspaceTable = (props) => { return manager.username }).join(", "), el.created_by && el.created_by.username, - + { + /* eslint-disable react-hooks/exhaustive-deps */ + + const classes = DatasetStyle(); const [selectedTab, setSelectedTab] = useState(0); diff --git a/src/components/datasets/BasicDatasetSettings.jsx b/src/components/datasets/BasicDatasetSettings.jsx new file mode 100644 index 00000000..ca95068e --- /dev/null +++ b/src/components/datasets/BasicDatasetSettings.jsx @@ -0,0 +1,240 @@ + +import { Grid, ThemeProvider, Typography, Autocomplete, TextField } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import themeDefault from '@/themes/theme' +import { useNavigate, useParams } from 'react-router-dom'; +import OutlinedTextField from "../common/OutlinedTextField"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import CustomButton from "../common/Button"; +import CustomizedSnackbars from "../common/Snackbar"; +import { snakeToTitleCase } from "@/utils/utils"; +import Spinner from "../common/Spinner"; +import { fetchDatasetDetails } from "@/Lib/Features/datasets/getDatasetDetails"; +import GetSaveButtonAPI from "@/app/actions/api/Projects/getSaveButtonAPI"; + + + +const BasicDatasetSettings = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + const [value, setValue] = useState(); + const [loading, setLoading] = useState(false); + const [newDetails, setNewDetails] = useState(); + const { datasetId } = useParams(); + const navigate = useNavigate(); + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const apiLoading = useSelector(state => state.apiStatus.loading); + const DatasetDetails = useSelector(state => state.getDatasetDetails.data); + console.log(DatasetDetails) + + const GetDatasetDetails = () => { + dispatch(fetchDatasetDetails(datasetId)); + } + + useEffect(() => { + GetDatasetDetails(); + }, []); + + useEffect(() => { + setNewDetails({ + instance_name: DatasetDetails?.instance_name, + instance_description: DatasetDetails?.instance_description=='' || DatasetDetails?.instance_description=='None'?'':DatasetDetails.instance_description, + }); + }, [DatasetDetails]); + + const handleSave = async () => { + + const sendData = { + instance_name: newDetails.instance_name, + instance_description: newDetails.instance_description, + + parent_instance_id: DatasetDetails.parent_instance_id, + dataset_type: DatasetDetails.dataset_type, + organisation_id: DatasetDetails.organisation_id, + users: DatasetDetails.users, + } + const DatasetObj = new GetSaveButtonAPI(datasetId, sendData); + dispatch(APITransport(DatasetObj)); + const res = await fetch(DatasetObj.apiEndPoint(), { + method: "PUT", + body: JSON.stringify(DatasetObj.getBody()), + headers: DatasetObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: "success", + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + + } + + function snakeToTitleCase(str) { + return str.split("_").map((word) => { + return word.charAt(0).toUpperCase() + word.slice(1); + }).join(" "); + } + useEffect(() => { + setLoading(apiLoading); + }, [apiLoading]) + + const handleDatasetName = (event) => { + + event.preventDefault(); + setNewDetails((prev) => ({ + ...prev, + [event.target.name]: event.target.value, + })); + } + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + return ( + + + {/*
*/} + {loading && } + + {renderSnackBar()} + + + + + + + + Dataset Name + + + + + + + + + + + Dataset Description + + + + + + + + navigate(`/dataset/:id/`)} + // onClick={handleCancel} + label="Cancel" /> + + + + + ) +} + +export default BasicDatasetSettings; \ No newline at end of file diff --git a/src/components/datasets/CreateNewDatasetInstance.jsx b/src/components/datasets/CreateNewDatasetInstance.jsx new file mode 100644 index 00000000..7038e5d3 --- /dev/null +++ b/src/components/datasets/CreateNewDatasetInstance.jsx @@ -0,0 +1,311 @@ +import { + Box, + Card, + Grid, + Tab, + Tabs, + ThemeProvider, + Typography, +} from "@mui/material"; +import React, { useEffect, useState } from "react"; +import themeDefault from "@/themes/theme"; +import { Link, useNavigate, useParams } from "react-router-dom"; +import Button from "@/components/common/Button"; +import OutlinedTextField from "@/components/common/OutlinedTextField"; +import Spinner from "@/components/common/Spinner"; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import MenuItems from "@/components/common/MenuItems" +import { fetchDatasetType } from "@/Lib/Features/datasets/GetDatasetType"; +import CreateNewDatasetInstanceAPI from "@/app/actions/api/dataset/CreateNewDatasetInstance"; + +const CollectionProject = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const { id } = useParams(); + const navigate = useNavigate(); + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const [instance_Name, setInstance_Name] = useState("") + const [parent_Instance_Id, setParent_Instance_Id] = useState(null) + const [instance_Description, setInstance_Description] = useState("") + const [organisation_Id, setOrganisation_Id] = useState("") + const [users, setUsers] = useState("") + const [datasettype, setDatasettype] = useState(""); + const [type, setType] = useState([]); + const [loading, setLoading] = useState(false); + const [snackbarState, setSnackbarState] = useState({ open: false, message: "", variant: ""}); + const [errors, setErrors] = useState({}); + + + const loggedInUserData = useSelector( + (state) => state.getLoggedInData.data + ); + + useEffect(() => { + setUsers([loggedInUserData.id]) + },[]) + + const handleCreate = () => { + setLoading(true); + setErrors({}); + const CreateDatasetInstance = { + instance_name: instance_Name, + parent_instance_id: parent_Instance_Id, + instance_description: instance_Description, + dataset_type: datasettype, + organisation_id: organisation_Id, + users: users, + } + const apiObj = new CreateNewDatasetInstanceAPI(CreateDatasetInstance); + fetch(apiObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(apiObj.getBody()), + headers: apiObj.getHeaders().headers, + }).then(async (res) => { + if (!res.ok) throw await res.json(); + else return await res.json(); + }).then((res) => { + setLoading(false); + navigate(`/datasets/${res.instance_id}`); + }).catch((err) => { + setErrors(err); + setSnackbarState({ open: true, message: "Failed to create dataset instance", variant: "error" }); + setLoading(false); + }); + } + + const datasetType = useSelector(state => state.GetDatasetType.data); + + const getProjectDetails = () => { + dispatch(fetchDatasetType(id)); + } + + useEffect(() => { + getProjectDetails(); + + }, []); + + useEffect(() => { + if (datasetType && datasetType.length > 0) { + let temp = []; + datasetType.forEach((element) => { + temp.push({ + + name: element, + value: element, + + }); + }); + setType(temp); + } + }, [datasetType]); + + const renderSnackBar = () => { + return ( + setSnackbarState({ open: false, message: "", variant: "" })} + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbarState.variant} + message={snackbarState.message} + /> + ); +}; + + console.log(loggedInUserData,"loggedInUserData") + return ( + + {/*
*/} + {/* + */} + + + {loading && } + + + + + + Create New Dataset Instance + + + + + Instance_Name *: + + + + setInstance_Name(e.target.value)} + required + helperText={errors.instance_name ? errors.instance_name : ""} + error={errors.instance_name ? true : false} + /> + + + + Parent_Instance_Id: + + + + setParent_Instance_Id(e.target.value)} + helperText={errors.parent_instance_id ? errors.parent_instance_id : ""} + error={errors.parent_instance_id ? true : false} + /> + + + + Instance_Description: + + + + setInstance_Description(e.target.value)} + helperText={errors.instance_description ? errors.instance_description : ""} + error={errors.instance_description ? true : false} + /> + + + + Dataset_Type *: + + + + setDatasettype(value)} + value={datasettype} + helperText={errors.dataset_type ? errors.dataset_type : ""} + error={errors.dataset_type ? true : false} + /> + + + + Organisation_Id *: + + + + setOrganisation_Id(e.target.value)} + helperText={errors.organisation_id ? errors.organisation_id : ""} + error={errors.organisation_id ? true : false} + /> + + + + User *: + + + + setUsers(e.target.value)} + helperText={errors.users ? errors.users : ""} + error={errors.users ? true : false} + /> + + + + + + {showPicker && + + + + } + + { showSpinner ? : ( + + + ) + } + + ); +}; + +export default DatasetLogs; diff --git a/src/components/datasets/DatasetProjectsTable.jsx b/src/components/datasets/DatasetProjectsTable.jsx new file mode 100644 index 00000000..6d693345 --- /dev/null +++ b/src/components/datasets/DatasetProjectsTable.jsx @@ -0,0 +1,232 @@ +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Link, useParams } from "react-router-dom"; + +import CustomButton from "@/components/common/Button"; +import CustomizedSnackbars from "@/components/common/Snackbar" +import Spinner from "@/components/common/Spinner"; +import MUIDataTable from "mui-datatables"; +import Search from "@/components/common/Search"; + + +import { Grid, Stack, ThemeProvider } from "@mui/material"; +import tableTheme from "@/themes/tableTheme"; +import { width } from "@mui/system"; +import { fetchDatasetProjects } from "@/Lib/Features/datasets/GetDatasetProjects"; +import GetExportProjectButtonAPI from "@/app/actions/api/Projects/GetExportProjectButtonAPI"; +import GetPullNewDataAPI from "@/app/actions/api/Projects/GetPullNewDataAPI"; + +const columns = [ + { + name: "id", + label: "Id", + options: { + filter: false, + sort: false, + align: "center", + setCellHeaderProps: sort => ({ style: { height: "70px", padding: "16px" } }), + }, + }, + { + name: "title", + label: "Title", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "last_project_export_status", + label: "Last Project Export Status", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "last_project_export_date", + label: "Last Project Export Date", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "last_project_export_time", + label: "Last Project Export Time", + options: { + filter: false, + sort: false, + align: "center", + }, + }, + { + name: "actions", + label: "Actions", + options: { + sort: false, + filter: false, + align: "center", + }, + }, +]; + + +const options = { + filterType: "checkbox", + selectableRows: "none", + download: false, + filter: false, + print: false, + search: false, + viewColumns: false, + jumpToPage: true, +}; + +export default function DatasetProjectsTable({ datasetId }) { + /* eslint-disable react-hooks/exhaustive-deps */ + + const dispatch = useDispatch(); + const datasetProjects = useSelector((state) => + state.getDatasetProjects?.data); + + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + const [loading, setLoading] = useState(false); + + useEffect(() => { + dispatch(fetchDatasetProjects((datasetId))); + }, [dispatch, datasetId]); + + const getExportProjectButton = async (project) => { + setLoading(true); + const projectObj = project.project_type === "ConversationTranslation" ? + new GetExportProjectButtonAPI(project.id, project.dataset_id[0]) : new GetExportProjectButtonAPI(project.id); + dispatch(APITransport(projectObj)); + const res = await fetch(projectObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(projectObj.getBody()), + headers: projectObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + } + const SearchWorkspaceMembers = useSelector( + (state) => state.searchProjectCard?.searchValue + ); + const pageSearch = () => { + return datasetProjects.filter((el) => { + if (SearchWorkspaceMembers == "") { + return el; + } else if ( + el.title + ?.toLowerCase() + .includes(SearchWorkspaceMembers?.toLowerCase()) + ) { + + return el; + } + // } else if ( + // el.email?.toLowerCase().includes(SearchWorkspaceMembers?.toLowerCase()) + // ) { + // return el; + // } + }); + }; + + + + const getPullNewDataAPI = async (project) => { + const projectObj = new GetPullNewDataAPI(project.id); + //dispatch(APITransport(projectObj)); + const res = await fetch(projectObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(projectObj.getBody()), + headers: projectObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }); + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }); + } + }; + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + const data = datasetProjects? pageSearch().map((project) => ({ + ...project, + actions: () => ( + + + + + getExportProjectButton(project)} label="Export" /> + getPullNewDataAPI(project)} label="Pull New Data Items" /> + + ), + })):[] + // ) + + return ( + <> + + {loading && } + + {renderSnackBar()} + + + + + + + + ); +} diff --git a/src/components/datasets/DatasetReports.jsx b/src/components/datasets/DatasetReports.jsx new file mode 100644 index 00000000..28d47594 --- /dev/null +++ b/src/components/datasets/DatasetReports.jsx @@ -0,0 +1,293 @@ +// DatasetReports + +import React, { useState, useEffect } from "react"; +import MUIDataTable from "mui-datatables"; +import { + Box, + Button, + Grid, + ThemeProvider, +} from "@mui/material"; +import tableTheme from "@/themes/tableTheme"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +import Select from "@mui/material/Select"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; +import DatasetStyle from "@/styles/dataset"; +import ColumnList from "../common/ColumnList"; +import { MenuProps } from "@/utils/utils"; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import { fetchProjectDomains } from "@/Lib/Features/getProjectDomains"; +import fetchLanguages from "@/Lib/Features/fetchLanguages"; +import { fetchDatasetProjectReports } from "@/Lib/Features/datasets/getDatasetProjectReports"; +import { fetchDatasetDetailedReports } from "@/Lib/Features/datasets/GetDatasetDetailedReports"; + +const DatasetReports = () => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const [projectTypes, setProjectTypes] = useState([]); + const [selectedType, setSelectedType] = useState(""); + const [language, setLanguage] = useState("all"); + const [columns, setColumns] = useState([]); + const [selectedColumns, setSelectedColumns] = useState([]); + const [showSpinner, setShowSpinner] = useState(false); + const [reportData, setReportData] = useState([]); + const [reportRequested, setReportRequested] = useState(false); + const classes = DatasetStyle(); + + const { datasetId } = useParams(); + const dispatch = useDispatch(); + const DatasetDetails = useSelector((state) => state.getDatasetDetails.data); + const ProjectTypes = useSelector((state) => state.getProjectDomains.data); + const DatasetReports = useSelector((state) => state.getDatasetProjectReports.data); + const LanguageChoices = useSelector((state) => state.fetchLanguages.data); + const [projectReportType, setProjectReportType] = useState(1); + const [statisticsType, setStatisticsType] = useState(1); + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + useEffect(() => { + + dispatch(fetchProjectDomains()); + dispatch(fetchLanguages()); + }, []); + + useEffect(() => { + if (ProjectTypes) { + let types = []; + Object.keys(ProjectTypes).forEach((key) => { + let subTypes = Object.keys(ProjectTypes[key]["project_types"]); + types.push(...subTypes); + }); + setProjectTypes(types); + setSelectedType(types[0]); + } + }, [ProjectTypes]); + + useEffect(() => { + if (reportRequested && DatasetReports?.length) { + let tempColumns = []; + let tempSelected = []; + Object.keys(DatasetReports[0]).forEach((key) => { + tempColumns.push({ + name: key, + label: key, + options: { + filter: false, + sort: true, + align: "center", + }, + }); + tempSelected.push(key); + }); + setColumns(tempColumns); + setReportData(DatasetReports); + setSelectedColumns(tempSelected); + } else { + setColumns([]); + setReportData([]); + setSelectedColumns([]); + } + setShowSpinner(false); + }, [DatasetReports]); + + const renderToolBar = () => { + return ( + + + + ); + }; + + const options = { + filterType: "checkbox", + selectableRows: "none", + download: true, + filter: false, + print: false, + search: false, + viewColumns: false, + jumpToPage: true, + customToolbar: renderToolBar, + textLabels: { + body: { + noMatch: "No Record Found", + }, + }, + }; + + const userId = useSelector((state) => state.fetchLoggedInUserData.data.id); + + const handleSubmit = () => { + if(projectReportType === 1){ + setReportRequested(true); + const projectReportObj = ( + datasetId, + selectedType, + language + ) + dispatch(fetchDatasetProjectReports(projectReportObj)); + setShowSpinner(true); + }else if(projectReportType === 2){ + const projectReportObj = ( + Number(datasetId), + selectedType, + userId, + statisticsType + ); + dispatch(fetchDatasetDetailedReports(projectReportObj)); + setSnackbarInfo({ + open: true, + message: "Detailed Dataset Reports will be e-mailed to you shortly", + variant: "success", + }); + } + }; + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + return ( + + {renderSnackBar()} + + + + Type + + + + + + + Project Type + + + + + {projectReportType === 1 && + + + Target Language + + + + } + {projectReportType===2 && + + Statistics + + + } + + + + + {showSpinner ?
: reportRequested && ( + + 0 ? "Reports" : ""} + data={reportData} + columns={columns.filter((col) => selectedColumns.includes(col.name))} + options={options} + /> + ) + } +
+ ); +}; + +export default DatasetReports; diff --git a/src/components/datasets/DatasetSearchPopup.jsx b/src/components/datasets/DatasetSearchPopup.jsx new file mode 100644 index 00000000..70c4df5d --- /dev/null +++ b/src/components/datasets/DatasetSearchPopup.jsx @@ -0,0 +1,107 @@ +import React, { useState } from "react"; +import { + Button, + Divider, + Typography, + Popover, + Box, + TextField +} from "@mui/material"; +import { translate } from "@/config/localisation"; +import { snakeToTitleCase } from "@/utils/utils"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; + +const DatasetSearchPopup = (props) => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const { datasetId } = useParams(); + const { currentFilters, updateFilters, searchedCol } = props; + const [searchValue, setSearchValue] = useState(currentFilters[searchedCol]); + const [loading, setLoading] = useState(false); + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + + const handleSearchSubmit = async(e) => { + document.getElementById(searchedCol + "_btn").style.color = "#2C2799"; + props.handleClose(); + updateFilters({ + ...currentFilters, + [searchedCol]: searchValue, + }); + }; +console.log(searchedCol,"searchedCol",searchValue) + const handleClearSearch = (e) => { + updateFilters({ + ...currentFilters, + ["search_"+searchedCol]: "", + }); + setSearchValue(""); + document.getElementById(searchedCol + "_btn").style.color = "rgba(0, 0, 0, 0.54)"; + props.handleClose(); + }; + + + return ( + + + setSearchValue(e.target.value)} + inputProps={{ + style: { + fontSize: "16px" + } + }} + /> + + + + + + + + ); +}; +export default DatasetSearchPopup; diff --git a/src/components/datasets/DatasetSettingTab.jsx b/src/components/datasets/DatasetSettingTab.jsx new file mode 100644 index 00000000..2bb317ea --- /dev/null +++ b/src/components/datasets/DatasetSettingTab.jsx @@ -0,0 +1,79 @@ +import { Box,Grid,Tab, Card,Tabs, Typography, Divider } from '@mui/material' +import React from 'react' +import { useState } from 'react' +import BasicDatasetSettings from './BasicDatasetSettings'; +import DatasetSettings from './DatasetSettings'; + + +function TabPanel(props) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +const DatasetSettingTabs = () => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const [tabValue, setTabValue] = useState(0); + const handleTabChange = (e, v) => { + setTabValue(v) + } + return ( + + + + + + DataSet Settings + + + + + + + + + + + + + + + + + + + + ) +} + +export default DatasetSettingTabs \ No newline at end of file diff --git a/src/components/datasets/DatasetSettings.jsx b/src/components/datasets/DatasetSettings.jsx new file mode 100644 index 00000000..b60edecf --- /dev/null +++ b/src/components/datasets/DatasetSettings.jsx @@ -0,0 +1,327 @@ +import { useState, useEffect, useRef } from "react"; +import { useParams,useNavigate } from "react-router-dom"; +import { Card, CircularProgress, Grid, Typography,Modal,Box } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { translate } from "@/config/localisation"; +import CustomButton from "@/components/common/Button"; +//import Modal from "@/components/common/Modal"; +import IconButton from "@material-ui/core/IconButton"; +import CloseIcon from "@material-ui/icons/Close"; +import MenuItems from "@/components/common/MenuItems"; +import { FileUploader } from "react-drag-drop-files"; +import Switch from "@mui/material/Switch"; +import DownloadDatasetButton from "./DownloadDataSetButton"; +import DeleteDataItems from "./DeleteDataItems"; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import DeduplicateDataItems from "./DeduplicateDataItems"; +import UploaddataAPI from "@/app/actions/api/dataset/UploaddataAPI"; +import { fetchDatasetDownloadCSV } from "@/Lib/Features/datasets/GetDatasetDownloadCSV"; + + +const style = { + position: "absolute", + top: "50%", + left: "50%", + transform: "translate(-50%, -50%)", + width: 600, + bgcolor: "background.paper", + //border: "2px solid #000", + boxShadow: 24, + p: 4, +}; +const label = { inputProps: { "aria-label": "Switch demo" } }; + +export default function DatasetSettings() { + /* eslint-disable react-hooks/exhaustive-deps */ + + const { datasetId } = useParams(); + // console.log('current',datasetId) + const dispatch = useDispatch(); + const fileRef = useRef(); + const [loading, setLoading] = useState(false); + const [modal, setModal] = useState(false); + const [file, setFile] = useState([]); + const [filetype, setFiletype] = useState(""); + const [type, setType] = useState([]); + const [switchs, setswitchs] = useState("True"); + const [anchorEl, setAnchorEl] = useState(null); + console.log(file, filetype, switchs, "switchs"); + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + const GetFileTypes = useSelector((state) => state.GetFileTypes.data); + const FileTypes = () => { + const projectObj = new GetFileTypesAPI(); + dispatch(APITransport(projectObj)); + }; + + useEffect(() => { + if (GetFileTypes && GetFileTypes.length > 0) { + let temp = []; + GetFileTypes.forEach((element) => { + temp.push({ + name: element, + value: element, + }); + }); + setType(temp); + } + }, [GetFileTypes]); + + const handleClick = () => { + console.log("called download"); + setLoading(true); + dispatch(fetchDatasetDownloadCSV((datasetId))); + }; + + useEffect(() => { + setLoading(false); + }, [setLoading]); + + const handleOnChange = (e) => { + // const [file] = e.target.files; + setFile(e.target.files[0]); + console.log("select file ", e.target.files[0]); + }; + const handleChange = (file) => { + setFile(file[0]); + console.log("drag and drop file ", file); + }; + + const handleUpload = (e) => { + setModal(true); + FileTypes(); + }; + + const handleModalClose = () => { + setModal(false); + setFile([]); + setFiletype(""); + }; + + const handleUploadFile = async () => { + let UploadFile = new FormData(); + UploadFile.append("dataset", file); + UploadFile.append("filetype", filetype); + UploadFile.append("deduplicate", switchs); + setLoading(true); + const projectObj = new UploaddataAPI(datasetId,UploadFile); + const res = await fetch(projectObj.apiEndPoint(), { + method: "POST", + body: projectObj.getBody(), + headers: projectObj.getHeaders().headers, + }); + + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }); + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }); + } + handleModalClose(); + }; + + const handleswitchchange = () => { + setswitchs("false"); + }; + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + return ( + + {renderSnackBar()} + + + {loading ? ( + + ) : ( + <> + + {/* */} + + + + + + + + + + + + + + +
+ handleModalClose()} + aria-labelledby="modal-modal-title" + aria-describedby="modal-modal-description" + > + + + Upload Data + + + + + + Select File : + + + + + + + + + + Select File Format : + + + + setFiletype(value)} + value={filetype} + /> + + + + + + Delete Duplicate Records : + + + + + + + + + + handleModalClose()} + /> + + + + +
+ + )} +
+
+
+ ); +} diff --git a/src/components/datasets/DeduplicateDataItems.jsx b/src/components/datasets/DeduplicateDataItems.jsx new file mode 100644 index 00000000..44093bbb --- /dev/null +++ b/src/components/datasets/DeduplicateDataItems.jsx @@ -0,0 +1,334 @@ +import React, { useState ,useEffect} from "react"; +import { + Button, + Popover, + Box, + TextField, + Grid, + Typography, + ListItemIcon, + ListItemText, + Checkbox, + MenuItem, + Select, + InputLabel, + FormControl, + Radio, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + FormControlLabel, + FormGroup, +} from "@mui/material"; +import { translate } from "@/config/localisation"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import { snakeToTitleCase } from "@/utils/utils"; +import { useParams } from 'react-router-dom'; +import CustomizedSnackbars from "@/components/common/Snackbar" +import LoginAPI from "@/app/actions/api/user/Login"; +import removeDuplicatesDatasetInstanceAPI from "@/app/actions/api/dataset/removeDuplicatesDatasetInstanceAPI"; + +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, + getContentAnchorEl: null, + anchorOrigin: { + vertical: "bottom", + horizontal: "center", + }, + transformOrigin: { + vertical: "top", + horizontal: "center", + }, + variant: "menu", +}; +export default function DeduplicateDataItems() { + /* eslint-disable react-hooks/exhaustive-deps */ + + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const { datasetId } = useParams(); + + const [anchorEl, setAnchorEl] = useState(null); + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + const [openDialog, setOpenDialog] = useState(false); + const [dataitems, setDataitems] = useState([]); + const [dataitemsvalues, setDataitemsvalues] = useState([]); + const [selectedColumns, setSelectedColumns] = useState([]); + const [columns, setColumns] = useState([]); + + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", +}); + + +useEffect(() => { + const storedData = localStorage.getItem("Dataitem"); + + if (storedData!=="undefined") { + const Dataitems = JSON.parse(storedData); + setDataitemsvalues(Dataitems) + } +}, []) + + + +useEffect(() => { + let fetchedItems =dataitemsvalues.results; + + +let tempSelected = []; +if (fetchedItems?.length) { + Object.keys(fetchedItems[0]).forEach((key) => { + + tempSelected.push({ name: key, + label: snakeToTitleCase(key),}); + + }); +} +setSelectedColumns(tempSelected); + + + }, [dataitemsvalues]) + + useEffect(() => { + const newCols = columns.map(col => { + col.options.display = selectedColumns.includes(col.name) ? "true" : "false"; + return col; + }); + setColumns(newCols); + +}, [selectedColumns]); + +const handleChange = (event) => { + const value = event.target.value; + + setDataitems(value); + }; + const handleSearchSubmit = () => { + setOpenDialog(true); + setAnchorEl(null); + }; + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + setDataitems([]) + }; + const handleClearSearch = () => { + setAnchorEl(null); + setDataitems([]) + }; + const handleCloseDialog = () => { + setOpenDialog(false); + setDataitems([]) +}; + +const handleok = async() => { + const datasetObj = new removeDuplicatesDatasetInstanceAPI(datasetId,dataitems.toString()) + // dispatch(APITransport(datasetObj)); + const res = await fetch(datasetObj.apiEndPoint(), { + method: "GET", + body: JSON.stringify(datasetObj.getBody()), + headers: datasetObj.getHeaders().headers, + }); + const resp = await res.json(); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + setOpenDialog(false); + setDataitems([]) +} + +const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); +}; + + const emailId = localStorage.getItem("email_id"); + const [password, setPassword] = useState(""); + const handleConfirm = async () => { + const apiObj = new LoginAPI(emailId, password); + const res = await fetch(apiObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(apiObj.getBody()), + headers: apiObj.getHeaders().headers, + }); + const rsp_data = await res.json(); + if (res.ok) { + handleok(); + }else{ + window.alert("Invalid credentials, please try again"); + console.log(rsp_data); + } + }; + + return ( +
+ {renderSnackBar()} + + + + <> + + + + + Select Fields to Deduplicate + + + + + + + + + + + + + + + + + + Are you sure you want to delete the Duplicate Data Items ? Please note this action cannot be undone. + + setPassword(e.target.value)} + /> + + + + + + +
+ ); +} diff --git a/src/components/datasets/DeleteDataItems.jsx b/src/components/datasets/DeleteDataItems.jsx new file mode 100644 index 00000000..07ddf7cc --- /dev/null +++ b/src/components/datasets/DeleteDataItems.jsx @@ -0,0 +1,412 @@ +import React, { useState } from "react"; +import { + Button, + Popover, + Box, + TextField, + Grid, Typography, Radio,Dialog, DialogActions, DialogContent, DialogContentText, +} from "@mui/material"; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import { translate } from "@/config/localisation"; +import DatasetStyle from "@/styles/dataset"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from 'react-router-dom'; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import LoginAPI from "@/app/actions/api/user/Login"; +import DeleteDataItemsAPI from "@/app/actions/api/dataset/DeleteDataItemsAPI"; + +export default function DeleteDataItems() { + /* eslint-disable react-hooks/exhaustive-deps */ + + const classes = DatasetStyle(); + const { datasetId } = useParams(); + const dispatch = useDispatch(); + const [anchorEl, setAnchorEl] = useState(null); + const [startdataid, setStartDataId] = useState(""); + const [enddataid, setEndDataId] = useState(""); + const [loading, setLoading] = useState(false); + const [radiobutton, setRadiobutton] = useState(true) + const [dataIds, setDataIds] = useState("") + const [openDialog, setOpenDialog] = useState(false); + + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + const Dataitems = JSON.parse( localStorage.getItem("DataitemsList")) + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + const handleCloseDialog = () => { + setOpenDialog(false); + }; + + let datasetitem = dataIds.split(",") + var value = datasetitem.map(function (str) { + return parseInt(str); + }); + + + const handleClose = () => { + setAnchorEl(null); + }; + const handleClearSearch = () => { + setAnchorEl(null); + setStartDataId(); + setEndDataId(); + setDataIds(""); + + }; + const handleDeletebyids = () => { + setRadiobutton(true) + + } + const handleDeletebyrange = () => { + setRadiobutton(false) + } + + + const handledataIds = (e,) => { + setDataIds(e.target.value); + + + } + const handleok = async() => { + setOpenDialog(false); + setAnchorEl(null); + setStartDataId(); + setEndDataId(); + setDataIds(""); + let datasetObj; + const DeleteDataItems = { + data_item_start_id: parseInt(startdataid), + data_item_end_id: parseInt(enddataid) + } + + const dataitemids = { + data_item_ids: value + } + + if (radiobutton === true) { + datasetObj = new DeleteDataItemsAPI(datasetId, DeleteDataItems) + + + } else { + datasetObj = new DeleteDataItemsAPI(datasetId, dataitemids) + } + // dispatch(APITransport(datasetObj)); + const res = await fetch(datasetObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(datasetObj.getBody()), + headers: datasetObj.getHeaders().headers, + }); + const resp = await res.json(); + setLoading(false); + if (res.ok) { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "success", + }) + + } else { + setSnackbarInfo({ + open: true, + message: resp?.message, + variant: "error", + }) + } + } + + const handleSearchSubmit = async () => { + setOpenDialog(true); + + } + + + const open = Boolean(anchorEl); + const id = open ? 'simple-popover' : undefined; + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + + const emailId = localStorage.getItem("email_id"); + const [password, setPassword] = useState(""); + const handleConfirm = async () => { + const apiObj = new LoginAPI(emailId, password); + const res = await fetch(apiObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(apiObj.getBody()), + headers: apiObj.getHeaders().headers, + }); + const rsp_data = await res.json(); + if (res.ok) { + handleok(); + }else{ + window.alert("Invalid credentials, please try again"); + console.log(rsp_data); + } + }; + + return ( +
+ {renderSnackBar()} + + + + + + + + + } label="Delete by Range" onClick={handleDeletebyids} /> + } label="Delete by IDs" onClick={handleDeletebyrange} /> + + + + + + + {radiobutton === true && + <> + + + + + + Start Data ID: + + + + setStartDataId(e.target.value)} + inputProps={{ + style: { + fontSize: "16px" + } + }} + /> + + + + + + + End Data ID: + + + + setEndDataId(e.target.value)} + inputProps={{ + style: { + fontSize: "16px" + } + }} + /> + + + + } + {radiobutton === false && + + + + Data IDs: + + + + + + + + } + + + + + + + + + + + + Are you sure you want to delete the data items? Please note this action cannot be undone. + + setPassword(e.target.value)} + /> + + + + + + +
+ ); +} diff --git a/src/components/datasets/DownloadDataSetButton.jsx b/src/components/datasets/DownloadDataSetButton.jsx new file mode 100644 index 00000000..2f012ac9 --- /dev/null +++ b/src/components/datasets/DownloadDataSetButton.jsx @@ -0,0 +1,149 @@ +import React, { useState, useEffect } from "react"; +import { styled } from '@mui/material/styles'; +import {CircularProgress} from "@mui/material"; +import Button from '@mui/material/Button'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; +import { useDispatch, useSelector } from "react-redux"; +import { Link, useNavigate, useParams } from 'react-router-dom'; +import CustomizedSnackbars from "@/components/common/Snackbar"; +import GetDatasetDownloadJSON, { fetchDatasetDownloadJSON } from "@/Lib/Features/datasets/GetDatasetDownloadJSON"; +import { fetchDatasetDownloadCSV } from "@/Lib/Features/datasets/GetDatasetDownloadCSV"; +import { fetchDatasetDownloadTSV } from "@/Lib/Features/datasets/GetDatasetDownloadTSV"; +const StyledMenu = styled((props) => ( + +))(({ theme }) => ({ + '& .MuiPaper-root': { + borderRadius: 6, + marginTop: theme.spacing(1), + minWidth: 100, + + + }, +})); + + +function DownloadDatasetButton(props) { + /* eslint-disable react-hooks/exhaustive-deps */ + + const [anchorEl, setAnchorEl] = useState(null); + const [loading, setLoading] = useState(false); + + const apiLoading = useSelector(state => state.apiStatus.loading); + const downloadCSV = useSelector((state) => state.getDatasetDownloadCSV?.data); + const downloadJSON = useSelector((state) => state.getDatasetDownloadJSON?.data); + const downloadTSV = useSelector((state) => state.getDatasetDownloadTSV?.data); + const open = Boolean(anchorEl); + const { datasetId } = useParams(); + const dispatch = useDispatch(); + let csvLink = React.createRef() + const [snackbar, setSnackbarInfo] = useState({ + open: false, + message: "", + variant: "success", + }); + + useEffect(() => { + setLoading(false); + }, [downloadCSV,downloadJSON,downloadTSV]) + + + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + + }; + const handleDownloadJSONDataset = async () => { + setLoading(true); + const projectObj = (datasetId); + dispatch(fetchDatasetDownloadJSON(projectObj)); + setAnchorEl(null); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleDownloadCSVDataset = async () => { + setLoading(true); + dispatch(fetchDatasetDownloadCSV((datasetId))); + setAnchorEl(null); + } + + const handleDownloadTSVDataset = async () => { + setLoading(true); + dispatch(fetchDatasetDownloadTSV((datasetId))); + setAnchorEl(null); + } + + const renderSnackBar = () => { + return ( + + setSnackbarInfo({ open: false, message: "", variant: "" }) + } + anchorOrigin={{ vertical: "top", horizontal: "right" }} + variant={snackbar.variant} + message={snackbar.message} + /> + ); + }; + return ( +
+ {renderSnackBar()} + + {loading ? ( + + ) : (<> + + + + CSV + + + TSV + + + JSON + + + + )} +
+ ); +} +export default DownloadDatasetButton; \ No newline at end of file diff --git a/src/components/datasets/DraftDataPopulation.jsx b/src/components/datasets/DraftDataPopulation.jsx new file mode 100644 index 00000000..9307ff5d --- /dev/null +++ b/src/components/datasets/DraftDataPopulation.jsx @@ -0,0 +1,286 @@ +import React, { useState, useEffect } from 'react'; +import { + FormControl, + InputLabel, + MenuItem, + Select, + FormControlLabel, + ListItemText, + OutlinedInput, + Checkbox, + Grid, + Card, + ThemeProvider, + Typography, + Item +} from '@mui/material'; +import Spinner from "@/components/common/Spinner"; +import Snackbar from "@/components/common/Snackbar"; +import DatasetStyle from "@/styles/dataset"; +import Button from "@/components/common/Button"; +import { useNavigate } from "react-router-dom"; +import { useDispatch, useSelector } from "react-redux"; +import MenuItems from "@/components/common/MenuItems"; +import { MenuProps } from "@/utils/utils"; +import themeDefault from "@/themes/theme"; +import { fetchDatasetsByType } from '@/Lib/Features/actions/getDatasetsByType'; +import { fetchDataitemsById } from '@/Lib/Features/datasets/GetDataitemsById'; +import intraAutomateDatasetsAPI from '@/app/actions/api/dataset/intraAutomateDatasetsAPI'; + + +const DraftDataPopulation = () => { + /* eslint-disable react-hooks/exhaustive-deps */ + + const classes = DatasetStyle(); + const dispatch = useDispatch(); + const navigate = useNavigate(); + + + const [srcDatasetTypes, setSrcDatasetTypes] = useState([]); + const [srcDatasetType, setSrcDatasetType] = useState(''); + const [srcInstances, setSrcInstances] = useState([]); + const [field, setfield] = useState([]); + const [Field,setField] = useState([]); + const [srcInstance, setSrcInstance] = useState(''); + // const [instance, setinstance] = useState(""); + // const [org_id, setorg_id] = useState(""); + const [loading, setLoading] = useState(false); + const [snackbarState, setSnackbarState] = useState({ open: false, message: '', variant: '' }); + + // const Fields = ["draft_data_json", "input_language", "output_language", "input_text", "output_text", "machine_translation", "context", "labse_score", "rating", "domain", "parent_data", "instance_id"]; + + const loggedInUserData = useSelector((state) => state.getLoggedInData.data); + const DatasetInstances = useSelector((state) => state.getDatasetsByType?.data); + const DatasetTypes = useSelector((state) => state.GetDatasetType?.data); + const dataitemsList = useSelector((state) => state.getDataitemsById?.data); + + + useEffect(() => { + if (DatasetTypes && DatasetTypes.length > 0) { + let temp = []; + DatasetTypes.forEach((element) => { + temp.push({ + name: element, + value: element + // disabled: (element !== "SentenceText" && element !== "Conversation") + }); + }); + setSrcDatasetTypes(temp); + temp = []; + DatasetTypes.forEach((element) => { + temp.push({ + name: element, + value: element + // disabled: (srcDatasetType === "SentenceText" ? element !== "TranslationPair" : element !== "Conversation") + }); + }); + } + }, [DatasetTypes, srcDatasetType]); + + const handleChange = (event) => { + const { + target: { value }, + } = event; + setfield( + typeof value === 'string' ? value.split(',') : value, + ); + }; + useEffect(() => { + setLoading(false); + if (dataitemsList?.results?.length > 0) { + let values = Object.keys(dataitemsList.results[0]) + setField(values) + } + }, [dataitemsList]); + + + + useEffect(() => { + setLoading(false); + if (DatasetInstances?.length > 0) { + if (DatasetInstances[0].dataset_type === srcDatasetType) + setSrcInstances(DatasetInstances) + } + }, [DatasetInstances]); + + + + const handleSrcDatasetTypeChange = (value) => { + setSrcDatasetType(value); + setLoading(true); + const instancesObj = (value); + dispatch(fetchDatasetsByType(instancesObj)); + }; + + const handleField =(value)=>{ + setSrcInstance(value); + setLoading(true); + const fieldObj =(value,srcDatasetType); + dispatch(fetchDataitemsById(fieldObj)); + } + + + const handleConfirm = async () => { + setLoading(true); + const org_id = await (DatasetInstances.filter((items) => { + return items.instance_id === srcInstance + })[0].organisation_id); + const apiObj = new intraAutomateDatasetsAPI(srcInstance, org_id, field); + fetch(apiObj.apiEndPoint(), { + method: "POST", + body: JSON.stringify(apiObj.getBody()), + headers: apiObj.getHeaders().headers, + }).then(async (res) => { + setLoading(false); + if (!res.ok) throw await res.json(); + else return await res.json(); + }).then((res) => { + console.log(res); + setSnackbarState({ open: true, message: res.message, variant: "success" }); + }).catch((err) => { + console.log(err); + setSnackbarState({ open: true, message: err.message, variant: "error" }); + }); + setSrcDatasetType(''); + setSrcInstance(''); + setfield([]) + + } + + return ( + + {loading && } + + {/* + + + */} + + Populate Draft Data Json + + {/* */} + + + + Select dataset type: + + + + + {srcDatasetType && srcInstances.length > 0 && <> + + + Source dataset instance: + + + + + + + + } + + + Select Field: + + + + + Tag + + + + + +