WIP: DataSets Module
This commit is contained in:
71
Frontend/package-lock.json
generated
71
Frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "diuna",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "diuna",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"dependencies": {
|
||||
"@abacritt/angularx-social-login": "^1.2.5",
|
||||
"@angular/animations": "^15.0.3",
|
||||
@@ -16,6 +16,7 @@
|
||||
"@angular/core": "^15.0.3",
|
||||
"@angular/forms": "^15.0.3",
|
||||
"@angular/material": "^15.0.2",
|
||||
"@angular/material-moment-adapter": "^15.0.2",
|
||||
"@angular/platform-browser": "^15.0.3",
|
||||
"@angular/platform-browser-dynamic": "^15.0.3",
|
||||
"@angular/pwa": "^15.0.3",
|
||||
@@ -24,6 +25,7 @@
|
||||
"jwt-decode": "^3.1.2",
|
||||
"moment": "^2.29.4",
|
||||
"rxjs": "^7.6.0",
|
||||
"uuid": "^9.0.0",
|
||||
"zone.js": "^0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -31,6 +33,7 @@
|
||||
"@angular/cli": "~15.0.3",
|
||||
"@angular/compiler-cli": "^15.0.3",
|
||||
"@types/jasmine": "^4.3.1",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"jasmine-core": "^4.5.0",
|
||||
"karma": "~6.4.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
@@ -651,6 +654,19 @@
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/material-moment-adapter": {
|
||||
"version": "15.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-15.0.2.tgz",
|
||||
"integrity": "sha512-d74B4DpZrT89F2EMYcaXcvjp+SJ3gNdI8dVY9iCLHuK3Zy1RN1q1DIlg4qMaZYA+fjmRSu0fh+elRRw6wTVPOQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^15.0.0 || ^16.0.0",
|
||||
"@angular/material": "15.0.2",
|
||||
"moment": "^2.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/platform-browser": {
|
||||
"version": "15.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.0.3.tgz",
|
||||
@@ -3753,6 +3769,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz",
|
||||
"integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
|
||||
@@ -10663,6 +10685,15 @@
|
||||
"websocket-driver": "^0.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/sockjs/node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/socks": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
|
||||
@@ -11394,10 +11425,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
@@ -12339,6 +12369,14 @@
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"@angular/material-moment-adapter": {
|
||||
"version": "15.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-15.0.2.tgz",
|
||||
"integrity": "sha512-d74B4DpZrT89F2EMYcaXcvjp+SJ3gNdI8dVY9iCLHuK3Zy1RN1q1DIlg4qMaZYA+fjmRSu0fh+elRRw6wTVPOQ==",
|
||||
"requires": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"@angular/platform-browser": {
|
||||
"version": "15.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.0.3.tgz",
|
||||
@@ -14781,6 +14819,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz",
|
||||
"integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/ws": {
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
|
||||
@@ -19922,6 +19966,14 @@
|
||||
"faye-websocket": "^0.11.3",
|
||||
"uuid": "^8.3.2",
|
||||
"websocket-driver": "^0.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"socks": {
|
||||
@@ -20456,10 +20508,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"@angular/core": "^15.0.3",
|
||||
"@angular/forms": "^15.0.3",
|
||||
"@angular/material": "^15.0.2",
|
||||
"@angular/material-moment-adapter": "^15.0.2",
|
||||
"@angular/platform-browser": "^15.0.3",
|
||||
"@angular/platform-browser-dynamic": "^15.0.3",
|
||||
"@angular/pwa": "^15.0.3",
|
||||
@@ -26,6 +27,7 @@
|
||||
"jwt-decode": "^3.1.2",
|
||||
"moment": "^2.29.4",
|
||||
"rxjs": "^7.6.0",
|
||||
"uuid": "^9.0.0",
|
||||
"zone.js": "^0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -33,6 +35,7 @@
|
||||
"@angular/cli": "~15.0.3",
|
||||
"@angular/compiler-cli": "^15.0.3",
|
||||
"@types/jasmine": "^4.3.1",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"jasmine-core": "^4.5.0",
|
||||
"karma": "~6.4.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
@@ -42,4 +45,4 @@
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ const routes: Routes = [
|
||||
path: '',
|
||||
loadChildren: () => import('./modules/dashboard/dashboard.module').then(m => m.DashboardModule)
|
||||
},
|
||||
{
|
||||
path: 'datasets',
|
||||
loadChildren: () => import('./modules/data-sets/data-sets.module').then(m => m.DataSetsModule)
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { NgModule, isDevMode } from '@angular/core';
|
||||
import { NgModule, isDevMode, LOCALE_ID } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
@@ -11,7 +10,12 @@ import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { ServiceWorkerModule } from '@angular/service-worker';
|
||||
import { LoaderInterceptor } from './interceptors/loader.interceptor';
|
||||
import { AuthInterceptor } from './interceptors/auth.interceptor';
|
||||
import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MomentDateAdapter } from '@angular/material-moment-adapter';
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localePl from '@angular/common/locales/pl';
|
||||
|
||||
registerLocaleData(localePl, 'pl-PL');
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -33,6 +37,9 @@ import { AuthInterceptor } from './interceptors/auth.interceptor';
|
||||
})
|
||||
],
|
||||
providers: [
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS] },
|
||||
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } },
|
||||
{ provide: LOCALE_ID, useValue: 'pl-PL' },
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LoaderInterceptor,
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DataService } from '../services/data.service';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(
|
||||
private data$: DataService,
|
||||
private auth$: AuthService,
|
||||
private router$: Router
|
||||
) {}
|
||||
canActivate(
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||
if (this.data$.currentUser) {
|
||||
if (this.auth$.user && this.auth$.user.googleCredentials) {
|
||||
return true;
|
||||
} else {
|
||||
this.router$.navigate(['']);
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { User } from '../models/user';
|
||||
import { User } from '../models/user.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthService {
|
||||
|
||||
apiToken: string | null = null;
|
||||
user: User | null = null;
|
||||
apiToken!: string;
|
||||
user!: User;
|
||||
|
||||
constructor(
|
||||
private http$: HttpClient
|
||||
@@ -35,7 +35,7 @@ export class AuthService {
|
||||
const header = new HttpHeaders().set('Content-type', 'application/json');
|
||||
this.http$.post<any>(`${environment.api.url}/auth/apiToken`, JSON.stringify(credentials), { headers: header }).subscribe({
|
||||
next: (data) => {
|
||||
if (this.user) { this.user.id = data.id }
|
||||
this.user.id = data.id;
|
||||
this.apiToken = data.token;
|
||||
resolve(data);
|
||||
},
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Component, NgZone, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import jwt_decode from "jwt-decode";
|
||||
import { AuthService } from 'src/app/auth/auth.service';
|
||||
import { User } from 'src/app/models/user';
|
||||
import { User } from 'src/app/models/user.model';
|
||||
import { DataService } from 'src/app/services/data.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@@ -44,7 +44,7 @@ export class LoginPageComponent implements OnInit {
|
||||
async handleCredentialResponse(response: any) {
|
||||
try {
|
||||
const responsePayload: any = jwt_decode(response.credential);
|
||||
this.data$.currentUser = new User({
|
||||
this.auth$.user = new User({
|
||||
googleCredentials: response.credential,
|
||||
userName: `${responsePayload.given_name} ${responsePayload.family_name}`,
|
||||
email: responsePayload.email,
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
</button>
|
||||
<h1 class="topbar-app-name">Diuna</h1>
|
||||
<span class="fill-to-right"></span>
|
||||
<span class="topbar-user-name" *ngIf="data$.currentUser">
|
||||
<img *ngIf="data$.currentUser.avatar" src="{{data$.currentUser.avatar}}" class="avatar">
|
||||
{{data$.currentUser.userName}}
|
||||
<span class="topbar-user-name" *ngIf="auth$.user">
|
||||
<img *ngIf="auth$.user.avatar" src="{{auth$.user.avatar}}" class="avatar">
|
||||
{{auth$.user.userName}}
|
||||
</span>
|
||||
<button mat-icon-button (click)="logout()">
|
||||
<mat-icon>exit_to_app</mat-icon>
|
||||
@@ -25,14 +25,18 @@
|
||||
<mat-sidenav-container class="sidenav-container">
|
||||
<mat-sidenav #snav fixedTopGap="56" mode="side" opened="true">
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="./">
|
||||
<a mat-list-item routerLink=".">
|
||||
<mat-icon class="menu-icon">dashboard</mat-icon>
|
||||
Dashboard
|
||||
</a>
|
||||
<a mat-list-item routerLink="Invoices">
|
||||
<mat-icon class="menu-icon">request_quote</mat-icon>
|
||||
<a mat-list-item routerLink="./datasets">
|
||||
<mat-icon class="menu-icon">table</mat-icon>
|
||||
Zbiory danych
|
||||
</a>
|
||||
<a mat-list-item routerLink=".">
|
||||
<mat-icon class="menu-icon">insights</mat-icon>
|
||||
Analiza MPK
|
||||
</a>
|
||||
<mat-divider></mat-divider>
|
||||
<a mat-list-item (click)="reloadApp()">
|
||||
<mat-icon class="menu-icon">refresh</mat-icon>
|
||||
|
||||
@@ -5,6 +5,8 @@ import { SwUpdate } from '@angular/service-worker';
|
||||
import * as moment from 'moment';
|
||||
import packageInfo from 'package.json';
|
||||
import { delay } from 'rxjs';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { User } from '../models/user.model';
|
||||
import { DataService } from '../services/data.service';
|
||||
import { DeviceService } from '../services/device.service';
|
||||
|
||||
@@ -26,7 +28,8 @@ export class MainViewComponent {
|
||||
public device$: DeviceService,
|
||||
private router$: Router,
|
||||
private swUpdate$: SwUpdate,
|
||||
private ngZone$: NgZone
|
||||
private ngZone$: NgZone,
|
||||
public auth$: AuthService
|
||||
) {
|
||||
this.swUpdate$.versionUpdates.subscribe(() => {
|
||||
this.reloadApp();
|
||||
@@ -38,7 +41,7 @@ export class MainViewComponent {
|
||||
});
|
||||
|
||||
//listen to loading subject
|
||||
data$.showLoader.subscribe(loading => {
|
||||
data$.showLoader.pipe(delay(0)).subscribe(loading => {
|
||||
this.ngZone$.run(() => {
|
||||
this.loading = loading;
|
||||
});
|
||||
@@ -51,6 +54,6 @@ export class MainViewComponent {
|
||||
// @ts-ignore
|
||||
google.accounts.id.disableAutoSelect();
|
||||
this.router$.navigate(['']);
|
||||
this.data$.currentUser = null;
|
||||
this.auth$.user = new User({});
|
||||
}
|
||||
}
|
||||
|
||||
33
Frontend/src/app/models/base.model.ts
Normal file
33
Frontend/src/app/models/base.model.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Moment } from 'moment';
|
||||
|
||||
import { Deserializable } from './deserializable.model';
|
||||
import { Serializable } from './serializable.model';
|
||||
import * as moment from 'moment';
|
||||
import { User } from './user.model';
|
||||
|
||||
export class Base implements Deserializable, Serializable {
|
||||
id?: string;
|
||||
createdAt?: Moment;
|
||||
modifiedAt?: Moment;
|
||||
createdById?: string;
|
||||
modifiedById?: string;
|
||||
createdBy?: User;
|
||||
modifiedBy?: User;
|
||||
|
||||
constructor(data: Partial<Base> = {}) {
|
||||
Object.assign(this, data);
|
||||
}
|
||||
|
||||
deserialize(input: any): this {
|
||||
if (input.createdAt) { input.createdAt = moment(input.createdAt); }
|
||||
if (input.modifiedAt) { input.modifiedAt = moment(input.modifiedAt); }
|
||||
if (input.createdBy) { input.createdBy = new User(input.createdBy); }
|
||||
if (input.modifiedBy) { input.modifiedBy = new User(input.modifiedBy); }
|
||||
Object.assign(this, input);
|
||||
return this;
|
||||
}
|
||||
|
||||
serialize() : any {
|
||||
return Object.assign({}, this);
|
||||
}
|
||||
}
|
||||
26
Frontend/src/app/models/dataRow.model copy.ts
Normal file
26
Frontend/src/app/models/dataRow.model copy.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Base } from './base.model';
|
||||
import { UntypedFormBuilder, Validators, UntypedFormGroup, FormControl } from '@angular/forms';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { DataService } from '../services/data.service';
|
||||
import { map } from 'rxjs';
|
||||
|
||||
export class DataRow extends Base {
|
||||
mpk?: string;
|
||||
value?: number;
|
||||
desc1?: string;
|
||||
desc2?: string;
|
||||
desc3?: string;
|
||||
desc4?: string;
|
||||
desc5?: string;
|
||||
|
||||
constructor(data: Partial<DataRow> = {}) {
|
||||
super();
|
||||
Object.assign(this, data);
|
||||
}
|
||||
|
||||
override deserialize(input: any): this {
|
||||
Object.assign(this, Object.assign(this, super.deserialize(input)));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
97
Frontend/src/app/models/dataSet.model.ts
Normal file
97
Frontend/src/app/models/dataSet.model.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { Base } from './base.model';
|
||||
import { UntypedFormBuilder, Validators, UntypedFormGroup } from '@angular/forms';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { DataService } from '../services/data.service';
|
||||
import { map } from 'rxjs';
|
||||
import { DataRow } from './dataRow.model copy';
|
||||
|
||||
export class DataSet extends Base {
|
||||
number?: string;
|
||||
name?: string;
|
||||
dataRows: DataRow[] = [];
|
||||
|
||||
constructor(data: Partial<DataSet> = {}) {
|
||||
super();
|
||||
Object.assign(this, data);
|
||||
}
|
||||
override deserialize(input: any): this {
|
||||
Object.assign(this, Object.assign(this, super.deserialize(input)));
|
||||
return this;
|
||||
}
|
||||
static getForm(fb: UntypedFormBuilder) {
|
||||
return fb.group({
|
||||
id: [null],
|
||||
number: ['', Validators.required],
|
||||
name: ['', Validators.required],
|
||||
createdAt: '',
|
||||
modifiedAt: '',
|
||||
createdBy: '',
|
||||
modifiedBy: '',
|
||||
});
|
||||
}
|
||||
fillForm(form: UntypedFormGroup) {
|
||||
form.patchValue(this);
|
||||
form.patchValue({
|
||||
createdBy: this.createdBy?.userName,
|
||||
modifiedBy: this.modifiedBy?.userName
|
||||
});
|
||||
}
|
||||
loadForm(form: UntypedFormGroup) {
|
||||
for (let field of Object.keys(form.controls)) {
|
||||
this[field as keyof DataSet] = form.controls[field].value;
|
||||
}
|
||||
this.createdBy = undefined;
|
||||
this.modifiedBy = undefined;
|
||||
}
|
||||
//API Actions
|
||||
/*
|
||||
static add(input: Account, _http: HttpClient, _data: DataService): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
_http.post<string>(`${environment.api.url}/accounts`, {...input.serialize(), modifiedById: _data.currentUser.id }).subscribe({
|
||||
next: (data) => resolve(data),
|
||||
error: (e) => reject(e)
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
static update(input: Account, _http: HttpClient, _data: DataService): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
_http.patch<string>(`${environment.api.url}/accounts`, {...input.serialize(), modifiedById: _data.currentUser.id }).subscribe({
|
||||
next: (data) => resolve(data),
|
||||
error: (e) => reject(e)
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
*/
|
||||
static getList(_http: HttpClient): any {
|
||||
return new Promise((resolve, reject) => {
|
||||
_http.get<DataSet[]>(`${environment.api.url}/datasets`)
|
||||
.pipe(map(data => data.map(x => new DataSet().deserialize(x))))
|
||||
.subscribe({
|
||||
next: (data) => resolve(data),
|
||||
error: (e) => reject(e)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
static getById(id: string, _http: HttpClient): Promise<DataSet> {
|
||||
return new Promise((resolve, reject) => {
|
||||
_http.get<DataSet>(`${environment.api.url}/datasets/${id}`).pipe(map(x => new DataSet().deserialize(x))).subscribe({
|
||||
next: (data) => resolve(data),
|
||||
error: (e) => reject(e)
|
||||
})
|
||||
});
|
||||
}
|
||||
/*
|
||||
static delete(id: string, _http: HttpClient): Promise<string> {
|
||||
return new Promise((resolve, reject)=> {
|
||||
_http.delete<string>(`${environment.api.url}/accounts/${id}`).subscribe({
|
||||
next: (data) => resolve(data),
|
||||
error: (e) => reject(e)
|
||||
})
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
3
Frontend/src/app/models/deserializable.model.ts
Normal file
3
Frontend/src/app/models/deserializable.model.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface Deserializable {
|
||||
deserialize(input: any): this;
|
||||
}
|
||||
3
Frontend/src/app/models/serializable.model.ts
Normal file
3
Frontend/src/app/models/serializable.model.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface Serializable {
|
||||
serialize(input: this): any;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>data-set-detail works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DataSetDetailComponent } from './data-set-detail.component';
|
||||
|
||||
describe('DataSetDetailComponent', () => {
|
||||
let component: DataSetDetailComponent;
|
||||
let fixture: ComponentFixture<DataSetDetailComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DataSetDetailComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DataSetDetailComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-data-set-detail',
|
||||
templateUrl: './data-set-detail.component.html',
|
||||
styleUrls: ['./data-set-detail.component.scss']
|
||||
})
|
||||
export class DataSetDetailComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<div>
|
||||
<form [formGroup]="form" (ngSubmit)="save()" novalidate>
|
||||
<mat-card appearance="outlined">
|
||||
<mat-toolbar color="secondary">
|
||||
Edycja zbioru danych
|
||||
<span class="fill-to-right"></span>
|
||||
<button mat-button type="submit" [disabled]="form.invalid">Zapisz</button>
|
||||
<button mat-button type="button" routerLink="../..">Anuluj</button>
|
||||
</mat-toolbar>
|
||||
<mat-card-content>
|
||||
<mat-grid-list cols="2" rowHeight="90px">
|
||||
<mat-grid-tile>
|
||||
<mat-form-field class="detail-input">
|
||||
<mat-label>Numer</mat-label>
|
||||
<input matInput formControlName="number">
|
||||
<mat-error *ngIf="form.controls['number'].touched && form.controls['number'].invalid">
|
||||
Pole obowiązkowe
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</mat-grid-tile>
|
||||
|
||||
<mat-grid-tile>
|
||||
<mat-form-field class="detail-input">
|
||||
<mat-select placeholder="Źródło" formControlName="name" (selectionChange)="generateNumber()">
|
||||
<mat-option value="Import ręczny">Import ręczny</mat-option>
|
||||
<mat-option value="Arkusz Google">Arkusz Google</mat-option>
|
||||
<mat-option value="SAP">SAP</mat-option>
|
||||
<mat-option value="Symfonia">Symfonia</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="form.controls['name'].touched && form.controls['name'].invalid">
|
||||
Pole obowiązkowe
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
@import "../../../main-view/main-view.component.scss";
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DataSetEditComponent } from './data-set-edit.component';
|
||||
|
||||
describe('DataSetEditComponent', () => {
|
||||
let component: DataSetEditComponent;
|
||||
let fixture: ComponentFixture<DataSetEditComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DataSetEditComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DataSetEditComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import moment from 'moment';
|
||||
import { AuthService } from 'src/app/auth/auth.service';
|
||||
import { DataSet } from 'src/app/models/dataSet.model';
|
||||
import { DataService } from 'src/app/services/data.service';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@Component({
|
||||
selector: 'app-data-set-edit',
|
||||
templateUrl: './data-set-edit.component.html',
|
||||
styleUrls: ['./data-set-edit.component.scss']
|
||||
})
|
||||
export class DataSetEditComponent implements OnInit {
|
||||
|
||||
public form!: UntypedFormGroup;
|
||||
private document!: DataSet;
|
||||
|
||||
constructor(
|
||||
private fb$: UntypedFormBuilder,
|
||||
private router$: Router,
|
||||
private http$: HttpClient,
|
||||
private data$: DataService,
|
||||
private route$: ActivatedRoute,
|
||||
private dialog$: MatDialog,
|
||||
private auth$: AuthService
|
||||
) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.form = DataSet.getForm(this.fb$);
|
||||
this.document = await this.load();
|
||||
this.document.fillForm(this.form);
|
||||
}
|
||||
private load(): Promise<DataSet> {
|
||||
return new Promise((resolve) => {
|
||||
const id = this.route$.snapshot.paramMap.get('id') || "";
|
||||
if (this.route$.snapshot.paramMap.get('id') === 'new') {
|
||||
resolve(new DataSet({ id: uuidv4(), createdById: this.auth$.user.id, createdAt: moment(),
|
||||
modifiedAt: moment() })) // new element
|
||||
return;
|
||||
}
|
||||
resolve(DataSet.getById(id, this.http$))
|
||||
});
|
||||
}
|
||||
async save() {
|
||||
if (this.form.invalid) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
this.document.loadForm(this.form);
|
||||
let id;
|
||||
if (this.route$.snapshot.paramMap.get('id') === 'new') {
|
||||
id = await DataSet.add(this.document, this.http$, this._data);
|
||||
} else {
|
||||
id = await DataSet.update(this.document, this._http, this._data);
|
||||
}
|
||||
this._router.navigate(['../../Detail', id], { relativeTo: this._route});
|
||||
*/
|
||||
}
|
||||
generateNumber() {
|
||||
this.form.patchValue({
|
||||
number: `${this.form.controls['name'].value}-${moment().format("YYYY")}-${moment().format("MM")}`
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<div class="list-container mat-elevation-z8">
|
||||
<div class="list-header">
|
||||
<mat-grid-list cols="10" rowHeight="60">
|
||||
<mat-grid-tile>
|
||||
<button mat-button routerLink="Edit/new">
|
||||
Dodaj
|
||||
</button>
|
||||
</mat-grid-tile>
|
||||
<mat-grid-tile [colspan]="8">
|
||||
<mat-form-field class="searchListInput">
|
||||
<mat-label>Filtruj</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event)">
|
||||
</mat-form-field>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
</div>
|
||||
|
||||
<mat-table #table [dataSource]="dataSource" [trackBy]="trackByUid" matSort class="animate">
|
||||
|
||||
<ng-container matColumnDef="number">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Numer</mat-header-cell>
|
||||
<mat-cell *matCellDef="let item">{{item.number}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Źródło</mat-header-cell>
|
||||
<mat-cell *matCellDef="let item">{{item.name}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let item; columns: displayedColumns;" [routerLink]="['Detail/', item.id]"></mat-row>
|
||||
</mat-table>
|
||||
<mat-paginator #paginator
|
||||
[pageSize]="10"
|
||||
[pageSizeOptions]="[5, 10, 20]">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
@import "../../../main-view/main-view.component.scss";
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DataSetsListComponent } from './data-sets-list.component';
|
||||
|
||||
describe('DataSetsListComponent', () => {
|
||||
let component: DataSetsListComponent;
|
||||
let fixture: ComponentFixture<DataSetsListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DataSetsListComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DataSetsListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { DataSet } from 'src/app/models/dataSet.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-data-sets-list',
|
||||
templateUrl: './data-sets-list.component.html',
|
||||
styleUrls: ['./data-sets-list.component.scss']
|
||||
})
|
||||
export class DataSetsListComponent implements OnInit {
|
||||
displayedColumns = ['number', 'name'];
|
||||
dataSource!: MatTableDataSource<DataSet>;
|
||||
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
|
||||
constructor(
|
||||
private _http: HttpClient
|
||||
) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.dataSource = new MatTableDataSource(await DataSet.getList(this._http));
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
applyFilter(event: Event) {
|
||||
const filterValue = (event.target as HTMLInputElement).value;
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
}
|
||||
trackByUid(index : number, item : DataSet) {
|
||||
return item.id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { DataSetDetailComponent } from './data-set-detail/data-set-detail.component';
|
||||
import { DataSetEditComponent } from './data-set-edit/data-set-edit.component';
|
||||
import { DataSetsListComponent } from './data-sets-list/data-sets-list.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: DataSetsListComponent },
|
||||
{ path: 'Edit/:id', component: DataSetEditComponent },
|
||||
{ path: 'Detail/:id', component: DataSetDetailComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class DataSetsRoutingModule { }
|
||||
24
Frontend/src/app/modules/data-sets/data-sets.module.ts
Normal file
24
Frontend/src/app/modules/data-sets/data-sets.module.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { DataSetsRoutingModule } from './data-sets-routing.module';
|
||||
import { DataSetsListComponent } from './data-sets-list/data-sets-list.component';
|
||||
import { MaterialModule } from 'src/app/material.module';
|
||||
import { DataSetDetailComponent } from './data-set-detail/data-set-detail.component';
|
||||
import { DataSetEditComponent } from './data-set-edit/data-set-edit.component';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DataSetsListComponent,
|
||||
DataSetDetailComponent,
|
||||
DataSetEditComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
DataSetsRoutingModule,
|
||||
MaterialModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule
|
||||
]
|
||||
})
|
||||
export class DataSetsModule { }
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { User } from '../models/user';
|
||||
import { User } from '../models/user.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DataService {
|
||||
currentUser?: User | null;
|
||||
public showLoader: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
|
||||
constructor() { }
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
export const environment = {
|
||||
production: false,
|
||||
api: {
|
||||
//url: "http://localhost:5400/api"
|
||||
url: "https://diuna.bim-it.pl/api"
|
||||
url: "http://localhost:5400/api"
|
||||
//url: "https://diuna.bim-it.pl/api"
|
||||
},
|
||||
google: {
|
||||
clientId: "107631825312-bkfe438ehr9k9ecb2h76g802tj6advma.apps.googleusercontent.com"
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace WebAPI
|
||||
public class AppDbContext : DbContext
|
||||
{
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<DataSet> DataSets { get; set; }
|
||||
public DbSet<DataRow> DataRows { get; set; }
|
||||
|
||||
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
|
||||
{
|
||||
|
||||
37
WebAPI/Controllers/DataSetsController.cs
Normal file
37
WebAPI/Controllers/DataSetsController.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Google.Apis.Auth;
|
||||
using Google.Apis.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Identity.Client.Platforms.Features.DesktopOs.Kerberos;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Configuration;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using WebAPI.Models;
|
||||
|
||||
namespace WebAPI.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
public class DataSetsController : Controller
|
||||
{
|
||||
private readonly AppDbContext db;
|
||||
public DataSetsController(AppDbContext _db) { db = _db; }
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(db.DataSets.Where(x => !x.IsDeleted).ToList());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
192
WebAPI/Migrations/20221211210507_DataSetsAndDataRows.Designer.cs
generated
Normal file
192
WebAPI/Migrations/20221211210507_DataSetsAndDataRows.Designer.cs
generated
Normal file
@@ -0,0 +1,192 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using WebAPI;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace WebAPI.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20221211210507_DataSetsAndDataRows")]
|
||||
partial class DataSetsAndDataRows
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataRow", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("CreatedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<Guid?>("DataSetId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("Desc1")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc2")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc3")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc4")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc5")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("MPK")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("ModifiedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("ModifiedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<float>("Value")
|
||||
.HasColumnType("real");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("DataSetId");
|
||||
|
||||
b.HasIndex("ModifiedById");
|
||||
|
||||
b.ToTable("DataRows");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataSet", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("CreatedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTime>("ModifiedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("ModifiedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("ModifiedById");
|
||||
|
||||
b.ToTable("DataSets");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataRow", b =>
|
||||
{
|
||||
b.HasOne("WebAPI.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("WebAPI.Models.DataSet", null)
|
||||
.WithMany("DataRows")
|
||||
.HasForeignKey("DataSetId");
|
||||
|
||||
b.HasOne("WebAPI.Models.User", "ModifiedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("ModifiedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("ModifiedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataSet", b =>
|
||||
{
|
||||
b.HasOne("WebAPI.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("WebAPI.Models.User", "ModifiedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("ModifiedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("ModifiedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataSet", b =>
|
||||
{
|
||||
b.Navigation("DataRows");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
121
WebAPI/Migrations/20221211210507_DataSetsAndDataRows.cs
Normal file
121
WebAPI/Migrations/20221211210507_DataSetsAndDataRows.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace WebAPI.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class DataSetsAndDataRows : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DataSets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Number = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
ModifiedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
IsDeleted = table.Column<bool>(type: "bit", nullable: false),
|
||||
CreatedById = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
ModifiedById = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DataSets", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_DataSets_Users_CreatedById",
|
||||
column: x => x.CreatedById,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.NoAction);
|
||||
table.ForeignKey(
|
||||
name: "FK_DataSets_Users_ModifiedById",
|
||||
column: x => x.ModifiedById,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.NoAction);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DataRows",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
MPK = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
Value = table.Column<float>(type: "real", nullable: false),
|
||||
Desc1 = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
Desc2 = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
Desc3 = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
Desc4 = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
Desc5 = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
ModifiedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
IsDeleted = table.Column<bool>(type: "bit", nullable: false),
|
||||
CreatedById = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
ModifiedById = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
DataSetId = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DataRows", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_DataRows_DataSets_DataSetId",
|
||||
column: x => x.DataSetId,
|
||||
principalTable: "DataSets",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_DataRows_Users_CreatedById",
|
||||
column: x => x.CreatedById,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.NoAction);
|
||||
table.ForeignKey(
|
||||
name: "FK_DataRows_Users_ModifiedById",
|
||||
column: x => x.ModifiedById,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.NoAction);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataRows_CreatedById",
|
||||
table: "DataRows",
|
||||
column: "CreatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataRows_DataSetId",
|
||||
table: "DataRows",
|
||||
column: "DataSetId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataRows_ModifiedById",
|
||||
table: "DataRows",
|
||||
column: "ModifiedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataSets_CreatedById",
|
||||
table: "DataSets",
|
||||
column: "CreatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DataSets_ModifiedById",
|
||||
table: "DataSets",
|
||||
column: "ModifiedById");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "DataRows");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DataSets");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,100 @@ namespace WebAPI.Migrations
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataRow", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("CreatedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<Guid?>("DataSetId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("Desc1")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc2")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc3")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc4")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Desc5")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("MPK")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("ModifiedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("ModifiedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<float>("Value")
|
||||
.HasColumnType("real");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("DataSetId");
|
||||
|
||||
b.HasIndex("ModifiedById");
|
||||
|
||||
b.ToTable("DataRows");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataSet", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("CreatedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTime>("ModifiedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("ModifiedById")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("ModifiedById");
|
||||
|
||||
b.ToTable("DataSets");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -42,6 +136,53 @@ namespace WebAPI.Migrations
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataRow", b =>
|
||||
{
|
||||
b.HasOne("WebAPI.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("WebAPI.Models.DataSet", null)
|
||||
.WithMany("DataRows")
|
||||
.HasForeignKey("DataSetId");
|
||||
|
||||
b.HasOne("WebAPI.Models.User", "ModifiedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("ModifiedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("ModifiedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataSet", b =>
|
||||
{
|
||||
b.HasOne("WebAPI.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("WebAPI.Models.User", "ModifiedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("ModifiedById")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("ModifiedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WebAPI.Models.DataSet", b =>
|
||||
{
|
||||
b.Navigation("DataRows");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
||||
31
WebAPI/Models/DataRow.cs
Normal file
31
WebAPI/Models/DataRow.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace WebAPI.Models
|
||||
{
|
||||
public class DataRow
|
||||
{
|
||||
#region Properties
|
||||
[Key]
|
||||
public Guid Id { get; set; }
|
||||
[Required]
|
||||
public string? MPK { get; set; }
|
||||
[Required]
|
||||
public float Value { get; set; }
|
||||
//Description fields
|
||||
public string? Desc1 { get; set; }
|
||||
public string? Desc2 { get; set; }
|
||||
public string? Desc3 { get; set; }
|
||||
public string? Desc4 { get; set; }
|
||||
public string? Desc5 { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime ModifiedAt { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
#endregion
|
||||
#region Relations
|
||||
public Guid CreatedById { get; set; }
|
||||
public User? CreatedBy { get; set; }
|
||||
public Guid ModifiedById { get; set; }
|
||||
public User? ModifiedBy { get; set; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
25
WebAPI/Models/DataSet.cs
Normal file
25
WebAPI/Models/DataSet.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace WebAPI.Models
|
||||
{
|
||||
public class DataSet
|
||||
{
|
||||
#region Properties
|
||||
[Key]
|
||||
public Guid Id { get; set; }
|
||||
[Required]
|
||||
public string? Number { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime ModifiedAt { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
#endregion
|
||||
#region Relations
|
||||
public ICollection<DataRow>? DataRows { get; set; }
|
||||
public Guid CreatedById { get; set; }
|
||||
public User? CreatedBy { get; set; }
|
||||
public Guid ModifiedById { get; set; }
|
||||
public User? ModifiedBy { get; set; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user