- - -
- - - Rocket Ship - - - - - - - - - - {{ title }} app is running! - - - Rocket Ship Smoke - - - + +
+
+
+ +
- - -

Resources

-

Here are some links to help you get started:

- - - - -

Next Steps

-

What do you want to do next with your app?

- - - -
- - - - - - - - - - - -
- - -
-
ng generate component xyz
-
ng add @angular/material
-
ng add @angular/pwa
-
ng add _____
-
ng test
-
ng build
-
- - - - - - - - - Gray Clouds Background - - - -
- - - - - - - - - - +
\ No newline at end of file diff --git a/Frontend/src/app/app.module.ts b/Frontend/src/app/app.module.ts index b1c6c96..f8bb714 100644 --- a/Frontend/src/app/app.module.ts +++ b/Frontend/src/app/app.module.ts @@ -3,14 +3,20 @@ 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'; @NgModule({ declarations: [ - AppComponent + AppComponent, + MainViewComponent ], imports: [ BrowserModule, - AppRoutingModule + AppRoutingModule, + BrowserAnimationsModule, + MaterialModule ], providers: [], bootstrap: [AppComponent] diff --git a/Frontend/src/app/main-view/main-view.component.html b/Frontend/src/app/main-view/main-view.component.html new file mode 100644 index 0000000..34c8de1 --- /dev/null +++ b/Frontend/src/app/main-view/main-view.component.html @@ -0,0 +1,51 @@ +
+ +
+
+
+ Obróć telefon.
+ screen_rotation +
+
+
+ + +

Diuna

