mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-25 12:15:18 +01:00
AC-2410 Migrate Events Component (#8970)
* AC-2410 Migrate Events Component * AC-2410 Addressed a minor correction
This commit is contained in:
parent
ad3c40297f
commit
dd53a1c5ce
@ -1,4 +1,5 @@
|
|||||||
import { Directive } from "@angular/core";
|
import { Directive } from "@angular/core";
|
||||||
|
import { FormControl, FormGroup } from "@angular/forms";
|
||||||
|
|
||||||
import { EventResponse } from "@bitwarden/common/models/response/event.response";
|
import { EventResponse } from "@bitwarden/common/models/response/event.response";
|
||||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||||
@ -16,16 +17,16 @@ export abstract class BaseEventsComponent {
|
|||||||
loading = true;
|
loading = true;
|
||||||
loaded = false;
|
loaded = false;
|
||||||
events: EventView[];
|
events: EventView[];
|
||||||
start: string;
|
|
||||||
end: string;
|
|
||||||
dirtyDates = true;
|
dirtyDates = true;
|
||||||
continuationToken: string;
|
continuationToken: string;
|
||||||
refreshPromise: Promise<any>;
|
|
||||||
exportPromise: Promise<any>;
|
|
||||||
morePromise: Promise<any>;
|
|
||||||
|
|
||||||
abstract readonly exportFileName: string;
|
abstract readonly exportFileName: string;
|
||||||
|
|
||||||
|
protected eventsForm = new FormGroup({
|
||||||
|
start: new FormControl(null),
|
||||||
|
end: new FormControl(null),
|
||||||
|
});
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected eventService: EventService,
|
protected eventService: EventService,
|
||||||
protected i18nService: I18nService,
|
protected i18nService: I18nService,
|
||||||
@ -39,8 +40,32 @@ export abstract class BaseEventsComponent {
|
|||||||
this.end = defaultDates[1];
|
this.end = defaultDates[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
async exportEvents() {
|
get start(): string {
|
||||||
if (this.appApiPromiseUnfulfilled() || this.dirtyDates) {
|
return this.eventsForm.value.start;
|
||||||
|
}
|
||||||
|
|
||||||
|
set start(val: string) {
|
||||||
|
this.eventsForm.get("start").setValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
get end(): string {
|
||||||
|
return this.eventsForm.value.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
set end(val: string) {
|
||||||
|
this.eventsForm.get("end").setValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMoreEvents = async () => {
|
||||||
|
await this.loadEvents(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
refreshEvents = async () => {
|
||||||
|
await this.loadEvents(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
exportEvents = async () => {
|
||||||
|
if (this.dirtyDates) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,23 +76,19 @@ export abstract class BaseEventsComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let promise: Promise<any>;
|
||||||
try {
|
try {
|
||||||
this.exportPromise = this.export(dates[0], dates[1]);
|
promise = this.export(dates[0], dates[1]);
|
||||||
|
await promise;
|
||||||
await this.exportPromise;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logService.error(`Handled exception: ${e}`);
|
this.logService.error(`Handled exception: ${e}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.exportPromise = null;
|
promise = null;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
async loadEvents(clearExisting: boolean) {
|
|
||||||
if (this.appApiPromiseUnfulfilled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
loadEvents = async (clearExisting: boolean) => {
|
||||||
const dates = this.parseDates();
|
const dates = this.parseDates();
|
||||||
if (dates == null) {
|
if (dates == null) {
|
||||||
return;
|
return;
|
||||||
@ -75,17 +96,14 @@ export abstract class BaseEventsComponent {
|
|||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
let events: EventView[] = [];
|
let events: EventView[] = [];
|
||||||
|
let promise: Promise<any>;
|
||||||
try {
|
try {
|
||||||
const promise = this.loadAndParseEvents(
|
promise = this.loadAndParseEvents(
|
||||||
dates[0],
|
dates[0],
|
||||||
dates[1],
|
dates[1],
|
||||||
clearExisting ? null : this.continuationToken,
|
clearExisting ? null : this.continuationToken,
|
||||||
);
|
);
|
||||||
if (clearExisting) {
|
|
||||||
this.refreshPromise = promise;
|
|
||||||
} else {
|
|
||||||
this.morePromise = promise;
|
|
||||||
}
|
|
||||||
const result = await promise;
|
const result = await promise;
|
||||||
this.continuationToken = result.continuationToken;
|
this.continuationToken = result.continuationToken;
|
||||||
events = result.events;
|
events = result.events;
|
||||||
@ -101,9 +119,8 @@ export abstract class BaseEventsComponent {
|
|||||||
|
|
||||||
this.dirtyDates = false;
|
this.dirtyDates = false;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.morePromise = null;
|
promise = null;
|
||||||
this.refreshPromise = null;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract requestEvents(
|
protected abstract requestEvents(
|
||||||
startDate: string,
|
startDate: string,
|
||||||
@ -161,10 +178,6 @@ export abstract class BaseEventsComponent {
|
|||||||
return dates;
|
return dates;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected appApiPromiseUnfulfilled() {
|
|
||||||
return this.refreshPromise != null || this.morePromise != null || this.exportPromise != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async export(start: string, end: string) {
|
private async export(start: string, end: string) {
|
||||||
let continuationToken = this.continuationToken;
|
let continuationToken = this.continuationToken;
|
||||||
let events = [].concat(this.events);
|
let events = [].concat(this.events);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
|
|
||||||
<div class="tw-mb-4">
|
<div class="tw-mb-4" [formGroup]="eventsForm">
|
||||||
<div class="tw-mt-4 tw-flex tw-items-center">
|
<div class="tw-mt-4 tw-flex tw-items-center">
|
||||||
<bit-form-field>
|
<bit-form-field>
|
||||||
<bit-label>{{ "from" | i18n }}</bit-label>
|
<bit-label>{{ "from" | i18n }}</bit-label>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
bitInput
|
bitInput
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
placeholder="{{ 'startDate' | i18n }}"
|
placeholder="{{ 'startDate' | i18n }}"
|
||||||
[(ngModel)]="start"
|
formControlName="start"
|
||||||
(change)="dirtyDates = true"
|
(change)="dirtyDates = true"
|
||||||
/>
|
/>
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
@ -19,51 +19,44 @@
|
|||||||
bitInput
|
bitInput
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
placeholder="{{ 'endDate' | i18n }}"
|
placeholder="{{ 'endDate' | i18n }}"
|
||||||
[(ngModel)]="end"
|
formControlName="end"
|
||||||
(change)="dirtyDates = true"
|
(change)="dirtyDates = true"
|
||||||
/>
|
/>
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
<form #refreshForm [appApiAction]="refreshPromise">
|
<form>
|
||||||
<button
|
<button
|
||||||
class="tw-mx-3 tw-mt-1"
|
class="tw-mx-3 tw-mt-1"
|
||||||
type="button"
|
type="button"
|
||||||
bitButton
|
bitButton
|
||||||
|
bitFormButton
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
(click)="loadEvents(true)"
|
[bitAction]="refreshEvents"
|
||||||
[disabled]="loaded && refreshForm.loading"
|
|
||||||
>
|
>
|
||||||
{{ "update" | i18n }}
|
{{ "update" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<form #exportForm [appApiAction]="exportPromise">
|
<form>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="tw-mt-1"
|
class="tw-mt-1"
|
||||||
bitButton
|
bitButton
|
||||||
[ngClass]="{ loading: exportForm.loading }"
|
bitFormButton
|
||||||
(click)="exportEvents()"
|
[bitAction]="exportEvents"
|
||||||
[disabled]="(loaded && exportForm.loading) || dirtyDates"
|
[disabled]="dirtyDates"
|
||||||
>
|
>
|
||||||
<span>{{ "export" | i18n }}</span>
|
<span>{{ "export" | i18n }}</span>
|
||||||
<i
|
<i class="bwi bwi-fw bwi-sign-in" aria-hidden="true"></i>
|
||||||
class="bwi bwi-fw"
|
|
||||||
aria-hidden="true"
|
|
||||||
[ngClass]="{
|
|
||||||
'bwi-sign-in': !exportForm.loading,
|
|
||||||
'bwi-spinner bwi-spin': exportForm.loading
|
|
||||||
}"
|
|
||||||
></i>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="!loaded">
|
<ng-container *ngIf="!loaded">
|
||||||
<i
|
<i
|
||||||
class="bwi bwi-spinner bwi-spin text-muted"
|
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||||
title="{{ 'loading' | i18n }}"
|
title="{{ 'loading' | i18n }}"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
<span class="sr-only">{{ "loading" | i18n }}</span>
|
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="loaded">
|
<ng-container *ngIf="loaded">
|
||||||
<p *ngIf="!events || !events.length">{{ "noEventsInList" | i18n }}</p>
|
<p *ngIf="!events || !events.length">{{ "noEventsInList" | i18n }}</p>
|
||||||
@ -90,21 +83,12 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
</bit-table>
|
</bit-table>
|
||||||
<button
|
<button
|
||||||
#moreBtn
|
|
||||||
[appApiAction]="morePromise"
|
|
||||||
type="button"
|
type="button"
|
||||||
bitButton
|
bitButton
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
(click)="loadEvents(false)"
|
[bitAction]="loadMoreEvents"
|
||||||
[disabled]="loaded && $any(moreBtn).loading"
|
|
||||||
*ngIf="continuationToken"
|
*ngIf="continuationToken"
|
||||||
>
|
>
|
||||||
<i
|
{{ "loadMore" | i18n }}
|
||||||
class="bwi bwi-spinner bwi-spin"
|
|
||||||
title="{{ 'loading' | i18n }}"
|
|
||||||
aria-hidden="true"
|
|
||||||
*ngIf="moreBtn.loading"
|
|
||||||
></i>
|
|
||||||
<span>{{ "loadMore" | i18n }}</span>
|
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -108,7 +108,7 @@ export class EventsComponent extends BaseEventsComponent implements OnInit, OnDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.loadEvents(true);
|
await this.refreshEvents();
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,104 +1,97 @@
|
|||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
|
|
||||||
<div class="ml-auto d-flex">
|
<div class="tw-mb-4" [formGroup]="eventsForm">
|
||||||
<div class="form-inline">
|
<div class="tw-mt-4 tw-flex tw-items-center">
|
||||||
<label class="sr-only" for="start">{{ "startDate" | i18n }}</label>
|
<bit-form-field>
|
||||||
|
<bit-label>{{ "startDate" | i18n }}</bit-label>
|
||||||
<input
|
<input
|
||||||
|
bitInput
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
class="form-control form-control-sm"
|
|
||||||
id="start"
|
|
||||||
placeholder="{{ 'startDate' | i18n }}"
|
placeholder="{{ 'startDate' | i18n }}"
|
||||||
[(ngModel)]="start"
|
formControlName="start"
|
||||||
placeholder="YYYY-MM-DDTHH:MM"
|
|
||||||
(change)="dirtyDates = true"
|
(change)="dirtyDates = true"
|
||||||
/>
|
/>
|
||||||
<span class="mx-2">-</span>
|
</bit-form-field>
|
||||||
<label class="sr-only" for="end">{{ "endDate" | i18n }}</label>
|
<span class="tw-mx-2">-</span>
|
||||||
|
<bit-form-field>
|
||||||
|
<bit-label>{{ "endDate" | i18n }}</bit-label>
|
||||||
<input
|
<input
|
||||||
|
bitInput
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
class="form-control form-control-sm"
|
|
||||||
id="end"
|
|
||||||
placeholder="{{ 'endDate' | i18n }}"
|
placeholder="{{ 'endDate' | i18n }}"
|
||||||
[(ngModel)]="end"
|
formControlName="end"
|
||||||
placeholder="YYYY-MM-DDTHH:MM"
|
|
||||||
(change)="dirtyDates = true"
|
(change)="dirtyDates = true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</bit-form-field>
|
||||||
<form #refreshForm [appApiAction]="refreshPromise" class="d-inline">
|
<form>
|
||||||
<button
|
<button
|
||||||
|
class="tw-mx-3 tw-mt-1"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-sm btn-outline-primary ml-3"
|
bitButton
|
||||||
(click)="loadEvents(true)"
|
bitFormButton
|
||||||
[disabled]="loaded && refreshForm.loading"
|
buttonType="primary"
|
||||||
|
[bitAction]="refreshEvents"
|
||||||
>
|
>
|
||||||
<i
|
|
||||||
class="bwi bwi-refresh bwi-fw"
|
|
||||||
aria-hidden="true"
|
|
||||||
[ngClass]="{ 'bwi-spin': loaded && refreshForm.loading }"
|
|
||||||
></i>
|
|
||||||
{{ "refresh" | i18n }}
|
{{ "refresh" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<form #exportForm [appApiAction]="exportPromise" class="d-inline">
|
<form>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-sm btn-outline-primary btn-submit manual ml-3"
|
class="tw-mt-1"
|
||||||
[ngClass]="{ loading: exportForm.loading }"
|
bitButton
|
||||||
(click)="exportEvents()"
|
bitFormButton
|
||||||
[disabled]="(loaded && exportForm.loading) || dirtyDates"
|
[bitAction]="exportEvents"
|
||||||
|
[disabled]="dirtyDates"
|
||||||
>
|
>
|
||||||
<i class="bwi bwi-spinner bwi-spin" aria-hidden="true"></i>
|
|
||||||
<span>{{ "export" | i18n }}</span>
|
<span>{{ "export" | i18n }}</span>
|
||||||
|
<i class="bwi bwi-fw bwi-sign-in" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<ng-container *ngIf="!loaded">
|
<ng-container *ngIf="!loaded">
|
||||||
<i
|
<i
|
||||||
class="bwi bwi-spinner bwi-spin text-muted"
|
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||||
title="{{ 'loading' | i18n }}"
|
title="{{ 'loading' | i18n }}"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
<span class="sr-only">{{ "loading" | i18n }}</span>
|
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="loaded">
|
<ng-container *ngIf="loaded">
|
||||||
<p *ngIf="!events || !events.length">{{ "noEventsInList" | i18n }}</p>
|
<p *ngIf="!events || !events.length">{{ "noEventsInList" | i18n }}</p>
|
||||||
<table class="table table-hover" *ngIf="events && events.length">
|
<bit-table *ngIf="events && events.length">
|
||||||
<thead>
|
<ng-container header>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="border-top-0" width="210">{{ "timestamp" | i18n }}</th>
|
<th bitCell>{{ "timestamp" | i18n }}</th>
|
||||||
<th class="border-top-0" width="40">
|
<th bitCell>{{ "device" | i18n }}</th>
|
||||||
<span class="sr-only">{{ "device" | i18n }}</span>
|
<th bitCell>{{ "user" | i18n }}</th>
|
||||||
</th>
|
<th bitCell>{{ "event" | i18n }}</th>
|
||||||
<th class="border-top-0" width="150">{{ "user" | i18n }}</th>
|
|
||||||
<th class="border-top-0">{{ "event" | i18n }}</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</ng-container>
|
||||||
<tbody>
|
<ng-template body>
|
||||||
<tr *ngFor="let e of events">
|
<tr bitRow *ngFor="let e of events" alignContent="top">
|
||||||
<td>{{ e.date | date: "medium" }}</td>
|
<td bitCell class="tw-whitespace-nowrap">{{ e.date | date: "medium" }}</td>
|
||||||
<td>
|
<td bitCell>
|
||||||
<i
|
<i
|
||||||
class="text-muted bwi bwi-lg {{ e.appIcon }}"
|
class="tw-text-muted bwi bwi-lg {{ e.appIcon }}"
|
||||||
title="{{ e.appName }}, {{ e.ip }}"
|
title="{{ e.appName }}, {{ e.ip }}"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
<span class="sr-only">{{ e.appName }}, {{ e.ip }}</span>
|
<span class="tw-sr-only">{{ e.appName }}, {{ e.ip }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td bitCell>
|
||||||
<span title="{{ e.userEmail }}">{{ e.userName }}</span>
|
<span title="{{ e.userEmail }}">{{ e.userName }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td [innerHTML]="e.message"></td>
|
<td bitCell [innerHTML]="e.message"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</ng-template>
|
||||||
</table>
|
</bit-table>
|
||||||
<button
|
<button
|
||||||
#moreBtn
|
bitButton
|
||||||
[appApiAction]="morePromise"
|
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-block btn-link btn-submit"
|
buttonType="primary"
|
||||||
(click)="loadEvents(false)"
|
[bitAction]="loadMoreEvents"
|
||||||
[disabled]="loaded && $any(moreBtn).loading"
|
|
||||||
*ngIf="continuationToken"
|
*ngIf="continuationToken"
|
||||||
>
|
>
|
||||||
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
|
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
|
||||||
|
@ -70,7 +70,7 @@ export class EventsComponent extends BaseEventsComponent implements OnInit {
|
|||||||
this.providerUsersIdMap.set(u.id, { name: name, email: u.email });
|
this.providerUsersIdMap.set(u.id, { name: name, email: u.email });
|
||||||
this.providerUsersUserIdMap.set(u.userId, { name: name, email: u.email });
|
this.providerUsersUserIdMap.set(u.userId, { name: name, email: u.email });
|
||||||
});
|
});
|
||||||
await this.loadEvents(true);
|
await this.refreshEvents();
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<div class="tw-mb-4">
|
<div class="tw-mb-4">
|
||||||
<h1>{{ "eventLogs" | i18n }}</h1>
|
<h1>{{ "eventLogs" | i18n }}</h1>
|
||||||
<div class="tw-mt-4 tw-flex tw-items-center">
|
<div class="tw-mt-4 tw-flex tw-items-center" [formGroup]="eventsForm">
|
||||||
<bit-form-field>
|
<bit-form-field>
|
||||||
<bit-label>{{ "from" | i18n }}</bit-label>
|
<bit-label>{{ "from" | i18n }}</bit-label>
|
||||||
<input
|
<input
|
||||||
bitInput
|
bitInput
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
placeholder="{{ 'startDate' | i18n }}"
|
placeholder="{{ 'startDate' | i18n }}"
|
||||||
[(ngModel)]="start"
|
formControlName="start"
|
||||||
(change)="dirtyDates = true"
|
(change)="dirtyDates = true"
|
||||||
/>
|
/>
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
@ -18,51 +18,43 @@
|
|||||||
bitInput
|
bitInput
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
placeholder="{{ 'endDate' | i18n }}"
|
placeholder="{{ 'endDate' | i18n }}"
|
||||||
[(ngModel)]="end"
|
formControlName="end"
|
||||||
(change)="dirtyDates = true"
|
(change)="dirtyDates = true"
|
||||||
/>
|
/>
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
<form #refreshForm [appApiAction]="refreshPromise">
|
<form>
|
||||||
<button
|
<button
|
||||||
class="tw-mx-3 tw-mt-1"
|
class="tw-mx-3 tw-mt-1"
|
||||||
type="button"
|
type="button"
|
||||||
bitButton
|
bitButton
|
||||||
|
bitFormButton
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
(click)="loadEvents(true)"
|
[bitAction]="refreshEvents"
|
||||||
[disabled]="loaded && refreshForm.loading"
|
|
||||||
>
|
>
|
||||||
{{ "update" | i18n }}
|
{{ "update" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<form #exportForm [appApiAction]="exportPromise">
|
<form>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="tw-mt-1"
|
class="tw-mt-1"
|
||||||
bitButton
|
bitButton
|
||||||
[ngClass]="{ loading: exportForm.loading }"
|
[bitAction]="exportEvents"
|
||||||
(click)="exportEvents()"
|
[disabled]="dirtyDates"
|
||||||
[disabled]="(loaded && exportForm.loading) || dirtyDates"
|
|
||||||
>
|
>
|
||||||
<span>{{ "export" | i18n }}</span>
|
<span>{{ "export" | i18n }}</span>
|
||||||
<i
|
<i class="bwi bwi-fw bwi-sign-in" aria-hidden="true"></i>
|
||||||
class="bwi bwi-fw"
|
|
||||||
aria-hidden="true"
|
|
||||||
[ngClass]="{
|
|
||||||
'bwi-sign-in': !exportForm.loading,
|
|
||||||
'bwi-spinner bwi-spin': exportForm.loading
|
|
||||||
}"
|
|
||||||
></i>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="!loaded">
|
<ng-container *ngIf="!loaded">
|
||||||
<i
|
<i
|
||||||
class="bwi bwi-spinner bwi-spin text-muted"
|
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||||
title="{{ 'loading' | i18n }}"
|
title="{{ 'loading' | i18n }}"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
<span class="sr-only">{{ "loading" | i18n }}</span>
|
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="loaded">
|
<ng-container *ngIf="loaded">
|
||||||
<p *ngIf="!events || !events.length">{{ "noEventsInList" | i18n }}</p>
|
<p *ngIf="!events || !events.length">{{ "noEventsInList" | i18n }}</p>
|
||||||
@ -85,21 +77,12 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
</bit-table>
|
</bit-table>
|
||||||
<button
|
<button
|
||||||
#moreBtn
|
|
||||||
[appApiAction]="morePromise"
|
|
||||||
type="button"
|
type="button"
|
||||||
bitButton
|
bitButton
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
(click)="loadEvents(false)"
|
[bitAction]="loadMoreEvents"
|
||||||
[disabled]="loaded && $any(moreBtn).loading"
|
|
||||||
*ngIf="continuationToken"
|
*ngIf="continuationToken"
|
||||||
>
|
>
|
||||||
<i
|
|
||||||
class="bwi bwi-spinner bwi-spin"
|
|
||||||
title="{{ 'loading' | i18n }}"
|
|
||||||
aria-hidden="true"
|
|
||||||
*ngIf="moreBtn.loading"
|
|
||||||
></i>
|
|
||||||
<span>{{ "loadMore" | i18n }}</span>
|
<span>{{ "loadMore" | i18n }}</span>
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -50,7 +50,7 @@ export class ServiceAccountEventsComponent extends BaseEventsComponent implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
await this.loadEvents(true);
|
await this.refreshEvents();
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user