mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-26 17:06:28 +00:00
feat(console): update deps, alternative hash function with fixed colors, use preferrenLoginName for hashing, fix iam write permissions, user img upload (#1846)
* chore(deps-dev): bump @types/jasmine from 3.6.9 to 3.7.7 in /console (#1824) Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.6.9 to 3.7.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine) --- updated-dependencies: - dependency-name: "@types/jasmine" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump google-protobuf from 3.15.8 to 3.17.2 in /console (#1823) Bumps [google-protobuf](https://github.com/protocolbuffers/protobuf) from 3.15.8 to 3.17.2. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/master/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.15.8...v3.17.2) --- updated-dependencies: - dependency-name: google-protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @angular/animations from 12.0.0 to 12.0.3 in /console (#1821) Bumps [@angular/animations](https://github.com/angular/angular/tree/HEAD/packages/animations) from 12.0.0 to 12.0.3. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/12.0.3/packages/animations) --- updated-dependencies: - dependency-name: "@angular/animations" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @angular/material from 12.0.0 to 12.0.3 in /console (#1819) Bumps [@angular/material](https://github.com/angular/components) from 12.0.0 to 12.0.3. - [Release notes](https://github.com/angular/components/releases) - [Changelog](https://github.com/angular/components/blob/12.0.3/CHANGELOG.md) - [Commits](https://github.com/angular/components/compare/12.0.0...12.0.3) --- updated-dependencies: - dependency-name: "@angular/material" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump prettier from 2.2.1 to 2.3.1 in /console (#1818) Bumps [prettier](https://github.com/prettier/prettier) from 2.2.1 to 2.3.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.2.1...2.3.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @angular/platform-browser-dynamic in /console (#1817) Bumps [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) from 12.0.0 to 12.0.3. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/12.0.3/packages/platform-browser-dynamic) --- updated-dependencies: - dependency-name: "@angular/platform-browser-dynamic" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/node from 14.14.37 to 15.12.1 in /console (#1815) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.37 to 15.12.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @angular/common from 12.0.0 to 12.0.3 in /console (#1814) Bumps [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) from 12.0.0 to 12.0.3. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/12.0.3/packages/common) --- updated-dependencies: - dependency-name: "@angular/common" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @angular/material-moment-adapter from 12.0.0 to 12.0.3 in /console (#1816) * chore(deps): bump @angular/material-moment-adapter in /console Bumps [@angular/material-moment-adapter](https://github.com/angular/components) from 12.0.0 to 12.0.3. - [Release notes](https://github.com/angular/components/releases) - [Changelog](https://github.com/angular/components/blob/12.0.3/CHANGELOG.md) - [Commits](https://github.com/angular/components/compare/12.0.0...12.0.3) --- updated-dependencies: - dependency-name: "@angular/material-moment-adapter" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * sort Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> * chore(deps-dev): bump @angular/language-service in /console (#1822) Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 12.0.0 to 12.0.3. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/12.0.3/packages/language-service) --- updated-dependencies: - dependency-name: "@angular/language-service" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> * image cropper * fix: avatar bg colors, preferred username, login script * lint * membership color * rem logs * profile picture component * pic comp * dialog tirgger btn * trigger dialog, styles * lock * interceptor for org, upload, remove * tooltip * lint * stylelint * generate same credentials of username as in login * deletepic * fix disable privatelabeling on missing feature, i18n * lint * stylelint * block loading images if no feature * lint * optimize feature check Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
@@ -6,254 +6,256 @@ import { catchError, debounceTime, scan, take, takeUntil, tap } from 'rxjs/opera
|
||||
import { ListMyUserChangesResponse } from 'src/app/proto/generated/zitadel/auth_pb';
|
||||
import { Change } from 'src/app/proto/generated/zitadel/change_pb';
|
||||
import {
|
||||
ListAppChangesResponse,
|
||||
ListOrgChangesResponse,
|
||||
ListProjectChangesResponse,
|
||||
ListUserChangesResponse,
|
||||
ListAppChangesResponse,
|
||||
ListOrgChangesResponse,
|
||||
ListProjectChangesResponse,
|
||||
ListUserChangesResponse,
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
|
||||
export enum ChangeType {
|
||||
MYUSER = 'myuser',
|
||||
USER = 'user',
|
||||
ORG = 'org',
|
||||
PROJECT = 'project',
|
||||
APP = 'app',
|
||||
MYUSER = 'myuser',
|
||||
USER = 'user',
|
||||
ORG = 'org',
|
||||
PROJECT = 'project',
|
||||
APP = 'app',
|
||||
}
|
||||
|
||||
export interface MappedChange {
|
||||
key: string;
|
||||
values: Array<{
|
||||
data: any[];
|
||||
dates: Timestamp.AsObject[];
|
||||
editorId: string;
|
||||
editorName: string;
|
||||
eventTypes: Array<{ key: string; localizedMessage: string; }>;
|
||||
sequences: number[];
|
||||
}>;
|
||||
key: string;
|
||||
values: Array<{
|
||||
data: any[];
|
||||
dates: Timestamp.AsObject[];
|
||||
editorId: string;
|
||||
editorName: string;
|
||||
eventTypes: Array<{ key: string; localizedMessage: string; }>;
|
||||
sequences: number[];
|
||||
}>;
|
||||
}
|
||||
|
||||
type ListChanges = ListMyUserChangesResponse.AsObject |
|
||||
ListUserChangesResponse.AsObject |
|
||||
ListProjectChangesResponse.AsObject |
|
||||
ListOrgChangesResponse.AsObject |
|
||||
ListAppChangesResponse.AsObject;
|
||||
ListUserChangesResponse.AsObject |
|
||||
ListProjectChangesResponse.AsObject |
|
||||
ListOrgChangesResponse.AsObject |
|
||||
ListAppChangesResponse.AsObject;
|
||||
|
||||
@Component({
|
||||
selector: 'app-changes',
|
||||
templateUrl: './changes.component.html',
|
||||
styleUrls: ['./changes.component.scss'],
|
||||
selector: 'app-changes',
|
||||
templateUrl: './changes.component.html',
|
||||
styleUrls: ['./changes.component.scss'],
|
||||
})
|
||||
export class ChangesComponent implements OnInit, OnDestroy {
|
||||
@Input() public changeType: ChangeType = ChangeType.USER;
|
||||
@Input() public id: string = '';
|
||||
@Input() public secId: string = '';
|
||||
@Input() public sortDirectionAsc: boolean = true;
|
||||
@Input() public refresh!: Observable<void>;
|
||||
public bottom: boolean = false;
|
||||
@Input() public changeType: ChangeType = ChangeType.USER;
|
||||
@Input() public id: string = '';
|
||||
@Input() public secId: string = '';
|
||||
@Input() public sortDirectionAsc: boolean = true;
|
||||
@Input() public refresh!: Observable<void>;
|
||||
public bottom: boolean = false;
|
||||
|
||||
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
private _loading: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
private _data: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
private _loading: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
private _data: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||
|
||||
loading: Observable<boolean> = this._loading.asObservable();
|
||||
public data!: Observable<MappedChange[]>;
|
||||
public changes!: ListChanges;
|
||||
private destroyed$: Subject<void> = new Subject();
|
||||
constructor(private mgmtUserService: ManagementService, private authUserService: GrpcAuthService) {
|
||||
loading: Observable<boolean> = this._loading.asObservable();
|
||||
public data!: Observable<MappedChange[]>;
|
||||
public changes!: ListChanges;
|
||||
private destroyed$: Subject<void> = new Subject();
|
||||
constructor(private mgmtUserService: ManagementService, private authUserService: GrpcAuthService) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
ngOnInit(): void {
|
||||
this.init();
|
||||
if (this.refresh) {
|
||||
this.refresh.pipe(takeUntil(this.destroyed$), debounceTime(2000)).subscribe(() => {
|
||||
this.init();
|
||||
if (this.refresh) {
|
||||
this.refresh.pipe(takeUntil(this.destroyed$), debounceTime(2000)).subscribe(() => {
|
||||
this.init();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroyed$.next();
|
||||
}
|
||||
|
||||
public scrollHandler(e: any): void {
|
||||
if (e === 'bottom') {
|
||||
this.more();
|
||||
}
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
let first: Promise<ListChanges>;
|
||||
switch (this.changeType) {
|
||||
case ChangeType.MYUSER: first = this.authUserService.listMyUserChanges(20, 0);
|
||||
break;
|
||||
case ChangeType.USER: first = this.mgmtUserService.listUserChanges(this.id, 20, 0);
|
||||
break;
|
||||
case ChangeType.PROJECT: first = this.mgmtUserService.listProjectChanges(this.id, 20, 0);
|
||||
break;
|
||||
case ChangeType.ORG: first = this.mgmtUserService.listOrgChanges(20, 0);
|
||||
break;
|
||||
case ChangeType.APP: first = this.mgmtUserService.listAppChanges(this.id, this.secId, 20, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroyed$.next();
|
||||
this.mapAndUpdate(first);
|
||||
|
||||
// Create the observable array for consumption in components
|
||||
this.data = this._data.asObservable().pipe(
|
||||
scan((acc, val) => {
|
||||
return false ? val.concat(acc) : acc.concat(val);
|
||||
}));
|
||||
}
|
||||
|
||||
private more(): void {
|
||||
const cursor = this.getCursor();
|
||||
|
||||
let more: Promise<ListChanges>;
|
||||
|
||||
switch (this.changeType) {
|
||||
case ChangeType.MYUSER: more = this.authUserService.listMyUserChanges(20, cursor);
|
||||
break;
|
||||
case ChangeType.USER: more = this.mgmtUserService.listUserChanges(this.id, 20, cursor);
|
||||
break;
|
||||
case ChangeType.PROJECT: more = this.mgmtUserService.listProjectChanges(this.id, 20, cursor);
|
||||
break;
|
||||
case ChangeType.ORG: more = this.mgmtUserService.listOrgChanges(20, cursor);
|
||||
break;
|
||||
case ChangeType.APP: more = this.mgmtUserService.listAppChanges(this.id, this.secId, 20, cursor);
|
||||
break;
|
||||
}
|
||||
|
||||
public scrollHandler(e: any): void {
|
||||
if (e === 'bottom') {
|
||||
this.more();
|
||||
}
|
||||
this.mapAndUpdate(more);
|
||||
}
|
||||
|
||||
// Determines the snapshot to paginate query
|
||||
private getCursor(): number {
|
||||
const current = this._data.value;
|
||||
|
||||
if (current.length) {
|
||||
const lastElementValues = current[current.length - 1].values;
|
||||
const seq = lastElementValues[lastElementValues.length - 1].sequences;
|
||||
return seq[seq.length - 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
let first: Promise<ListChanges>;
|
||||
switch (this.changeType) {
|
||||
case ChangeType.MYUSER: first = this.authUserService.listMyUserChanges(20, 0);
|
||||
break;
|
||||
case ChangeType.USER: first = this.mgmtUserService.listUserChanges(this.id, 20, 0);
|
||||
break;
|
||||
case ChangeType.PROJECT: first = this.mgmtUserService.listProjectChanges(this.id, 20, 0);
|
||||
break;
|
||||
case ChangeType.ORG: first = this.mgmtUserService.listOrgChanges(20, 0);
|
||||
break;
|
||||
case ChangeType.APP: first = this.mgmtUserService.listAppChanges(this.id, this.secId, 20, 0);
|
||||
break;
|
||||
}
|
||||
// Maps the snapshot to usable format the updates source
|
||||
private mapAndUpdate(col: Promise<ListChanges>): any {
|
||||
if (this._done.value || this._loading.value) { return; }
|
||||
|
||||
this.mapAndUpdate(first);
|
||||
// Map snapshot with doc ref (needed for cursor)
|
||||
if (!this.bottom) {
|
||||
// loading
|
||||
this._loading.next(true);
|
||||
|
||||
// Create the observable array for consumption in components
|
||||
this.data = this._data.asObservable().pipe(
|
||||
scan((acc, val) => {
|
||||
return false ? val.concat(acc) : acc.concat(val);
|
||||
}));
|
||||
return from(col).pipe(
|
||||
take(1),
|
||||
tap((res: ListChanges) => {
|
||||
const values = res.resultList;
|
||||
const mapped = this.mapChanges(values);
|
||||
// update source with new values, done loading
|
||||
// this._data.next(values);
|
||||
this._data.next(mapped);
|
||||
|
||||
this._loading.next(false);
|
||||
|
||||
// no more values, mark done
|
||||
if (!values.length) {
|
||||
this._done.next(true);
|
||||
}
|
||||
}),
|
||||
catchError(_ => {
|
||||
this._loading.next(false);
|
||||
this.bottom = true;
|
||||
return of([]);
|
||||
}),
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
private more(): void {
|
||||
const cursor = this.getCursor();
|
||||
private mapChanges(changes: Change.AsObject[]): {
|
||||
key: string; values: any[];
|
||||
}[] {
|
||||
const splitted: { [editorId: string]: any[]; } = {};
|
||||
changes.forEach((change) => {
|
||||
if (change.changeDate) {
|
||||
const index = `${this.getDateString(change.changeDate)}`;
|
||||
// `${this.getDateString(change.changeDate)}:${change.editorId}`;
|
||||
|
||||
let more: Promise<ListChanges>;
|
||||
if (index) {
|
||||
if (splitted[index]) {
|
||||
const userData: any = {
|
||||
editor: change.editorDisplayName,
|
||||
editorId: change.editorId,
|
||||
editorDisplayName: change.editorDisplayName,
|
||||
|
||||
switch (this.changeType) {
|
||||
case ChangeType.MYUSER: more = this.authUserService.listMyUserChanges(20, cursor);
|
||||
break;
|
||||
case ChangeType.USER: more = this.mgmtUserService.listUserChanges(this.id, 20, cursor);
|
||||
break;
|
||||
case ChangeType.PROJECT: more = this.mgmtUserService.listProjectChanges(this.id, 20, cursor);
|
||||
break;
|
||||
case ChangeType.ORG: more = this.mgmtUserService.listOrgChanges(20, cursor);
|
||||
break;
|
||||
case ChangeType.APP: more = this.mgmtUserService.listAppChanges(this.id, this.secId, 20, cursor);
|
||||
break;
|
||||
}
|
||||
|
||||
this.mapAndUpdate(more);
|
||||
}
|
||||
|
||||
// Determines the snapshot to paginate query
|
||||
private getCursor(): number {
|
||||
const current = this._data.value;
|
||||
|
||||
if (current.length) {
|
||||
const lastElementValues = current[current.length - 1].values;
|
||||
const seq = lastElementValues[lastElementValues.length - 1].sequences;
|
||||
return seq[seq.length - 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Maps the snapshot to usable format the updates source
|
||||
private mapAndUpdate(col: Promise<ListChanges>): any {
|
||||
if (this._done.value || this._loading.value) { return; }
|
||||
|
||||
// Map snapshot with doc ref (needed for cursor)
|
||||
if (!this.bottom) {
|
||||
// loading
|
||||
this._loading.next(true);
|
||||
|
||||
return from(col).pipe(
|
||||
take(1),
|
||||
tap((res: ListChanges) => {
|
||||
const values = res.resultList;
|
||||
const mapped = this.mapChanges(values);
|
||||
// update source with new values, done loading
|
||||
// this._data.next(values);
|
||||
this._data.next(mapped);
|
||||
|
||||
this._loading.next(false);
|
||||
|
||||
// no more values, mark done
|
||||
if (!values.length) {
|
||||
this._done.next(true);
|
||||
}
|
||||
}),
|
||||
catchError(_ => {
|
||||
this._loading.next(false);
|
||||
this.bottom = true;
|
||||
return of([]);
|
||||
}),
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
private mapChanges(changes: Change.AsObject[]): {
|
||||
key: string; values: any[];
|
||||
}[] {
|
||||
const splitted: { [editorId: string]: any[]; } = {};
|
||||
changes.forEach((change) => {
|
||||
if (change.changeDate) {
|
||||
const index = `${this.getDateString(change.changeDate)}`;
|
||||
// `${this.getDateString(change.changeDate)}:${change.editorId}`;
|
||||
|
||||
if (index) {
|
||||
if (splitted[index]) {
|
||||
const userData: any = {
|
||||
editor: change.editorDisplayName,
|
||||
editorId: change.editorId,
|
||||
editorDisplayName: change.editorDisplayName,
|
||||
|
||||
dates: [change.changeDate],
|
||||
// data: [change.data],
|
||||
eventTypes: [change.eventType],
|
||||
sequences: [change.sequence],
|
||||
};
|
||||
const lastIndex = splitted[index].length - 1;
|
||||
if (lastIndex > -1 && splitted[index][lastIndex].editor === change.editorDisplayName) {
|
||||
splitted[index][lastIndex].dates.push(change.changeDate);
|
||||
// splitted[index][lastIndex].data.push(change.data);
|
||||
splitted[index][lastIndex].eventTypes.push(change.eventType);
|
||||
splitted[index][lastIndex].sequences.push(change.sequence);
|
||||
} else {
|
||||
splitted[index].push(userData);
|
||||
}
|
||||
} else {
|
||||
splitted[index] = [
|
||||
{
|
||||
editor: change.editorDisplayName,
|
||||
editorId: change.editorId,
|
||||
editorDisplayName: change.editorDisplayName,
|
||||
|
||||
dates: [change.changeDate],
|
||||
// data: [change.data],
|
||||
eventTypes: [change.eventType],
|
||||
sequences: [change.sequence],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
dates: [change.changeDate],
|
||||
// data: [change.data],
|
||||
eventTypes: [change.eventType],
|
||||
sequences: [change.sequence],
|
||||
};
|
||||
const lastIndex = splitted[index].length - 1;
|
||||
if (lastIndex > -1 && splitted[index][lastIndex].editor === change.editorDisplayName) {
|
||||
splitted[index][lastIndex].dates.push(change.changeDate);
|
||||
// splitted[index][lastIndex].data.push(change.data);
|
||||
splitted[index][lastIndex].eventTypes.push(change.eventType);
|
||||
splitted[index][lastIndex].sequences.push(change.sequence);
|
||||
} else {
|
||||
splitted[index].push(userData);
|
||||
}
|
||||
});
|
||||
const arr = Object.keys(splitted).map(key => {
|
||||
return { key: key, values: splitted[key] };
|
||||
});
|
||||
} else {
|
||||
splitted[index] = [
|
||||
{
|
||||
editor: change.editorDisplayName,
|
||||
editorId: change.editorId,
|
||||
editorDisplayName: change.editorDisplayName,
|
||||
|
||||
arr.sort((a, b) => {
|
||||
return parseFloat(b.key) - parseFloat(a.key);
|
||||
});
|
||||
dates: [change.changeDate],
|
||||
// data: [change.data],
|
||||
eventTypes: [change.eventType],
|
||||
sequences: [change.sequence],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const arr = Object.keys(splitted).map(key => {
|
||||
return { key: key, values: splitted[key] };
|
||||
});
|
||||
|
||||
return arr;
|
||||
}
|
||||
arr.sort((a, b) => {
|
||||
return parseFloat(b.key) - parseFloat(a.key);
|
||||
});
|
||||
|
||||
getDateString(ts: Timestamp.AsObject): string {
|
||||
const date = new Date(ts.seconds * 1000 + ts.nanos / 1000 / 1000);
|
||||
return date.getUTCFullYear() + this.pad(date.getUTCMonth() + 1) + this.pad(date.getUTCDate());
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
getTimestampIndex(date: any): number {
|
||||
const ts: Date = new Date(date.seconds * 1000 + date.nanos / 1000 / 1000);
|
||||
return ts.getTime();
|
||||
}
|
||||
getDateString(ts: Timestamp.AsObject): string {
|
||||
const date = new Date(ts.seconds * 1000 + ts.nanos / 1000 / 1000);
|
||||
return date.getUTCFullYear() + this.pad(date.getUTCMonth() + 1) + this.pad(date.getUTCDate());
|
||||
}
|
||||
|
||||
pad(n: number): string {
|
||||
return n < 10 ? '0' + n : n.toString();
|
||||
}
|
||||
getTimestampIndex(date: any): number {
|
||||
const ts: Date = new Date(date.seconds * 1000 + date.nanos / 1000 / 1000);
|
||||
return ts.getTime();
|
||||
}
|
||||
|
||||
// Order by ascending property value
|
||||
valueAscOrder = (a: KeyValue<number, string>, b: KeyValue<number, string>): number => {
|
||||
return a.value.localeCompare(b.value);
|
||||
}
|
||||
pad(n: number): string {
|
||||
return n < 10 ? '0' + n : n.toString();
|
||||
}
|
||||
|
||||
// Order by descending property key
|
||||
keyDescOrder = (a: KeyValue<number, string>, b: KeyValue<number, string>): number => {
|
||||
return a.key > b.key ? -1 : (b.key > a.key ? 1 : 0);
|
||||
}
|
||||
// Order by ascending property value
|
||||
// tslint:disable
|
||||
valueAscOrder = (a: KeyValue<number, string>, b: KeyValue<number, string>): number => {
|
||||
return a.value.localeCompare(b.value);
|
||||
};
|
||||
|
||||
// Order by descending property key
|
||||
keyDescOrder = (a: KeyValue<number, string>, b: KeyValue<number, string>): number => {
|
||||
return a.key > b.key ? -1 : (b.key > a.key ? 1 : 0);
|
||||
};
|
||||
// tslint:enable
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user