+ + + + {{_data.currentUser.userName}} + + +
+ + + + + dashboard + Dashboard + + + request_quote + Zbiory danych + + + + refresh + {{appVersion}} + + + + + + + + + +
\ No newline at end of file diff --git a/Frontend/src/app/main-view/main-view.component.scss b/Frontend/src/app/main-view/main-view.component.scss new file mode 100644 index 0000000..b95f92c --- /dev/null +++ b/Frontend/src/app/main-view/main-view.component.scss @@ -0,0 +1,228 @@ +.main-container { + display: flex; + flex-direction: column; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} +.sidenav-container { + flex: 1; +} +mat-icon.menu-icon { + margin-right: 3px; + color: gray; +} +mat-nav-list.menu-sublist { + padding-left: 10px; +} +mat-nav-list.menu-sublist > a { + font-size: small; +} +div.footer { + text-align: right; + font-size: smaller; + color: gray; + padding-right: 5px; +} +.fill-to-right { + flex: 1 1 auto; +} +span.topbar-user-name { + font-size: small; +} +h1.topbar-app-name { + margin-left: 8px; +} +mat-sidenav { + width: 200px; +} +mat-card.app-card { + margin: 5px; +} +.list-container { + display: flex; + flex-direction: column; + min-width: 300px; + height: 98%; +} +.top-list-container { + display: flex; + flex-direction: column; + min-width: 30vh; + height: 54vh; +} +.bottom-list-container { + display: flex; + flex-direction: column; + height: 35vh; +} +.table { + overflow: auto; + height: 100%; +} +.list-header { + min-height: 50px; + padding: 4px 12px 0; +} +.mat-form-field { + font-size: 14px; + width: 100%; +} +mat-form-field.detail-input { + width: 90%; + text-align: left; + color: black; +} +mat-form-field.detail-input-full-width { + width: 96%; + text-align: left; + color: black; +} +input[disabled] { + color: black; + -webkit-text-fill-color: black; + opacity: 1; /* required on iOS */ +} +textarea[disabled] { + color: black; + -webkit-text-fill-color: black; + opacity: 1; /* required on iOS */ +} +.loading-container { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: rgba(100, 100, 100, 0.3); + z-index: 1400; +} +.loading-img { + position: absolute; + margin: auto; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +.flip-container { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: rgba(100, 100, 100, 0.95); + z-index: 1500; +} +.flip-msg { + margin: auto; + text-align: center; + padding-top: 45vh; + color: rgb(205, 206, 177); + font-size: larger; +} +.errorMsg { + font-size: small; + margin-top: 10px; +} + +/* links */ +a:link, +a:visited { + color: black; +} +.stock-state-error { + color: red; + font-weight: bold; +} +.listContainer { + height: 100%; + width: 100%; + overflow: scroll; +} +.listItem { + height: 40px; + font-size: medium; +} + +.listItem:hover { + width: 100%; + cursor: pointer; + background: rgba(130, 130, 130, 0.2); +} + +/* snack bars */ +.snack-error { + background: #f44336; +} + +.input-right { + display: block; + direction: rtl; +} + +.background-red { + background-color: rgba(255, 0, 0, 0.6); +} + +.background-orange { + background-color: rgba(255, 145, 0, 0.6); +} + +.background-green { + background-color: rgba(0, 255, 0, 0.6); +} + +.background-grey { + background-color: rgba(100, 100, 100, 0.3); +} + +.mat-dialog-container { + padding: 0px !important; +} + +.tab-loader { + width: 25px; + margin-right: 10px; +} + +.cell-border { + border-left: 1px solid #e0e0e0; + padding-left: 4px; +} + +.cell-background { + background-color: #eeeeee; +} + +.breadcrumbs { + width: 100%; + text-align: right; + font-size: small; + color: gray; + margin-top: 0px; + padding-top: 0px; +} + +.breadcrumbs a { + color: gray; + text-decoration: none; +} + +::ng-deep snack-bar-container.custom-snackbar-error { + background: #ff3452; +} + +::ng-deep snack-bar-container.custom-snackbar-success { + background: #9ad284; +} + +::ng-deep .mat-simple-snackbar { + color: #000; +} + +::ng-deep .mat-simple-snackbar-action { + color: #000; +} \ No newline at end of file diff --git a/Frontend/src/app/main-view/main-view.component.spec.ts b/Frontend/src/app/main-view/main-view.component.spec.ts new file mode 100644 index 0000000..74526c7 --- /dev/null +++ b/Frontend/src/app/main-view/main-view.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MainViewComponent } from './main-view.component'; + +describe('MainViewComponent', () => { + let component: MainViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ MainViewComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(MainViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/Frontend/src/app/main-view/main-view.component.ts b/Frontend/src/app/main-view/main-view.component.ts new file mode 100644 index 0000000..e317e49 --- /dev/null +++ b/Frontend/src/app/main-view/main-view.component.ts @@ -0,0 +1,35 @@ +import { Component, ViewChild } from '@angular/core'; +import { MatSidenav } from '@angular/material/sidenav'; +import * as moment from 'moment'; +import packageInfo from 'package.json'; +import { DataService } from '../services/data.service'; +import { DeviceService } from '../services/device.service'; + +@Component({ + selector: 'app-main-view', + templateUrl: './main-view.component.html', + styleUrls: ['./main-view.component.scss'] +}) +export class MainViewComponent { + @ViewChild('snav') snav?: MatSidenav; + appVersion = packageInfo.version; + + submenus = { + administration: false, + }; + currentDate = moment().toDate(); + flipPhone: boolean = false; + loading: boolean = false; + + constructor( + public _data: DataService, + public _device: DeviceService + ) {} + + reloadApp() { + document.location.reload(); + } + logout() { + + } +} diff --git a/Frontend/src/app/material.module.ts b/Frontend/src/app/material.module.ts new file mode 100644 index 0000000..0db0386 --- /dev/null +++ b/Frontend/src/app/material.module.ts @@ -0,0 +1,73 @@ +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 { MatPaginatorIntl, 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 { MatSnackBarModule } from '@angular/material/snack-bar'; +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'; + +@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, + MatSnackBarModule, + MatSortModule, + MatTableModule, + MatTabsModule, + MatToolbarModule, + MatTooltipModule, + MatSidenavModule, + MatBadgeModule + ], + providers: [] +}) +export class MaterialModule {} \ No newline at end of file diff --git a/Frontend/src/app/models/user.ts b/Frontend/src/app/models/user.ts new file mode 100644 index 0000000..2f2ce5f --- /dev/null +++ b/Frontend/src/app/models/user.ts @@ -0,0 +1,10 @@ +export class User { + id!: string; + email!: string; + userName!: string; + googleId!: string; + avatar?: string | ArrayBuffer; + constructor(input: any) { + Object.assign(this, input) + } + } \ No newline at end of file diff --git a/Frontend/src/app/services/data.service.spec.ts b/Frontend/src/app/services/data.service.spec.ts new file mode 100644 index 0000000..38e8d9e --- /dev/null +++ b/Frontend/src/app/services/data.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { DataService } from './data.service'; + +describe('DataService', () => { + let service: DataService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(DataService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/Frontend/src/app/services/data.service.ts b/Frontend/src/app/services/data.service.ts new file mode 100644 index 0000000..af49fab --- /dev/null +++ b/Frontend/src/app/services/data.service.ts @@ -0,0 +1,13 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { User } from '../models/user'; + +@Injectable({ + providedIn: 'root' +}) +export class DataService { + currentUser?: User; + public showLoader: BehaviorSubject = new BehaviorSubject(false); + + constructor() { } +} diff --git a/Frontend/src/app/services/device.service.spec.ts b/Frontend/src/app/services/device.service.spec.ts new file mode 100644 index 0000000..d55f5fb --- /dev/null +++ b/Frontend/src/app/services/device.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { DeviceService } from './device.service'; + +describe('DeviceService', () => { + let service: DeviceService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(DeviceService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/Frontend/src/app/services/device.service.ts b/Frontend/src/app/services/device.service.ts new file mode 100644 index 0000000..5ed5f11 --- /dev/null +++ b/Frontend/src/app/services/device.service.ts @@ -0,0 +1,50 @@ +import { MediaMatcher } from '@angular/cdk/layout'; +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class DeviceService { + + private TABLET_WIDTH = 1000; + private DESKTOP_WIDTH = 1400; + + public orientation?: "landscape" | "portraid"; + public flipPhone: boolean = false; + public width?: number; + + constructor( + private mediaMacher: MediaMatcher + ) { + this.checkScreen(); + window.addEventListener("resize", () => { + this.checkScreen(); + }); + } + checkScreen() { + const isPortrait = window.outerWidth < window.outerHeight; + if ( + isPortrait && + window.outerWidth this.TABLET_WIDTH && window.outerWidth < this.DESKTOP_WIDTH; + } + isDesktop(): boolean { + return window.outerWidth > this.DESKTOP_WIDTH; + } + toString() { + return `Orientation: ${this.orientation}, Width: ${this.width}, Flip: ${this.flipPhone}, IsMobile: ${this.isMobile()} + IsTablet: ${this.isTablet()}, IsDesktop: ${this.isDesktop()}`; + } +} diff --git a/Frontend/src/assets/loader.gif b/Frontend/src/assets/loader.gif new file mode 100644 index 0000000..a6e2dde Binary files /dev/null and b/Frontend/src/assets/loader.gif differ diff --git a/Frontend/src/index.html b/Frontend/src/index.html index ae63f56..5895774 100644 --- a/Frontend/src/index.html +++ b/Frontend/src/index.html @@ -6,8 +6,11 @@ + + + - + diff --git a/Frontend/src/styles.scss b/Frontend/src/styles.scss index 90d4ee0..02df3a1 100644 --- a/Frontend/src/styles.scss +++ b/Frontend/src/styles.scss @@ -1 +1,46 @@ -/* 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; } + +/* default .loading styles, .loading should be invisible, opacity: 0, z-index: -1 */ +.AppLoading { + margin-top: -10px; + margin-left: -10px; + opacity: 0; + transition: opacity .8s ease-in-out; + position: fixed; + height: 105%; + width: 105%; + z-index: -1; + background-color: lightgrey; + background-image: url('./assets/loader.gif'); + background-repeat: no-repeat; + background-position: center; + } + + /* .loading screen is visible when app is not bootstrapped yet, my-app is empty */ + app-root:empty + .AppLoading { + opacity: 1; + z-index: 100; + } + + .snackbar-success { + background: #BEFF33; + } + + .snackbar-error { + background: #e7334b; + } + + :root { + --avatar-size: 30px; + } + + .avatar { + background-color: #ccc; + border-radius: 50%; + height: var(--avatar-size); + text-align: center; + width: var(--avatar-size); + vertical-align: middle; + margin-right: 10px; + } \ No newline at end of file diff --git a/Frontend/src/test.ts b/Frontend/src/test.ts index c04c876..51bb020 100644 --- a/Frontend/src/test.ts +++ b/Frontend/src/test.ts @@ -7,20 +7,8 @@ import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { - (id: string): T; - keys(): string[]; - }; -}; - // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting(), ); - -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().forEach(context); diff --git a/Frontend/tsconfig.json b/Frontend/tsconfig.json index ff06eae..cf61615 100644 --- a/Frontend/tsconfig.json +++ b/Frontend/tsconfig.json @@ -16,12 +16,15 @@ "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true, - "target": "es2020", + "target": "ES2022", "module": "es2020", "lib": [ "es2020", "dom" - ] + ], + "useDefineForClassFields": false, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false,