aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rw-r--r--frontend/angular.json3
-rw-r--r--frontend/package-lock.json361
-rw-r--r--frontend/package.json13
-rw-r--r--frontend/src/app/_data/Model.ts53
-rw-r--r--frontend/src/app/_elements/dataset-load/dataset-load.component.css0
-rw-r--r--frontend/src/app/_elements/dataset-load/dataset-load.component.html42
-rw-r--r--frontend/src/app/_elements/dataset-load/dataset-load.component.spec.ts25
-rw-r--r--frontend/src/app/_elements/dataset-load/dataset-load.component.ts54
-rw-r--r--frontend/src/app/_modals/login-modal/login-modal.component.css0
-rw-r--r--frontend/src/app/_modals/login-modal/login-modal.component.html49
-rw-r--r--frontend/src/app/_modals/login-modal/login-modal.component.spec.ts25
-rw-r--r--frontend/src/app/_modals/login-modal/login-modal.component.ts51
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.css0
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.html189
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.spec.ts25
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.ts32
-rw-r--r--frontend/src/app/_pages/login-page/login-page.component.html38
-rw-r--r--frontend/src/app/_pages/login-page/login-page.component.ts55
-rw-r--r--frontend/src/app/_pages/register-page/register-page.component.ts16
-rw-r--r--frontend/src/app/_services/auth.service.ts2
-rw-r--r--frontend/src/app/app-routing.module.ts9
-rw-r--r--frontend/src/app/app.module.ts17
-rw-r--r--frontend/src/app/material.module.ts18
-rw-r--r--frontend/src/custom-theme.scss35
-rw-r--r--frontend/src/index.html5
-rw-r--r--frontend/src/styles.css6
26 files changed, 1009 insertions, 114 deletions
diff --git a/frontend/angular.json b/frontend/angular.json
index edf0140f..bbbe3eaa 100644
--- a/frontend/angular.json
+++ b/frontend/angular.json
@@ -27,10 +27,11 @@
"src/assets"
],
"styles": [
+ "src/custom-theme.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
- "scripts": []
+ "scripts": ["node_modules/bootstrap/dist/js/bootstrap.min.js"]
},
"configurations": {
"production": {
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 2bc6994f..ffe47b6a 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -7,13 +7,16 @@
"": {
"name": "frontend",
"version": "0.0.0",
+ "hasInstallScript": true,
"dependencies": {
"@angular/animations": "~13.2.0",
+ "@angular/cdk": "^13.2.6",
"@angular/common": "~13.2.0",
"@angular/compiler": "~13.2.0",
"@angular/core": "~13.2.0",
"@angular/forms": "~13.2.0",
"@angular/localize": "~13.2.0",
+ "@angular/material": "^13.2.6",
"@angular/platform-browser": "~13.2.0",
"@angular/platform-browser-dynamic": "~13.2.0",
"@angular/router": "~13.2.0",
@@ -21,7 +24,11 @@
"@ng-bootstrap/ng-bootstrap": "^12.0.0",
"@popperjs/core": "^2.10.2",
"bootstrap": "^5.1.3",
+ "csv-parser": "^3.0.0",
+ "mdb-angular-ui-kit": "^2.0.0",
+ "ng-uikit-pro-standard": "^1.0.0",
"ngx-cookie-service": "^13.1.2",
+ "ngx-csv-parser": "^0.0.7",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
@@ -334,9 +341,9 @@
"dev": true
},
"node_modules/@angular/animations": {
- "version": "13.2.5",
- "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.5.tgz",
- "integrity": "sha512-1mGOePSDTiVwNIuV2g3+mUHrZJAkqJVzRKqKyNPXdwZupzVAgAfLbfUC07hhD/H53mXupIVugcUMFC3dvMu7uQ==",
+ "version": "13.2.6",
+ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.6.tgz",
+ "integrity": "sha512-DrjpKo68uR3lSLQQXosoTCbjKQS6IKRCpR14E2t8fo0AX8i2hkB8je4SrhdCyB7FgFN7l2kgUYo4Qa8+BOB+aA==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -344,9 +351,31 @@
"node": "^12.20.0 || ^14.15.0 || >=16.10.0"
},
"peerDependencies": {
- "@angular/core": "13.2.5"
+ "@angular/core": "13.2.6"
+ }
+ },
+ "node_modules/@angular/cdk": {
+ "version": "13.2.6",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.2.6.tgz",
+ "integrity": "sha512-epuXmaHqfukwPsYvIksbuHLXDtb6GALV2Vgv6W2asj4TorD584CeQTs0EcdPGmCzhGUYI8U8QV63WOxu9YFcNA==",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "optionalDependencies": {
+ "parse5": "^5.0.0"
+ },
+ "peerDependencies": {
+ "@angular/common": "^13.0.0 || ^14.0.0-0",
+ "@angular/core": "^13.0.0 || ^14.0.0-0",
+ "rxjs": "^6.5.3 || ^7.4.0"
}
},
+ "node_modules/@angular/cdk/node_modules/parse5": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "optional": true
+ },
"node_modules/@angular/cli": {
"version": "13.2.5",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.2.5.tgz",
@@ -413,6 +442,7 @@
"version": "13.2.5",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.2.5.tgz",
"integrity": "sha512-Xd8xj2Z0ilA4TJAM/JkTtA1CAa6SuebFsEEvabHCRO5MDvtdsIUP91ADUZIqDHy7qe6Qift/rAVN2PXxT2aaNA==",
+ "dev": true,
"dependencies": {
"@babel/core": "^7.17.2",
"chokidar": "^3.0.0",
@@ -442,6 +472,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz",
"integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==",
+ "dev": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.0"
},
@@ -453,6 +484,7 @@
"version": "7.17.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz",
"integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==",
+ "dev": true,
"dependencies": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.16.7",
@@ -482,6 +514,7 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
"bin": {
"semver": "bin/semver.js"
}
@@ -490,6 +523,7 @@
"version": "7.17.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz",
"integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==",
+ "dev": true,
"dependencies": {
"@babel/types": "^7.17.0",
"jsesc": "^2.5.1",
@@ -503,6 +537,7 @@
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -630,6 +665,23 @@
"node": ">=0.10.0"
}
},
+ "node_modules/@angular/material": {
+ "version": "13.2.6",
+ "resolved": "https://registry.npmjs.org/@angular/material/-/material-13.2.6.tgz",
+ "integrity": "sha512-/h5wa/tXE0DMIIEQX+rozFkUWHYUWg1Xf1R2tXUFLslLQ0KRCGyNo225Sv/1wrxXHxfrML787lA9ex4p90Feqw==",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "peerDependencies": {
+ "@angular/animations": "^13.0.0 || ^14.0.0-0",
+ "@angular/cdk": "13.2.6",
+ "@angular/common": "^13.0.0 || ^14.0.0-0",
+ "@angular/core": "^13.0.0 || ^14.0.0-0",
+ "@angular/forms": "^13.0.0 || ^14.0.0-0",
+ "@angular/platform-browser": "^13.0.0 || ^14.0.0-0",
+ "rxjs": "^6.5.3 || ^7.4.0"
+ }
+ },
"node_modules/@angular/platform-browser": {
"version": "13.2.5",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.2.5.tgz",
@@ -725,6 +777,7 @@
"version": "7.16.12",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz",
"integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==",
+ "dev": true,
"dependencies": {
"@babel/code-frame": "^7.16.7",
"@babel/generator": "^7.16.8",
@@ -754,6 +807,7 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
"bin": {
"semver": "bin/semver.js"
}
@@ -762,6 +816,7 @@
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -770,6 +825,7 @@
"version": "7.16.8",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz",
"integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==",
+ "dev": true,
"dependencies": {
"@babel/types": "^7.16.8",
"jsesc": "^2.5.1",
@@ -783,6 +839,7 @@
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3209,6 +3266,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -3482,6 +3540,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
"engines": {
"node": ">=8"
}
@@ -3578,6 +3637,7 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
"dependencies": {
"fill-range": "^7.0.1"
},
@@ -3750,6 +3810,7 @@
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
"funding": [
{
"type": "individual",
@@ -4483,6 +4544,20 @@
"node": ">=4"
}
},
+ "node_modules/csv-parser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.0.0.tgz",
+ "integrity": "sha512-s6OYSXAK3IdKqYO33y09jhypG/bSDHPuyCme/IdEHfWpLf/jKcpitVFyOC6UemgGk8v7Q5u2XE0vvwmanxhGlQ==",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "csv-parser": "bin/csv-parser"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/custom-event": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
@@ -4661,6 +4736,7 @@
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
"integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
+ "dev": true,
"engines": {
"node": ">= 0.6.0"
}
@@ -5609,6 +5685,7 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -5777,6 +5854,7 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
@@ -5886,6 +5964,7 @@
"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": {
"is-glob": "^4.0.1"
},
@@ -6478,6 +6557,7 @@
"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"
},
@@ -6531,6 +6611,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -6547,6 +6628,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
@@ -6573,6 +6655,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
"engines": {
"node": ">=0.12.0"
}
@@ -7428,6 +7511,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -7439,6 +7523,7 @@
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+ "dev": true,
"dependencies": {
"sourcemap-codec": "^1.4.4"
}
@@ -7494,6 +7579,21 @@
"node": ">= 10"
}
},
+ "node_modules/mdb-angular-ui-kit": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdb-angular-ui-kit/-/mdb-angular-ui-kit-2.0.0.tgz",
+ "integrity": "sha512-atwGldhGszfrWvQBcmaxhTPV4XjvbaJ030Ma6XAbPsdtN2UZio5qPlCb6sJHAGQOKusVq++4EmtYYnT0u51bLg==",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "@angular/animations": "^13.0.0",
+ "@angular/cdk": "^13.0.0",
+ "@angular/common": "^13.0.0",
+ "@angular/core": "^13.0.0",
+ "@angular/forms": "^13.0.0"
+ }
+ },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -7857,6 +7957,23 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
+ "node_modules/ng-uikit-pro-standard": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ng-uikit-pro-standard/-/ng-uikit-pro-standard-1.0.0.tgz",
+ "integrity": "sha512-GaG4Ek8pJRdHdr6JtkE4mHMvhb619mJI9VOIXKas4F0iGRyTb7U4rc2Y9AFgsysOYBZKCYifSzKxCf3NukZj0w==",
+ "dependencies": {
+ "tslib": "^1.9.0"
+ },
+ "peerDependencies": {
+ "@angular/common": "^8.0.0",
+ "@angular/core": "^8.0.0"
+ }
+ },
+ "node_modules/ng-uikit-pro-standard/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
"node_modules/ngx-cookie-service": {
"version": "13.1.2",
"resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-13.1.2.tgz",
@@ -7869,6 +7986,23 @@
"@angular/core": "^13.0.0"
}
},
+ "node_modules/ngx-csv-parser": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ngx-csv-parser/-/ngx-csv-parser-0.0.7.tgz",
+ "integrity": "sha512-KCos2rxjkPqw/gQfd+0TYnf4bWHY4zyC8G5JB09DEnHrHz2RReKgSccJO+4SzApG7O6asDtUV4qfa94/uZ10ZQ==",
+ "dependencies": {
+ "tslib": "^1.10.0"
+ },
+ "peerDependencies": {
+ "@angular/common": "^8.1.3",
+ "@angular/core": "^8.1.3"
+ }
+ },
+ "node_modules/ngx-csv-parser/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
"node_modules/nice-napi": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
@@ -7975,6 +8109,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -8662,6 +8797,7 @@
"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"
},
@@ -9457,6 +9593,7 @@
"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"
},
@@ -9467,7 +9604,8 @@
"node_modules/reflect-metadata": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
- "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
+ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
+ "dev": true
},
"node_modules/regenerate": {
"version": "1.4.2",
@@ -9888,6 +10026,7 @@
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -10272,7 +10411,8 @@
"node_modules/sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
- "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "dev": true
},
"node_modules/spdy": {
"version": "4.0.2",
@@ -10673,6 +10813,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
"dependencies": {
"is-number": "^7.0.0"
},
@@ -10738,6 +10879,7 @@
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+ "dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -11343,7 +11485,8 @@
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
},
"node_modules/yaml": {
"version": "1.10.2",
@@ -11607,11 +11750,28 @@
}
},
"@angular/animations": {
- "version": "13.2.5",
- "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.5.tgz",
- "integrity": "sha512-1mGOePSDTiVwNIuV2g3+mUHrZJAkqJVzRKqKyNPXdwZupzVAgAfLbfUC07hhD/H53mXupIVugcUMFC3dvMu7uQ==",
+ "version": "13.2.6",
+ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.6.tgz",
+ "integrity": "sha512-DrjpKo68uR3lSLQQXosoTCbjKQS6IKRCpR14E2t8fo0AX8i2hkB8je4SrhdCyB7FgFN7l2kgUYo4Qa8+BOB+aA==",
+ "requires": {
+ "tslib": "^2.3.0"
+ }
+ },
+ "@angular/cdk": {
+ "version": "13.2.6",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.2.6.tgz",
+ "integrity": "sha512-epuXmaHqfukwPsYvIksbuHLXDtb6GALV2Vgv6W2asj4TorD584CeQTs0EcdPGmCzhGUYI8U8QV63WOxu9YFcNA==",
"requires": {
+ "parse5": "^5.0.0",
"tslib": "^2.3.0"
+ },
+ "dependencies": {
+ "parse5": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "optional": true
+ }
}
},
"@angular/cli": {
@@ -11661,6 +11821,7 @@
"version": "13.2.5",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.2.5.tgz",
"integrity": "sha512-Xd8xj2Z0ilA4TJAM/JkTtA1CAa6SuebFsEEvabHCRO5MDvtdsIUP91ADUZIqDHy7qe6Qift/rAVN2PXxT2aaNA==",
+ "dev": true,
"requires": {
"@babel/core": "^7.17.2",
"chokidar": "^3.0.0",
@@ -11678,6 +11839,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz",
"integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==",
+ "dev": true,
"requires": {
"@jridgewell/trace-mapping": "^0.3.0"
}
@@ -11686,6 +11848,7 @@
"version": "7.17.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz",
"integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==",
+ "dev": true,
"requires": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.16.7",
@@ -11707,7 +11870,8 @@
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
}
}
},
@@ -11715,6 +11879,7 @@
"version": "7.17.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz",
"integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==",
+ "dev": true,
"requires": {
"@babel/types": "^7.17.0",
"jsesc": "^2.5.1",
@@ -11724,7 +11889,8 @@
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
}
}
},
@@ -11806,6 +11972,14 @@
}
}
},
+ "@angular/material": {
+ "version": "13.2.6",
+ "resolved": "https://registry.npmjs.org/@angular/material/-/material-13.2.6.tgz",
+ "integrity": "sha512-/h5wa/tXE0DMIIEQX+rozFkUWHYUWg1Xf1R2tXUFLslLQ0KRCGyNo225Sv/1wrxXHxfrML787lA9ex4p90Feqw==",
+ "requires": {
+ "tslib": "^2.3.0"
+ }
+ },
"@angular/platform-browser": {
"version": "13.2.5",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.2.5.tgz",
@@ -11861,6 +12035,7 @@
"version": "7.16.12",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz",
"integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==",
+ "dev": true,
"requires": {
"@babel/code-frame": "^7.16.7",
"@babel/generator": "^7.16.8",
@@ -11882,12 +12057,14 @@
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
}
}
},
@@ -11895,6 +12072,7 @@
"version": "7.16.8",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz",
"integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==",
+ "dev": true,
"requires": {
"@babel/types": "^7.16.8",
"jsesc": "^2.5.1",
@@ -11904,7 +12082,8 @@
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
}
}
},
@@ -13062,8 +13241,7 @@
"version": "13.2.5",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.2.5.tgz",
"integrity": "sha512-obiPvwPe+UJUO8cfNbBxukLKG30F+gLF5/erexwklRknJzS4KP8ciH2on6XlTuXUahpDjbO0pffugFE2I/IszQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
@@ -13598,8 +13776,7 @@
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"adjust-sourcemap-loader": {
"version": "4.0.0",
@@ -13722,6 +13899,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -13919,7 +14097,8 @@
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
},
"bl": {
"version": "4.1.0",
@@ -13990,8 +14169,7 @@
"bootstrap": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
- "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
- "requires": {}
+ "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q=="
},
"brace-expansion": {
"version": "1.1.11",
@@ -14006,6 +14184,7 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
"requires": {
"fill-range": "^7.0.1"
}
@@ -14129,6 +14308,7 @@
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
"requires": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -14156,8 +14336,7 @@
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz",
"integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"clean-stack": {
"version": "2.2.0",
@@ -14635,8 +14814,7 @@
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
"integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"css-select": {
"version": "4.2.1",
@@ -14669,6 +14847,14 @@
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true
},
+ "csv-parser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.0.0.tgz",
+ "integrity": "sha512-s6OYSXAK3IdKqYO33y09jhypG/bSDHPuyCme/IdEHfWpLf/jKcpitVFyOC6UemgGk8v7Q5u2XE0vvwmanxhGlQ==",
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
"custom-event": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
@@ -14801,7 +14987,8 @@
"dependency-graph": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
- "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg=="
+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
+ "dev": true
},
"destroy": {
"version": "1.0.4",
@@ -15449,6 +15636,7 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
@@ -15571,6 +15759,7 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
"optional": true
},
"function-bind": {
@@ -15646,6 +15835,7 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
"requires": {
"is-glob": "^4.0.1"
}
@@ -15902,8 +16092,7 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"ieee754": {
"version": "1.2.1",
@@ -16100,6 +16289,7 @@
"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,
"requires": {
"binary-extensions": "^2.0.0"
}
@@ -16131,7 +16321,8 @@
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
@@ -16142,6 +16333,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
@@ -16161,7 +16353,8 @@
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
},
"is-path-cwd": {
"version": "2.2.0",
@@ -16580,8 +16773,7 @@
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz",
"integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"karma-source-map-support": {
"version": "1.4.0",
@@ -16798,6 +16990,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
"requires": {
"yallist": "^4.0.0"
}
@@ -16806,6 +16999,7 @@
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+ "dev": true,
"requires": {
"sourcemap-codec": "^1.4.4"
}
@@ -16851,6 +17045,14 @@
"ssri": "^8.0.0"
}
},
+ "mdb-angular-ui-kit": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdb-angular-ui-kit/-/mdb-angular-ui-kit-2.0.0.tgz",
+ "integrity": "sha512-atwGldhGszfrWvQBcmaxhTPV4XjvbaJ030Ma6XAbPsdtN2UZio5qPlCb6sJHAGQOKusVq++4EmtYYnT0u51bLg==",
+ "requires": {
+ "tslib": "^2.0.0"
+ }
+ },
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -17121,6 +17323,21 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
+ "ng-uikit-pro-standard": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ng-uikit-pro-standard/-/ng-uikit-pro-standard-1.0.0.tgz",
+ "integrity": "sha512-GaG4Ek8pJRdHdr6JtkE4mHMvhb619mJI9VOIXKas4F0iGRyTb7U4rc2Y9AFgsysOYBZKCYifSzKxCf3NukZj0w==",
+ "requires": {
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"ngx-cookie-service": {
"version": "13.1.2",
"resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-13.1.2.tgz",
@@ -17129,6 +17346,21 @@
"tslib": "^2.0.0"
}
},
+ "ngx-csv-parser": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ngx-csv-parser/-/ngx-csv-parser-0.0.7.tgz",
+ "integrity": "sha512-KCos2rxjkPqw/gQfd+0TYnf4bWHY4zyC8G5JB09DEnHrHz2RReKgSccJO+4SzApG7O6asDtUV4qfa94/uZ10ZQ==",
+ "requires": {
+ "tslib": "^1.10.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"nice-napi": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
@@ -17206,7 +17438,8 @@
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
},
"normalize-range": {
"version": "0.1.2",
@@ -17731,7 +17964,8 @@
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
},
"pify": {
"version": "2.3.0",
@@ -17842,8 +18076,7 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz",
"integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-custom-properties": {
"version": "12.1.4",
@@ -17913,15 +18146,13 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
"integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-gap-properties": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz",
"integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-image-set-function": {
"version": "4.0.6",
@@ -17947,8 +18178,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz",
"integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-lab-function": {
"version": "4.1.1",
@@ -17975,22 +18205,19 @@
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
"integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-media-minmax": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz",
"integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-modules-extract-imports": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-modules-local-by-default": {
"version": "4.0.0",
@@ -18034,15 +18261,13 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz",
"integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-page-break": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz",
"integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-place": {
"version": "7.0.4",
@@ -18107,8 +18332,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz",
"integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-selector-not": {
"version": "5.0.0",
@@ -18273,6 +18497,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
"requires": {
"picomatch": "^2.2.1"
}
@@ -18280,7 +18505,8 @@
"reflect-metadata": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
- "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
+ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
+ "dev": true
},
"regenerate": {
"version": "1.4.2",
@@ -18556,8 +18782,7 @@
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
@@ -18586,6 +18811,7 @@
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
@@ -18901,7 +19127,8 @@
"sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
- "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "dev": true
},
"spdy": {
"version": "4.0.2",
@@ -19109,8 +19336,7 @@
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
@@ -19184,6 +19410,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
"requires": {
"is-number": "^7.0.0"
}
@@ -19230,7 +19457,8 @@
"typescript": {
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
- "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA=="
+ "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+ "dev": true
},
"ua-parser-js": {
"version": "0.7.31",
@@ -19420,8 +19648,7 @@
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
@@ -19643,8 +19870,7 @@
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"y18n": {
"version": "5.0.8",
@@ -19654,7 +19880,8 @@
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
},
"yaml": {
"version": "1.10.2",
diff --git a/frontend/package.json b/frontend/package.json
index 5d3ab5e3..0b32837f 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -6,24 +6,31 @@
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
- "test": "ng test"
+ "test": "ng test",
+ "postinstall": "ngcc"
},
"private": true,
"dependencies": {
"@angular/animations": "~13.2.0",
+ "@angular/cdk": "^13.2.6",
"@angular/common": "~13.2.0",
"@angular/compiler": "~13.2.0",
"@angular/core": "~13.2.0",
"@angular/forms": "~13.2.0",
"@angular/localize": "~13.2.0",
+ "@angular/material": "^13.2.6",
"@angular/platform-browser": "~13.2.0",
"@angular/platform-browser-dynamic": "~13.2.0",
"@angular/router": "~13.2.0",
"@auth0/angular-jwt": "^5.0.2",
- "ngx-cookie-service": "^13.1.2",
"@ng-bootstrap/ng-bootstrap": "^12.0.0",
"@popperjs/core": "^2.10.2",
"bootstrap": "^5.1.3",
+ "csv-parser": "^3.0.0",
+ "mdb-angular-ui-kit": "^2.0.0",
+ "ng-uikit-pro-standard": "^1.0.0",
+ "ngx-cookie-service": "^13.1.2",
+ "ngx-csv-parser": "^0.0.7",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
@@ -42,4 +49,4 @@
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.5.2"
}
-} \ No newline at end of file
+}
diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts
new file mode 100644
index 00000000..216e1c36
--- /dev/null
+++ b/frontend/src/app/_data/Model.ts
@@ -0,0 +1,53 @@
+export default class Model {
+ constructor(
+ public name: string = 'Novi model',
+ public description: string = '',
+ public dateCreated: Date = new Date(),
+ public datasetId?: number,
+
+ //Test set settings
+ public inputColumns: number[] = [0],
+ public columnToPredict: number = 1,
+ public randomTestSet: boolean = true,
+ public randomTestSetDistribution: number = 0.10, //0.1-0.9 (10% - 90%)
+
+ // Neural net training settings
+ public type: ANNType = ANNType.FullyConnected,
+ public encoding: Encoding = Encoding.Label,
+ public optimizer: Optimizer = Optimizer.Adam,
+ public lossFunction: LossFunction = LossFunction.MeanSquaredError,
+ public inputNeurons: number = 1,
+ public hiddenLayerNeurons: number = 1,
+ public hiddenLayers: number = 1,
+ public batchSize: number = 5,
+ public inputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid,
+ public hiddenLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid,
+ public outputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid
+ ) { }
+}
+
+export enum ANNType {
+ FullyConnected = 'potpuno povezana',
+ Convolutional = 'konvoluciona'
+}
+
+export enum Encoding {
+ Label = 'label',
+ OneHot = 'one hot'
+}
+
+export enum ActivationFunction {
+ Relu = 'relu',
+ Sigmoid = 'sigmoid',
+ Tanh = 'tanh',
+ Linear = 'linear'
+}
+
+export enum LossFunction {
+ BinaryCrossEntropy = 'binary_crossentropy',
+ MeanSquaredError = 'mean_squared_error'
+}
+
+export enum Optimizer {
+ Adam = 'adam'
+} \ No newline at end of file
diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.css b/frontend/src/app/_elements/dataset-load/dataset-load.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.css
diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.html b/frontend/src/app/_elements/dataset-load/dataset-load.component.html
new file mode 100644
index 00000000..c89add43
--- /dev/null
+++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.html
@@ -0,0 +1,42 @@
+<div>
+
+ <input style="display: inline-block; width:350px;" list=delimiterOptions
+ placeholder="Izaberite ili ukucajte delimiter za .csv fajl" class="form-control" [(ngModel)]="delimiter"
+ (input)="update()">
+ <datalist id=delimiterOptions>
+ <option *ngFor="let option of delimiterOptions">{{option}}</option>
+ </datalist>
+ &nbsp;&nbsp;&nbsp;&nbsp;
+ <label for="checkboxHeader">Da li .csv ima header?</label> &nbsp;
+ <input (input)="update()" [(ngModel)]="hasHeader" type="checkbox" value="" id="checkboxHeader" checked>
+ <br><br>
+
+ <input id="fileInput" class="form-control mb-5" type="file" class="upload" (change)="changeListener($event)" accept=".csv">
+
+ <table *ngIf="csvRecords.length > 0 && hasHeader" class="table table-bordered table-light mt-5">
+ <thead>
+ <tr>
+ <th *ngFor="let item of csvRecords[0]; let i = index">{{item}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let row of csvRecords | slice:1:11">
+ <td *ngFor="let col of row">{{col}}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <table *ngIf="csvRecords.length > 0 && !hasHeader" class="table table-bordered table-light mt-5">
+ <tbody>
+ <tr *ngFor="let row of csvRecords | slice:0:10">
+ <td *ngFor="let col of row">{{col}}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div *ngIf="csvRecords.length > 0" id="info">
+ . . . <br>
+ {{rowsNumber}} x {{colsNumber}}
+ </div>
+
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.spec.ts b/frontend/src/app/_elements/dataset-load/dataset-load.component.spec.ts
new file mode 100644
index 00000000..5601b57b
--- /dev/null
+++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DatasetLoadComponent } from './dataset-load.component';
+
+describe('DatasetLoadComponent', () => {
+ let component: DatasetLoadComponent;
+ let fixture: ComponentFixture<DatasetLoadComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ DatasetLoadComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DatasetLoadComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_elements/dataset-load/dataset-load.component.ts b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
new file mode 100644
index 00000000..843a5709
--- /dev/null
+++ b/frontend/src/app/_elements/dataset-load/dataset-load.component.ts
@@ -0,0 +1,54 @@
+import { Component, ViewChild } from '@angular/core';
+import { NgxCsvParser, NgxCSVParserError } from 'ngx-csv-parser';
+
+@Component({
+ selector: 'app-dataset-load',
+ templateUrl: './dataset-load.component.html',
+ styleUrls: ['./dataset-load.component.css']
+})
+export class DatasetLoadComponent {
+
+ delimiter: string = "";
+ delimiterOptions: Array<string> = [",", ";", "\t", "razmak", "|"]; //podrazumevano ","
+
+ hasHeader: boolean = true;
+
+ slice: string = "";
+
+ csvRecords: any[] = [];
+ files: any[] = [];
+ rowsNumber: number = 0;
+ colsNumber: number = 0;
+
+ constructor(private ngxCsvParser: NgxCsvParser) {
+ }
+
+ @ViewChild('fileImportInput', { static: false }) fileImportInput: any;
+
+ changeListener($event: any): void {
+ this.files = $event.srcElement.files;
+ this.update();
+ }
+
+ update() {
+
+ if (this.files.length < 1)
+ return;
+
+ this.ngxCsvParser.parse(this.files[0], { header: false, delimiter: (this.delimiter == "razmak") ? " " : (this.delimiter == "") ? "," : this.delimiter})
+ .pipe().subscribe((result) => {
+
+ //console.log('Result', result);
+ if (result.constructor === Array) {
+ this.csvRecords = result;
+ if (this.hasHeader)
+ this.rowsNumber = this.csvRecords.length - 1;
+ else
+ this.rowsNumber = this.csvRecords.length;
+ this.colsNumber = this.csvRecords[0].length;
+ }
+ }, (error: NgxCSVParserError) => {
+ console.log('Error', error);
+ });
+ }
+}
diff --git a/frontend/src/app/_modals/login-modal/login-modal.component.css b/frontend/src/app/_modals/login-modal/login-modal.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_modals/login-modal/login-modal.component.css
diff --git a/frontend/src/app/_modals/login-modal/login-modal.component.html b/frontend/src/app/_modals/login-modal/login-modal.component.html
new file mode 100644
index 00000000..22f50de2
--- /dev/null
+++ b/frontend/src/app/_modals/login-modal/login-modal.component.html
@@ -0,0 +1,49 @@
+<!-- Button trigger modal, OVO JE U STVARI DUGME U NAVBARU -->
+<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalForLogin" (click)="openModal()">
+ Otvori login modal
+</button>
+
+<!-- Modal -->
+<div class="modal fade" id="modalForLogin" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered">
+ <div class="modal-content">
+ <div class="modal-header bg-info">
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+ </div>
+ <div class="modal-body px-5" style="color:#003459">
+ <h1 class="text-center mt-2 mb-4">Prijavite se</h1>
+ <form>
+ <!-- Korisnicko ime -->
+ <div class="form-outline mb-3">
+ <label class="form-label" for="username">Korisničko ime</label>
+ <input [(ngModel)]="username" name="username" type="text" id="username"
+ class="form-control form-control" placeholder="Unesite korisničko ime..." />
+ </div>
+ <!-- Lozinka -->
+ <div class="form-outline mb-3">
+ <label class="form-label" for="password">Lozinka</label>
+ <input [(ngModel)]="password" name="password" type="password" id="password"
+ class="form-control form-control" placeholder="Unesite lozinku..." />
+ </div>
+
+ <div class="text-center text-lg-start mt-5 pt-2">
+ <p *ngIf="wrongCreds" class="small fw-bold mt-2 pt-1 mb-0 text-danger">Lozinka ili e-mail su pogrešni
+ </p>
+ </div>
+ </form>
+ <div class="col-md-12 d-flex justify-content-center">
+ <button type="button" class="btn btn-lg btn-info" style="color:white; border-color: #00a8e8; margin-right: 10px;" (click)="doLogin()">Prijavite se</button>
+ <button type="button" class="btn btn-lg btn-outline-secondary" data-bs-dismiss="modal">Odustanite</button>
+ </div>
+ <br>
+ </div>
+ <div class="modal-footer justify-content-center">
+ <p class="small fw-bold">Još uvek nemate nalog?
+ <a routerLink="/register" class="link-danger">Registrujte se</a>
+ </p>
+ </div>
+ </div>
+ </div>
+</div>
+
+
diff --git a/frontend/src/app/_modals/login-modal/login-modal.component.spec.ts b/frontend/src/app/_modals/login-modal/login-modal.component.spec.ts
new file mode 100644
index 00000000..7d0d526a
--- /dev/null
+++ b/frontend/src/app/_modals/login-modal/login-modal.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoginModalComponent } from './login-modal.component';
+
+describe('LoginModalComponent', () => {
+ let component: LoginModalComponent;
+ let fixture: ComponentFixture<LoginModalComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ LoginModalComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LoginModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_modals/login-modal/login-modal.component.ts b/frontend/src/app/_modals/login-modal/login-modal.component.ts
new file mode 100644
index 00000000..3a6fd8f1
--- /dev/null
+++ b/frontend/src/app/_modals/login-modal/login-modal.component.ts
@@ -0,0 +1,51 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { FormControl, FormGroup } from '@angular/forms';
+import { Router } from '@angular/router';
+import { CookieService } from 'ngx-cookie-service';
+import { AuthService } from 'src/app/_services/auth.service';
+import { ElementRef } from '@angular/core';
+
+declare var window: any;
+
+@Component({
+ selector: 'app-login-modal',
+ templateUrl: './login-modal.component.html',
+ styleUrls: ['./login-modal.component.css']
+})
+export class LoginModalComponent implements OnInit {
+
+ loginModal: any;
+ username: string = '';
+ password: string = '';
+
+ public wrongCreds: boolean = false; //RAZMOTRITI
+
+ constructor(
+ private authService: AuthService,
+ private cookie: CookieService,
+ private router: Router
+ ) { }
+
+ ngOnInit(): void {
+ this.loginModal = new window.bootstrap.Modal(
+ document.getElementById("modalForLogin")
+ );
+ }
+
+ openModal() {
+ this.loginModal.show();
+ //console.log("ok");
+ //(<HTMLInputElement>document.getElementById("exampleModal")).style.display = "block";
+ }
+ doLogin() {
+ this.authService.login(this.username, this.password).subscribe((response) => { //ako nisu ok podaci, ne ide hide nego mora opet da ukucava!!!!podesi
+ console.log(response);
+ this.cookie.set('token', response);
+ this.loginModal.hide(); //dodato
+ this.router.navigate(['add-model']);
+ });
+ }
+ sendToRegister() {
+
+ }
+}
diff --git a/frontend/src/app/_pages/add-model/add-model.component.css b/frontend/src/app/_pages/add-model/add-model.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/frontend/src/app/_pages/add-model/add-model.component.css
diff --git a/frontend/src/app/_pages/add-model/add-model.component.html b/frontend/src/app/_pages/add-model/add-model.component.html
new file mode 100644
index 00000000..bc292bb9
--- /dev/null
+++ b/frontend/src/app/_pages/add-model/add-model.component.html
@@ -0,0 +1,189 @@
+<div class="container p-3" style="background-color: rgb(249, 251, 253); min-height: 100%;">
+
+ <h2 class="my-4 text-primary"> Nov model: </h2>
+ <div class="form-group row align-items-center">
+ <label for="name" class="col-sm-2 col-form-label col-form-label-lg">Naziv</label>
+ <div class="col-sm-7">
+ <input type="text" class="form-control form-control-lg" name="name" placeholder="Naziv..."
+ [(ngModel)]="newModel.name">
+ </div>
+
+ <div class="col-sm-3">
+ <input type="text" class="form-control-plaintext text-center" id="dateCreated" placeholder="--/--/--"
+ value="{{newModel.dateCreated | date: 'dd/MM/yyyy'}}" readonly>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="desc" class="col-sm-2 col-form-label">Opis</label>
+ <div class="col-sm-10">
+ <textarea class="form-control" name="desc" rows="3" [(ngModel)]="newModel.description"></textarea>
+ </div>
+ </div>
+
+ <!--<div class="form-group row">
+ <label for="value" class="col-4">Vrednost</label>
+ <div class="input-group">
+ <input type="number" min="0" class="form-control" name="value" placeholder="Vrednost..."
+ [(ngModel)]="newModel.value">
+ <div class="input-group-prepend">
+ <span class="input-group-text">#</span>
+ </div>
+ <input type="number" min="1" class="form-control" name="count" placeholder="Br." [(ngModel)]="newModel.count">
+ <input type="text" class="form-control" name="sum" placeholder="Suma"
+ value="=({{newModel.value * newModel.count}})" readonly>
+ </div>
+ </div>-->
+
+ <div class="my-4">
+ <label for="dataset">Izvor podataka:</label>
+ <app-dataset-load id="dataset"></app-dataset-load>
+ </div>
+
+ <div class="form-group row my-2">
+ <div class="col-sm-2 col-form-label">
+ <label for="type" class="form-check-label">Podela test skupa:
+ <input class="mx-3 form-check-input" type="checkbox" [checked]="newModel.randomTestSet"
+ (change)="newModel.randomTestSet = !newModel.randomTestSet">
+ </label>
+
+ </div>
+ <div>
+ <input type="range" min="0.1" max="0.9" step="0.1" class="form-control" name="randomTestSetDistribution"
+ [disabled]="!newModel.randomTestSet" [(ngModel)]="newModel.randomTestSetDistribution">
+ </div>
+ </div>
+
+ <h3> Parametri treniranja </h3>
+
+ <div class="form-group row my-2">
+ <label for="type" class="col-sm-2 col-form-label">Tip mreže: </label>
+ <div class="col-sm-10">
+ <select id=typeOptions class="form-control" name="type" [(ngModel)]="newModel.type">
+ <option *ngFor="let option of Object.keys(ANNType); let optionName of Object.values(ANNType)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="encoding" class="col-sm-2 col-form-label">Enkoding: </label>
+ <div class="col-sm-10">
+ <select id=encodingOptions class="form-control" name="encoding" [(ngModel)]="newModel.encoding">
+ <option *ngFor="let option of Object.keys(Encoding); let optionName of Object.values(Encoding)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="optimizer" class="col-sm-2 col-form-label">Optimizacija: </label>
+ <div class="col-sm-10">
+ <select id=optimizerOptions class="form-control" name="optimizer" [(ngModel)]="newModel.optimizer">
+ <option *ngFor="let option of Object.keys(Optimizer); let optionName of Object.values(Optimizer)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="lossFunction" class="col-sm-2 col-form-label">Funkcija obrade gubitka: </label>
+ <div class="col-sm-10">
+ <select id=lossFunctionOptions class="form-control" name="lossFunction" [(ngModel)]="newModel.lossFunction">
+ <option *ngFor="let option of Object.keys(LossFunction); let optionName of Object.values(LossFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="inputNeurons" class="col-sm-2 col-form-label">Broj ulaznih neurona: </label>
+ <div class="col-sm-10">
+ <input type="number" min="1" class="form-control" name="inputNeurons" [(ngModel)]="newModel.inputNeurons">
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="inputLayerActivationFunction" class="col-sm-2 col-form-label">Funkcija aktivacije ulaznog sloja:
+ </label>
+ <div class="col-sm-10">
+ <select id=inputLayerActivationFunctionOptions class="form-control" name="inputLayerActivationFunction"
+ [(ngModel)]="newModel.inputLayerActivationFunction">
+ <option
+ *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="hiddenLayerNeurons" class="col-sm-2 col-form-label">Broj neurona skrivenih slojeva: </label>
+ <div class="col-sm-10">
+ <input type="number" min="1" class="form-control" name="hiddenLayerNeurons"
+ [(ngModel)]="newModel.hiddenLayerNeurons">
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="hiddenLayerActivationFunction" class="col-sm-2 col-form-label">Funkcija aktivacije skrivenih
+ slojeva:
+ </label>
+ <div class="col-sm-10">
+ <select id=hiddenLayerActivationFunctionOptions class="form-control" name="hiddenLayerActivationFunction"
+ [(ngModel)]="newModel.hiddenLayerActivationFunction">
+ <option
+ *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="hiddenLayers" class="col-sm-2 col-form-label">Broj skrivenih slojeva: </label>
+ <div class="col-sm-10">
+ <input type="number" min="1" class="form-control" name="hiddenLayers" [(ngModel)]="newModel.hiddenLayers">
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="outputLayerActivationFunction" class="col-sm-2 col-form-label">Funkcija aktivacije izlaznog
+ sloja:
+ </label>
+ <div class="col-sm-10">
+ <select id=outputLayerActivationFunctionOptions class="form-control" name="outputLayerActivationFunction"
+ [(ngModel)]="newModel.outputLayerActivationFunction">
+ <option
+ *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group row my-2">
+ <label for="batchSize" class="col-sm-2 col-form-label">Broj uzorka po iteraciji: </label>
+ <div class="col-sm-10">
+ <input type="number" min="1" class="form-control" name="batchSize" [(ngModel)]="newModel.batchSize">
+ </div>
+ </div>
+
+ <div class=" form-group row my-4">
+ <div class="col-4"></div>
+ <button class="btn btn-lg btn-primary col-4" (click)="addModel();">Dodaj</button>
+ <div class="col-4"></div>
+ </div>
+
+</div> \ No newline at end of file
diff --git a/frontend/src/app/_pages/add-model/add-model.component.spec.ts b/frontend/src/app/_pages/add-model/add-model.component.spec.ts
new file mode 100644
index 00000000..2926e1c4
--- /dev/null
+++ b/frontend/src/app/_pages/add-model/add-model.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddModelComponent } from './add-model.component';
+
+describe('AddModelComponent', () => {
+ let component: AddModelComponent;
+ let fixture: ComponentFixture<AddModelComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ AddModelComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AddModelComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/_pages/add-model/add-model.component.ts b/frontend/src/app/_pages/add-model/add-model.component.ts
new file mode 100644
index 00000000..3cb47d61
--- /dev/null
+++ b/frontend/src/app/_pages/add-model/add-model.component.ts
@@ -0,0 +1,32 @@
+import { Component, OnInit } from '@angular/core';
+import Model from 'src/app/_data/Model';
+import { ANNType, Encoding, ActivationFunction, LossFunction, Optimizer } from 'src/app/_data/Model';
+
+@Component({
+ selector: 'app-add-model',
+ templateUrl: './add-model.component.html',
+ styleUrls: ['./add-model.component.css']
+})
+export class AddModelComponent implements OnInit {
+
+ newModel: Model
+
+ ANNType = ANNType;
+ Encoding = Encoding;
+ ActivationFunction = ActivationFunction;
+ LossFunction = LossFunction;
+ Optimizer = Optimizer;
+ Object = Object;
+
+ constructor() {
+ this.newModel = new Model();
+ }
+
+ ngOnInit(): void {
+ }
+
+ addModel() {
+ //TODO
+ }
+
+}
diff --git a/frontend/src/app/_pages/login-page/login-page.component.html b/frontend/src/app/_pages/login-page/login-page.component.html
index 906eaba6..8deb5290 100644
--- a/frontend/src/app/_pages/login-page/login-page.component.html
+++ b/frontend/src/app/_pages/login-page/login-page.component.html
@@ -1,18 +1,33 @@
+<!--<script>
+ $(document).ready(function(){
+ $(".btn").click(function(){
+ $("#exampleModal").modal('show');
+ });
+
+ $('#exampleModal').modal({
+     backdrop: 'static',
+     keyboard: false
+ });
+ });
+</script>-->
+
+<!-- Button trigger modal -->
+<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalForLogin" (click)="openModal()">
+ Open Modal
+ </button>
+
+<!--
<div style="min-height: 100vh; position: relative;">
- <!-- TODO : <app-navbar [activeNav]="'login'"></app-navbar>-->
-
<div class="container p-5 rounded-3 shadow-sm border" style="max-width: 50em; margin-top: 50px;">
<h3 class="text-center pb-5">Prijavite se</h3>
<form>
- <!-- Email input -->
<div class="form-outline mb-4">
- <label class="form-label" for="email">Email adresa</label>
- <input [(ngModel)]="email" name="email" type="email" id="email" class="form-control form-control-lg"
- placeholder="Unesite email adresu..." />
+ <label class="form-label" for="username">Korisničko ime</label>
+ <input [(ngModel)]="username" name="username" type="text" id="username"
+ class="form-control form-control-lg" placeholder="Unesite korisničko ime..." />
</div>
- <!-- Password input -->
<div class="form-outline mb-3">
<label class="form-label" for="password">Lozinka</label>
<input [(ngModel)]="password" name="password" type="password" id="password"
@@ -20,17 +35,15 @@
</div>
<div class="text-center text-lg-start mt-4 pt-2">
- <!-- Pogresna lozinka -->
<p *ngIf="wrongCreds" class="small fw-bold mt-2 pt-1 mb-0 text-danger">Lozinka ili e-mail su pogrešni
</p>
- <!-- Nepotvrdjena registracija
- <p *ngIf="notApproved" class="small fw-bold mt-2 pt-1 mb-0 text-danger">Vaša registracija još uvek nije potvrđena</p>-->
<br>
<button type="button" class="btn btn-primary btn-lg"
style="padding-left: 2.5rem; padding-right: 2.5rem;" (click)="onSubmit()">Prijava
</button>
+ <br>
<p class="small fw-bold mt-2 pt-1 mb-0">Još uvek nemate nalog?
<a routerLink="/register" class="link-danger">Registrujte se</a>
</p>
@@ -38,6 +51,5 @@
</form>
</div>
- <!-- TODO: <app-footer></app-footer>-->
-
-</div> \ No newline at end of file
+</div>
+--> \ No newline at end of file
diff --git a/frontend/src/app/_pages/login-page/login-page.component.ts b/frontend/src/app/_pages/login-page/login-page.component.ts
index f8b429e3..e5366283 100644
--- a/frontend/src/app/_pages/login-page/login-page.component.ts
+++ b/frontend/src/app/_pages/login-page/login-page.component.ts
@@ -1,40 +1,63 @@
import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
import { CookieService } from 'ngx-cookie-service';
import { AuthService } from 'src/app/_services/auth.service';
+import { LoginModalComponent } from 'src/app/_modals/login-modal/login-modal.component';
+import { MDBModalRef, MDBModalService } from 'ng-uikit-pro-standard';
+
+
+declare var window: any;
+
@Component({
selector: 'app-login-page',
templateUrl: './login-page.component.html',
- styleUrls: ['./login-page.component.css']
+ styleUrls: ['./login-page.component.css'],
+
})
-export class LoginPageComponent implements OnInit {
- email: string = '';
+export class LoginPageComponent{
+
+ modalRef?: MDBModalRef;
+
+ //email: string = '';
+ username: string = '';
password: string = '';
public wrongCreds: boolean = false; //RAZMOTRITI
//public notApproved: boolean = false; //RAZMOTRITI
- pattEmail: RegExp = /^[a-zA-Z0-9]+([\.\-\+][a-zA-Z0-9]+)*\@([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}$/;
+ formModal: any;
constructor(
private authService: AuthService,
- private cookie: CookieService
+ private cookie: CookieService,
+ private router: Router,
+ private modalService: MDBModalService
) { }
+ openModal() {
+ //this.modalRef = this.modalService.show(LoginModalComponent);
+ }
+ /*
ngOnInit(): void {
+ this.formModal = new window.bootstrap.Modal(
+ document.getElementById("exampleModal")
+ );
}
- onSubmit() {
- if (!this.pattEmail.test(this.email)) {
- console.warn('Bad email!');
- return;
- }
- else {
- this.authService.login(this.email, this.password).subscribe((response) => {
- console.log(response);
- this.cookie.set('token', response);
- })
- }
+ openModal() {
+ this.formModal.show();
+ //console.log("ok");
+ //(<HTMLInputElement>document.getElementById("exampleModal")).style.display = "block";
}
+ onSubmit() {
+
+ this.authService.login(this.username, this.password).subscribe((response) => {
+ console.log(response);
+ this.cookie.set('token', response);
+ this.router.navigate(['add-model']);
+ });
+ }
+*/
}
diff --git a/frontend/src/app/_pages/register-page/register-page.component.ts b/frontend/src/app/_pages/register-page/register-page.component.ts
index e8d4c036..712fc55e 100644
--- a/frontend/src/app/_pages/register-page/register-page.component.ts
+++ b/frontend/src/app/_pages/register-page/register-page.component.ts
@@ -104,7 +104,7 @@ export class RegisterPageComponent implements OnInit {
this.firstNameValidation();
this.lastNameValidation();
- this.nickNameValidation();
+ //this.nickNameValidation();
this.emailValidation();
this.passwordValidation();
@@ -114,19 +114,21 @@ export class RegisterPageComponent implements OnInit {
let user = {
firstName: this.firstName,
lastName: this.lastName,
- nickName: this.nickName,
- email: this.email,
- password: this.pass1
+ username: this.nickName,
+ password: this.pass1,
+ email: this.email
}
this.authService.register(user)
.subscribe(
(response) => {
console.log(response);
- /*if ()
+ if (response === 'User added')
this.router.navigate(['/login']); //registracija uspesna, idi na login
- else if ()
- alert('Nalog sa unetim email-om već postoji!');*/
+ else if (response === 'Email Already Exists')
+ alert('Nalog sa unetim email-om već postoji!');
+ else if (response === 'Username Already Exists')
+ alert('Nalog sa unetim korisnićkim imenom već postoji!');
}
);
}
diff --git a/frontend/src/app/_services/auth.service.ts b/frontend/src/app/_services/auth.service.ts
index 7129b95b..c96c2dae 100644
--- a/frontend/src/app/_services/auth.service.ts
+++ b/frontend/src/app/_services/auth.service.ts
@@ -18,7 +18,7 @@ export class AuthService {
}
register(user: any) {
- return this.http.post(`${API_SETTINGS.apiURL}/auth/register`, user);
+ return this.http.post(`${API_SETTINGS.apiURL}/auth/register`, { ...user }, { responseType: 'text' });
}
isAuthenticated(): boolean {
diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts
index 1868e56c..cd86ef5c 100644
--- a/frontend/src/app/app-routing.module.ts
+++ b/frontend/src/app/app-routing.module.ts
@@ -1,15 +1,20 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
+import { AuthGuardService } from './_services/auth-guard.service';
import { LoginPageComponent } from './_pages/login-page/login-page.component';
import { OnlyAuthorizedComponent } from './_pages/only-authorized/only-authorized.component';
import { RegisterPageComponent } from './_pages/register-page/register-page.component';
-import { AuthGuardService } from './_services/auth-guard.service';
+import { AddModelComponent } from './_pages/add-model/add-model.component';
+import { LoginModalComponent } from './_modals/login-modal/login-modal.component';
const routes: Routes = [
+ { path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: 'login', component: LoginPageComponent },
{ path: 'register', component: RegisterPageComponent },
- { path: 'only-authorized', component: OnlyAuthorizedComponent, canActivate: [AuthGuardService] }
+ { path: 'only-authorized', component: OnlyAuthorizedComponent, canActivate: [AuthGuardService] },
+ { path: 'add-model', component: AddModelComponent },
+ { path: 'login-modal-test', component: LoginModalComponent }
];
@NgModule({
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index 9ccd7ddb..d95252ad 100644
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -9,20 +9,33 @@ import { LoginPageComponent } from './_pages/login-page/login-page.component';
import { RegisterPageComponent } from './_pages/register-page/register-page.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { OnlyAuthorizedComponent } from './_pages/only-authorized/only-authorized.component';
+import { DatasetLoadComponent } from './_elements/dataset-load/dataset-load.component';
+import { AddModelComponent } from './_pages/add-model/add-model.component';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { LoginModalComponent } from './_modals/login-modal/login-modal.component';
+
+import { MaterialModule } from './material.module';
+import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
LoginPageComponent,
RegisterPageComponent,
- OnlyAuthorizedComponent
+ OnlyAuthorizedComponent,
+ DatasetLoadComponent,
+ AddModelComponent,
+ LoginModalComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule,
- NgbModule
+ NgbModule,
+ BrowserAnimationsModule,
+ MaterialModule,
+ ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/frontend/src/app/material.module.ts b/frontend/src/app/material.module.ts
new file mode 100644
index 00000000..e85419ee
--- /dev/null
+++ b/frontend/src/app/material.module.ts
@@ -0,0 +1,18 @@
+import { NgModule } from '@angular/core';
+
+import { MatDialogModule } from '@angular/material/dialog';
+import { MatButtonModule } from '@angular/material/button';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+
+@NgModule({
+ exports: [
+ MatDialogModule,
+ MatButtonModule,
+ MatFormFieldModule,
+ MatInputModule,
+ MatCheckboxModule
+ ]
+})
+export class MaterialModule {} \ No newline at end of file
diff --git a/frontend/src/custom-theme.scss b/frontend/src/custom-theme.scss
new file mode 100644
index 00000000..a6538c37
--- /dev/null
+++ b/frontend/src/custom-theme.scss
@@ -0,0 +1,35 @@
+
+// Custom Theming for Angular Material
+// For more information: https://material.angular.io/guide/theming
+@use '@angular/material' as mat;
+// Plus imports for other components in your app.
+
+// Include the common styles for Angular Material. We include this here so that you only
+// have to load a single css file for Angular Material in your app.
+// Be sure that you only ever include this mixin once!
+@include mat.core();
+
+// Define the palettes for your theme using the Material Design palettes available in palette.scss
+// (imported above). For each palette, you can optionally specify a default, lighter, and darker
+// hue. Available color palettes: https://material.io/design/color/
+$frontend-primary: mat.define-palette(mat.$indigo-palette);
+$frontend-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
+
+// The warn palette is optional (defaults to red).
+$frontend-warn: mat.define-palette(mat.$red-palette);
+
+// Create the theme object. A theme consists of configurations for individual
+// theming systems such as "color" or "typography".
+$frontend-theme: mat.define-light-theme((
+ color: (
+ primary: $frontend-primary,
+ accent: $frontend-accent,
+ warn: $frontend-warn,
+ )
+));
+
+// Include theme styles for core and each component used in your app.
+// Alternatively, you can import and @include the theme mixins for each component
+// that you are using.
+@include mat.all-component-themes($frontend-theme);
+
diff --git a/frontend/src/index.html b/frontend/src/index.html
index 3af61ec9..b3b6eb54 100644
--- a/frontend/src/index.html
+++ b/frontend/src/index.html
@@ -6,8 +6,11 @@
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
+ <link rel="preconnect" href="https://fonts.gstatic.com">
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
-<body>
+<body class="mat-typography">
<app-root></app-root>
</body>
</html>
diff --git a/frontend/src/styles.css b/frontend/src/styles.css
index 90d4ee00..8997c10e 100644
--- a/frontend/src/styles.css
+++ b/frontend/src/styles.css
@@ -1 +1,5 @@
-/* You can add global styles to this file, and also import other style files */
+/* You can add global styles to this file, and also import other style files
+
+html, body { height: 100%; }
+body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
+*/ \ No newline at end of file