diff --git a/src/app/app.component.html b/src/app/app.component.html
index 14ce919..bcd2663 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,5 +1,6 @@
+
diff --git a/src/app/modules/accounts/services/account.service.ts b/src/app/modules/accounts/services/account.service.ts
index 6d02458..fda72d8 100644
--- a/src/app/modules/accounts/services/account.service.ts
+++ b/src/app/modules/accounts/services/account.service.ts
@@ -7,6 +7,7 @@ import {environment} from '../../../../environments/environment'
import {ApiService} from '../../shared/service/api.service'
import {Employee, EmployeePermission} from '../../shared/model/employee'
import {ErrorService} from '../../shared/service/error.service'
+import {globalLoadingWheel} from '../../shared/components/loading-wheel/loading-wheel.component'
@Injectable({
providedIn: 'root'
@@ -47,6 +48,7 @@ export class AccountService implements OnDestroy {
login(id: number, password: string, success: () => void) {
const loginForm = {id, password}
+ globalLoadingWheel.show()
this.http.post
(`${environment.apiUrl}/login`, loginForm, {
withCredentials: true,
observe: 'response' as 'body'
@@ -92,7 +94,11 @@ export class AccountService implements OnDestroy {
takeUntil(this.destroy$)
)
.subscribe({
- next: employee => this.appState.authenticatedEmployee = employee,
+ next: employee => {
+ this.appState.authenticatedEmployee = employee
+ // At this point the loading wheel should be visible
+ globalLoadingWheel.hide()
+ },
error: err => this.errorService.handleError(err)
})
}
diff --git a/src/app/modules/colors/components/images-editor/images-editor.component.ts b/src/app/modules/colors/components/images-editor/images-editor.component.ts
index 42c4499..55814bd 100644
--- a/src/app/modules/colors/components/images-editor/images-editor.component.ts
+++ b/src/app/modules/colors/components/images-editor/images-editor.component.ts
@@ -6,6 +6,7 @@ import {Observable} from 'rxjs'
import {RecipeImageService} from '../../services/recipe-image.service'
import {environment} from '../../../../../environments/environment'
import {ErrorService} from '../../../shared/service/error.service'
+import {globalLoadingWheel} from '../../../shared/components/loading-wheel/loading-wheel.component'
@Component({
selector: 'cre-images-editor',
@@ -36,6 +37,7 @@ export class ImagesEditorComponent extends SubscribingComponent {
this.subscribe(
this.imageIds$,
ids => this.hasImages = ids.length > 0,
+ false,
1
)
}
diff --git a/src/app/modules/colors/pages/explore/explore.component.ts b/src/app/modules/colors/pages/explore/explore.component.ts
index 5f68076..65f7f28 100644
--- a/src/app/modules/colors/pages/explore/explore.component.ts
+++ b/src/app/modules/colors/pages/explore/explore.component.ts
@@ -7,6 +7,7 @@ import {Observable, Subject} from 'rxjs'
import {ErrorModel, ErrorService} from '../../../shared/service/error.service'
import {AlertService} from '../../../shared/service/alert.service'
import {GlobalAlertHandlerComponent} from '../../../shared/components/global-alert-handler/global-alert-handler.component'
+import {globalLoadingWheel} from '../../../shared/components/loading-wheel/loading-wheel.component'
@Component({
selector: 'cre-explore',
@@ -88,7 +89,8 @@ export class ExploreComponent extends ErrorHandlingComponent {
saveModifications() {
this.subscribe(
this.recipeService.saveExplorerModifications(this.recipe.id, this.note, this.mixesLocationChanges),
- () => this.alertService.pushSuccess('Les modifications ont été enregistrées')
+ () => this.alertService.pushSuccess('Les modifications ont été enregistrées'),
+ true
)
}
@@ -103,7 +105,8 @@ export class ExploreComponent extends ErrorHandlingComponent {
performDeductQuantities(observable: Observable) {
this.subscribe(
observable,
- () => this.alertService.pushSuccess('Les quantités des produits utilisés ont été déduites de l\'inventaire')
+ () => this.alertService.pushSuccess('Les quantités des produits utilisés ont été déduites de l\'inventaire'),
+ true
)
}
}
diff --git a/src/app/modules/groups/pages/list/list.component.ts b/src/app/modules/groups/pages/list/list.component.ts
index a98648c..4844dbf 100644
--- a/src/app/modules/groups/pages/list/list.component.ts
+++ b/src/app/modules/groups/pages/list/list.component.ts
@@ -8,6 +8,7 @@ import {ErrorHandlingComponent} from '../../../shared/components/subscribing.com
import {ActivatedRoute, Router} from '@angular/router'
import {ErrorModel, ErrorService} from '../../../shared/service/error.service'
import {AlertService} from '../../../shared/service/alert.service'
+import {globalLoadingWheel} from '../../../shared/components/loading-wheel/loading-wheel.component'
@Component({
selector: 'cre-groups',
@@ -53,7 +54,8 @@ export class ListComponent extends ErrorHandlingComponent {
setDefaultGroup(group: EmployeeGroup) {
this.subscribe(
this.groupService.setDefaultGroup(group),
- () => this.defaultGroup = group
+ () => this.defaultGroup = group,
+ true
)
}
diff --git a/src/app/modules/material/pages/list/list.component.ts b/src/app/modules/material/pages/list/list.component.ts
index 7092ac6..96686fa 100644
--- a/src/app/modules/material/pages/list/list.component.ts
+++ b/src/app/modules/material/pages/list/list.component.ts
@@ -62,6 +62,7 @@ export class ListComponent extends ErrorHandlingComponent {
)
})
},
+ false,
1
)
}
diff --git a/src/app/modules/shared/components/header/header.component.ts b/src/app/modules/shared/components/header/header.component.ts
index 9f3585f..ea14e7d 100644
--- a/src/app/modules/shared/components/header/header.component.ts
+++ b/src/app/modules/shared/components/header/header.component.ts
@@ -46,6 +46,7 @@ export class HeaderComponent extends SubscribingComponent {
this._activeLink = data.url
}
},
+ false,
1
)
diff --git a/src/app/modules/shared/components/loading-wheel/loading-wheel.component.html b/src/app/modules/shared/components/loading-wheel/loading-wheel.component.html
new file mode 100644
index 0000000..67b0f2f
--- /dev/null
+++ b/src/app/modules/shared/components/loading-wheel/loading-wheel.component.html
@@ -0,0 +1,6 @@
+
diff --git a/src/app/modules/shared/components/loading-wheel/loading-wheel.component.sass b/src/app/modules/shared/components/loading-wheel/loading-wheel.component.sass
new file mode 100644
index 0000000..27c3fcb
--- /dev/null
+++ b/src/app/modules/shared/components/loading-wheel/loading-wheel.component.sass
@@ -0,0 +1,18 @@
+.spinner-wrapper
+ transition: all 100ms
+
+ &.visible
+ opacity: 1 !important
+ visibility: unset !important
+
+ &:not(.visible)
+ opacity: 0
+ visibility: hidden
+
+ .spinner
+ max-width: max-content
+ position: fixed
+ left: 50%
+ top: 50%
+ transform: translate(-50%, -50%)
+ z-index: 11
diff --git a/src/app/modules/shared/components/loading-wheel/loading-wheel.component.ts b/src/app/modules/shared/components/loading-wheel/loading-wheel.component.ts
new file mode 100644
index 0000000..0f648f9
--- /dev/null
+++ b/src/app/modules/shared/components/loading-wheel/loading-wheel.component.ts
@@ -0,0 +1,24 @@
+import {Component} from '@angular/core'
+
+export let globalLoadingWheel: LoadingWheelComponent | null
+
+@Component({
+ selector: 'cre-loading-wheel',
+ templateUrl: './loading-wheel.component.html',
+ styleUrls: ['./loading-wheel.component.sass']
+})
+export class LoadingWheelComponent {
+ visible = false
+
+ constructor() {
+ globalLoadingWheel = this
+ }
+
+ show() {
+ this.visible = true
+ }
+
+ hide() {
+ this.visible = false
+ }
+}
diff --git a/src/app/modules/shared/components/subscribing.component.ts b/src/app/modules/shared/components/subscribing.component.ts
index d19ce1b..c73a786 100644
--- a/src/app/modules/shared/components/subscribing.component.ts
+++ b/src/app/modules/shared/components/subscribing.component.ts
@@ -4,6 +4,7 @@ import {Observable, Subject} from 'rxjs'
import {ActivatedRoute, Router} from '@angular/router'
import {UrlUtils} from '../utils/url.utils'
import {ErrorHandler, ErrorModel, ErrorService} from '../service/error.service'
+import {globalLoadingWheel} from './loading-wheel/loading-wheel.component'
export abstract class SubscribingComponent implements OnInit, OnDestroy {
protected subscribers$ = []
@@ -17,33 +18,48 @@ export abstract class SubscribingComponent implements OnInit, OnDestroy {
) {
}
- subscribe(observable: Observable, resultConsumer: (T) => void, take_count = -1) {
+ subscribe(observable: Observable, resultConsumer: (T) => void, showWheel = false, take_count = -1) {
if (take_count >= 0) {
observable.pipe(take(take_count), takeUntil(this.destroy$))
} else {
observable.pipe(takeUntil(this.destroy$))
}
+ this.showLoadingWheel(showWheel)
this.subscribers$.push(observable.subscribe({
- next: resultConsumer,
- error: err => this.errorService.handleError(err)
+ next: t => {
+ resultConsumer(t)
+ this.hideLoadingWheel(showWheel)
+ },
+ error: err => {
+ this.errorService.handleError(err)
+ this.hideLoadingWheel(showWheel)
+ }
}))
}
- subscribeAndNavigate(observable: Observable, route: string) {
+ subscribeAndNavigate(observable: Observable, route: string, showWheel = true) {
this.subscribe(
observable,
() => this.urlUtils.navigateTo(route),
+ showWheel,
1
)
}
- subscribeEntityById(service: any, id: number, resultConsumer: (T) => void, notFoundRoute: string) {
+ subscribeEntityById(service: any, id: number, resultConsumer: (T) => void, notFoundRoute: string, showWheel = true) {
+ this.showLoadingWheel(showWheel)
this.subscribers$.push(service.getById(id)
.pipe(take(1), takeUntil(this.destroy$))
.subscribe({
- next: e => resultConsumer(e),
- error: err => this.handleNotFoundError(err, notFoundRoute)
+ next: e => {
+ resultConsumer(e)
+ this.hideLoadingWheel(showWheel)
+ },
+ error: err => {
+ this.handleNotFoundError(err, notFoundRoute)
+ this.hideLoadingWheel(showWheel)
+ }
}))
}
@@ -62,6 +78,18 @@ export abstract class SubscribingComponent implements OnInit, OnDestroy {
this.errorService.handleError(error)
}
}
+
+ protected showLoadingWheel(shouldShowWheel) {
+ if (shouldShowWheel) {
+ globalLoadingWheel.show()
+ }
+ }
+
+ protected hideLoadingWheel(shouldShowWheel) {
+ if (shouldShowWheel) {
+ globalLoadingWheel.hide()
+ }
+ }
}
export abstract class ErrorHandlingComponent extends SubscribingComponent implements ErrorHandler {
diff --git a/src/app/modules/shared/service/api.service.ts b/src/app/modules/shared/service/api.service.ts
index 3deff1e..5389e7d 100644
--- a/src/app/modules/shared/service/api.service.ts
+++ b/src/app/modules/shared/service/api.service.ts
@@ -4,10 +4,10 @@ import {Observable, Subject} from 'rxjs'
import {environment} from '../../../../environments/environment'
import {AppState} from '../app-state'
import {Router} from '@angular/router'
-import {map, share, takeUntil} from 'rxjs/operators'
+import {map, share, takeUntil, tap} from 'rxjs/operators'
import {valueOr} from '../utils/utils'
import {ErrorService} from './error.service'
-import {AccountService} from '../../accounts/services/account.service'
+import {globalLoadingWheel} from '../components/loading-wheel/loading-wheel.component'
@Injectable({
providedIn: 'root'
diff --git a/src/app/modules/shared/shared.module.ts b/src/app/modules/shared/shared.module.ts
index 3d8407a..c2325f0 100644
--- a/src/app/modules/shared/shared.module.ts
+++ b/src/app/modules/shared/shared.module.ts
@@ -28,12 +28,14 @@ import {MatOptionModule} from '@angular/material/core'
import {MaterialFileInputModule} from 'ngx-material-file-input'
import {FileButtonComponent} from './file-button/file-button.component'
import {GlobalAlertHandlerComponent} from './components/global-alert-handler/global-alert-handler.component'
-import {MatSliderModule} from '@angular/material/slider';
-import { SliderFieldComponent } from './components/slider-field/slider-field.component'
+import {MatSliderModule} from '@angular/material/slider'
+import {SliderFieldComponent} from './components/slider-field/slider-field.component'
+import {LoadingWheelComponent} from './components/loading-wheel/loading-wheel.component'
+import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'
@NgModule({
- declarations: [HeaderComponent, EmployeeInfoComponent, LabeledIconComponent, ConfirmBoxComponent, PermissionsListComponent, PermissionsFieldComponent, NavComponent, EntityListComponent, EntityAddComponent, EntityEditComponent, FileButtonComponent, GlobalAlertHandlerComponent, SliderFieldComponent],
+ declarations: [HeaderComponent, EmployeeInfoComponent, LabeledIconComponent, ConfirmBoxComponent, PermissionsListComponent, PermissionsFieldComponent, NavComponent, EntityListComponent, EntityAddComponent, EntityEditComponent, FileButtonComponent, GlobalAlertHandlerComponent, SliderFieldComponent, LoadingWheelComponent],
exports: [
CommonModule,
HttpClientModule,
@@ -60,7 +62,8 @@ import { SliderFieldComponent } from './components/slider-field/slider-field.com
EntityAddComponent,
EntityEditComponent,
FileButtonComponent,
- GlobalAlertHandlerComponent
+ GlobalAlertHandlerComponent,
+ LoadingWheelComponent
],
imports: [
MatTabsModule,
@@ -76,6 +79,7 @@ import { SliderFieldComponent } from './components/slider-field/slider-field.com
MatSelectModule,
MatOptionModule,
MatSliderModule,
+ MatProgressSpinnerModule,
ReactiveFormsModule,
RouterModule,
CommonModule,
diff --git a/src/styles.sass b/src/styles.sass
index 5896eac..2e6f3f5 100644
--- a/src/styles.sass
+++ b/src/styles.sass
@@ -200,6 +200,7 @@ div.empty
left: 0
background-color: black
opacity: 0.4
+ z-index: 10
.color-warning
color: #fdd835