Skip to content
Open
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
23 changes: 23 additions & 0 deletions frontend/webEditor/src/dfdApiClient/backendUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { injectable } from "inversify";
import { SettingsValue } from "../settings/SettingsValue";

@injectable()
export class BackEndURL extends SettingsValue<string> {
private static readonly DEFAULT_URL = "https://websocket.dataflowanalysis.org/api/";

constructor() {
super(BackEndURL.DEFAULT_URL);
}

set(newValue: string): void {
super.set(newValue.endsWith("/") ? newValue : newValue + "/");
}

setDefault(): void {
this.set(BackEndURL.DEFAULT_URL);
}

isDefault(): boolean {
return this.get() === BackEndURL.DEFAULT_URL;
}
}
8 changes: 6 additions & 2 deletions frontend/webEditor/src/dfdApiClient/dfdApiClient.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { inject, injectable } from "inversify";
import { FileName } from "../fileName/fileName";
import { BackEndURL } from "./backendUrl";

@injectable()
export class DfdApiClient {
constructor(@inject(FileName) private readonly fileName: FileName) {}
constructor(
@inject(BackEndURL) private readonly backEndURL: BackEndURL,
@inject(FileName) private readonly fileName: FileName,
) {}

public async requestDiagram(message: string, action: string) {
try {
Expand All @@ -23,7 +27,7 @@ export class DfdApiClient {
}

public sendMessage(message: string, action: string, name?: string): Promise<string> {
const apiUrl = `https://websocket.dataflowanalysis.org/api/${action}`;
const apiUrl = `${this.backEndURL.get()}${action}`;
const fileName = name ?? this.fileName.getName();

return fetch(apiUrl, {
Expand Down
5 changes: 5 additions & 0 deletions frontend/webEditor/src/dfdApiClient/di.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ContainerModule } from "inversify";
import { DfdApiClient } from "./dfdApiClient";
import { BackEndURL } from "./backendUrl";
import { SETTINGS } from "../settings/Settings";

export const dfdApiModule = new ContainerModule((bind) => {
bind(BackEndURL).toSelf().inSingletonScope();
bind(SETTINGS.BackEndURL).toService(BackEndURL);

bind(DfdApiClient).toSelf().inSingletonScope();
});
1 change: 1 addition & 0 deletions frontend/webEditor/src/settings/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const SETTINGS = {
HideEdgeNames: Symbol("HideEdgeNames"),
SimplifyNodeNames: Symbol("SimplifyNodeNames"),
ShownLabels: Symbol("ShownLabels"),
BackEndURL: Symbol("BackEndURL"),
};

export type SimplifyNodeNames = BoolSettingsValue;
Expand Down
47 changes: 47 additions & 0 deletions frontend/webEditor/src/settings/SettingsUi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { HideEdgeNames, SETTINGS, SimplifyNodeNames } from "./Settings";
import { EditorModeController } from "./editorMode";
import { Theme, ThemeManager } from "./Theme";
import { ShownLabels, ShownLabelsValue } from "./ShownLabels";
import { BackEndURL } from "../dfdApiClient/backendUrl";

@injectable()
export class SettingsUI extends AccordionUiExtension {
Expand All @@ -17,6 +18,7 @@ export class SettingsUI extends AccordionUiExtension {
@inject(SETTINGS.HideEdgeNames) private readonly hideEdgeNames: HideEdgeNames,
@inject(SETTINGS.SimplifyNodeNames) private readonly simplifyNodeNames: SimplifyNodeNames,
@inject(SETTINGS.Mode) private readonly editorModeController: EditorModeController,
@inject(SETTINGS.BackEndURL) private readonly backEndURL: BackEndURL,
) {
super("right", "up");
}
Expand All @@ -42,6 +44,7 @@ export class SettingsUI extends AccordionUiExtension {
this.addBooleanSwitch(grid, "Hide Edge Names", this.hideEdgeNames);
this.addBooleanSwitch(grid, "Simplify Node Names", this.simplifyNodeNames);
this.addSwitch(grid, "Read Only", this.editorModeController, { true: "view", false: "edit" });
this.addURLInput(grid);
}

protected initializeHeaderContent(headerElement: HTMLElement): void {
Expand Down Expand Up @@ -118,6 +121,50 @@ export class SettingsUI extends AccordionUiExtension {
container.appendChild(textLabel);
container.appendChild(dropDown);
}

private addURLInput(container: HTMLElement) {
const title = "Backend URL";
const textLabel = document.createElement("label");
textLabel.textContent = title;
textLabel.htmlFor = `setting-${title.toLowerCase().replace(/\s+/g, "-")}`;

const inputHolder = document.createElement("div");
inputHolder.id = "url-input-holder";
const textInput = document.createElement("input");
textInput.id = `setting-${title.toLowerCase().replace(/\s+/g, "-")}`;
textInput.value = this.backEndURL.get();
const resetButton = document.createElement("button");
resetButton.id = "url-reset";
inputHolder.appendChild(textInput);
inputHolder.appendChild(resetButton);

const visibilityClass = "visible";
this.backEndURL.registerListener((v) => {
textInput.value = v;
if (!this.backEndURL.isDefault()) {
resetButton.classList.add(visibilityClass);
} else {
resetButton.classList.remove(visibilityClass);
}
});
textInput.onchange = () => {
// when changing from the default URL we ask the user for confirmation
const confirmation = this.backEndURL.isDefault()
? confirm("Are you sure you want to change the Backend URL?")
: true;
if (confirmation) {
this.backEndURL.set(textInput.value);
} else {
textInput.value = this.backEndURL.get();
}
};
resetButton.onclick = () => {
this.backEndURL.setDefault();
};

container.appendChild(textLabel);
container.appendChild(inputHolder);
}
}

interface ToString {
Expand Down
32 changes: 32 additions & 0 deletions frontend/webEditor/src/settings/settingsUi.css
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,35 @@ input:checked + .slider:before {
.slider.round:before {
border-radius: 50%;
}

#url-input-holder {
display: flex;
gap: 4px;
align-items: center;
width: 250px;
overflow: hidden;
}

#url-input-holder input {
flex: 1 1 auto;
background-color: var(--color-background);
color: var(--color-foreground);
border: 1px solid var(--color-foreground);
border-radius: 6px;
font-size: 12px;
padding: 2px 4px;
}

#url-reset {
background-color: transparent;
background-image: url("@fortawesome/fontawesome-free/svgs/solid/arrow-rotate-left.svg");
color: var(--color-foreground);
border: none;
height: 12px;
width: 12px;
cursor: pointer;
display: none;
}
#url-reset.visible {
display: inline-block;
}
Loading