diff --git a/index.html b/index.html index bc3f33d..28150ea 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - + diff --git a/package-lock.json b/package-lock.json index 54eeec3..b2e025e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "exceljs": "^4.4.0", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-drag-drop-files": "^2.3.10", + "react-icons": "^5.2.1", "react-router-dom": "^6.23.1" }, "devDependencies": { @@ -32,10 +34,13 @@ "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@vitest/coverage-v8": "^1.6.0", + "autoprefixer": "^10.4.19", "electron": "31.0.1", "eslint": "^8.57.0", "eslint-plugin-import": "^2.29.1", "jsdom": "^24.1.0", + "postcss": "^8.4.39", + "tailwindcss": "^3.4.4", "ts-node": "^10.9.2", "typescript": "~4.5.4", "vite": "^5.3.1", @@ -48,11 +53,22 @@ "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", "dev": true }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -65,7 +81,6 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -75,8 +90,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "peer": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -85,11 +98,241 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "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/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.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "peer": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "peer": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -98,7 +341,28 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "peer": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, "engines": { "node": ">=6.9.0" } @@ -107,8 +371,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -123,8 +385,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -136,8 +396,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -151,8 +409,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -160,16 +416,12 @@ "node_modules/@babel/highlight/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==", - "dev": true, - "peer": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -178,8 +430,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -188,8 +438,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -201,7 +449,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -209,6 +456,20 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", @@ -221,11 +482,51 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "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.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -965,6 +1266,29 @@ "node": ">=14.14" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "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.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -1467,6 +1791,50 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -1492,7 +1860,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1506,7 +1873,6 @@ "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1516,7 +1882,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1525,7 +1890,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1533,8 +1897,7 @@ "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.9", @@ -1630,6 +1993,16 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@remix-run/router": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz", @@ -2676,6 +3049,25 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -2976,6 +3368,43 @@ "node": ">=0.8" } }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2991,6 +3420,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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", @@ -3035,6 +3479,18 @@ "node": "*" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3118,6 +3574,37 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -3314,6 +3801,42 @@ "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "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.30001639", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz", + "integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/chai": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", @@ -3349,26 +3872,62 @@ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=10" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "get-func-name": "^2.0.2" + "is-glob": "^4.0.1" }, "engines": { - "node": "*" + "node": ">= 6" } }, "node_modules/chownr": { @@ -3644,6 +4203,12 @@ "node": ">= 0.6" } }, + "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/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", @@ -3736,12 +4301,42 @@ "node": ">=12.10" } }, + "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.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/cssstyle": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", @@ -3873,7 +4468,6 @@ "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -4051,6 +4645,12 @@ "dev": true, "optional": true }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -4091,6 +4691,12 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4580,6 +5186,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/electron-to-chromium": { + "version": "1.4.815", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.815.tgz", + "integrity": "sha512-OvpTT2ItpOXJL7IGcYakRjHCt8L5GrrN/wHCQsRB4PQa1X9fe+X9oen245mIId7s14xvArCGSTIq644yPUKKLg==" + }, "node_modules/electron-winstaller": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.3.1.tgz", @@ -4962,7 +5573,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, "engines": { "node": ">=6" } @@ -5752,6 +6362,34 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -5775,6 +6413,19 @@ "node": ">= 0.6" } }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -5979,6 +6630,15 @@ "node": ">=8" } }, + "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", @@ -6379,6 +7039,19 @@ "node": ">= 0.4" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/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/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -6680,6 +7353,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -7051,6 +7736,33 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7207,6 +7919,17 @@ } } }, + "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", @@ -7381,6 +8104,21 @@ "immediate": "~3.0.5" } }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/listenercount": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", @@ -7452,8 +8190,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.defaults": { "version": "4.2.0", @@ -7997,8 +8734,18 @@ "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/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } }, "node_modules/nanoid": { "version": "3.3.7", @@ -8111,6 +8858,11 @@ "node": "^12.13 || ^14.13 || >=16" } }, + "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==" + }, "node_modules/nopt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", @@ -8155,6 +8907,15 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", @@ -8210,6 +8971,23 @@ "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", "dev": true }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -8485,6 +9263,12 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -8588,6 +9372,40 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -8641,14 +9459,12 @@ "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "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" }, @@ -8665,6 +9481,15 @@ "node": ">=0.10.0" } }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -8764,9 +9589,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -8784,13 +9609,133 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" } }, + "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==" + }, "node_modules/postject": { "version": "1.0.0-alpha.6", "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", @@ -8883,6 +9828,21 @@ "node": ">=10" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/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/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -9021,11 +9981,31 @@ "react": "^18.3.1" } }, + "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-icons": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", + "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/react-router": { "version": "6.23.1", @@ -9069,6 +10049,15 @@ "read-binary-file-arch": "cli.js" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -9215,6 +10204,18 @@ "node": ">=10" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", @@ -9742,6 +10743,11 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "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", @@ -9992,6 +10998,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -10080,6 +11116,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -10173,6 +11222,141 @@ "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/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/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/sudo-prompt": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", @@ -10221,6 +11405,49 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/tailwindcss": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz", + "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, "node_modules/tar": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", @@ -10323,6 +11550,27 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tiny-each-async": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", @@ -10376,7 +11624,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -10461,6 +11708,12 @@ "node": ">=0.8.0" } }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -10792,6 +12045,35 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -11326,6 +12608,53 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -11456,6 +12785,18 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 1765b21..3ed7553 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,13 @@ "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@vitest/coverage-v8": "^1.6.0", + "autoprefixer": "^10.4.19", "electron": "31.0.1", "eslint": "^8.57.0", "eslint-plugin-import": "^2.29.1", "jsdom": "^24.1.0", + "postcss": "^8.4.39", + "tailwindcss": "^3.4.4", "ts-node": "^10.9.2", "typescript": "~4.5.4", "vite": "^5.3.1", @@ -50,6 +53,8 @@ "exceljs": "^4.4.0", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-drag-drop-files": "^2.3.10", + "react-icons": "^5.2.1", "react-router-dom": "^6.23.1" } } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/src/@types/interface.d.ts b/src/@types/interface.d.ts new file mode 100644 index 0000000..fa7866e --- /dev/null +++ b/src/@types/interface.d.ts @@ -0,0 +1,25 @@ +import { CourseGetCommand } from 'src/application/courses/courseGetCommand' +import { ReportListImportCommand } from 'src/application/reportLists/reportListImportCommand' +import { ReportGetResult } from 'src/application/reports/reportGetResult' + +// 型付きで API を公開するための定義 +// https://www.electronjs.org/docs/latest/tutorial/context-isolation#usage-with-typescript +export interface IElectronAPI { + importReportListAsync: ( + reportListImportCommand: ReportListImportCommand + ) => Promise + + getReportAsync: ( + reportGetCommand: ReportGetCommand + ) => Promise + + getCourseAsync: ( + courseGetCommand: CourseGetCommand + ) => Promise +} + +declare global { + interface Window { + electronAPI: IElectronAPI + } +} diff --git a/src/App.tsx b/src/App.tsx index 42f1215..c12459d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,19 +1,16 @@ import { HashRouter, Route, Routes } from "react-router-dom"; -import CommonLayout from "./common/CommonLayout"; // ページコンポーネントのインポート -import Home from "./pages/Home"; -import Evaluation from "./pages/Evaluation"; +import Home from "./presentation/pages/Home"; +import Evaluation from "./presentation/pages/Evaluation"; export default function App() { return ( // Electron では BrowserRouter ではなく HashRouter を使う - }> - } /> - } /> - + } /> + } /> ); diff --git a/src/application/courses/courseApplicationService.test.ts b/src/application/courses/courseApplicationService.test.ts new file mode 100644 index 0000000..73a0d2e --- /dev/null +++ b/src/application/courses/courseApplicationService.test.ts @@ -0,0 +1,20 @@ +import { InMemoryCourseRepository } from 'src/infrastructure/inMemory/courses/inMemoryCourseRepository' +import { describe, expect, test } from 'vitest' +import { CourseApplicationService } from './courseApplicationService' +import { CourseGetCommand } from './courseGetCommand' +import { Course } from 'src/domain/models/courses/course' + +describe('get', () => { + test('The service can get the course saved in the repository.', async () => { + const repository = new InMemoryCourseRepository() + const course = new Course(1, 'name') + await repository.saveAsync(course) + const service = new CourseApplicationService(repository) + const command = new CourseGetCommand(course.id) + + const result = await service.getAsync(command) + + expect(result.courseData.id).toBe(course.id) + expect(result.courseData.name).toBe(course.name) + }) +}) diff --git a/src/application/courses/courseApplicationService.ts b/src/application/courses/courseApplicationService.ts new file mode 100644 index 0000000..09be9a3 --- /dev/null +++ b/src/application/courses/courseApplicationService.ts @@ -0,0 +1,29 @@ +import { CourseRepository } from 'src/domain/models/courses/courseRepository' +import { CourseGetResult } from './courseGetResult' +import { CourseGetCommand } from './courseGetCommand' +import { CourseData } from './courseData' + +/** + * コースアプリケーションサービス + */ +export class CourseApplicationService { + /** + * コンストラクタ + * + * @param courseRepository コースリポジトリ + */ + public constructor(private readonly courseRepository: CourseRepository) {} + + /** + * コースを取得する + * + * @param courseGetCommand コース取得コマンド + * @returns コース取得結果 + */ + public async getAsync( + courseGetCommand: CourseGetCommand + ): Promise { + const course = await this.courseRepository.findAsync(courseGetCommand.id) + return new CourseGetResult(new CourseData(course)) + } +} diff --git a/src/application/courses/courseData.ts b/src/application/courses/courseData.ts new file mode 100644 index 0000000..7870e7f --- /dev/null +++ b/src/application/courses/courseData.ts @@ -0,0 +1,26 @@ +import { Course } from 'src/domain/models/courses/course' + +/** + * コースデータ(DTO) + */ +export class CourseData { + /** + * ID + */ + public readonly id: number + + /** + * 名前 + */ + public readonly name: string + + /** + * コンストラクタ + * + * @param course コース + */ + public constructor(course: Course) { + this.id = course.id + this.name = course.name + } +} diff --git a/src/application/courses/courseGetCommand.ts b/src/application/courses/courseGetCommand.ts new file mode 100644 index 0000000..1e0c828 --- /dev/null +++ b/src/application/courses/courseGetCommand.ts @@ -0,0 +1,11 @@ +/** + * コース取得コマンド + */ +export class CourseGetCommand { + /** + * コンストラクタ + * + * @param id ID + */ + public constructor(public readonly id: number) {} +} diff --git a/src/application/courses/courseGetResult.ts b/src/application/courses/courseGetResult.ts new file mode 100644 index 0000000..b0bdf1d --- /dev/null +++ b/src/application/courses/courseGetResult.ts @@ -0,0 +1,13 @@ +import { CourseData } from './courseData' + +/** + * コース取得結果 + */ +export class CourseGetResult { + /** + * コンストラクタ + * + * @param courseData コースデータ + */ + public constructor(public readonly courseData: CourseData) {} +} diff --git a/src/application/reportLists/reportListApplicationService.test.ts b/src/application/reportLists/reportListApplicationService.test.ts new file mode 100644 index 0000000..1dfa65c --- /dev/null +++ b/src/application/reportLists/reportListApplicationService.test.ts @@ -0,0 +1,167 @@ +import { describe, expect, test } from 'vitest' +import { ReportListApplicationService } from './reportListApplicationService' +import { InMemoryCourseRepository } from 'src/infrastructure/inMemory/courses/inMemoryCourseRepository' +import { ReportListImportCommand } from './reportListImportCommand' +import path from 'path' +import { InMemoryReportRepository } from 'src/infrastructure/inMemory/reports/inMemoryReportRepository' +import { InMemoryStudentRepository } from 'src/infrastructure/inMemory/students/inMemoryStudentRepository' +import { InMemorySubmissionRepository } from 'src/infrastructure/inMemory/submissions/inMemorySubmissionRepository' +import { InMemoryAssessmentRepository } from 'src/infrastructure/inMemory/assessments/inMemoryAssessmentRepository' + +describe('import', () => { + test('The course of the report is saved.', async () => { + const courseRepository = new InMemoryCourseRepository() + const reportRepository = new InMemoryReportRepository() + const studentRepository = new InMemoryStudentRepository() + const submissionRepository = new InMemorySubmissionRepository() + const assessmentRepository = new InMemoryAssessmentRepository() + const service = new ReportListApplicationService( + courseRepository, + reportRepository, + studentRepository, + submissionRepository, + assessmentRepository + ) + const command = new ReportListImportCommand( + path.join(__dirname, 'reportListImportTestFiles', 'reportlist.xlsx') + ) + + await service.importAsync(command) + + const course = await courseRepository.findAsync(27048) + expect(course.id).toBe(27048) + expect(course.name).toBe('コミュニケーション技術特論2') + }) + + test('The report is saved.', async () => { + const courseRepository = new InMemoryCourseRepository() + const reportRepository = new InMemoryReportRepository() + const studentRepository = new InMemoryStudentRepository() + const submissionRepository = new InMemorySubmissionRepository() + const assessmentRepository = new InMemoryAssessmentRepository() + const service = new ReportListApplicationService( + courseRepository, + reportRepository, + studentRepository, + submissionRepository, + assessmentRepository + ) + const command = new ReportListImportCommand( + path.join(__dirname, 'reportListImportTestFiles', 'reportlist.xlsx') + ) + + await service.importAsync(command) + + const report = await reportRepository.findAsync(35677) + expect(report.courseId).toBe(27048) + expect(report.id).toBe(35677) + expect(report.title).toBe('個人レポート課題') + }) + + test('The first student is saved.', async () => { + const courseRepository = new InMemoryCourseRepository() + const reportRepository = new InMemoryReportRepository() + const studentRepository = new InMemoryStudentRepository() + const submissionRepository = new InMemorySubmissionRepository() + const assessmentRepository = new InMemoryAssessmentRepository() + const service = new ReportListApplicationService( + courseRepository, + reportRepository, + studentRepository, + submissionRepository, + assessmentRepository + ) + const command = new ReportListImportCommand( + path.join(__dirname, 'reportListImportTestFiles', 'reportlist.xlsx') + ) + + await service.importAsync(command) + + const student = await studentRepository.findAsync(23745148) + expect(student.userId).toBe('a2348mt') + expect(student.numId).toBe(23745148) + expect(student.name).toBe('田中 真') + }) + + test('The last student is saved.', async () => { + const courseRepository = new InMemoryCourseRepository() + const reportRepository = new InMemoryReportRepository() + const studentRepository = new InMemoryStudentRepository() + const submissionRepository = new InMemorySubmissionRepository() + const assessmentRepository = new InMemoryAssessmentRepository() + const service = new ReportListApplicationService( + courseRepository, + reportRepository, + studentRepository, + submissionRepository, + assessmentRepository + ) + const command = new ReportListImportCommand( + path.join(__dirname, 'reportListImportTestFiles', 'reportlist.xlsx') + ) + + await service.importAsync(command) + + const student = await studentRepository.findAsync(23745197) + expect(student.userId).toBe('a2397ka') + expect(student.numId).toBe(23745197) + expect(student.name).toBe('安藤 健') + }) + + test('The first submission is saved.', async () => { + const courseRepository = new InMemoryCourseRepository() + const reportRepository = new InMemoryReportRepository() + const studentRepository = new InMemoryStudentRepository() + const submissionRepository = new InMemorySubmissionRepository() + const assessmentRepository = new InMemoryAssessmentRepository() + const service = new ReportListApplicationService( + courseRepository, + reportRepository, + studentRepository, + submissionRepository, + assessmentRepository + ) + const command = new ReportListImportCommand( + path.join(__dirname, 'reportListImportTestFiles', 'reportlist.xlsx') + ) + + await service.importAsync(command) + + const submissions = await submissionRepository.findAsync(35677) + const submission = submissions.find((x) => x.studentNumId === 23745148) + expect(submission.reportId).toBe(35677) + expect(submission.studentNumId).toBe(23745148) + expect(submission.folderRelativePath).toBe('23745148@a2348mt') + }) + + test('The first assessment is saved.', async () => { + const courseRepository = new InMemoryCourseRepository() + const reportRepository = new InMemoryReportRepository() + const studentRepository = new InMemoryStudentRepository() + const submissionRepository = new InMemorySubmissionRepository() + const assessmentRepository = new InMemoryAssessmentRepository() + const service = new ReportListApplicationService( + courseRepository, + reportRepository, + studentRepository, + submissionRepository, + assessmentRepository + ) + const command = new ReportListImportCommand( + path.join(__dirname, 'reportListImportTestFiles', 'reportlist.xlsx') + ) + + await service.importAsync(command) + + const assessments = await assessmentRepository.findAsync(35677) + const assessment = assessments.find((x) => x.studentNumId === 23745148) + + expect(assessment.reportId).toBe(35677) + expect(assessment.studentNumId).toBe(23745148) + expect(assessment.feedback).toBeUndefined() + expect(assessment.memo).toBeUndefined() + expect(assessment.grade).toBeUndefined() + expect(assessment.rank).toBeUndefined() + expect(assessment.score).toBeUndefined() + }) +}) diff --git a/src/application/reportLists/reportListApplicationService.ts b/src/application/reportLists/reportListApplicationService.ts new file mode 100644 index 0000000..3663400 --- /dev/null +++ b/src/application/reportLists/reportListApplicationService.ts @@ -0,0 +1,93 @@ +import { CourseRepository } from 'src/domain/models/courses/courseRepository' +import { ReportListImportCommand } from './reportListImportCommand' +import * as Excel from 'exceljs' +import { Course } from 'src/domain/models/courses/course' +import { ReportRepository } from 'src/domain/models/reports/reportRepository' +import { Report } from 'src/domain/models/reports/report' +import { StudentRepository } from 'src/domain/models/students/studentRepository' +import { Student } from 'src/domain/models/students/student' +import { SubmissionRepository } from 'src/domain/models/submissions/submissionRepository' +import { Submission } from 'src/domain/models/submissions/submission' +import { AssessmentRepository } from 'src/domain/models/assessments/assessmentRepository' +import { Assessment } from 'src/domain/models/assessments/assessment' + +/** + * レポートリストアプリケーションサービス + */ +export class ReportListApplicationService { + /** + * コンストラクタ + * + * @param courseRepository コースリポジトリ + * @param reportRepository レポートリポジトリ + * @param studentRepository 学生リポジトリ + * @param submissionRepository 提出物リポジトリ + * @param assessmentRepository 個別評価リポジトリ + */ + public constructor( + private readonly courseRepository: CourseRepository, + private readonly reportRepository: ReportRepository, + private readonly studentRepository: StudentRepository, + private readonly submissionRepository: SubmissionRepository, + private readonly assessmentRepository: AssessmentRepository + ) {} + + /** + * レポートリストをインポートする + * + * @param reportListImportCommand レポートリストインポートコマンド + * @returns レポート ID + */ + public async importAsync( + reportListImportCommand: ReportListImportCommand + ): Promise { + const workbook = new Excel.Workbook() + await workbook.xlsx.readFile(reportListImportCommand.reportListFilePath) + + // id によるアクセスは非推奨らしいので、名前でアクセス + // https://github.com/exceljs/exceljs?tab=readme-ov-file#access-worksheets + const worksheet = workbook.getWorksheet('Sheet1') + if (!worksheet) { + throw new Error('The Worksheet Sheet1 is not found.') + } + + const courseId = Number(worksheet.getCell('B2').text) + const courseName = worksheet.getCell('C2').text + await this.courseRepository.saveAsync(new Course(courseId, courseName)) + + const reportId = Number(worksheet.getCell('B3').text) + const reportTitle = worksheet.getCell('C3').text + await this.reportRepository.saveAsync( + new Report(courseId, reportId, reportTitle) + ) + + for (let i = 8; ; i++) { + const row = worksheet.getRow(i) + const role = row.getCell('A').text + if (role === '#end') { + break + } + if (role !== '履修生') { + continue + } + + const userId: string = row.getCell('B').text + const numId: number = Number(row.getCell('C').text) + const name: string = row.getCell('D').text + await this.studentRepository.saveAsync(new Student(userId, numId, name)) + + // TODO できればハイパーリンクから取得 + // なぜか isHyperlink が false, hyperlink が undefined で取得できなかった + const folderRelativePath = `${numId}@${userId}` + await this.submissionRepository.saveAsync( + new Submission(reportId, numId, folderRelativePath) + ) + + // レポート ID と学籍番号以外は未定義で作成 + // もし、最初から Excel に値が入っていることがあり得るなら要修正 + await this.assessmentRepository.saveAsync(new Assessment(reportId, numId)) + } + + return reportId + } +} diff --git a/src/application/reportLists/reportListImportCommand.ts b/src/application/reportLists/reportListImportCommand.ts new file mode 100644 index 0000000..f2fde55 --- /dev/null +++ b/src/application/reportLists/reportListImportCommand.ts @@ -0,0 +1,11 @@ +/** + * レポートリストインポートコマンド + */ +export class ReportListImportCommand { + /** + * コンストラクタ + * + * @param reportListFilePath レポートリストファイルパス + */ + public constructor(public readonly reportListFilePath: string) {} +} diff --git a/src/application/reportLists/reportListImportTestFiles/reportlist.xlsx b/src/application/reportLists/reportListImportTestFiles/reportlist.xlsx new file mode 100644 index 0000000..27474ab Binary files /dev/null and b/src/application/reportLists/reportListImportTestFiles/reportlist.xlsx differ diff --git a/src/application/reports/reportApplicationService.test.ts b/src/application/reports/reportApplicationService.test.ts new file mode 100644 index 0000000..c87ee5b --- /dev/null +++ b/src/application/reports/reportApplicationService.test.ts @@ -0,0 +1,21 @@ +import { InMemoryReportRepository } from 'src/infrastructure/inMemory/reports/inMemoryReportRepository' +import { describe, expect, test } from 'vitest' +import { Report } from 'src/domain/models/reports/report' +import { ReportApplicationService } from './reportApplicationService' +import { ReportGetCommand } from './reportGetCommand' + +describe('get', () => { + test('The service can get the report saved in the repository.', async () => { + const repository = new InMemoryReportRepository() + const report = new Report(1, 2, 'name') + await repository.saveAsync(report) + const service = new ReportApplicationService(repository) + const command = new ReportGetCommand(report.id) + + const result = await service.getAsync(command) + + expect(result.reportData.courseId).toBe(report.courseId) + expect(result.reportData.id).toBe(report.id) + expect(result.reportData.title).toBe(report.title) + }) +}) diff --git a/src/application/reports/reportApplicationService.ts b/src/application/reports/reportApplicationService.ts new file mode 100644 index 0000000..13b0af6 --- /dev/null +++ b/src/application/reports/reportApplicationService.ts @@ -0,0 +1,29 @@ +import { ReportRepository } from 'src/domain/models/reports/reportRepository' +import { ReportGetCommand } from './reportGetCommand' +import { ReportGetResult } from './reportGetResult' +import { ReportData } from './reportData' + +/** + * レポートアプリケーションサービス + */ +export class ReportApplicationService { + /** + * コンストラクタ + * + * @param reportRepository レポートリポジトリ + */ + public constructor(private readonly reportRepository: ReportRepository) {} + + /** + * レポートを取得する + * + * @param reportGetCommand レポート取得コマンド + * @returns レポート取得結果 + */ + public async getAsync( + reportGetCommand: ReportGetCommand + ): Promise { + const report = await this.reportRepository.findAsync(reportGetCommand.id) + return new ReportGetResult(new ReportData(report)) + } +} diff --git a/src/application/reports/reportData.ts b/src/application/reports/reportData.ts new file mode 100644 index 0000000..e9c3af9 --- /dev/null +++ b/src/application/reports/reportData.ts @@ -0,0 +1,32 @@ +import { Report } from 'src/domain/models/reports/report' + +/** + * レポートデータ(DTO) + */ +export class ReportData { + /** + * コース ID + */ + public readonly courseId: number + + /** + * ID + */ + public readonly id: number + + /** + * タイトル + */ + public readonly title: string + + /** + * コンストラクタ + * + * @param report レポート + */ + public constructor(report: Report) { + this.courseId = report.courseId + this.id = report.id + this.title = report.title + } +} diff --git a/src/application/reports/reportGetCommand.ts b/src/application/reports/reportGetCommand.ts new file mode 100644 index 0000000..23afe30 --- /dev/null +++ b/src/application/reports/reportGetCommand.ts @@ -0,0 +1,11 @@ +/** + * レポート取得コマンド + */ +export class ReportGetCommand { + /** + * コンストラクタ + * + * @param id ID + */ + public constructor(public readonly id: number) {} +} diff --git a/src/application/reports/reportGetResult.ts b/src/application/reports/reportGetResult.ts new file mode 100644 index 0000000..a347b14 --- /dev/null +++ b/src/application/reports/reportGetResult.ts @@ -0,0 +1,13 @@ +import { ReportData } from './reportData' + +/** + * レポート取得結果 + */ +export class ReportGetResult { + /** + * コンストラクタ + * + * @param reportData レポートデータ + */ + public constructor(public readonly reportData: ReportData) {} +} diff --git a/src/common/CommonLayout.tsx b/src/common/CommonLayout.tsx deleted file mode 100644 index f80037c..0000000 --- a/src/common/CommonLayout.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Outlet, NavLink } from "react-router-dom"; - -const CommonLayout = () => { - return ( - <> -
- -

