Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce standalone mode #162

Merged
merged 4 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@
},
"es5": {
"tsConfig": "tsconfig.app.es5.json"
},
"standalone": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.standalone.ts"
}
]
}
},
"defaultConfiguration": ""
Expand All @@ -125,6 +133,9 @@
},
"es5": {
"buildTarget": "netzgrafik-frontend:build:es5"
},
"standalone": {
"buildTarget": "netzgrafik-frontend:build:standalone"
}
}
},
Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
"ng": "ng",
"start": "ng serve",
"start:local": "ng serve --configuration=local",
"start:standalone": "ng serve --configuration=standalone",
"e2e:browserstack": "ng e2e -c browserstack",
"e2e:puppeteer": "ng e2e -c puppeteer",
"build": "ng run netzgrafik-frontend:ngsscbuild",
"build:standalone": "ng build --configuration=standalone",
"test": "ng test -c ci",
"lint": "ng lint",
"e2e": "ng e2e",
Expand All @@ -24,6 +26,7 @@
"@angular/common": "^17.0.5",
"@angular/compiler": "^17.0.5",
"@angular/core": "^17.0.5",
"@angular/elements": "^17.1.0",
"@angular/forms": "^17.0.5",
"@angular/localize": "^17.0.5",
"@angular/platform-browser": "^17.0.5",
Expand Down
14 changes: 11 additions & 3 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@
</button>
</sbb-menu>
</sbb-header-lean>
<sbb-navigation-bar class="noprint"></sbb-navigation-bar>
<ng-container *ngIf="!disableBackend">
<sbb-navigation-bar class="noprint"></sbb-navigation-bar>
</ng-container>
<router-outlet *ngIf="authenticated | async; else loading"></router-outlet>
<ng-template #loading>
<sbb-loading-indicator mode="big"></sbb-loading-indicator>
<div class="login-message">Sie werden angemeldet...</div>
<ng-container *ngIf="!disableBackend">
<sbb-loading-indicator mode="big"></sbb-loading-indicator>
<div class="login-message">Sie werden angemeldet...</div>
</ng-container>
<ng-container *ngIf="disableBackend">
<sbb-netzgrafik-editor></sbb-netzgrafik-editor>
</ng-container>
</ng-template>

16 changes: 14 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,37 @@ import {ProjectDto} from "./api/generated";
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
readonly disableBackend = environment.disableBackend;

version = packageJson.version;
environmentLabel = environment.label;
authenticated: Promise<unknown>;

projectInMenu: Observable<ProjectDto | null>;

get userName() {
if (this.disableBackend) {
return undefined;
}
return this.authService.claims?.name;
}

get email() {
if (this.disableBackend) {
return undefined;
}
return this.authService.claims?.email;
}

constructor(private authService: AuthService) {
this.authenticated = authService.initialized;
if (!this.disableBackend) {
this.authenticated = authService.initialized;
}
}

logout() {
this.authService.logOut();
if (!this.disableBackend) {
this.authService.logOut();
}
}
}
21 changes: 16 additions & 5 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {NgModule} from "@angular/core";
import {NgModule, Injector, ApplicationRef, DoBootstrap} from "@angular/core";
import {NgxEditorModule} from "ngx-editor";
import {BrowserModule} from "@angular/platform-browser";
import {createCustomElement} from "@angular/elements";
import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http";
import {OAuthModule} from "angular-oauth2-oidc";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
Expand Down Expand Up @@ -203,7 +204,7 @@ import {ActionMenuComponent} from "./view/action-menu/action-menu/action-menu.co
// and you send a request to these, the access token is appended.
// Documentation:
// https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/working-with-httpinterceptors.html
allowedUrls: [environment.backendUrl],
allowedUrls: environment.backendUrl ? [environment.backendUrl] : [],
sendAccessToken: true,
},
}),
Expand All @@ -230,10 +231,20 @@ import {ActionMenuComponent} from "./view/action-menu/action-menu/action-menu.co
SbbBreadcrumbModule,
SbbAutocompleteModule,
],
bootstrap: [AppComponent],
bootstrap: environment.customElement ? [] : [AppComponent],
providers: [
{provide: BASE_PATH, useValue: environment.backendUrl},
... environment.backendUrl ? [{provide: BASE_PATH, useValue: environment.backendUrl}] : [],
{provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true},
],
})
export class AppModule {}

