fix: Remade menu editor loading logic
This commit is contained in:
@@ -43,7 +43,7 @@ export class AccountMgmtComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
this.ac.refresh()
|
this.ac.refresh()
|
||||||
this.ac.accs.subscribe(d => {
|
this.ac.accs.subscribe(d => {
|
||||||
this.users.data = d ?? []
|
this.users.data = d
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,31 @@
|
|||||||
<div id="upper-bar">
|
<div id="upper-bar">
|
||||||
<mat-form-field>
|
<mat-form-field subscriptSizing="dynamic">
|
||||||
<mat-label>Wybierz tydzień</mat-label>
|
<mat-label>Wybierz tydzień</mat-label>
|
||||||
<mat-date-range-input [rangePicker]="picker" [formGroup]="range">
|
<mat-date-range-input [rangePicker]="picker" [formGroup]="range">
|
||||||
<input matStartDate formControlName="start" (dateChange)="requestData()">
|
<input matStartDate formControlName="start">
|
||||||
<input matEndDate formControlName="end" (dateChange)="requestData()">
|
<input matEndDate formControlName="end">
|
||||||
</mat-date-range-input>
|
</mat-date-range-input>
|
||||||
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
|
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
|
||||||
<mat-date-range-picker #picker></mat-date-range-picker>
|
<mat-date-range-picker #picker></mat-date-range-picker>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<button mat-icon-button (click)="requestData()"><mat-icon>refresh</mat-icon></button>
|
<button mat-icon-button (click)="ac.refresh()"><mat-icon>search</mat-icon></button>
|
||||||
<button mat-icon-button (click)="addDate()"><mat-icon>add</mat-icon></button>
|
<button mat-icon-button (click)="addDate()"><mat-icon>add</mat-icon></button>
|
||||||
<button mat-icon-button (click)="print()"><mat-icon>print</mat-icon></button>
|
<button mat-icon-button (click)="print()"><mat-icon>print</mat-icon></button>
|
||||||
</div>
|
</div>
|
||||||
@if (loading) {
|
@if (loading) {
|
||||||
<mat-spinner></mat-spinner>
|
<mat-spinner></mat-spinner>
|
||||||
}
|
}
|
||||||
|
<div class="mainc">
|
||||||
|
@switch (ac.state()) {
|
||||||
|
@case (0) {
|
||||||
|
<p>Wybierz zakres dat powyżej i kliknij szukaj</p>
|
||||||
|
}
|
||||||
|
@case (1) {
|
||||||
|
<div class="spinner">
|
||||||
|
<mat-spinner/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@case (2) {
|
||||||
<table mat-table [dataSource]="dataSource">
|
<table mat-table [dataSource]="dataSource">
|
||||||
<div matColumnDef="day">
|
<div matColumnDef="day">
|
||||||
<th mat-header-cell *matHeaderCellDef>Dzień</th>
|
<th mat-header-cell *matHeaderCellDef>Dzień</th>
|
||||||
@@ -91,6 +102,9 @@
|
|||||||
<tr mat-header-row *matHeaderRowDef="dcols"></tr>
|
<tr mat-header-row *matHeaderRowDef="dcols"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: dcols"></tr>
|
<tr mat-row *matRowDef="let row; columns: dcols"></tr>
|
||||||
</table>
|
</table>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
@if (options) {
|
@if (options) {
|
||||||
<datalist id="sn-fancy">
|
<datalist id="sn-fancy">
|
||||||
|
|||||||
@@ -16,3 +16,19 @@ button[mat-icon-button] {
|
|||||||
color: gray;
|
color: gray;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mainc {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,11 +33,18 @@ export class MenuEditComponent {
|
|||||||
public options: any
|
public options: any
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private ac: MenuEditService,
|
protected ac: MenuEditService,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private sb: MatSnackBar,
|
private sb: MatSnackBar,
|
||||||
readonly ls: LocalStorageService
|
readonly ls: LocalStorageService
|
||||||
) {}
|
) {
|
||||||
|
this.range.valueChanges.subscribe(v => {
|
||||||
|
ac.setDates(v.start!, v.end!)
|
||||||
|
})
|
||||||
|
ac.menuItems.subscribe(v => {
|
||||||
|
this.dataSource.data = v
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
print() {
|
print() {
|
||||||
this.ac
|
this.ac
|
||||||
@@ -74,7 +81,7 @@ export class MenuEditComponent {
|
|||||||
.subscribe(s => this.refreshIfGood(s))
|
.subscribe(s => this.refreshIfGood(s))
|
||||||
break
|
break
|
||||||
case 'file':
|
case 'file':
|
||||||
this.requestData()
|
this.refresh()
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@@ -83,29 +90,15 @@ export class MenuEditComponent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
requestData() {
|
refresh() {
|
||||||
this.loading = true
|
this.ac.refresh()
|
||||||
this.ac.getOpts().subscribe(o => {
|
this.ac.getOpts().subscribe(o => {
|
||||||
this.options = o
|
this.options = o
|
||||||
})
|
})
|
||||||
this.ac
|
|
||||||
.getMenu(this.range.value.start, this.range.value.end)
|
|
||||||
?.subscribe(data => {
|
|
||||||
this.loading = false
|
|
||||||
this.dataSource.data = data.map(v => {
|
|
||||||
let newMenu: Menu = {
|
|
||||||
...v,
|
|
||||||
day: DateTime.fromISO(v.day),
|
|
||||||
}
|
|
||||||
return newMenu
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private refreshIfGood(s: Status) {
|
private refreshIfGood(s: Status) {
|
||||||
if (s.status.toString().match(/2\d\d/)) {
|
if (s.status.toString().match(/2\d\d/)) this.refresh()
|
||||||
this.requestData()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
activateUpload() {
|
activateUpload() {
|
||||||
@@ -113,9 +106,7 @@ export class MenuEditComponent {
|
|||||||
.open(MenuUploadComponent)
|
.open(MenuUploadComponent)
|
||||||
.afterClosed()
|
.afterClosed()
|
||||||
.subscribe(data => {
|
.subscribe(data => {
|
||||||
if (data) {
|
if (data) this.refresh()
|
||||||
this.requestData()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, signal } from '@angular/core';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { Menu } from 'src/app/types/menu';
|
import { BehaviorSubject, catchError, map, of } from 'rxjs';
|
||||||
|
import { Menu, MenuAPI } from 'src/app/types/menu';
|
||||||
|
import { STATE } from 'src/app/types/state';
|
||||||
import { Status } from 'src/app/types/status';
|
import { Status } from 'src/app/types/status';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
@@ -10,19 +12,57 @@ import { environment } from 'src/environments/environment';
|
|||||||
})
|
})
|
||||||
export class MenuEditService {
|
export class MenuEditService {
|
||||||
|
|
||||||
constructor(private http: HttpClient) { }
|
private _menuItems = new BehaviorSubject<Menu[]>([])
|
||||||
|
public readonly menuItems = this._menuItems.asObservable()
|
||||||
|
private _state = signal(STATE.NOT_LOADED);
|
||||||
|
public readonly state = this._state.asReadonly();
|
||||||
|
private _error = signal<string | undefined>(undefined);
|
||||||
|
public readonly error = this._error.asReadonly();
|
||||||
|
|
||||||
getMenu(start?: DateTime | null, end?: DateTime | null) {
|
private seDates: {
|
||||||
if (start && end) {
|
start: DateTime | null,
|
||||||
const body = { start: start.toString(), end: end.toString() }
|
end: DateTime | null
|
||||||
return this.http.get<(Omit<Menu, 'day'> & { day: string })[]>(
|
} = {
|
||||||
environment.apiEndpoint + '/admin/menu',
|
start: null,
|
||||||
{ withCredentials: true, params: body }
|
end: null
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
public setDates(start: DateTime | null, end: DateTime | null) {
|
||||||
|
this.seDates.start = start
|
||||||
|
this.seDates.end = end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public refresh() {
|
||||||
|
this.getMenu()
|
||||||
|
}
|
||||||
|
|
||||||
|
private getMenu() {
|
||||||
|
if (!(this.seDates.start && this.seDates.end)) return
|
||||||
|
this._state.set(STATE.PENDING)
|
||||||
|
const body = { start: this.seDates.start.toString(), end: this.seDates.end.toString() }
|
||||||
|
this.http.get
|
||||||
|
<MenuAPI[]>
|
||||||
|
(environment.apiEndpoint + `/admin/menu`, { withCredentials: true, params: body })
|
||||||
|
.pipe(
|
||||||
|
catchError((err: Error) => {
|
||||||
|
this._state.set(STATE.ERROR)
|
||||||
|
this._error.set(err.message)
|
||||||
|
return of()
|
||||||
|
}),
|
||||||
|
map<MenuAPI[], Menu[]>(v =>
|
||||||
|
v.map(i => ({
|
||||||
|
...i,
|
||||||
|
day: DateTime.fromISO(i.day)
|
||||||
|
})))
|
||||||
|
).subscribe(v => {
|
||||||
|
this._error.set(undefined)
|
||||||
|
this._menuItems.next(v ?? [])
|
||||||
|
this._state.set(STATE.LOADED)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
getOpts() {
|
getOpts() {
|
||||||
return this.http.get<any>(environment.apiEndpoint + `/admin/menu/opts`, {
|
return this.http.get<any>(environment.apiEndpoint + `/admin/menu/opts`, {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { DateTime } from 'luxon'
|
import { DateTime } from 'luxon'
|
||||||
|
|
||||||
|
export type MenuAPI = Omit<Menu, "day"> & {day: string}
|
||||||
|
|
||||||
export interface Menu {
|
export interface Menu {
|
||||||
_id: string
|
_id: string
|
||||||
day: DateTime
|
day: DateTime
|
||||||
|
|||||||
Reference in New Issue
Block a user