Manakan

-
-
-
- {/* ルーティングでここが置き換わる */} - - ); -}; - -export default CommonLayout; diff --git a/src/components/ReportImport.tsx b/src/components/ReportImport.tsx deleted file mode 100644 index 035c413..0000000 --- a/src/components/ReportImport.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { useContext } from 'react'; -import { useNavigate } from 'react-router-dom'; -import * as Excel from 'exceljs'; - -// 型定義をimport -import { Report } from '../types'; - -// コンテキストをimport -import { ReportContext } from '../context/ReportContext'; - -const ReportImport = () => { - const navigate = useNavigate(); // ルーティング用の関数 - - const { setReport } = useContext(ReportContext); - - const handleImport = async (event: React.ChangeEvent) => { - if (!event.target.files) return; - const fileList = event.target.files; - - // reportlist.xlsxがインポートされたフォルダのすぐ下に含まれているか確認 - // 含まれていない場合は処理を中断 - // 判定方法は改善の余地あり - if (!Array.from(fileList).some((file) => file.webkitRelativePath.split('/')[1] === 'reportlist.xlsx')) { - alert('reportlist.xlsxが含まれていません'); - return; - } - - // 提出物だけを取得 - const submissionList = Array.from(fileList).filter((file) => file.name !== 'reportlist.xlsx'); - if (!submissionList) return; - - // コース名を取得 - const arrayBuffer = await Array.from(fileList).find((file) => file.name === 'reportlist.xlsx')?.arrayBuffer(); - const workbook = new Excel.Workbook(); - await workbook.xlsx.load(arrayBuffer); // reportlist.xlsxファイルを読み込む - const worksheet = workbook.getWorksheet(1); // 1番目のシートを取得 - const course = worksheet.getCell('C2').value as string; // C2セルの値を取得(レポート名) - - // 提出物を学生ごとに分類 - // 複数のファイルが提出されることを考慮 - const studentMap = new Map(); - submissionList - .forEach((file) => { - // file.webkitRelativePathは選択されたフォルダからの相対パスが取得できる - // 例えば、選択されたフォルダが「$HOME/AIIT/PBL/manaba/report-27048-35677」であれば、 - // file.webkitRelativePathは「/report-27048-35677/23745140@a2340sw/テスト.pdf」となる - const studentFolderPath = file.webkitRelativePath.split('/')[1]; - if (!studentMap.has(studentFolderPath)) { - studentMap.set(studentFolderPath, [file]); - } else { - studentMap.get(studentFolderPath).push(file); - } - }); - - - // 学生情報を取得 - // 学生もProviderで管理することも考えられるしれない - const newReport: Report = { - id: 1, - course: course, - students: Array.from(studentMap.entries()).map(([key, value], index) => { - const atIndex = key.indexOf('@'); - const numId = parseInt(key.substring(0, atIndex)); - const userId = key.substring(atIndex + 1); - return { - id: index + 1, - userId: userId, - numId: numId, - grade: null, - symgrade: null, - comment: null, - files: value, - }; - }), - }; - - setReport(newReport); - - // 評価画面に遷移 - navigate('/evaluation') - }; - - return ( - <> - - - ); -} - -export default ReportImport; diff --git a/src/context/ReportContext.tsx b/src/context/ReportContext.tsx deleted file mode 100644 index 10e9da2..0000000 --- a/src/context/ReportContext.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { createContext } from "react"; -import { Report } from "../types"; - -// ReportContext: Reportの状態とsetReport関数を格納するコンテキストを作成 -// 初期値はnull -export const ReportContext = createContext<{ - report: Report | null; - setReport: (report: Report) => void; -} | null>(null); diff --git a/src/context/ReportProvider.tsx b/src/context/ReportProvider.tsx deleted file mode 100644 index 13d715e..0000000 --- a/src/context/ReportProvider.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React, { useReducer } from "react"; -import { ReportContext } from "./ReportContext"; -import { Report } from "../types"; -import { reportReducer } from "./ReportReducer"; - -// ReportProvider: 子コンポーネントにReportContextを提供するコンポーネント -const ReportProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - // useReducerを使用してreportの状態管理を行う - const [report, dispatch] = useReducer(reportReducer, null); - - // setReport: Reportを更新するための関数 - const setReport = (report: Report) => { - dispatch({ type: 'SET_REPORT', report }); - }; - - // ReportContext.Providerを使用してコンテキストの値を提供 - return ( - - {children} - - ); -}; - -export { ReportProvider }; diff --git a/src/context/ReportReducer.ts b/src/context/ReportReducer.ts deleted file mode 100644 index f374e0e..0000000 --- a/src/context/ReportReducer.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Report, ReportAction } from "../types"; - -// ReportReducer: reportの状態を管理するReducer関数 -// アクションに基づいて状態を更新 -export const reportReducer = (state: Report | null, action: ReportAction): Report | null => { - switch (action.type) { - case 'SET_REPORT': - return action.report; - default: - return state; - } -} diff --git a/src/domain/models/assessments/assessment.ts b/src/domain/models/assessments/assessment.ts new file mode 100644 index 0000000..fb42d1f --- /dev/null +++ b/src/domain/models/assessments/assessment.ts @@ -0,0 +1,35 @@ +/** + * 個別評価 + */ +export class Assessment { + /** + * コンストラクタ + * + * @param reportId レポート ID + * @param studentNumId 学籍番号 + * @param feedback フィードバック + * @param memo メモ + * @param grade 評点 + * @param rank 評点内の位置 + * @param score 点数 + */ + public constructor( + public readonly reportId: number, + public readonly studentNumId: number, + public readonly feedback?: string, + public readonly memo?: string, + public readonly grade?: number, + public readonly rank?: number, + public readonly score?: number + ) { + if (!grade && (grade < 0 || grade > 5)) { + throw new TypeError('The grade must be in [0, 5].') + } + + // TODO rank の仕様決定後、バリデーション + + if (!score && (score < 0 || score > 100)) { + throw new TypeError('The score must be in [0, 100].') + } + } +} diff --git a/src/domain/models/assessments/assessmentRepository.ts b/src/domain/models/assessments/assessmentRepository.ts new file mode 100644 index 0000000..8a0d187 --- /dev/null +++ b/src/domain/models/assessments/assessmentRepository.ts @@ -0,0 +1,21 @@ +import { Assessment } from './assessment' + +/** + * 個別評価リポジトリ + */ +export interface AssessmentRepository { + /** + * 個別評価を保存する + * + * @param assessment 個別評価 + */ + saveAsync(assessment: Assessment): Promise + + /** + * 個別評価を検索する + * + * @param reportId レポート ID + * @returns 個別評価 + */ + findAsync(reportId: number): Promise +} diff --git a/src/domain/models/courses/course.ts b/src/domain/models/courses/course.ts new file mode 100644 index 0000000..256d62b --- /dev/null +++ b/src/domain/models/courses/course.ts @@ -0,0 +1,15 @@ +/** + * コース + */ +export class Course { + /** + * コンストラクタ + * + * @param id ID + * @param name コース名 + */ + public constructor( + public readonly id: number, + public readonly name: string + ) {} +} diff --git a/src/domain/models/courses/courseRepository.ts b/src/domain/models/courses/courseRepository.ts new file mode 100644 index 0000000..f574b98 --- /dev/null +++ b/src/domain/models/courses/courseRepository.ts @@ -0,0 +1,20 @@ +import { Course } from './course' + +/** + * コースリポジトリ + */ +export interface CourseRepository { + /** + * コースを保存する + * + * @param course コース + */ + saveAsync(course: Course): Promise + + /** + * コースを検索する + * + * @param id ID + */ + findAsync(id: number): Promise +} diff --git a/src/domain/models/reports/report.ts b/src/domain/models/reports/report.ts new file mode 100644 index 0000000..08559bd --- /dev/null +++ b/src/domain/models/reports/report.ts @@ -0,0 +1,17 @@ +/** + * レポート + */ +export class Report { + /** + * コンストラクタ + * + * @param courseId コース ID + * @param id ID + * @param title タイトル + */ + public constructor( + public readonly courseId: number, + public readonly id: number, + public readonly title: string + ) {} +} diff --git a/src/domain/models/reports/reportRepository.ts b/src/domain/models/reports/reportRepository.ts new file mode 100644 index 0000000..c0be5b5 --- /dev/null +++ b/src/domain/models/reports/reportRepository.ts @@ -0,0 +1,20 @@ +import { Report } from './report' + +/** + * レポートリポジトリ + */ +export interface ReportRepository { + /** + * レポートを保存する + * + * @param report レポート + */ + saveAsync(report: Report): Promise + + /** + * レポートを検索する + * + * @param id ID + */ + findAsync(id: number): Promise +} diff --git a/src/domain/models/students/student.ts b/src/domain/models/students/student.ts new file mode 100644 index 0000000..552b0c5 --- /dev/null +++ b/src/domain/models/students/student.ts @@ -0,0 +1,17 @@ +/** + * 学生 + */ +export class Student { + /** + * コンストラクタ + * + * @param userId ユーザ ID + * @param numId 学籍番号 + * @param name 氏名 + */ + public constructor( + public readonly userId: string, + public readonly numId: number, + public readonly name: string + ) {} +} diff --git a/src/domain/models/students/studentRepository.ts b/src/domain/models/students/studentRepository.ts new file mode 100644 index 0000000..8560411 --- /dev/null +++ b/src/domain/models/students/studentRepository.ts @@ -0,0 +1,21 @@ +import { Student } from './student' + +/** + * 学生リポジトリ + */ +export interface StudentRepository { + /** + * 学生を保存する + * + * @param student 学生 + */ + saveAsync(student: Student): Promise + + /** + * 学生を検索する + * + * @param numId 学籍番号 + * @returns 学生 + */ + findAsync(numId: number): Promise +} diff --git a/src/domain/models/submissions/submission.ts b/src/domain/models/submissions/submission.ts new file mode 100644 index 0000000..b681ff8 --- /dev/null +++ b/src/domain/models/submissions/submission.ts @@ -0,0 +1,17 @@ +/** + * 提出物 + */ +export class Submission { + /** + * コンストラクタ + * + * @param reportId レポート ID + * @param studentNumId 学籍番号 + * @param folderRelativePath 提出物フォルダの相対パス + */ + public constructor( + public readonly reportId: number, + public readonly studentNumId: number, + public readonly folderRelativePath: string + ) {} +} diff --git a/src/domain/models/submissions/submissionRepository.ts b/src/domain/models/submissions/submissionRepository.ts new file mode 100644 index 0000000..2c45504 --- /dev/null +++ b/src/domain/models/submissions/submissionRepository.ts @@ -0,0 +1,21 @@ +import { Submission } from './submission' + +/** + * 提出物リポジトリ + */ +export interface SubmissionRepository { + /** + * 提出物を保存する + * + * @param submission 提出物 + */ + saveAsync(submission: Submission): Promise + + /** + * 提出物を検索する + * + * @param reportId レポート ID + * @returns 提出物 + */ + findAsync(reportId: number): Promise +} diff --git a/src/index.css b/src/index.css index 0c74078..c0d4e02 100644 --- a/src/index.css +++ b/src/index.css @@ -1,3 +1,7 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; diff --git a/src/index.tsx b/src/index.tsx index f2f9c5d..a1c8afd 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,16 +2,12 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import App from './App'; -// リポートデータを、どのコンポーネントからでも取得できるようにするため、Providerを使う -import { ReportProvider } from './context/ReportProvider'; const root = createRoot( document.body ); root.render( - - - + ); diff --git a/src/infrastructure/inMemory/assessments/inMemoryAssessmentRepository.test.ts b/src/infrastructure/inMemory/assessments/inMemoryAssessmentRepository.test.ts new file mode 100644 index 0000000..508f9c4 --- /dev/null +++ b/src/infrastructure/inMemory/assessments/inMemoryAssessmentRepository.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, test } from 'vitest' +import { InMemoryAssessmentRepository } from './inMemoryAssessmentRepository' +import { Assessment } from 'src/domain/models/assessments/assessment' + +describe('save', () => { + test('The saved assessment exists.', async () => { + const repository = new InMemoryAssessmentRepository() + const expected = new Assessment(1, 2) + await repository.saveAsync(expected) + + const actual = await repository.findAsync(expected.reportId) + + expect(actual.length).toBe(1) + expect(actual[0].reportId).toBe(expected.reportId) + expect(actual[0].studentNumId).toBe(expected.studentNumId) + expect(actual[0].feedback).toBe(expected.feedback) + expect(actual[0].memo).toBe(expected.memo) + expect(actual[0].grade).toBe(expected.grade) + expect(actual[0].rank).toBe(expected.rank) + expect(actual[0].score).toBe(expected.score) + }) +}) diff --git a/src/infrastructure/inMemory/assessments/inMemoryAssessmentRepository.ts b/src/infrastructure/inMemory/assessments/inMemoryAssessmentRepository.ts new file mode 100644 index 0000000..9b55d90 --- /dev/null +++ b/src/infrastructure/inMemory/assessments/inMemoryAssessmentRepository.ts @@ -0,0 +1,35 @@ +import { Assessment } from 'src/domain/models/assessments/assessment' +import { AssessmentRepository } from 'src/domain/models/assessments/assessmentRepository' + +export class InMemoryAssessmentRepository implements AssessmentRepository { + /** + * 提出物 + * 1 つ目の Key がレポート ID, 2 つ目の Key が学籍番号 + */ + private readonly assessments = new Map>() + + /** + * 個別評価を保存する + * + * @param assessment 個別評価 + */ + async saveAsync(assessment: Assessment): Promise { + let map = this.assessments.get(assessment.reportId) + if (!map) { + map = new Map() + this.assessments.set(assessment.reportId, map) + } + map.set(assessment.studentNumId, assessment) + } + + /** + * 個別評価を検索する + * + * @param reportId レポート ID + * @returns 個別評価 + */ + async findAsync(reportId: number): Promise { + const map = this.assessments.get(reportId) ?? new Map() + return [...map.values()] + } +} diff --git a/src/infrastructure/inMemory/courses/inMemoryCourseRepository.test.ts b/src/infrastructure/inMemory/courses/inMemoryCourseRepository.test.ts new file mode 100644 index 0000000..c87d3c1 --- /dev/null +++ b/src/infrastructure/inMemory/courses/inMemoryCourseRepository.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, test } from 'vitest' +import { InMemoryCourseRepository } from './inMemoryCourseRepository' +import { Course } from 'src/domain/models/courses/course' + +describe('save', () => { + test('The saved course exists.', async () => { + const repository = new InMemoryCourseRepository() + const expected = new Course(1, 'name') + + await repository.saveAsync(expected) + + const actual = await repository.findAsync(expected.id) + expect(actual.id).toBe(expected.id) + expect(actual.name).toBe(expected.name) + }) +}) diff --git a/src/infrastructure/inMemory/courses/inMemoryCourseRepository.ts b/src/infrastructure/inMemory/courses/inMemoryCourseRepository.ts new file mode 100644 index 0000000..036cefe --- /dev/null +++ b/src/infrastructure/inMemory/courses/inMemoryCourseRepository.ts @@ -0,0 +1,35 @@ +import { Course } from 'src/domain/models/courses/course' +import { CourseRepository } from 'src/domain/models/courses/courseRepository' + +/** + * インメモリコースリポジトリ + */ +export class InMemoryCourseRepository implements CourseRepository { + /** + * コース + */ + private readonly courses = new Map() + + /** + * コースを保存する + * + * @param course コース + */ + public async saveAsync(course: Course): Promise { + this.courses.set(course.id, course) + } + + /** + * コースを検索する + * + * @param id ID + * @returns コース + */ + public async findAsync(id: number): Promise { + const course = this.courses.get(id) + if (!course) { + throw new Error('The course is not found.') + } + return course + } +} diff --git a/src/infrastructure/inMemory/reports/inMemoryReportRepository.test.ts b/src/infrastructure/inMemory/reports/inMemoryReportRepository.test.ts new file mode 100644 index 0000000..cbedb5f --- /dev/null +++ b/src/infrastructure/inMemory/reports/inMemoryReportRepository.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, test } from 'vitest' +import { InMemoryReportRepository } from './inMemoryReportRepository' +import { Report } from 'src/domain/models/reports/report' + +describe('save', () => { + test('The saved report exists.', async () => { + const repository = new InMemoryReportRepository() + const expected = new Report(1, 2, 'title') + + await repository.saveAsync(expected) + + const actual = await repository.findAsync(expected.id) + expect(actual.courseId).toBe(expected.courseId) + expect(actual.id).toBe(expected.id) + expect(actual.title).toBe(expected.title) + }) +}) diff --git a/src/infrastructure/inMemory/reports/inMemoryReportRepository.ts b/src/infrastructure/inMemory/reports/inMemoryReportRepository.ts new file mode 100644 index 0000000..9ec9fca --- /dev/null +++ b/src/infrastructure/inMemory/reports/inMemoryReportRepository.ts @@ -0,0 +1,35 @@ +import { Report } from 'src/domain/models/reports/report' +import { ReportRepository } from 'src/domain/models/reports/reportRepository' + +/** + * インメモリレポートリポジトリ + */ +export class InMemoryReportRepository implements ReportRepository { + /** + * レポート + */ + private readonly reports = new Map() + + /** + * レポートを保存する + * + * @param report レポート + */ + public async saveAsync(report: Report): Promise { + this.reports.set(report.id, report) + } + + /** + * レポートを検索する + * + * @param id ID + * @returns レポート + */ + public async findAsync(id: number): Promise { + const report = this.reports.get(id) + if (!report) { + throw new Error('The report is not found.') + } + return report + } +} diff --git a/src/infrastructure/inMemory/students/inMemoryStudentRepository.test.ts b/src/infrastructure/inMemory/students/inMemoryStudentRepository.test.ts new file mode 100644 index 0000000..486359d --- /dev/null +++ b/src/infrastructure/inMemory/students/inMemoryStudentRepository.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, test } from 'vitest' +import { InMemoryStudentRepository } from './inMemoryStudentRepository' +import { Student } from 'src/domain/models/students/student' + +describe('save', () => { + test('The saved student exists.', async () => { + const repository = new InMemoryStudentRepository() + const expected = new Student('a2301aa', 1, 'name') + + await repository.saveAsync(expected) + + const actual = await repository.findAsync(expected.numId) + expect(actual.userId).toBe(expected.userId) + expect(actual.numId).toBe(expected.numId) + expect(actual.name).toBe(expected.name) + }) +}) diff --git a/src/infrastructure/inMemory/students/inMemoryStudentRepository.ts b/src/infrastructure/inMemory/students/inMemoryStudentRepository.ts new file mode 100644 index 0000000..8253f50 --- /dev/null +++ b/src/infrastructure/inMemory/students/inMemoryStudentRepository.ts @@ -0,0 +1,35 @@ +import { Student } from 'src/domain/models/students/student' +import { StudentRepository } from 'src/domain/models/students/studentRepository' + +/** + * インメモリ学生リポジトリ + */ +export class InMemoryStudentRepository implements StudentRepository { + /** + * 学生 + */ + private readonly students = new Map() + + /** + * 学生を保存する + * + * @param student 学生 + */ + public async saveAsync(student: Student): Promise { + this.students.set(student.numId, student) + } + + /** + * 学生を検索する + * + * @param numId 学籍番号 + * @returns 学生 + */ + public async findAsync(numId: number): Promise { + const student = this.students.get(numId) + if (!student) { + throw new Error('The student is not found.') + } + return student + } +} diff --git a/src/infrastructure/inMemory/submissions/inMemorySubmissionRepository.test.ts b/src/infrastructure/inMemory/submissions/inMemorySubmissionRepository.test.ts new file mode 100644 index 0000000..d672899 --- /dev/null +++ b/src/infrastructure/inMemory/submissions/inMemorySubmissionRepository.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, test } from 'vitest' +import { InMemorySubmissionRepository } from './inMemorySubmissionRepository' +import { Submission } from 'src/domain/models/submissions/submission' + +describe('save', () => { + test('The saved submission exists.', async () => { + const repository = new InMemorySubmissionRepository() + const expected = new Submission(1, 2, '23745101@a2301aa') + await repository.saveAsync(expected) + + const actual = await repository.findAsync(expected.reportId) + + expect(actual.length).toBe(1) + expect(actual[0].reportId).toBe(expected.reportId) + expect(actual[0].studentNumId).toBe(expected.studentNumId) + expect(actual[0].folderRelativePath).toBe(expected.folderRelativePath) + }) +}) diff --git a/src/infrastructure/inMemory/submissions/inMemorySubmissionRepository.ts b/src/infrastructure/inMemory/submissions/inMemorySubmissionRepository.ts new file mode 100644 index 0000000..176d86b --- /dev/null +++ b/src/infrastructure/inMemory/submissions/inMemorySubmissionRepository.ts @@ -0,0 +1,38 @@ +import { Submission } from 'src/domain/models/submissions/submission' +import { SubmissionRepository } from 'src/domain/models/submissions/submissionRepository' + +/** + * インメモリ提出物リポジトリ + */ +export class InMemorySubmissionRepository implements SubmissionRepository { + /** + * 提出物 + * 1 つ目の Key がレポート ID, 2 つ目の Key が学籍番号 + */ + private readonly submissions = new Map>() + + /** + * 提出物を保存する + * + * @param submission 提出物 + */ + async saveAsync(submission: Submission): Promise { + let map = this.submissions.get(submission.reportId) + if (!map) { + map = new Map() + this.submissions.set(submission.reportId, map) + } + map.set(submission.studentNumId, submission) + } + + /** + * 提出物を検索する + * + * @param reportId レポート ID + * @returns 提出物 + */ + async findAsync(reportId: number): Promise { + const map = this.submissions.get(reportId) ?? new Map() + return [...map.values()] + } +} diff --git a/src/main.ts b/src/main.ts index cbd9c22..e2b1042 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,21 @@ -import { app, BrowserWindow } from 'electron'; -import path from 'path'; +// 'electron/main' から import すると Vite がエラーを出す +import { app, BrowserWindow, ipcMain } from 'electron' +import path from 'path' +import { ReportListApplicationService } from './application/reportLists/reportListApplicationService' +import { InMemoryStudentRepository } from './infrastructure/inMemory/students/inMemoryStudentRepository' +import { InMemoryReportRepository } from './infrastructure/inMemory/reports/inMemoryReportRepository' +import { InMemoryCourseRepository } from './infrastructure/inMemory/courses/inMemoryCourseRepository' +import { ReportListImportCommand } from './application/reportLists/reportListImportCommand' +import { ReportGetCommand } from './application/reports/reportGetCommand' +import { ReportApplicationService } from './application/reports/reportApplicationService' +import { CourseGetCommand } from './application/courses/courseGetCommand' +import { CourseApplicationService } from './application/courses/courseApplicationService' +import { InMemorySubmissionRepository } from './infrastructure/inMemory/submissions/inMemorySubmissionRepository' +import { InMemoryAssessmentRepository } from './infrastructure/inMemory/assessments/inMemoryAssessmentRepository' // Handle creating/removing shortcuts on Windows when installing/uninstalling. if (require('electron-squirrel-startup')) { - app.quit(); + app.quit() } const createWindow = () => { @@ -14,40 +26,79 @@ const createWindow = () => { webPreferences: { preload: path.join(__dirname, 'preload.js'), }, - }); + }) // and load the index.html of the app. if (MAIN_WINDOW_VITE_DEV_SERVER_URL) { - mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL); + mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL) } else { - mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)); + mainWindow.loadFile( + path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`) + ) } // Open the DevTools. - mainWindow.webContents.openDevTools(); -}; + mainWindow.webContents.openDevTools() +} + +// TODO 定義場所の検討 +// TODO DI フレームワークの利用を検討 +const courseRepository = new InMemoryCourseRepository() +const reportRepository = new InMemoryReportRepository() +const studentRepository = new InMemoryStudentRepository() +const submissionRepository = new InMemorySubmissionRepository() +const assessmentRepository = new InMemoryAssessmentRepository() +const reportListApplicationService = new ReportListApplicationService( + courseRepository, + reportRepository, + studentRepository, + submissionRepository, + assessmentRepository +) +const reportApplicationService = new ReportApplicationService(reportRepository) +const courseApplicationService = new CourseApplicationService(courseRepository) // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. -app.on('ready', createWindow); +app.whenReady().then(() => { + ipcMain.handle( + 'importReportListAsync', + async (_, reportListImportCommand: ReportListImportCommand) => + await reportListApplicationService.importAsync(reportListImportCommand) + ) + + ipcMain.handle( + 'getReportAsync', + async (_, reportGetCommand: ReportGetCommand) => + await reportApplicationService.getAsync(reportGetCommand) + ) + + ipcMain.handle( + 'getCourseAsync', + async (_, courseGetCommand: CourseGetCommand) => + await courseApplicationService.getAsync(courseGetCommand) + ) + + createWindow() +}) // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. app.on('window-all-closed', () => { if (process.platform !== 'darwin') { - app.quit(); + app.quit() } -}); +}) app.on('activate', () => { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); + createWindow() } -}); +}) // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and import them here. diff --git a/src/pages/Evaluation.tsx b/src/pages/Evaluation.tsx deleted file mode 100644 index 29f7a9d..0000000 --- a/src/pages/Evaluation.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { useContext } from "react"; -import { Student } from "../types"; -import { ReportContext } from "../context/ReportContext"; - -// ページ名称については検討の余地あり -const Evaluation = () => { - - // ここで、ReportContextから取得した値を使う - const { report } = useContext(ReportContext); - - return ( - <> -

