Skip to content

Commit

Permalink
First implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms committed Oct 9, 2023
1 parent 3af6571 commit 81decc8
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 2 deletions.
21 changes: 20 additions & 1 deletion frontend/src/framework/ModuleContext.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import React from "react";

import { BroadcastChannel } from "./Broadcaster";
import { ModuleInstance } from "./ModuleInstance";
import { ModuleInstance, ModuleInstanceLogEntryType } from "./ModuleInstance";
import { StateBaseType, StateStore, useSetStoreValue, useStoreState, useStoreValue } from "./StateStore";
import { SyncSettingKey } from "./SyncSettings";

export enum ModuleInstanceState {
LOADING,
READY,
ERROR,
WARNING,
}

export class ModuleContext<S extends StateBaseType> {
private _moduleInstance: ModuleInstance<S>;
private _stateStore: StateStore<S>;
Expand Down Expand Up @@ -56,4 +63,16 @@ export class ModuleContext<S extends StateBaseType> {
setInstanceTitle(title: string): void {
this._moduleInstance.setTitle(title);
}

setLoading(isLoading: boolean): void {
this._moduleInstance.setLoading(isLoading);
}

log(message: string, type: ModuleInstanceLogEntryType = ModuleInstanceLogEntryType.INFO): void {
this._moduleInstance.log(message, type);
}

clearLog(): void {
this._moduleInstance.clearLog();
}
}
48 changes: 48 additions & 0 deletions frontend/src/framework/ModuleInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ export enum ModuleInstanceState {
RESETTING,
}

export enum ModuleInstanceLogEntryType {
INFO,
WARNING,
ERROR,
}

export type ModuleInstanceLogEntry = {
message: string;
timestamp: number;
type: ModuleInstanceLogEntryType;
};

export class ModuleInstance<StateType extends StateBaseType> {
private _id: string;
private _title: string;
Expand All @@ -35,6 +47,8 @@ export class ModuleInstance<StateType extends StateBaseType> {
private _cachedDefaultState: StateType | null;
private _cachedStateStoreOptions?: StateOptions<StateType>;
private _initialSettings: InitialSettings | null;
private _contentIsLoading: boolean;
private _logEntries: ModuleInstanceLogEntry[];

constructor(
module: Module<StateType>,
Expand All @@ -57,6 +71,8 @@ export class ModuleInstance<StateType extends StateBaseType> {
this._fatalError = null;
this._cachedDefaultState = null;
this._initialSettings = null;
this._contentIsLoading = false;
this._logEntries = [];

this._broadcastChannels = {} as Record<string, BroadcastChannel>;

Expand Down Expand Up @@ -161,6 +177,38 @@ export class ModuleInstance<StateType extends StateBaseType> {
this.notifySubscribersAboutTitleChange();
}

setLoading(isLoading: boolean): void {
this._contentIsLoading = isLoading;
}

isLoading(): boolean {
return this._contentIsLoading;
}

log(message: string, type: ModuleInstanceLogEntryType = ModuleInstanceLogEntryType.INFO): void {
this._logEntries.push({
message,
timestamp: Date.now(),
type,
});
}

getLogEntries(): ModuleInstanceLogEntry[] {
return this._logEntries;
}

clearLog(): void {
this._logEntries = [];
}

hasLoggedErrors(): boolean {
return this._logEntries.some((entry) => entry.type === ModuleInstanceLogEntryType.ERROR);
}

hasLoggedWarnings(): boolean {
return this._logEntries.some((entry) => entry.type === ModuleInstanceLogEntryType.WARNING);
}

subscribeToTitleChange(cb: (title: string) => void): () => void {
this._titleChangeSubscribers.add(cb);
return () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import React from "react";

import { ModuleInstance } from "@framework/ModuleInstance";
import { SyncSettingKey, SyncSettingsMeta } from "@framework/SyncSettings";
import { CircularProgress } from "@lib/components/CircularProgress";
import { isDevMode } from "@lib/utils/devMode";
import { Close } from "@mui/icons-material";
import { Close, Error, Warning } from "@mui/icons-material";

export type HeaderProps = {
moduleInstance: ModuleInstance<any>;
Expand Down Expand Up @@ -42,6 +43,32 @@ export const Header: React.FC<HeaderProps> = (props) => {
e.stopPropagation();
}

function makeStateIndicator() {
if (props.moduleInstance.isLoading()) {
return (
<div className="flex items-center justify-center rounded p-1 leading-none bg-indigo-700 text-white ml-2 text-xs mr-2 cursor-help">
<CircularProgress size="small" />
</div>
);
}

if (props.moduleInstance.hasLoggedErrors()) {
return (
<div className="flex items-center justify-center rounded p-1 leading-none bg-red-700 text-white ml-2 text-xs mr-2 cursor-help">
<Error fontSize="small" />
</div>
);
}

if (props.moduleInstance.hasLoggedWarnings()) {
return (
<div className="flex items-center justify-center rounded p-1 leading-none bg-orange-700 text-white ml-2 text-xs mr-2 cursor-help">
<Warning fontSize="small" />
</div>
);
}
}

return (
<div
className={`bg-slate-100 p-2 pl-4 pr-4 flex items-center select-none shadow ${
Expand All @@ -50,6 +77,7 @@ export const Header: React.FC<HeaderProps> = (props) => {
onPointerDown={props.onPointerDown}
>
<div className="flex-grow flex items-center text-sm font-bold min-w-0">
{makeStateIndicator()}
<span title={title} className="flex-grow text-ellipsis whitespace-nowrap overflow-hidden min-w-0">
{title}
</span>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/modules/DistributionPlot/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export const view = ({ moduleContext, workbenchServices, workbenchSettings }: Mo
const numBins = moduleContext.useStoreValue("numBins");
const orientation = moduleContext.useStoreValue("orientation");

moduleContext.setLoading(true);

const [highlightedKey, setHighlightedKey] = React.useState<number | null>(null);
const [dataX, setDataX] = React.useState<any[] | null>(null);
const [dataY, setDataY] = React.useState<any[] | null>(null);
Expand Down

0 comments on commit 81decc8

Please sign in to comment.