From 314edeec40a86f4c4d637569381d8bfeb0e2db18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Zieli=C5=84ski?= Date: Fri, 23 Jun 2023 15:32:59 +0200 Subject: [PATCH] Standalone app - auto migrate --- Frontend/src/app/app.component.ts | 9 ++- Frontend/src/app/app.module.ts | 58 --------------- .../login-page/login-page.component.ts | 14 ++-- .../notifications.component.spec.ts | 4 +- .../notifications/notifications.component.ts | 14 +++- .../src/app/main-view/main-view.component.ts | 18 +++-- Frontend/src/app/material.module.ts | 73 ------------------- .../dashboard/board/board.component.ts | 9 ++- .../app/modules/dashboard/dashboard.module.ts | 14 ++-- .../layer-detail/layer-detail.component.ts | 22 ++++-- .../layers/layer-edit/layer-edit.component.ts | 26 +++++-- .../layers-list/layers-list.component.ts | 19 +++-- .../src/app/modules/layers/layers.module.ts | 23 +++--- Frontend/src/main.ts | 40 +++++++++- WebAPI/Models/Record.cs | 6 +- 15 files changed, 149 insertions(+), 200 deletions(-) delete mode 100644 Frontend/src/app/app.module.ts delete mode 100644 Frontend/src/app/material.module.ts diff --git a/Frontend/src/app/app.component.ts b/Frontend/src/app/app.component.ts index 35d3e1b..da92df9 100644 --- a/Frontend/src/app/app.component.ts +++ b/Frontend/src/app/app.component.ts @@ -1,9 +1,12 @@ import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'] + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], + standalone: true, + imports: [RouterOutlet] }) export class AppComponent { title = 'DiunaBI'; diff --git a/Frontend/src/app/app.module.ts b/Frontend/src/app/app.module.ts deleted file mode 100644 index 908df17..0000000 --- a/Frontend/src/app/app.module.ts +++ /dev/null @@ -1,58 +0,0 @@ -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'; -import { MainViewComponent } from './main-view/main-view.component'; -import { MaterialModule } from './material.module'; -import { LoginPageComponent } from './components/login-page/login-page.component'; -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'; -import { NotificationsComponent } from './components/notifications/notifications.component'; - -registerLocaleData(localePl, 'pl-PL'); - -@NgModule({ - declarations: [ - AppComponent, - MainViewComponent, - LoginPageComponent, - NotificationsComponent - ], - imports: [ - BrowserModule, - AppRoutingModule, - BrowserAnimationsModule, - MaterialModule, - HttpClientModule, - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: !isDevMode(), - // Register the ServiceWorker as soon as the application is stable - // or after 30 seconds (whichever comes first). - registrationStrategy: 'registerWhenStable:30000' - }) - ], - 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, - multi: true - }, - { - provide: HTTP_INTERCEPTORS, - useClass: AuthInterceptor, - multi: true - }, - ], - bootstrap: [AppComponent] -}) -export class AppModule { } diff --git a/Frontend/src/app/components/login-page/login-page.component.ts b/Frontend/src/app/components/login-page/login-page.component.ts index 1d5152d..f3da9c3 100644 --- a/Frontend/src/app/components/login-page/login-page.component.ts +++ b/Frontend/src/app/components/login-page/login-page.component.ts @@ -4,12 +4,16 @@ import jwt_decode from "jwt-decode"; import { AuthService } from 'src/app/auth/auth.service'; import { User } from 'src/app/models/user.model'; import { NotificationsService } from 'src/app/services/notifications.service'; -import { environment } from 'src/environments/environment'; +import { environment } from 'src/environments/environment'; +import { MatCardModule } from '@angular/material/card'; +import { NgIf } from '@angular/common'; -@Component({ - selector: 'app-login-page', - templateUrl: './login-page.component.html', - styleUrls: ['./login-page.component.scss'] +@Component({ + selector: 'app-login-page', + templateUrl: './login-page.component.html', + styleUrls: ['./login-page.component.scss'], + standalone: true, + imports: [NgIf, MatCardModule] }) export class LoginPageComponent implements OnInit { diff --git a/Frontend/src/app/components/notifications/notifications.component.spec.ts b/Frontend/src/app/components/notifications/notifications.component.spec.ts index 07f2f87..f0e076e 100644 --- a/Frontend/src/app/components/notifications/notifications.component.spec.ts +++ b/Frontend/src/app/components/notifications/notifications.component.spec.ts @@ -8,8 +8,8 @@ describe('NotificationsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ NotificationsComponent ] - }) + imports: [NotificationsComponent] +}) .compileComponents(); fixture = TestBed.createComponent(NotificationsComponent); diff --git a/Frontend/src/app/components/notifications/notifications.component.ts b/Frontend/src/app/components/notifications/notifications.component.ts index ebb4747..7cc1fb0 100644 --- a/Frontend/src/app/components/notifications/notifications.component.ts +++ b/Frontend/src/app/components/notifications/notifications.component.ts @@ -1,10 +1,18 @@ import { Component } from '@angular/core'; import { NotificationsService } from 'src/app/services/notifications.service'; +import { MatCardModule } from '@angular/material/card'; +import { NgFor, NgIf } from '@angular/common'; @Component({ - selector: 'app-notifications', - templateUrl: './notifications.component.html', - styleUrls: ['./notifications.component.scss'], + selector: 'app-notifications', + templateUrl: './notifications.component.html', + styleUrls: ['./notifications.component.scss'], + standalone: true, + imports: [ + NgFor, + MatCardModule, + NgIf, + ], }) export class NotificationsComponent { constructor( diff --git a/Frontend/src/app/main-view/main-view.component.ts b/Frontend/src/app/main-view/main-view.component.ts index 0a7aae5..1d1b8f6 100644 --- a/Frontend/src/app/main-view/main-view.component.ts +++ b/Frontend/src/app/main-view/main-view.component.ts @@ -1,6 +1,6 @@ import { Component, NgZone, ViewChild } from '@angular/core'; -import { MatSidenav } from '@angular/material/sidenav'; -import { NavigationStart, Router } from '@angular/router'; +import { MatSidenav, MatSidenavModule } from '@angular/material/sidenav'; +import { NavigationStart, Router, RouterLink, RouterOutlet } from '@angular/router'; import { SwUpdate } from '@angular/service-worker'; import * as moment from 'moment'; import packageInfo from 'package.json'; @@ -10,11 +10,19 @@ import { AuthService } from '../auth/auth.service'; import { DataService } from '../services/data.service'; import { DeviceService } from '../services/device.service'; import { NotificationsService } from '../services/notifications.service'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatListModule } from '@angular/material/list'; +import { MatButtonModule } from '@angular/material/button'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatIconModule } from '@angular/material/icon'; +import { NgIf, DatePipe } from '@angular/common'; @Component({ - selector: 'app-main-view', - templateUrl: './main-view.component.html', - styleUrls: ['./main-view.component.scss'] + selector: 'app-main-view', + templateUrl: './main-view.component.html', + styleUrls: ['./main-view.component.scss'], + standalone: true, + imports: [NgIf, MatIconModule, MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, RouterLink, MatDividerModule, RouterOutlet, DatePipe] }) export class MainViewComponent { @ViewChild('snav') snav?: MatSidenav; diff --git a/Frontend/src/app/material.module.ts b/Frontend/src/app/material.module.ts deleted file mode 100644 index ab90923..0000000 --- a/Frontend/src/app/material.module.ts +++ /dev/null @@ -1,73 +0,0 @@ -import {NgModule} from '@angular/core'; -//import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { MatButtonModule } from '@angular/material/button'; -//import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatCardModule } from '@angular/material/card'; -//import { MatCheckboxModule } from '@angular/material/checkbox'; -//import { MatChipsModule } from '@angular/material/chips'; -//import { MatStepperModule } from '@angular/material/stepper'; -//import { MatDatepickerModule } from '@angular/material/datepicker'; -//import { MatDialogModule } from '@angular/material/dialog'; -//import { MatExpansionModule } from '@angular/material/expansion'; -import { MatGridListModule } from '@angular/material/grid-list'; -import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; -import { MatListModule } from '@angular/material/list'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatPaginatorModule } from '@angular/material/paginator'; -//import { MatProgressBarModule } from '@angular/material/progress-bar'; -//import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -//import { MatRadioModule } from '@angular/material/radio'; -//import { MatRippleModule } from '@angular/material/core'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -//import { MatSliderModule } from '@angular/material/slider'; -//import { MatSlideToggleModule } from '@angular/material/slide-toggle'; -import { MatSortModule } from '@angular/material/sort'; -import { MatTableModule } from '@angular/material/table'; -//import { MatTabsModule } from '@angular/material/tabs'; -import { MatToolbarModule } from '@angular/material/toolbar'; -//import { MatTooltipModule } from '@angular/material/tooltip'; -//import {CdkTableModule} from '@angular/cdk/table'; -//import {MatBadgeModule} from '@angular/material/badge'; -import {MatBottomSheetModule} from '@angular/material/bottom-sheet'; - -@NgModule({ - exports: [ - // CdkTableModule, - // MatAutocompleteModule, - MatButtonModule, - // MatButtonToggleModule, - MatCardModule, - // MatCheckboxModule, - // MatChipsModule, - // MatStepperModule, - // MatDatepickerModule, - // MatDialogModule, - // MatExpansionModule, - MatGridListModule, - MatIconModule, - MatInputModule, - MatListModule, - MatMenuModule, - MatPaginatorModule, - // MatProgressBarModule, - // MatProgressSpinnerModule, - // MatRadioModule, - // MatRippleModule, - MatSelectModule, - // MatSidenavModule, - // MatSliderModule, - // MatSlideToggleModule, - MatSortModule, - MatTableModule, - // MatTabsModule, - MatToolbarModule, - // MatTooltipModule, - MatSidenavModule, - // MatBadgeModule, - MatBottomSheetModule - ], - providers: [] -}) -export class MaterialModule {} \ No newline at end of file diff --git a/Frontend/src/app/modules/dashboard/board/board.component.ts b/Frontend/src/app/modules/dashboard/board/board.component.ts index 41c3d00..7b0921e 100644 --- a/Frontend/src/app/modules/dashboard/board/board.component.ts +++ b/Frontend/src/app/modules/dashboard/board/board.component.ts @@ -2,10 +2,11 @@ import { Component } from '@angular/core'; import { DeviceService } from 'src/app/services/device.service'; -@Component({ - selector: 'app-board', - templateUrl: './board.component.html', - styleUrls: ['./board.component.scss'] +@Component({ + selector: 'app-board', + templateUrl: './board.component.html', + styleUrls: ['./board.component.scss'], + standalone: true }) export class BoardComponent { constructor( diff --git a/Frontend/src/app/modules/dashboard/dashboard.module.ts b/Frontend/src/app/modules/dashboard/dashboard.module.ts index b119f9c..569da12 100644 --- a/Frontend/src/app/modules/dashboard/dashboard.module.ts +++ b/Frontend/src/app/modules/dashboard/dashboard.module.ts @@ -5,13 +5,11 @@ import { DashboardRoutingModule } from './dashboard-routing.module'; import { BoardComponent } from './board/board.component'; -@NgModule({ - declarations: [ - BoardComponent - ], - imports: [ - CommonModule, - DashboardRoutingModule - ] +@NgModule({ + imports: [ + CommonModule, + DashboardRoutingModule, + BoardComponent + ] }) export class DashboardModule { } diff --git a/Frontend/src/app/modules/layers/layer-detail/layer-detail.component.ts b/Frontend/src/app/modules/layers/layer-detail/layer-detail.component.ts index 8466d58..5fd0238 100644 --- a/Frontend/src/app/modules/layers/layer-detail/layer-detail.component.ts +++ b/Frontend/src/app/modules/layers/layer-detail/layer-detail.component.ts @@ -1,20 +1,28 @@ -import { DatePipe } from '@angular/common'; +import { DatePipe, NgIf, DecimalPipe } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { Component, OnInit, ViewChild } from '@angular/core'; -import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms'; -import { MatSort, MatSortable } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; +import { UntypedFormGroup, UntypedFormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatSort, MatSortable, MatSortModule } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { ActivatedRoute } from '@angular/router'; import { AuthService } from 'src/app/auth/auth.service'; import { Layer } from 'src/app/models/layer.model'; import { Record } from 'src/app/models/record.model'; import { NotificationsService } from 'src/app/services/notifications.service'; import { environment } from 'src/environments/environment'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatButtonModule } from '@angular/material/button'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatCardModule } from '@angular/material/card'; @Component({ - selector: 'app-layer-detail', - templateUrl: './layer-detail.component.html', - styleUrls: ['./layer-detail.component.scss'] + selector: 'app-layer-detail', + templateUrl: './layer-detail.component.html', + styleUrls: ['./layer-detail.component.scss'], + standalone: true, + imports: [FormsModule, ReactiveFormsModule, MatCardModule, MatToolbarModule, MatButtonModule, MatGridListModule, MatFormFieldModule, MatInputModule, NgIf, MatTableModule, MatSortModule, DecimalPipe] }) export class LayerDetailComponent implements OnInit { diff --git a/Frontend/src/app/modules/layers/layer-edit/layer-edit.component.ts b/Frontend/src/app/modules/layers/layer-edit/layer-edit.component.ts index f804d0d..4e81854 100644 --- a/Frontend/src/app/modules/layers/layer-edit/layer-edit.component.ts +++ b/Frontend/src/app/modules/layers/layer-edit/layer-edit.component.ts @@ -1,20 +1,32 @@ import { HttpClient } from '@angular/common/http'; import { Component, OnInit, ViewChild } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { Router, ActivatedRoute } from '@angular/router'; +import { UntypedFormBuilder, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatSort, MatSortModule } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { Router, ActivatedRoute, RouterLink } from '@angular/router'; import moment from 'moment'; import { AuthService } from 'src/app/auth/auth.service'; import { Layer } from 'src/app/models/layer.model'; import { Record } from 'src/app/models/record.model'; import { environment } from 'src/environments/environment'; import { v4 as uuidv4 } from 'uuid'; +import { MatIconModule } from '@angular/material/icon'; +import { MatOptionModule } from '@angular/material/core'; +import { MatSelectModule } from '@angular/material/select'; +import { NgIf, DecimalPipe } from '@angular/common'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatButtonModule } from '@angular/material/button'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatCardModule } from '@angular/material/card'; @Component({ - selector: 'app-layer-edit', - templateUrl: './layer-edit.component.html', - styleUrls: ['./layer-edit.component.scss'] + selector: 'app-layer-edit', + templateUrl: './layer-edit.component.html', + styleUrls: ['./layer-edit.component.scss'], + standalone: true, + imports: [FormsModule, ReactiveFormsModule, MatCardModule, MatToolbarModule, MatButtonModule, RouterLink, MatGridListModule, MatFormFieldModule, MatInputModule, NgIf, MatSelectModule, MatOptionModule, MatIconModule, MatTableModule, MatSortModule, DecimalPipe] }) export class LayerEditComponent implements OnInit { diff --git a/Frontend/src/app/modules/layers/layers-list/layers-list.component.ts b/Frontend/src/app/modules/layers/layers-list/layers-list.component.ts index 5828dde..e535760 100644 --- a/Frontend/src/app/modules/layers/layers-list/layers-list.component.ts +++ b/Frontend/src/app/modules/layers/layers-list/layers-list.component.ts @@ -1,14 +1,21 @@ import { HttpClient } from '@angular/common/http'; import { Component, OnInit, ViewChild } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort, MatSortable } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; +import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; +import { MatSort, MatSortable, MatSortModule } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { Layer } from 'src/app/models/layer.model'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatGridListModule } from '@angular/material/grid-list'; @Component({ - selector: 'app-layers-list', - templateUrl: './layers-list.component.html', - styleUrls: ['./layers-list.component.scss'] + selector: 'app-layers-list', + templateUrl: './layers-list.component.html', + styleUrls: ['./layers-list.component.scss'], + standalone: true, + imports: [MatGridListModule, MatButtonModule, RouterLink, MatFormFieldModule, MatInputModule, MatTableModule, MatSortModule, MatPaginatorModule] }) export class LayersListComponent implements OnInit { displayedColumns = ['number', 'name', 'source']; diff --git a/Frontend/src/app/modules/layers/layers.module.ts b/Frontend/src/app/modules/layers/layers.module.ts index cec47d4..e466a03 100644 --- a/Frontend/src/app/modules/layers/layers.module.ts +++ b/Frontend/src/app/modules/layers/layers.module.ts @@ -1,6 +1,6 @@ import { NgModule } from '@angular/core'; import { CommonModule, DatePipe } from '@angular/common'; -import { MaterialModule } from 'src/app/material.module'; + import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { LayersListComponent } from './layers-list/layers-list.component'; import { LayerEditComponent } from './layer-edit/layer-edit.component'; @@ -8,20 +8,17 @@ import { LayerDetailComponent } from './layer-detail/layer-detail.component'; import { LayersRoutingModule } from './layers-routing.module'; @NgModule({ - declarations: [ + imports: [ + CommonModule, + LayersRoutingModule, + FormsModule, + ReactiveFormsModule, LayersListComponent, LayerEditComponent, LayerDetailComponent - ], - imports: [ - CommonModule, - LayersRoutingModule, - MaterialModule, - FormsModule, - ReactiveFormsModule - ], - providers: [ - DatePipe - ] +], + providers: [ + DatePipe + ] }) export class LayersModule { } diff --git a/Frontend/src/main.ts b/Frontend/src/main.ts index c7b673c..d761781 100644 --- a/Frontend/src/main.ts +++ b/Frontend/src/main.ts @@ -1,12 +1,46 @@ -import { enableProdMode } from '@angular/core'; +import { enableProdMode, LOCALE_ID, isDevMode, importProvidersFrom } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app/app.module'; + import { environment } from './environments/environment'; +import { AppComponent } from './app/app.component'; +import { ServiceWorkerModule } from '@angular/service-worker'; +import { provideAnimations } from '@angular/platform-browser/animations'; +import { AppRoutingModule } from './app/app-routing.module'; +import { BrowserModule, bootstrapApplication } from '@angular/platform-browser'; +import { AuthInterceptor } from './app/interceptors/auth.interceptor'; +import { LoaderInterceptor } from './app/interceptors/loader.interceptor'; +import { HTTP_INTERCEPTORS, withInterceptorsFromDi, provideHttpClient } from '@angular/common/http'; +import { MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS } from '@angular/material-moment-adapter'; +import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom(BrowserModule, AppRoutingModule, ServiceWorkerModule.register('ngsw-worker.js', { + enabled: !isDevMode(), + // Register the ServiceWorker as soon as the application is stable + // or after 30 seconds (whichever comes first). + registrationStrategy: 'registerWhenStable:30000' + })), + { 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, + multi: true + }, + { + provide: HTTP_INTERCEPTORS, + useClass: AuthInterceptor, + multi: true + }, + provideAnimations(), + provideHttpClient(withInterceptorsFromDi()) + ] +}) .catch(err => console.error(err)); diff --git a/WebAPI/Models/Record.cs b/WebAPI/Models/Record.cs index a557ad4..f76f00e 100644 --- a/WebAPI/Models/Record.cs +++ b/WebAPI/Models/Record.cs @@ -8,11 +8,11 @@ namespace WebAPI.Models [Key] public Guid Id { get; set; } [Required] - public string? Code { get; set; } + public string? Code { get; set; } // number [Required] - public float Value { get; set; } + public float Value { get; set; } // string //Description fields - public string? Desc1 { get; set; } + public string? Desc1 { get; set; } // Desc1 => Value1 public string? Desc2 { get; set; } public string? Desc3 { get; set; } public string? Desc4 { get; set; }