Evaluation Page

-

評価対象のフォルダがインポートされたら、遷移されてくるページ

- {/* 学生と提出物がインポートされたかを確認している */} -

コース名: {report.course}

-

学生:

- {report.students.map((student: Student) => { - return ( -
-

{student.userId}

-

学籍番号: {student.numId}

-

提出物:

- {student.files?.map((file: File) => { - return ( -
-

{file.name}

-
- ); - })} -
- ); - })} - - ); -}; - -export default Evaluation; diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx deleted file mode 100644 index 61a0f2a..0000000 --- a/src/pages/Home.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import ReportImport from "../components/ReportImport"; - -const Home = () => { - return ( - <> -

Home Page

-

Homeページです

- - - ); -}; - -export default Home; diff --git a/src/preload.ts b/src/preload.ts index 5e9d369..f4be279 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -1,2 +1,19 @@ // See the Electron documentation for details on how to use preload scripts: // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts + +// 'electron/renderer' から import すると Vite がエラーを出す +import { contextBridge, ipcRenderer } from 'electron' +import { ReportListImportCommand } from './application/reportLists/reportListImportCommand' +import { ReportGetCommand } from './application/reports/reportGetCommand' +import { CourseGetCommand } from './application/courses/courseGetCommand' + +contextBridge.exposeInMainWorld('electronAPI', { + importReportListAsync: (reportListImportCommand: ReportListImportCommand) => + ipcRenderer.invoke('importReportListAsync', reportListImportCommand), + + getReportAsync: (reportGetCommand: ReportGetCommand) => + ipcRenderer.invoke('getReportAsync', reportGetCommand), + + getCourseAsync: (courseGetCommand: CourseGetCommand) => + ipcRenderer.invoke('getCourseAsync', courseGetCommand), +}) diff --git a/src/presentation/import/components/DropForm.tsx b/src/presentation/import/components/DropForm.tsx new file mode 100644 index 0000000..37a0fb0 --- /dev/null +++ b/src/presentation/import/components/DropForm.tsx @@ -0,0 +1,60 @@ +import { useNavigate } from 'react-router-dom'; +import { FileUploader } from "react-drag-drop-files"; +import { MdOutlineFileUpload } from "react-icons/md"; +import { ReportListImportCommand } from "src/application/reportLists/reportListImportCommand"; + +const DropForm = () => { + // ナビゲーション用フック + const navigate = useNavigate(); + + /** + * ファイルをドロップしたときの処理 + * + * @param {File} file - ドロップされたファイル + */ + const handleDrop = async (file: File) => { + // file名がreportlist.xlsxでない場合はエラー + if (file.name !== "reportlist.xlsx") { + alert("インポートされたファイルがreportlist.xlsxではありません。"); + return; + } + + try { + // レポートIDを取得 + const reportId = await window.electronAPI.importReportListAsync( + new ReportListImportCommand(file.path) + ); + + // 評価画面に遷移 + navigate(`/evaluation/${reportId}`); + + } catch (error) { + console.error(error); + alert("ファイルのインポートに失敗しました。"); + } + } + + return ( + <> + + +

