Skip to content

Commit

Permalink
feat: introduce standalone mode (#162)
Browse files Browse the repository at this point in the history
* feat: introduce standalone mode

Co-authored-by: adrian_egli <[email protected]>
Co-authored-by: Simon Ser <[email protected]>

* feat: register as a custom element

Co-authored-by: Louis Greiner <[email protected]>

* fix: easy return

* small fix - the use of ng-container embeded in the sbb-icon-sidebare doesn't work correctly. This fix resolves the issue.

---------

Co-authored-by: Louis Greiner <[email protected]>
Co-authored-by: adrian_egli <[email protected]>
  • Loading branch information
3 people authored Jul 2, 2024
1 parent cd4fbaf commit cc4c56b
Show file tree
Hide file tree
Showing 19 changed files with 156 additions and 45 deletions.
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 {
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;";
}

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 "";
}

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

0 comments on commit cc4c56b

Please sign in to comment.