export class AppModule implements DoBootstrap {
constructor(private injector: Injector) {}

ngDoBootstrap() {
if (environment.customElement) {
const element = createCustomElement(AppComponent, {injector: this.injector});
customElements.define("sbb-root", element);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<sbb-icon-sidebar-container>
<sbb-icon-sidebar [(expanded)]="expanded">
<sbb-icon-sidebar-container [attr.style]="getSidebarContainerStyle()">
<sbb-icon-sidebar [(expanded)]="expanded" >
<!--<a sbbIconSidebarItem label="Varianten" (click)="onVariantenClicked()" class="sbb-active">-->
<a
<a *ngIf="!disableBackend"
sbbIconSidebarItem
label="Varianten"
[class]="getVariantsActivatedTag()"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
sbb-icon-sidebar-container {
top: 85px;
}

::ng-deep a.SideBarMainIcon {
background: whitesmoke;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {DomSanitizer} from "@angular/platform-browser";
import {EditorMode} from "../view/editor-menu/editor-mode";
import {UndoService} from "../services/data/undo.service";
import {EditorView} from "../view/editor-main-view/data-views/editor.view";
import {NetzgrafikDefault} from "../sample-netzgrafik/netzgrafik.default";
import {environment} from "../../environments/environment";

export enum IconSidebarMode {
VARIANTEN = "varianten",
Expand All @@ -29,6 +31,8 @@ export class NetzgrafikApplicationComponent {
mode = IconSidebarMode.NONE;
expanded = false;

readonly disableBackend = environment.disableBackend;

private readonly destroyed = new Subject<void>();

constructor(
Expand All @@ -48,13 +52,24 @@ export class NetzgrafikApplicationComponent {
.subscribe((params) => {
uiInteractionService.setEditorMode(EditorMode.NetzgrafikEditing);
uiInteractionService.showNetzgrafik();
versionControlService.load(params.getVariantId(), true);
try {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why this is a try/catch instead of a if (disableBackend)?

versionControlService.load(params.getVariantId(), true);
} catch (e) {
versionControlService.loadNetzgrafikDTO(NetzgrafikDefault.getDefaultNetzgrafik());
}
uiInteractionService.setViewboxProperties(
EditorView.svgName,
uiInteractionService.getDefaultViewProperties());
});
}

getSidebarContainerStyle(): string {
if (this.disableBackend) {
return "top: 53px;";
}
return "top: 85px;";
}
Comment on lines +66 to +71
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I wonder if we should instead add a disable-backend CSS class, and use that to guard the CSS rules, instead of this?


getVariantIsWritable(): boolean {
if (this.versionControlService.variant === null) {
return true;
Expand Down
43 changes: 22 additions & 21 deletions src/app/services/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,28 @@ export class AuthService {
private router: Router,
location: Location,
) {
this.oauthService.configure(environment.authConfig);
this.oauthService.setupAutomaticSilentRefresh();
// If the user should not be forcefully logged in (e.g. if you have pages, which can be
// accessed anonymously), change loadDiscoveryDocumentAndLogin to
// loadDiscoveryDocumentAndTryLogin and have a login functionality in the
// template of the component injecting the AuthService which calls the login() method.
this.initialized = this.oauthService
.loadDiscoveryDocumentAndLogin({state: location.path()})
// If the user is not logged in, he will be forwarded to the identity provider
// and this promise will not resolve. After being redirected from the identity
// provider, the login promise will return true.
.then((v) => (v ? true : new Promise(() => {})));
// Redirect the user to the url configured with state above or in a separate login call.
this.oauthService.events
.pipe(first((e) => e.type === "token_received"))
.subscribe(() => {
const state = decodeURIComponent(this.oauthService.state || "");
if (state && state !== "/") {
this.router.navigate([state]);
}
});
if (environment.disableBackend) return;
this.oauthService.configure(environment.authConfig);
this.oauthService.setupAutomaticSilentRefresh();
// If the user should not be forcefully logged in (e.g. if you have pages, which can be
// accessed anonymously), change loadDiscoveryDocumentAndLogin to
// loadDiscoveryDocumentAndTryLogin and have a login functionality in the
// template of the component injecting the AuthService which calls the login() method.
this.initialized = this.oauthService
.loadDiscoveryDocumentAndLogin({state: location.path()})
// If the user is not logged in, he will be forwarded to the identity provider
// and this promise will not resolve. After being redirected from the identity
// provider, the login promise will return true.
.then((v) => (v ? true : new Promise(() => {})));
// Redirect the user to the url configured with state above or in a separate login call.
this.oauthService.events
.pipe(first((e) => e.type === "token_received"))
.subscribe(() => {
const state = decodeURIComponent(this.oauthService.state || "");
if (state && state !== "/") {
this.router.navigate([state]);
}
});
}

logOut() {
Expand Down
4 changes: 4 additions & 0 deletions src/app/services/data/undo.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,8 @@ export class UndoService implements OnDestroy {
}
this.currentVariantId = variantId;
}

public getCurrentVariantId():number{
return this.currentVariantId;
}
}
13 changes: 11 additions & 2 deletions src/app/services/data/version-control.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Injectable, OnDestroy} from "@angular/core";
import {HostListener, Injectable, OnDestroy} from "@angular/core";
import {
VariantControllerBackendService,
VariantDto,
Expand All @@ -13,6 +13,7 @@ import {AutoSaveService} from "./auto-save.service";
import {LogService} from "../../logger/log.service";
import {VersionId} from "../../view/variant/variant-view/variant-history/model";
import {UndoService} from "./undo.service";
import {environment} from "../../../environments/environment";

@Injectable({
providedIn: "root",
Expand All @@ -34,7 +35,8 @@ export class VersionControlService implements OnDestroy {
private readonly undoService: UndoService,
private readonly logService: LogService,
) {
autoSaveService.autosaveTrigger$
if (!environment.disableBackend) {
autoSaveService.autosaveTrigger$
.pipe(
takeUntil(this.destroyed),
filter(() => this.variant.isWritable),
Expand All @@ -43,6 +45,7 @@ export class VersionControlService implements OnDestroy {
logService.debug("auto saving changes");
this.createSnapshot();
});
}
}

get variant(): VariantDto {
Expand All @@ -69,6 +72,12 @@ export class VersionControlService implements OnDestroy {
});
}

loadNetzgrafikDTO(netzgrafik: NetzgrafikDto) {
this.dataService.loadNetzgrafikDto(netzgrafik);
this.autoSaveService.reset();
this.undoService.reset(this.undoService.getCurrentVariantId() + 1);
}

reload(loadModel = false): void {
this.load(this.variant.id, loadModel);
}
Expand Down
1 change: 1 addition & 0 deletions src/app/view/column-layout/column-layout.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
id="cd-layout-content"
[ngClass]="['mode-' + mode]"
[class.new-view]="newView"
[attr.style]="getLayoutContentStyle()"
>
<div
id="cd-layout-filter"
Expand Down
8 changes: 8 additions & 0 deletions src/app/view/column-layout/column-layout.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Input,
Output,
} from "@angular/core";
import {environment} from "../../../environments/environment";

/**
* Different layout modes. Generally the layout contains (up to) 3 columns that are distributed over a 4 columen layout:
Expand Down Expand Up @@ -70,6 +71,13 @@ export class ColumnLayoutComponent implements AfterViewInit {
this.newView = false;
}

getLayoutContentStyle(): string {
if (environment.disableBackend) {
return "height: 100%;";
}
return "";
}
Comment on lines +74 to +79
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: could use a CSS class here instead.


hideAside() {
switch (this.mode) {
case LayoutMode.FILTER_ONLY:
Expand Down
4 changes: 2 additions & 2 deletions src/app/view/editor-menu/editor-menu.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@
class="NoteEditor"
[class.isStreckengrafikEditing]="isStreckengrafikEditing()"
>
<ng-container *ngIf="!isNoteEditing()">
<ng-container *ngIf="!isNoteEditing() && !disableBackend">
<button
mode="icon"
class="ButtonNoteEditor NetzgrafikEditing"
Expand All @@ -254,7 +254,7 @@
></sbb-icon>
</button>
</ng-container>
<ng-container *ngIf="isNoteEditing()">
<ng-container *ngIf="isNoteEditing() && !disableBackend">
<button
mode="icon"
class="ButtonNoteEditor NoteEditing"
Expand Down
Loading