ここにreportlist.xlsxをドロップ

+

または

+
ファイルを選択
+ + } + /> + + ); +} + +export default DropForm; diff --git a/src/presentation/pages/Evaluation.tsx b/src/presentation/pages/Evaluation.tsx new file mode 100644 index 0000000..8a6f307 --- /dev/null +++ b/src/presentation/pages/Evaluation.tsx @@ -0,0 +1,12 @@ +// ページ名称については検討の余地あり +const Evaluation = () => { + + return ( + <> +

Evaluation Page

+

評価対象のフォルダがインポートされたら、遷移されてくるページ

+ + ); +}; + +export default Evaluation; diff --git a/src/presentation/pages/Home.tsx b/src/presentation/pages/Home.tsx new file mode 100644 index 0000000..21d3ec8 --- /dev/null +++ b/src/presentation/pages/Home.tsx @@ -0,0 +1,46 @@ +import DropForm from '../import/components/DropForm'; + +const Home = () => { + return ( + <> +
+ {/* ファイルのインポート */} + + + {/* 最近使用したデータリスト */} + +
+ + ); +}; + +export default Home; diff --git a/src/testSample/sum.test.ts b/src/testSample/sum.test.ts deleted file mode 100644 index d40f3ea..0000000 --- a/src/testSample/sum.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Vitestサンプルコード - -import { expect, test } from 'vitest' -import { sum } from './sum' - -test('adds 1 + 2 to equal 3', () => { - expect(sum(1, 2)).toBe(3) -}) diff --git a/src/testSample/sum.ts b/src/testSample/sum.ts deleted file mode 100644 index 7765d2a..0000000 --- a/src/testSample/sum.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Vitestサンプルコード -export function sum(a: number, b: number) { - return a + b -} \ No newline at end of file diff --git a/src/types/index.tsx b/src/types/index.tsx deleted file mode 100644 index 9c06740..0000000 --- a/src/types/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -export interface Report { - id: number; - course: string; - students: Student[]; -} - -// reportlist.xlsxの内容をもとに型定義 -// Excelファイルを参照しなくていいものだけを型定義している -// 提出の状態(未提出、提出済み)や提出日時を追加することも考えられる -export interface Student { - id: number; - userId: string; - numId: number; - grade: number; - symgrade: number; - comment: string; - files: File[]; -} - -export type ReportContextType = { - report: Report | null; - setReport: (foler: Report) => void; -}; - -export type ReportAction = - | { type: 'SET_REPORT'; report: Report }; diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..aec5ca6 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './index.html', + './src/**/*.{html,js,jsx,ts,tsx}', + ], + theme: { + extend: {}, + }, + plugins: [], +} + diff --git a/uml/manakan_model.drawio.svg b/uml/manakan_model.drawio.svg index f229342..1ea8adc 100644 --- a/uml/manakan_model.drawio.svg +++ b/uml/manakan_model.drawio.svg @@ -1,11 +1,11 @@ - + - + -
+
9.状態遷移図 @@ -13,16 +13,16 @@
- + 9.状態遷移図 - + -
+
メモ情報状態 @@ -30,16 +30,16 @@
- + メモ情報状態 - + -
+
提出物を評価する(変更後) @@ -47,16 +47,16 @@
- + 提出物を評価する(変更後) - + -
+
manabaに点数を登録する @@ -64,16 +64,16 @@
- + manabaに点数を登録する - + -
+
提出物を評価する @@ -81,16 +81,16 @@
- + 提出物を評価する - + -
+
提出物を回収する @@ -98,16 +98,16 @@
- + 提出物を回収する - + -
+

