feat(console): integrate frontend (#95)

* feat: console frontend

* chore(dependabot): cycle and npm

* chore: rename citadel to zitadel, remove generated files

* chore: delete go files

* chore(frontend): ci steps

* chore: remove docker and envoy files

* chore: remove docker file

* chore: working dir

* chore: run proto build

* add console start

* chore: restructure folders

* chore: remove gui build

* statikFs

* generate proto for console

* add statik import

* import

* chore: try statik

* chore: path

* chore: path

* chore: script in root

* chore: order build steps

* chore: go get

* chore: folder traversal

* chore: non empty test file

* chore: gitignore

* chore: gitignore

* chore: statik path

* chore: switch to failing FE build

* fix: build

* fix: project-grant-test

* fix: rm test

* add statik.go

* go mod tidy

* chore: place test, seperate test from build

* chore: lint all the world

* chore: ci the world instead

* chore: tune docker

* chore: undo container test

* chore: fix run

* chore: docker build

* chore: test docker build

* chore: go build flags

* finaly

* fix caos_local

* go mod

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
Co-authored-by: Max Peintner <max@caos.ch>
This commit is contained in:
Florian Forster
2020-05-13 14:41:43 +02:00
committed by GitHub
parent 9e32740eb8
commit 92a294f5c8
375 changed files with 97826 additions and 52 deletions

View File

@@ -0,0 +1,124 @@
import { Component, Input, OnInit } from '@angular/core';
import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';
import { BehaviorSubject, from, Observable } from 'rxjs';
import { scan, take, tap } from 'rxjs/operators';
import { Change, Changes } from 'src/app/proto/generated/management_pb';
import { MgmtUserService } from 'src/app/services/mgmt-user.service';
export enum ChangeType {
USER = 'user',
ORG = 'org',
PROJECT = 'project',
}
@Component({
selector: 'app-changes',
templateUrl: './changes.component.html',
styleUrls: ['./changes.component.scss'],
})
export class ChangesComponent implements OnInit {
@Input() public changeType: ChangeType = ChangeType.USER;
@Input() public id: string = '';
// Source data
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
private _loading: BehaviorSubject<any> = new BehaviorSubject(false);
private _data: BehaviorSubject<any> = new BehaviorSubject([]);
// Observable data
loading: Observable<boolean> = this._loading.asObservable();
public data!: Observable<Change.AsObject[]>;
public changes!: Changes.AsObject;
constructor(private mgmtUserService: MgmtUserService) { }
ngOnInit(): void {
this.init();
}
public scrollHandler(e: any): void {
if (e === 'bottom') {
this.more();
}
}
private init(): void {
let first: Promise<Changes>;
switch (this.changeType) {
case ChangeType.USER: first = this.mgmtUserService.UserChanges(this.id, 10, 0);
break;
case ChangeType.PROJECT: first = this.mgmtUserService.ProjectChanges(this.id, 20, 0);
break;
case ChangeType.ORG: first = this.mgmtUserService.OrgChanges(this.id, 10, 0);
break;
}
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<Changes>;
switch (this.changeType) {
case ChangeType.USER: more = this.mgmtUserService.UserChanges(this.id, 10, cursor);
break;
case ChangeType.PROJECT: more = this.mgmtUserService.ProjectChanges(this.id, 10, cursor);
break;
case ChangeType.ORG: more = this.mgmtUserService.OrgChanges(this.id, 10, cursor);
break;
}
this.mapAndUpdate(more);
}
// Determines the snapshot to paginate query
private getCursor(): number {
const current = this._data.value;
if (current.length) {
// return true ? current[0].sequence :
return current[current.length - 1].sequence;
}
return 0;
}
// Maps the snapshot to usable format the updates source
private mapAndUpdate(col: Promise<Changes>): any {
if (this._done.value || this._loading.value) { return; }
// loading
this._loading.next(true);
// Map snapshot with doc ref (needed for cursor)
return from(col).pipe(
tap((res: Changes) => {
let values = res.toObject().changesList;
// If prepending, reverse the batch order
values = false ? values.reverse() : values;
// update source with new values, done loading
this._data.next(values);
// console.log(values);
this._loading.next(false);
// no more values, mark done
if (!values.length) {
this._done.next(true);
}
}),
take(1)).subscribe();
}
public dateFromTimestamp(date: Timestamp.AsObject): any {
const ts: Date = new Date(date.seconds * 1000 + date.nanos / 1000);
return ts;
}
}