@@ -121,16 +121,16 @@

- + 1. AsIs のモデリング - + -
+
1. ビジネスコンテキスト図 @@ -138,18 +138,18 @@
- + 1. ビジネスコンテキスト図 - - - + + + -
+
教員 @@ -157,16 +157,16 @@
- + 教員 - + -
+
PBL @@ -174,16 +174,16 @@
- + PBL - + -
+
講義 @@ -191,16 +191,16 @@
- + 講義 - + -
+
研究 @@ -208,16 +208,16 @@
- + 研究 - + -
+
外部活動 @@ -225,17 +225,17 @@
- + 外部活動 - - + + -
+
学生 @@ -243,17 +243,17 @@
- + 学生 - - + + -
+
事務員 @@ -261,21 +261,21 @@
- + 事務員 - - - - - - + + + + + + -
+
2.ビジネスユースケース図 @@ -286,21 +286,21 @@
- + 2.ビジネスユースケース図 - - - - - - + + + + + + -
+
教員 @@ -311,16 +311,16 @@
- + 教員 - + -
+
担当科目の講義を行う @@ -328,16 +328,16 @@
- + 担当科目の講義を行う - + -
+
テストを行う @@ -345,16 +345,16 @@
- + テストを行う - + -
+
レポートを課す @@ -362,16 +362,16 @@
- + レポートを課す - + -
+
成績をつける @@ -379,16 +379,16 @@
- + 成績をつける - + -
+
4.業務フロー図 @@ -396,16 +396,16 @@
- + 4.業務フロー図 - + -
+

@@ -424,17 +424,17 @@

- + 教員%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D... - - + + -
+
レポートの課題を設定する @@ -442,18 +442,18 @@
- + レポートの課題を設定する - - - + + + -
+
manabaにレポートを公開する @@ -461,18 +461,18 @@
- + manabaにレポートを公開する - - - + + + -
+
提出物を回収する @@ -480,20 +480,20 @@
- + 提出物を回収する - - - - - + + + + + -
+
提出物を評価する @@ -501,18 +501,18 @@
- + 提出物を評価する - - - + + + -
+
manabaに点数を登録する @@ -520,16 +520,16 @@
- + manabaに点数を登録する - + -
+
manabaに点数を公開する @@ -537,22 +537,22 @@
- + manabaに点数を公開する - - - - - - - + + + + + + + -
+

@@ -571,16 +571,16 @@

- + 教員%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%... - + -
+

@@ -599,19 +599,19 @@

- + 教員%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%... - - - - + + + + -
+
manabaへログインする @@ -619,18 +619,18 @@
- + manabaへログインする - - - + + + -
+
レポートをエクスポートする @@ -638,18 +638,18 @@
- + レポートをエクスポートする - - - + + + -
+

@@ -668,19 +668,19 @@

- + 教員%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%... - - - - + + + + -
+
manabaにログイン @@ -688,16 +688,16 @@
- + manabaにログイン - + -
+
集計Excelをmanabaにインポート @@ -705,27 +705,27 @@
- + 集計Excelをmanabaにインポート - - - - - - - - - - - - + + + + + + + + + + + + -
+
提出物を開く @@ -733,20 +733,20 @@
- + 提出物を開く - - - - - + + + + + -
+
提出物を開く @@ -754,18 +754,18 @@
- + 提出物を開く - - - + + + -
+
@@ -785,18 +785,18 @@
- + 評価基準に基づいて提出物の点数を仮決めする... - - - + + + -
+
集計Excelに点数を入力する @@ -804,16 +804,16 @@
- + 集計Excelに点数を入力する - + -
+
評価状況? @@ -821,17 +821,17 @@
- + 評価状況? - - + + -
+
[未入力あり] @@ -839,19 +839,19 @@
- + [未入力あり] - - - - + + + + -
+
[不要] @@ -859,17 +859,17 @@
- + [不要] - - + + -
+
[必要] @@ -877,16 +877,16 @@
- + [必要] - + -
+
調整が必要? @@ -894,17 +894,17 @@
- + 調整が必要? - - + + -
+
[すべて入力済み] @@ -912,22 +912,22 @@
- + [すべて入力済み] - - - - - - - + + + + + + + -
+
提出物の点数を調整する @@ -935,18 +935,18 @@
- + 提出物の点数を調整する - - - + + + -
+
集計Excelに点数を入力する @@ -954,16 +954,16 @@
- + 集計Excelに点数を入力する - + -
+
@@ -973,17 +973,17 @@
- + 3.システムコンテキスト図 - - + + -
+
manaba @@ -991,17 +991,17 @@
- + manaba - - + + -
+
成績管理 @@ -1009,17 +1009,17 @@
- + 成績管理 - - + + -
+
教員 @@ -1027,17 +1027,17 @@
- + 教員 - - + + -
+
学生 @@ -1045,17 +1045,17 @@
- + 学生 - - + + -
+
事務員 @@ -1063,24 +1063,24 @@
- + 事務員 - - - - - - - - - + + + + + + + + + -
+
2.ビジネスユースケース図 @@ -1088,18 +1088,18 @@
- + 2.ビジネスユースケース図 - - - + + + -
+
4.業務フロー @@ -1107,17 +1107,17 @@
- + 4.業務フロー - - + + -
+
3.システムコンテキスト図 @@ -1125,25 +1125,25 @@
- + 3.システムコンテキスト図 - - - - - - - - - - + + + + + + + + + + -
+
No @@ -1151,16 +1151,16 @@
- + No - + -
+
@@ -1172,16 +1172,16 @@
- + 業務洗い出し - + -
+
1 @@ -1189,16 +1189,16 @@
- + 1 - + -
+
@@ -1209,16 +1209,16 @@
- + レポートの課題を設定する - + -
+
2 @@ -1226,16 +1226,16 @@
- + 2 - + -
+
@@ -1246,16 +1246,16 @@
- + manabaにレポートを公開する - + -
+
3 @@ -1263,16 +1263,16 @@
- + 3 - + -
+
@@ -1282,16 +1282,16 @@
- + 提出物を回収する - + -
+
4 @@ -1299,16 +1299,16 @@
- + 4 - + -
+
提出物を評価する @@ -1316,16 +1316,16 @@
- + 提出物を評価する - + -
+
5 @@ -1333,16 +1333,16 @@
- + 5 - + -
+
manabaに点数を登録する @@ -1350,16 +1350,16 @@
- + manabaに点数を登録する - + -
+
6 @@ -1367,16 +1367,16 @@
- + 6 - + -
+
manabaに点数を公開する @@ -1384,18 +1384,18 @@
- + manabaに点数を公開する - - - + + + -
+
@@ -1405,27 +1405,27 @@
- + 提出物を評価するアクティビティは提出物の点数を仮決めし、その後調整する必要があり作業の手間が多く教員の負荷が高い仕事だと考えられる - - - - + + + + - + モデル関連図 - - - + + + -
+
1.ビジネスコンテキスト図 @@ -1433,25 +1433,25 @@
- + 1.ビジネスコンテキスト図 - - - - - - - - - - + + + + + + + + + + -
+
1.AsIsモデル(業務分析) @@ -1459,16 +1459,16 @@
- + 1.AsIsモデル(業務分析) - + -
+
2.ビジネスユースケース図 @@ -1476,16 +1476,16 @@
- + 2.ビジネスユースケース図 - + -
+
3.システムコンテキスト図 @@ -1493,16 +1493,16 @@
- + 3.システムコンテキスト図 - + -
+
4.業務フロー図 @@ -1510,17 +1510,17 @@
- + 4.業務フロー図 - - + + -
+
提出物を回収する @@ -1528,17 +1528,17 @@
- + 提出物を回収する - - + + -
+
提出物を評価する @@ -1546,17 +1546,17 @@
- + 提出物を評価する - - + + -
+
manabaに点数を登録する @@ -1564,19 +1564,19 @@
- + manabaに点数を登録する - - - - + + + + -
+
3.ToBeモデル @@ -1584,16 +1584,16 @@
- + 3.ToBeモデル - + -
+
提出物を評価する(変更後) @@ -1601,16 +1601,16 @@
- + 提出物を評価する(変更後) - + -
+
@@ -1620,16 +1620,16 @@
- + 3.システムコンテキスト図(変更後) - + -
+
8.情報モデル図 @@ -1637,16 +1637,16 @@
- + 8.情報モデル図 - + -
+
9.状態遷移図 @@ -1654,18 +1654,18 @@
- + 9.状態遷移図 - - - + + + -
+
2.要求分析 @@ -1673,18 +1673,18 @@
- + 2.要求分析 - - - + + + -
+
要求モデル図(要求分析) @@ -1692,16 +1692,16 @@
- + 要求モデル図(要求分析) - + -
+
request1 @@ -1709,16 +1709,16 @@
- + request1 - + -
+
request2 @@ -1726,16 +1726,16 @@
- + request2 - + -
+
request3 @@ -1743,16 +1743,16 @@
- + request3 - + -
+
request4 @@ -1760,16 +1760,16 @@
- + request4 - + -
+
request5 @@ -1777,16 +1777,16 @@
- + request5 - + -
+
request6 @@ -1794,16 +1794,16 @@
- + request6 - + -
+
requirement1 @@ -1811,16 +1811,16 @@
- + requirement1 - + -
+
requirement2 @@ -1828,16 +1828,16 @@
- + requirement2 - + -
+
requirement3 @@ -1845,16 +1845,16 @@
- + requirement3 - + -
+
requirement4 @@ -1862,16 +1862,16 @@
- + requirement4 - + -
+
requirement5 @@ -1879,16 +1879,16 @@
- + requirement5 - + -
+
requirement6 @@ -1896,16 +1896,16 @@
- + requirement6 - + -
+
requirement7 @@ -1913,16 +1913,16 @@
- + requirement7 - + -
+
requirement8 @@ -1930,16 +1930,16 @@
- + requirement8 - + -
+
requirement9 @@ -1947,16 +1947,16 @@
- + requirement9 - + -
+
requirement10 @@ -1964,18 +1964,18 @@
- + requirement10 - - - + + + -
+
システムユースケース図 @@ -1983,16 +1983,16 @@
- + システムユースケース図 - + -
+
usecase1 @@ -2000,16 +2000,16 @@
- + usecase1 - + -
+
usecase2 @@ -2017,16 +2017,16 @@
- + usecase2 - + -
+
usecase3 @@ -2034,16 +2034,16 @@
- + usecase3 - + -
+
usecase4 @@ -2051,16 +2051,16 @@
- + usecase4 - + -
+
usecase6 @@ -2068,16 +2068,16 @@
- + usecase6 - + -
+
usecase7 @@ -2085,16 +2085,16 @@
- + usecase7 - + -
+
usecase8 @@ -2102,16 +2102,16 @@
- + usecase8 - + -
+
usecase9 @@ -2119,16 +2119,16 @@
- + usecase9 - + -
+
usecase5 @@ -2136,16 +2136,16 @@
- + usecase5 - + -
+
usecase10 @@ -2153,16 +2153,16 @@
- + usecase10 - + -
+

@@ -2176,16 +2176,16 @@

- + 2. 要望、要求の解析 - + -
+
5.要求モデル図 @@ -2193,19 +2193,19 @@
- + 5.要求モデル図 - - - - + + + + -
+
教員 @@ -2213,20 +2213,20 @@
- + 教員 - - - - - + + + + + -
+
@@ -2236,22 +2236,22 @@
- + manabaとデータ連携したい - - - - - - - - - - - + + + + + + + + + + + @@ -2265,7 +2265,7 @@
- + 評価した結果をmanaba形式でエクスポートできること @@ -2273,7 +2273,7 @@ -
+
要望レベル @@ -2281,7 +2281,7 @@
- + 要望レベル @@ -2289,7 +2289,7 @@ -
+
要求レベル @@ -2297,14 +2297,14 @@
- + 要求レベル - - - + + + @@ -2316,18 +2316,20 @@
- + ざっくりと評価分類レベルで決められる機能が欲しい
- - - - - - - + + + + + + + + + @@ -2341,20 +2343,20 @@
- + 提出物に対して、なぜその点数を与えたのか理由を、比較が出来るよう覚えておきたい
- - - - - - - - - + + + + + + + + + @@ -2368,12 +2370,12 @@
- + レポート採点の調整機能がほしい - + @@ -2385,16 +2387,16 @@
- + 提出物を比較できること - + -
+
いろんなファイル形式を表示できるようにしたい @@ -2402,14 +2404,14 @@
- + いろんなファイル形式を表示できるようにしたい - - - + + + @@ -2421,20 +2423,20 @@
- + 途中結果を一定期間で保存したい
- - - - - + + + + + -
+
機密情報のセキュリティを担保したい @@ -2442,16 +2444,16 @@
- + 機密情報のセキュリティを担保したい - + -
+
使うならGoogleDriveを使いたい @@ -2459,12 +2461,12 @@
- + 使うならGoogleDriveを使いたい - + @@ -2476,12 +2478,12 @@
- + 提出物を表示できること
- + @@ -2493,14 +2495,14 @@
- + メモ情報を入力できること
- - - + + + @@ -2512,12 +2514,12 @@
- + 提出物を評点ごとに分類できること - + @@ -2529,14 +2531,14 @@
- + 提出物を評点内で順位付けできること - - - + + + @@ -2548,12 +2550,12 @@
- + 途中結果を一定間隔で保存できること - + @@ -2565,16 +2567,16 @@
- + 途中から作業を再開できること - + -
+
複数レポート識別しそれぞれを評価したい @@ -2582,18 +2584,18 @@
- + 複数レポート識別しそれぞれを評価したい - - - + + + -
+
ネットワークに接続しなくてもツールが使えること @@ -2601,15 +2603,15 @@
- + ネットワークに接続しなくてもツールが使えること - - - - + + + + @@ -2623,14 +2625,14 @@
- + manabaのエクスポートファイルをインポートできること
- - - + + + @@ -2642,17 +2644,17 @@
- + フィードバック情報を入力できること
- - + + -
+
対象外 @@ -2660,16 +2662,16 @@
- + 対象外 - + -
+
@@ -2679,17 +2681,17 @@
- + 6.システムユースケース図 - - + + -
+
@@ -2699,16 +2701,16 @@
- + 評価した結果をmanaba形式でエクスポートする - + -
+
@@ -2718,16 +2720,16 @@
- + 提出物を比較する - + -
+
提出物を表示する @@ -2735,16 +2737,16 @@
- + 提出物を表示する - + -
+
メモ情報を入力する @@ -2752,16 +2754,16 @@
- + メモ情報を入力する - + -
+
提出物を評点ごとに分類する @@ -2769,16 +2771,16 @@
- + 提出物を評点ごとに分類する - + -
+
提出物を評点内で順位付けする @@ -2786,17 +2788,17 @@
- + 提出物を評点内で順位付けする - - + + -
+
途中結果を一定間隔で保存する @@ -2804,16 +2806,16 @@
- + 途中結果を一定間隔で保存する - + -
+
途中から作業を再開する @@ -2821,16 +2823,16 @@
- + 途中から作業を再開する - + -
+
manabaのエクスポートファイルをインポートする @@ -2838,16 +2840,16 @@
- + manabaのエクスポートファイルをインポートする - + -
+
フィードバック情報を入力する @@ -2855,16 +2857,16 @@
- + フィードバック情報を入力する - + -
+
@@ -2874,25 +2876,25 @@
- + manakan - - - - - - - - - - + + + + + + + + + + -
+
提出物を回収する @@ -2900,17 +2902,17 @@
- + 提出物を回収する - - + + -
+
提出物を評価する(変更後) @@ -2918,26 +2920,26 @@
- + 提出物を評価する(変更後) - - - - - - - - - - - + + + + + + + + + + + -
+
manabaに点数を登録する @@ -2945,17 +2947,17 @@
- + manabaに点数を登録する - - + + -
+
request1 @@ -2963,17 +2965,17 @@
- + request1 - - + + -
+
request1 @@ -2981,17 +2983,17 @@
- + request1 - - + + -
+
request2 @@ -2999,17 +3001,17 @@
- + request2 - - + + -
+
request2 @@ -3017,17 +3019,17 @@
- + request2 - - + + -
+
request3 @@ -3035,17 +3037,17 @@
- + request3 - - + + -
+
request4 @@ -3053,17 +3055,17 @@
- + request4 - - + + -
+
request5 @@ -3071,17 +3073,17 @@
- + request5 - - + + -
+
request6 @@ -3089,17 +3091,17 @@
- + request6 - - + + -
+
request6 @@ -3107,17 +3109,17 @@
- + request6 - - + + -
+
request1 @@ -3125,17 +3127,17 @@
- + request1 - - + + -
+
request1 @@ -3143,16 +3145,16 @@
- + request1 - + -
+

@@ -3166,16 +3168,16 @@

- + 3. ToBeモデリング - + -
+
7.システムコンテキスト図(変更後) @@ -3183,19 +3185,19 @@
- + 7.システムコンテキスト図(変更後) - - - - + + + + -
+
学生 @@ -3203,21 +3205,21 @@
- + 学生 - - - - - - + + + + + + -
+
教員 @@ -3225,16 +3227,16 @@
- + 教員 - + -
+
manakan @@ -3242,16 +3244,16 @@
- + manakan - + -
+

@@ -3274,18 +3276,18 @@

- + システム化の目的教員の成績評価業務を支援する。学生が提出したレポートを相対的に評価してグラフィカルにグルーピングを行い、個人への点数付け調整を行う。... - - - + + + -
+
manaba @@ -3293,17 +3295,17 @@
- + manaba - - + + -
+
成績管理 @@ -3311,19 +3313,19 @@
- + 成績管理 - - - - + + + + -
+
事務員 @@ -3331,18 +3333,18 @@
- + 事務員 - - - + + + -
+

@@ -3361,22 +3363,22 @@

- + 教員%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%... - - - - - - - + + + + + + + -
+
新規作成? @@ -3384,17 +3386,17 @@
- + 新規作成? - - + + -
+
[評価を再開する] @@ -3402,17 +3404,17 @@
- + [評価を再開する] - - + + -
+
[新規作成する] @@ -3420,16 +3422,16 @@
- + [新規作成する] - + -
+
中間保存データを読み込む @@ -3437,16 +3439,16 @@
- + 中間保存データを読み込む - + -
+
manakanに提出物を @@ -3457,16 +3459,16 @@
- + manakanに提出物を... - + -
+
提出物を表示する @@ -3474,16 +3476,16 @@
- + 提出物を表示する - + -
+
フィードバック情報を入力する @@ -3491,16 +3493,16 @@
- + フィードバック情報を入力する - + -
+
メモを入力する @@ -3508,16 +3510,16 @@
- + メモを入力する - + -
+
提出物を評点ごとに分類する @@ -3525,16 +3527,16 @@
- + 提出物を評点ごとに分類する - + -
+
全件分類済? @@ -3542,17 +3544,17 @@
- + 全件分類済? - - + + -
+
[未分類がある] @@ -3560,17 +3562,17 @@
- + [未分類がある] - - + + -
+
[全て分類済] @@ -3578,16 +3580,16 @@
- + [全て分類済] - + -
+
全件調整済? @@ -3595,17 +3597,17 @@
- + 全件調整済? - - + + -
+
[全て調整済] @@ -3613,17 +3615,17 @@
- + [全て調整済] - - + + -
+
[未調整がある] @@ -3631,16 +3633,16 @@
- + [未調整がある] - + -
+
フィードバック情報を入力する @@ -3648,16 +3650,16 @@
- + フィードバック情報を入力する - + -
+
メモを入力する @@ -3665,16 +3667,16 @@
- + メモを入力する - + -
+
提出物の内容を比較する @@ -3682,16 +3684,16 @@
- + 提出物の内容を比較する - + -
+
提出物を評点ごとに分類する @@ -3699,16 +3701,16 @@
- + 提出物を評点ごとに分類する - + -
+
順位付けする @@ -3716,16 +3718,16 @@
- + 順位付けする - + -
+
Excelファイルをエクスポートする @@ -3733,67 +3735,67 @@
- + Excelファイルをエクスポートする - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
保存要求 @@ -3801,16 +3803,16 @@
- + 保存要求 - + -
+
保存する @@ -3818,19 +3820,19 @@
- + 保存する - - - - + + + + -
+
割り込み可能アクティビティ領域 @@ -3838,17 +3840,17 @@
- + 割り込み可能アクティビティ領域 - - + + -
+
8.情報モデル図 @@ -3856,18 +3858,18 @@
- + 8.情報モデル図 - - - + + + -
+
教員 @@ -3878,16 +3880,16 @@
- + 教員 - + -
+
manabaから提出物をエクスポートする @@ -3895,16 +3897,16 @@
- + manabaから提出物をエクスポートする - + -
+
manabaに集計Excelをインポートする @@ -3912,17 +3914,17 @@
- + manabaに集計Excelをインポートする - - + + -
+
@@ -3932,17 +3934,17 @@
- + manaba - - + + -
+
usecase1 @@ -3950,17 +3952,17 @@
- + usecase1 - - + + -
+
usecase2 @@ -3968,17 +3970,17 @@
- + usecase2 - - + + -
+
usecase3 @@ -3986,17 +3988,17 @@
- + usecase3 - - + + -
+
usecase4 @@ -4004,17 +4006,17 @@
- + usecase4 - - + + -
+
usecase6 @@ -4022,16 +4024,16 @@
- + usecase6 - + -
+
usecase7 @@ -4039,16 +4041,16 @@
- + usecase7 - + -
+
usecase8 @@ -4056,17 +4058,17 @@
- + usecase8 - - + + -
+
usecase9 @@ -4074,17 +4076,17 @@
- + usecase9 - - + + -
+
usecase5 @@ -4092,17 +4094,17 @@
- + usecase5 - - + + -
+
usecase10 @@ -4110,17 +4112,17 @@
- + usecase10 - - + + -
+
usecase3 @@ -4128,17 +4130,17 @@
- + usecase3 - - + + -
+
usecase4 @@ -4146,18 +4148,18 @@
- + usecase4 - - - + + + -
+
提出物を評価する(変更後) @@ -4165,16 +4167,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4182,16 +4184,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4199,16 +4201,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4216,16 +4218,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4233,16 +4235,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4250,16 +4252,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4267,16 +4269,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4284,16 +4286,16 @@
- + 提出物を評価する(変更後) - + -
+
提出物を評価する(変更後) @@ -4301,16 +4303,16 @@
- + 提出物を評価する(変更後) - + -
+
0..* @@ -4318,7 +4320,7 @@
- + 0..* @@ -4326,7 +4328,7 @@ -
+
1 @@ -4334,7 +4336,7 @@
- + @@ -4342,7 +4344,7 @@ -
+
設定する▶ @@ -4350,16 +4352,16 @@
- + 設定する▶ - + -
+
1 @@ -4367,7 +4369,7 @@
- + 1 @@ -4375,7 +4377,7 @@ -
+
0..* @@ -4383,7 +4385,7 @@
- + 0..* @@ -4391,7 +4393,7 @@ -
+
▼評価する @@ -4399,16 +4401,16 @@
- + ▼評価する - + -
+

@@ -4437,16 +4439,16 @@

- + 教員教員ユーザID... - + -
+

@@ -4474,16 +4476,16 @@

- + 全体評価評価状態インポート日時情報インポートファイルインポートフォルダ情報提出物一覧エクスポート日時情報エクスポートファイル... - + -
+

@@ -4509,16 +4511,16 @@

- + 個別評価フィードバック情報メモ情報評価状態順位情報点数情報評点... - + -
+
0..1 @@ -4526,7 +4528,7 @@
- + 0..1 @@ -4534,7 +4536,7 @@ -
+
◀提出 @@ -4542,7 +4544,7 @@
- + ◀提出 @@ -4550,7 +4552,7 @@ -
+
1 @@ -4558,16 +4560,16 @@
- + 1 - + -
+

@@ -4594,16 +4596,16 @@

- + 学生学生ユーザID... - + -
+
1 @@ -4611,7 +4613,7 @@
- + 1 @@ -4619,7 +4621,7 @@ -
+
1 @@ -4627,7 +4629,7 @@
- + 1 @@ -4635,7 +4637,7 @@ -
+
与えられる▶ @@ -4643,16 +4645,16 @@
- + 与えられる▶ - + -
+

@@ -4677,16 +4679,16 @@

- + 提出物ファイル情報タイトル情報内容情報提出者情報提出日時... - + -
+
1 @@ -4694,7 +4696,7 @@
- + 1 @@ -4702,7 +4704,7 @@ -
+
0..* @@ -4710,7 +4712,7 @@
- + 0..* @@ -4718,7 +4720,7 @@ -
+
◀含まれる @@ -4726,16 +4728,16 @@
- + ◀含まれる - + -
+
1 @@ -4743,7 +4745,7 @@
- + 1 @@ -4751,7 +4753,7 @@ -
+
0..1 @@ -4759,7 +4761,7 @@
- + 0..1 @@ -4767,7 +4769,7 @@ -
+
▲登録する @@ -4775,16 +4777,16 @@
- + ▲登録する - + -
+

@@ -4815,16 +4817,16 @@

- + レポートタイトルコース問題受付開始日時受付終了日時状態担当教員情報評価基準... - + -
+
1 @@ -4832,7 +4834,7 @@
- + 1 @@ -4840,7 +4842,7 @@ -
+
1..* @@ -4848,7 +4850,7 @@
- + 1..* @@ -4856,7 +4858,7 @@ -
+
調整する▶ @@ -4864,17 +4866,17 @@
- + 調整する▶ - - + + -
+
@@ -4888,16 +4890,16 @@
- + 提出物は複数ファイルある場合はフォルダを対象とするため学生に対しては1対1... - + -
+
1 @@ -4905,7 +4907,7 @@
- + 1 @@ -4913,7 +4915,7 @@ -
+
0..* @@ -4921,7 +4923,7 @@
- + 0..* @@ -4929,7 +4931,7 @@ -
+
含まれる▶ @@ -4937,17 +4939,17 @@
- + 含まれる▶ - - + + -
+
@@ -4963,17 +4965,17 @@
- + 科目のクラスを追加年度・科目名:情報アーキテクチャ特論... - - + + -
+
@@ -4986,17 +4988,17 @@
- + 概念レベルではmanabaではなく大学組織(シラバス)の言葉を基準にしてほしい... - - + + -
+
@@ -5013,16 +5015,16 @@
- + 概念レベルではレポートの情報が細かいXX日時、状態は省略できないか... - + -
+
画面設計 @@ -5030,20 +5032,20 @@
- + 画面設計 - - - - - + + + + + -
+
画面1 ホーム @@ -5051,16 +5053,16 @@
- + 画面1 ホーム - + -
+
manabaのエクスポートファイルをインポートする @@ -5068,16 +5070,16 @@
- + manabaのエクスポートファイルをインポートする - + -
+
途中から作業を再開する @@ -5085,22 +5087,22 @@
- + 途中から作業を再開する - - - - - - - + + + + + + + -
+
画面2 全体評価画面 @@ -5108,16 +5110,16 @@
- + 画面2 全体評価画面 - + -
+
提出物一覧を表示する @@ -5125,20 +5127,20 @@
- + 提出物一覧を表示する - - - - - + + + + + -
+
モーダル1 詳細レポート表示 @@ -5146,16 +5148,16 @@
- + モーダル1 詳細レポート表示 - + -
+
提出物を表示する @@ -5163,16 +5165,16 @@
- + 提出物を表示する - + -
+
メモ情報を入力する @@ -5180,16 +5182,16 @@
- + メモ情報を入力する - + -
+
フィードバック情報を入力する @@ -5197,16 +5199,16 @@
- + フィードバック情報を入力する - + -
+
提出物を評点ごとに分類する @@ -5214,18 +5216,18 @@
- + 提出物を評点ごとに分類する - - - + + + -
+
全画面共通 @@ -5233,16 +5235,16 @@
- + 全画面共通 - + -
+
途中結果を一定間隔で保存する @@ -5250,18 +5252,18 @@
- + 途中結果を一定間隔で保存する - - - + + + -
+
画面3 相対評価ページ @@ -5269,16 +5271,16 @@
- + 画面3 相対評価ページ - + -
+
@@ -5288,16 +5290,16 @@
- + 評価した結果をmanaba形式でエクスポートする - + -
+
@@ -5307,16 +5309,16 @@
- + 提出物を比較する - + -
+
提出物を評点内で順位付けする @@ -5324,19 +5326,19 @@
- + 提出物を評点内で順位付けする - - - - + + + + -
+
:ユーザ @@ -5347,20 +5349,20 @@
- + :ユーザ インターフェース - - - - + + + + -
+
:アップロード @@ -5368,21 +5370,21 @@
- + :アップロード - - - - - - + + + + + + -
+
教員 @@ -5390,17 +5392,17 @@
- + 教員 - - + + -
+
1:起動 @@ -5408,20 +5410,20 @@
- + 1:起動 - - - - - + + + + + -
+
2:提出物ファイル提示 @@ -5429,19 +5431,19 @@
- + 2:提出物ファイル提示 - - - - + + + + -
+
2.1:インポート条件確認 @@ -5449,16 +5451,16 @@
- + 2.1:インポート条件確認 - + -
+
:提出物 @@ -5466,22 +5468,22 @@
- + :提出物 - - - - - - - + + + + + + + -
+
2.1:インポート実施 @@ -5489,18 +5491,18 @@
- + 2.1:インポート実施 - - - + + + -
+
2.1:提出物記録実施 @@ -5508,24 +5510,24 @@
- + 2.1:提出物記録実施 - - - - - - - - - + + + + + + + + + -
+
1:起動 @@ -5533,20 +5535,20 @@
- + 1:起動 - - - - - + + + + + -
+
:作業データ @@ -5554,17 +5556,17 @@
- + :作業データ - - + + -
+
1:作業データ取得可能? @@ -5572,19 +5574,19 @@
- + 1:作業データ取得可能? - - - - + + + + -
+
1:作業データ取得 @@ -5592,25 +5594,25 @@
- + 1:作業データ取得 - - - - - - - - - - + + + + + + + + + + -
+
:ユーザ @@ -5621,20 +5623,20 @@
- + :ユーザ インターフェース - - - - + + + + -
+
提出物 @@ -5642,21 +5644,21 @@
- + 提出物 - - - - - - + + + + + + -
+
教員 @@ -5664,17 +5666,17 @@
- + 教員 - - + + -
+
1:起動 @@ -5682,19 +5684,19 @@
- + 1:起動 - - - - + + + + -
+
1:レポート選択提示 @@ -5702,19 +5704,19 @@
- + 1:レポート選択提示 - - - - + + + + -
+
2:レポート提示実施 @@ -5722,16 +5724,16 @@
- + 2:レポート提示実施 - + -
+
ファイルの有無も確認すべきか?空を返すべき? @@ -5739,23 +5741,23 @@
- + ファイルの有無も確認すべきか?空を返すべき? - - - - - - - - + + + + + + + + -
+
:ユーザ @@ -5766,20 +5768,20 @@
- + :ユーザ インターフェース - - - - + + + + -
+
レポート @@ -5787,21 +5789,21 @@
- + レポート - - - - - - + + + + + + -
+
教員 @@ -5809,17 +5811,17 @@
- + 教員 - - + + -
+
1:起動 @@ -5827,19 +5829,19 @@
- + 1:起動 - - - - + + + + -
+
1:レポート選択提示 @@ -5847,19 +5849,19 @@
- + 1:レポート選択提示 - - - - + + + + -
+
2:レポート提示実施 @@ -5867,20 +5869,20 @@
- + 2:レポート提示実施 - - - - - + + + + + -
+
個別評価 @@ -5888,20 +5890,20 @@
- + 個別評価 - - - - - + + + + + -
+
2:個別評価取得実施 @@ -5909,27 +5911,27 @@
- + 2:個別評価取得実施 - - - - - - - - - - - - + + + + + + + + + + + + -
+
2:個別評価更新実施 @@ -5937,17 +5939,17 @@
- + 2:個別評価更新実施 - - + + -
+
2:個別評価更新実施 @@ -5955,18 +5957,18 @@
- + 2:個別評価更新実施 - - - + + + -
+
フィードバック情報状態 @@ -5974,18 +5976,18 @@
- + フィードバック情報状態 - - - + + + -
+
コメント未記載 @@ -5993,16 +5995,16 @@
- + コメント未記載 - + -
+
usecase4 @@ -6010,20 +6012,20 @@
- + usecase4 - - - - - + + + + + -
+
コメント記載済み @@ -6031,16 +6033,16 @@
- + コメント記載済み - + -
+
usecase3 @@ -6048,16 +6050,16 @@
- + usecase3 - + -
+
個別/全体評価状態 @@ -6065,23 +6067,23 @@
- + 個別/全体評価状態 - - - - - - - - + + + + + + + + -
+
メモ未記載 @@ -6089,18 +6091,18 @@
- + メモ未記載 - - - + + + -
+
メモ記載済み @@ -6108,23 +6110,23 @@
- + メモ記載済み - - - - - - - - + + + + + + + + -
+
全体評価中 @@ -6132,21 +6134,21 @@
- + 全体評価中 - - - - - - + + + + + + -
+
全体未評価 @@ -6154,16 +6156,16 @@
- + 全体未評価 - + -
+
個別評価中 @@ -6171,16 +6173,16 @@
- + 個別評価中 - + -
+
評点分類中 @@ -6188,18 +6190,18 @@
- + 評点分類中 - - - + + + -
+
個別未評価 @@ -6207,16 +6209,16 @@
- + 個別未評価 - + -
+
評点未分類 @@ -6224,16 +6226,16 @@
- + 評点未分類 - + -
+
評点分類済み @@ -6241,17 +6243,17 @@
- + 評点分類済み - - + + -
+
個別評価を終了する @@ -6259,16 +6261,16 @@
- + 個別評価を終了する - + -
+
順位付け中 @@ -6276,18 +6278,18 @@
- + 順位付け中 - - - + + + -
+
評点分類済み @@ -6295,16 +6297,16 @@
- + 評点分類済み - + -
+
順位付け済み @@ -6312,20 +6314,20 @@
- + 順位付け済み - - - - - + + + + + -
+
全体評価済み @@ -6333,18 +6335,18 @@
- + 全体評価済み - - - + + + -
+
usecase5 @@ -6352,16 +6354,16 @@
- + usecase5 - + -
+
usecase6 @@ -6369,17 +6371,17 @@
- + usecase6 - - + + -
+
@@ -6395,17 +6397,17 @@
- + 点数付けの状態も書いたほうがよい?(業務フローに載せていなかった)=> 点数付けまで入れるかは中鉢先生ヒアリング後に決定する。... - - + + -
+
情報には、提出物一覧に提出状態の記載があったがユースケース関連してこない(manakanスコープ外では?)なので、記載していない。 @@ -6413,16 +6415,16 @@
- + 情報には、提出物一覧に提出状態の記載があったがユースケース関連してこない(manakanスコープ外では?)なので、記載していない。 - + -
+
@@ -6432,16 +6434,16 @@
- + 型図 - + -
+
0..* @@ -6449,7 +6451,7 @@
- + 0..* @@ -6457,7 +6459,7 @@ -
+
1 @@ -6465,7 +6467,7 @@
- + @@ -6473,7 +6475,7 @@ -
+
設定する▶ @@ -6481,16 +6483,16 @@
- + 設定する▶ - + -
+
1 @@ -6498,7 +6500,7 @@
- + 1 @@ -6506,7 +6508,7 @@ -
+
0..* @@ -6514,7 +6516,7 @@
- + 0..* @@ -6522,7 +6524,7 @@ -
+
▼評価する @@ -6530,16 +6532,16 @@
- + ▼評価する - + -
+

@@ -6568,16 +6570,16 @@

- + 教員教員ユーザID... - + -
+

@@ -6605,16 +6607,16 @@

- + 全体評価評価状態インポート日時情報インポートファイルインポートフォルダ情報提出物一覧エクスポート日時情報エクスポートファイル... - + -
+

@@ -6640,16 +6642,16 @@

- + 個別評価フィードバック情報メモ情報評価状態順位情報点数情報評点... - + -
+
0..1 @@ -6657,7 +6659,7 @@
- + 0..1 @@ -6665,7 +6667,7 @@ -
+
◀提出 @@ -6673,7 +6675,7 @@
- + ◀提出 @@ -6681,7 +6683,7 @@ -
+
1 @@ -6689,16 +6691,16 @@
- + 1 - + -
+

@@ -6725,16 +6727,16 @@

- + 学生学生ユーザID... - + -
+
1 @@ -6742,7 +6744,7 @@
- + 1 @@ -6750,7 +6752,7 @@ -
+
1 @@ -6758,7 +6760,7 @@
- + 1 @@ -6766,7 +6768,7 @@ -
+
与えられる▶ @@ -6774,16 +6776,16 @@
- + 与えられる▶ - + -
+

@@ -6808,16 +6810,16 @@

- + 提出物ファイル情報タイトル情報内容情報提出者情報提出日時... - + -
+
1 @@ -6825,7 +6827,7 @@
- + 1 @@ -6833,7 +6835,7 @@ -
+
0..* @@ -6841,7 +6843,7 @@
- + 0..* @@ -6849,7 +6851,7 @@ -
+
◀含まれる @@ -6857,16 +6859,16 @@
- + ◀含まれる - + -
+
1 @@ -6874,7 +6876,7 @@
- + 1 @@ -6882,7 +6884,7 @@ -
+
0..1 @@ -6890,7 +6892,7 @@
- + 0..1 @@ -6898,7 +6900,7 @@ -
+
▲登録する @@ -6906,16 +6908,16 @@
- + ▲登録する - + -
+

@@ -6946,16 +6948,16 @@

- + レポートタイトルコース問題受付開始日時受付終了日時状態担当教員情報評価基準... - + -
+
1 @@ -6963,7 +6965,7 @@
- + 1 @@ -6971,7 +6973,7 @@ -
+
1..* @@ -6979,7 +6981,7 @@
- + 1..* @@ -6987,7 +6989,7 @@ -
+
調整する▶ @@ -6995,17 +6997,17 @@
- + 調整する▶ - - + + -
+
@@ -7019,16 +7021,16 @@
- + 提出物は複数ファイルある場合はフォルダを対象とするため学生に対しては1対1... - + -
+
1 @@ -7036,7 +7038,7 @@
- + 1 @@ -7044,7 +7046,7 @@ -
+
0..* @@ -7052,7 +7054,7 @@
- + 0..* @@ -7060,7 +7062,7 @@ -
+
含まれる▶ @@ -7068,17 +7070,17 @@
- + 含まれる▶ - - + + -
+
@@ -7094,17 +7096,17 @@
- + 科目のクラスを追加年度・科目名:情報アーキテクチャ特論... - - + + -
+
@@ -7117,17 +7119,17 @@
- + 概念レベルではmanabaではなく大学組織(シラバス)の言葉を基準にしてほしい... - - + + -
+
@@ -7144,16 +7146,16 @@
- + 概念レベルではレポートの情報が細かいXX日時、状態は省略できないか... - + -
+
レポート @@ -7161,16 +7163,16 @@
- + レポート - + -
+
提出物 @@ -7178,16 +7180,16 @@
- + 提出物 - + -
+
採点 @@ -7195,16 +7197,16 @@
- + 採点 - + -
+
インポート @@ -7212,16 +7214,16 @@
- + インポート - + -
+
エクスポート @@ -7229,16 +7231,16 @@
- + エクスポート - + -
+
manaba @@ -7246,16 +7248,16 @@
- + manaba - + -
+
manakan @@ -7263,16 +7265,16 @@
- + manakan - + -
+
学生 @@ -7280,16 +7282,16 @@
- + 学生 - + -
+
教員 @@ -7297,16 +7299,16 @@
- + 教員 - + -
+
分類 @@ -7314,16 +7316,16 @@
- + 分類 - + -
+
入力 @@ -7331,16 +7333,16 @@
- + 入力 - + -
+
usecase4 @@ -7348,16 +7350,16 @@
- + usecase4 - + -
+
評価 @@ -7365,16 +7367,16 @@
- + 評価 - + -
+
素点 @@ -7382,16 +7384,16 @@
- + 素点 - + -
+
フィードバック @@ -7399,16 +7401,16 @@
- + フィードバック - + -
+
コメント @@ -7416,16 +7418,16 @@
- + コメント - + -
+
点数 @@ -7433,16 +7435,16 @@
- + 点数 - + -
+
保存 @@ -7450,16 +7452,16 @@
- + 保存 - + -
+
全レポート @@ -7467,16 +7469,16 @@
- + 全レポート - + -
+
中間状態 @@ -7484,16 +7486,16 @@
- + 中間状態 - + -
+
比較 @@ -7501,16 +7503,16 @@
- + 比較 - + -
+
順位付け @@ -7518,16 +7520,16 @@
- + 順位付け - + -
+
メモ @@ -7535,16 +7537,16 @@
- + メモ - + -
+
微調整 @@ -7552,16 +7554,16 @@
- + 微調整 - + -
+
登録 @@ -7569,16 +7571,16 @@
- + 登録 - + -
+
エクスポート @@ -7588,17 +7590,17 @@
- + エクスポート ファイル - + -
+
開く @@ -7606,16 +7608,16 @@
- + 開く - + -
+
表示 @@ -7623,16 +7625,16 @@
- + 表示 - + -
+
中断 @@ -7640,16 +7642,16 @@
- + 中断 - + -
+
GPA @@ -7657,16 +7659,16 @@
- + GPA - + -
+
科目 @@ -7674,20 +7676,20 @@
- + 科目 - - - - - + + + + + -
+
usecase3 @@ -7695,16 +7697,16 @@
- + usecase3 - + -
+
usecase6 @@ -7712,26 +7714,26 @@
- + usecase6 - - - - - - - - - - - + + + + + + + + + + + -
+
H* @@ -7739,18 +7741,18 @@
- + H* - - - + + + -
+
H* @@ -7758,17 +7760,17 @@
- + H* - - + + -
+
@@ -7781,19 +7783,19 @@
- + 個別評価の途中保存を作るか (自動保存があるなら作るべきか) - - - + + + -
+
usecase5 @@ -7801,17 +7803,17 @@
- + usecase5 - - + + -
+
@@ -7821,17 +7823,17 @@
- + 分類の更新 - - + + -
+
@@ -7841,22 +7843,22 @@
- + 順位の更新 - - - - - - - + + + + + + + -
+
全体評価を終了する @@ -7864,22 +7866,22 @@
- + 全体評価を終了する - - - - - - - + + + + + + + -
+
他の学生の評価をする @@ -7887,23 +7889,23 @@
- + 他の学生の評価をする - - - - - - - - + + + + + + + + -
+
他の学生を @@ -7914,18 +7916,18 @@
- + 他の学生を 評価する - - + + -
+
個別評価済み @@ -7933,24 +7935,24 @@
- + 個別評価済み - - - - - - - - - + + + + + + + + + -
+
個別評価の保存 @@ -7961,19 +7963,19 @@
- + 個別評価の保存 (自動保存) - - - + + + -
+
全体評価の保存 @@ -7984,19 +7986,19 @@
- + 全体評価の保存 (自動保存) - - - + + + -
+
usecase8 @@ -8004,16 +8006,16 @@
- + usecase8 - + -
+
usecase8 @@ -8021,16 +8023,16 @@
- + usecase8 - + -
+
usecase9 @@ -8038,16 +8040,16 @@
- + usecase9 - + -
+
usecase9 @@ -8055,17 +8057,17 @@
- + usecase9 - - + + -
+
順位付けをやり直す @@ -8073,17 +8075,17 @@
- + 順位付けをやり直す - - + + -
+
評点分類をやり直す @@ -8091,17 +8093,17 @@
- + 評点分類をやり直す - - + + -
+
差分確認(後で消す) @@ -8109,11 +8111,150 @@
- + 差分確認(後で消す) + + + + + +
+
+
+
+ どの提出物を見直すか記録すること +
+
+
+
+
+ + どの提出物を見直すか記録すること + +
+
+ + + + +
+
+
+ 提出物を評価する(変更後) +
+
+
+
+ + 提出物を評価する(変更後) + +
+
+ + + + + +
+
+
+
+ 提出物にブックマークを付ける +
+
+
+
+
+ + 提出物にブックマークを付ける + +
+
+ + + + + +
+
+
+ usecase11 +
+
+
+
+ + usecase11 + +
+
+ + + + +
+
+
+ 見返したい提出物に +
+ ブックマークする +
+
+
+
+ + 見返したい提出物に +ブックマークする + +
+
+ + + + + + + +
+
+
+ 見返したい提出物に +
+ ブックマークする +
+
+
+
+ + 見返したい提出物に +ブックマークする + +
+
+ + + + + + + + +
+
+
+ usecase11 +
+
+
+
+ + usecase11 + +
+
diff --git a/vite.base.config.ts b/vite.base.config.ts index 25120d9..e6c94d6 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -1,14 +1,22 @@ -import { builtinModules } from 'node:module'; -import type { AddressInfo } from 'node:net'; -import type { ConfigEnv, Plugin, UserConfig } from 'vite'; -import pkg from './package.json'; +import { builtinModules } from 'node:module' +import type { AddressInfo } from 'node:net' +import type { ConfigEnv, Plugin, UserConfig } from 'vite' +import pkg from './package.json' -export const builtins = ['electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat()]; +export const builtins = [ + 'electron', + ...builtinModules.map((m) => [m, `node:${m}`]).flat(), +] -export const external = [...builtins, ...Object.keys('dependencies' in pkg ? (pkg.dependencies as Record) : {})]; +export const external = [ + ...builtins, + ...Object.keys( + 'dependencies' in pkg ? (pkg.dependencies as Record) : {} + ), +] export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig { - const { root, mode, command } = env; + const { root, mode, command } = env return { root, @@ -22,56 +30,68 @@ export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig { minify: command === 'build', }, clearScreen: false, - }; + resolve: { + alias: { + src: '/src', + }, + }, + } } export function getDefineKeys(names: string[]) { - const define: { [name: string]: VitePluginRuntimeKeys } = {}; + const define: { [name: string]: VitePluginRuntimeKeys } = {} return names.reduce((acc, name) => { - const NAME = name.toUpperCase(); + const NAME = name.toUpperCase() const keys: VitePluginRuntimeKeys = { VITE_DEV_SERVER_URL: `${NAME}_VITE_DEV_SERVER_URL`, VITE_NAME: `${NAME}_VITE_NAME`, - }; + } - return { ...acc, [name]: keys }; - }, define); + return { ...acc, [name]: keys } + }, define) } export function getBuildDefine(env: ConfigEnv<'build'>) { - const { command, forgeConfig } = env; - const names = forgeConfig.renderer.filter(({ name }) => name != null).map(({ name }) => name!); - const defineKeys = getDefineKeys(names); + const { command, forgeConfig } = env + const names = forgeConfig.renderer + .filter(({ name }) => name != null) + .map(({ name }) => name!) + const defineKeys = getDefineKeys(names) const define = Object.entries(defineKeys).reduce((acc, [name, keys]) => { - const { VITE_DEV_SERVER_URL, VITE_NAME } = keys; + const { VITE_DEV_SERVER_URL, VITE_NAME } = keys const def = { - [VITE_DEV_SERVER_URL]: command === 'serve' ? JSON.stringify(process.env[VITE_DEV_SERVER_URL]) : undefined, + [VITE_DEV_SERVER_URL]: + command === 'serve' + ? JSON.stringify(process.env[VITE_DEV_SERVER_URL]) + : undefined, [VITE_NAME]: JSON.stringify(name), - }; - return { ...acc, ...def }; - }, {} as Record); + } + return { ...acc, ...def } + }, {} as Record) - return define; + return define } export function pluginExposeRenderer(name: string): Plugin { - const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name]; + const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name] return { name: '@electron-forge/plugin-vite:expose-renderer', configureServer(server) { - process.viteDevServers ??= {}; + process.viteDevServers ??= {} // Expose server for preload scripts hot reload. - process.viteDevServers[name] = server; + process.viteDevServers[name] = server server.httpServer?.once('listening', () => { - const addressInfo = server.httpServer!.address() as AddressInfo; + const addressInfo = server.httpServer!.address() as AddressInfo // Expose env constant for main process use. - process.env[VITE_DEV_SERVER_URL] = `http://localhost:${addressInfo?.port}`; - }); + process.env[ + VITE_DEV_SERVER_URL + ] = `http://localhost:${addressInfo?.port}` + }) }, - }; + } } export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { @@ -81,13 +101,13 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { if (command === 'reload') { for (const server of Object.values(process.viteDevServers)) { // Preload scripts hot reload. - server.ws.send({ type: 'full-reload' }); + server.ws.send({ type: 'full-reload' }) } } else { // Main process hot restart. // https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223 - process.stdin.emit('data', 'rs'); + process.stdin.emit('data', 'rs') } }, - }; + } } diff --git a/vite.main.config.ts b/vite.main.config.ts index a4b3769..21e8ee4 100644 --- a/vite.main.config.ts +++ b/vite.main.config.ts @@ -1,12 +1,17 @@ -import type { ConfigEnv, UserConfig } from 'vite'; -import { defineConfig, mergeConfig } from 'vite'; -import { getBuildConfig, getBuildDefine, external, pluginHotRestart } from './vite.base.config'; +import type { ConfigEnv, UserConfig } from 'vite' +import { defineConfig, mergeConfig } from 'vite' +import { + getBuildConfig, + getBuildDefine, + external, + pluginHotRestart, +} from './vite.base.config' // https://vitejs.dev/config export default defineConfig((env) => { - const forgeEnv = env as ConfigEnv<'build'>; - const { forgeConfigSelf } = forgeEnv; - const define = getBuildDefine(forgeEnv); + const forgeEnv = env as ConfigEnv<'build'> + const { forgeConfigSelf } = forgeEnv + const define = getBuildDefine(forgeEnv) const config: UserConfig = { build: { lib: { @@ -23,8 +28,11 @@ export default defineConfig((env) => { resolve: { // Load the Node.js entry. mainFields: ['module', 'jsnext:main', 'jsnext'], + alias: { + src: '/src', + }, }, - }; + } - return mergeConfig(getBuildConfig(forgeEnv), config); -}); + return mergeConfig(getBuildConfig(forgeEnv), config) +}) diff --git a/vite.preload.config.ts b/vite.preload.config.ts index 3cbadf6..4f0191a 100644 --- a/vite.preload.config.ts +++ b/vite.preload.config.ts @@ -1,11 +1,11 @@ -import type { ConfigEnv, UserConfig } from 'vite'; -import { defineConfig, mergeConfig } from 'vite'; -import { getBuildConfig, external, pluginHotRestart } from './vite.base.config'; +import type { ConfigEnv, UserConfig } from 'vite' +import { defineConfig, mergeConfig } from 'vite' +import { getBuildConfig, external, pluginHotRestart } from './vite.base.config' // https://vitejs.dev/config export default defineConfig((env) => { - const forgeEnv = env as ConfigEnv<'build'>; - const { forgeConfigSelf } = forgeEnv; + const forgeEnv = env as ConfigEnv<'build'> + const { forgeConfigSelf } = forgeEnv const config: UserConfig = { build: { rollupOptions: { @@ -23,7 +23,12 @@ export default defineConfig((env) => { }, }, plugins: [pluginHotRestart('reload')], - }; + resolve: { + alias: { + src: '/src', + }, + }, + } - return mergeConfig(getBuildConfig(forgeEnv), config); -}); + return mergeConfig(getBuildConfig(forgeEnv), config) +}) diff --git a/vite.renderer.config.ts b/vite.renderer.config.ts index e821a3b..7e6ec70 100644 --- a/vite.renderer.config.ts +++ b/vite.renderer.config.ts @@ -1,12 +1,12 @@ -import type { ConfigEnv, UserConfig } from 'vite'; -import { defineConfig } from 'vite'; -import { pluginExposeRenderer } from './vite.base.config'; +import type { ConfigEnv, UserConfig } from 'vite' +import { defineConfig } from 'vite' +import { pluginExposeRenderer } from './vite.base.config' // https://vitejs.dev/config export default defineConfig((env) => { - const forgeEnv = env as ConfigEnv<'renderer'>; - const { root, mode, forgeConfigSelf } = forgeEnv; - const name = forgeConfigSelf.name ?? ''; + const forgeEnv = env as ConfigEnv<'renderer'> + const { root, mode, forgeConfigSelf } = forgeEnv + const name = forgeConfigSelf.name ?? '' return { root, @@ -18,7 +18,10 @@ export default defineConfig((env) => { plugins: [pluginExposeRenderer(name)], resolve: { preserveSymlinks: true, + alias: { + src: '/src', + }, }, clearScreen: false, - } as UserConfig; -}); + } as UserConfig +})