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

Fix Toast Theme Support and other minor improvements #7751

Merged
merged 17 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
6bea52d
enable proper toast support outside of component context and other mi…
MichaelBuessemeyer Apr 15, 2024
c2d6295
adjust toast lib to always render in correct theme
MichaelBuessemeyer Apr 15, 2024
d621b7c
update cyclic dependencies detection
MichaelBuessemeyer Apr 15, 2024
9877e47
UNDO: fix cyclic deps script output formatting
MichaelBuessemeyer Apr 15, 2024
3336fc5
fix import order in e2e tests
MichaelBuessemeyer Apr 15, 2024
d8561d5
Merge branch 'master' of github.com:scalableminds/webknossos into all…
MichaelBuessemeyer Apr 15, 2024
73a7d97
Apply suggestions from code review
MichaelBuessemeyer Apr 15, 2024
38a50c9
Merge branch 'master' into allow-toast-outside-renderin-context
MichaelBuessemeyer Apr 15, 2024
1d4cdd8
Apply pr feedback
MichaelBuessemeyer Apr 16, 2024
43a3bb0
apply pr feedback
MichaelBuessemeyer Apr 16, 2024
0e42b2f
Change to a permanent toast context root point to reenable closing to…
MichaelBuessemeyer Apr 16, 2024
77823b5
Merge branch 'master' of github.com:scalableminds/webknossos into all…
MichaelBuessemeyer Apr 16, 2024
4f8a2f9
update comment
MichaelBuessemeyer Apr 16, 2024
0fbe1a9
Merge branch 'master' of github.com:scalableminds/webknossos into all…
MichaelBuessemeyer Apr 24, 2024
4f28ba7
reopen toast upon repetitive open call with the same key
MichaelBuessemeyer Apr 24, 2024
e03c13e
move canceling closing of pending toast binding second wait expression
MichaelBuessemeyer Apr 30, 2024
f2f86f5
Merge branch 'master' of github.com:scalableminds/webknossos into all…
MichaelBuessemeyer Apr 30, 2024
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
2 changes: 1 addition & 1 deletion frontend/javascripts/libs/render_independently.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function renderIndependently(
ReactDOM.render(
// @ts-ignore
<Provider store={Store}>
<GlobalThemeProvider>{getComponent(destroy)}</GlobalThemeProvider>
<GlobalThemeProvider isMainProvider={false}>{getComponent(destroy)}</GlobalThemeProvider>
</Provider>,
div,
);
Expand Down
64 changes: 62 additions & 2 deletions frontend/javascripts/libs/toast.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { notification, Collapse } from "antd";
import { CloseCircleOutlined } from "@ant-design/icons";
import React from "react";
import { useEffectOnlyOnce } from "./react_hooks";
import renderIndependently from "./render_independently";
import { animationFrame, sleep } from "./utils";

export type ToastStyle = "info" | "warning" | "success" | "error";
Expand All @@ -18,6 +20,29 @@ export type ToastConfig = {
onClose?: () => void;
};

export type NotificationAPI = ReturnType<typeof notification.useNotification>[0];
type ToastMessageCallback = (api: NotificationAPI) => React.ReactNode;

function ToastFunctionalComponentWrapper(props: {
type: ToastStyle;
message: (api: NotificationAPI) => React.ReactNode;
MichaelBuessemeyer marked this conversation as resolved.
Show resolved Hide resolved
config: ToastConfig;
details: string | undefined;
}) {
const [toastAPI, contextHolder] = notification.useNotification();
useEffectOnlyOnce(() => {
Toast._messageInternal(
props.type,
props.message(toastAPI),
props.config,
toastAPI,
props.details,
);
});
// Return empty renderable component for "renderIndependently"
return <>{contextHolder}</>;
}

const Toast = {
messages(messages: Message[]): void {
const errorChainObject = messages.find((msg) => typeof msg.chain !== "undefined");
Expand Down Expand Up @@ -76,10 +101,11 @@ const Toast = {
);
},

async message(
async _messageInternal(
type: ToastStyle,
rawMessage: string | React.ReactNode,
config: ToastConfig,
notificationAPI: NotificationAPI,
details?: string,
): Promise<void> {
const message = this.buildContentWithDetails(rawMessage, details);
Expand Down Expand Up @@ -111,7 +137,7 @@ const Toast = {
});
}

notification[type](toastConfig);
notificationAPI[type](toastConfig);

// Make sure that toasts don't just disappear while the user has WK in a background tab (e.g. while uploading large dataset).
// Most browsers pause requestAnimationFrame() if the current tab is not active, but Firefox does not seem to do that.
Expand Down Expand Up @@ -155,5 +181,39 @@ const Toast = {
close(key: string) {
notification.destroy(key);
},
message(
type: ToastStyle,
message: ToastMessageCallback | React.ReactNode = "Success :-)",
config: ToastConfig = {},
details?: string | undefined,
) {
renderIndependently((destroy) => {
// Deferring destroy to give the Notification API a chance to close the toast via timeout
// before unmounting the parent component created with renderIndependently.
philippotto marked this conversation as resolved.
Show resolved Hide resolved
const deferredDestroy = () => setTimeout(destroy, 0);
const userOnClose = config.onClose;
// Making sure onClose destroys the ToastFunctionalComponentWrapper instance.
config.onClose =
userOnClose != null
? () => {
userOnClose();
deferredDestroy();
}
: () => {
deferredDestroy();
};
MichaelBuessemeyer marked this conversation as resolved.
Show resolved Hide resolved
const maybeWrappedMessage = (
typeof message === "function" ? message : () => message
) as ToastMessageCallback;
return (
<ToastFunctionalComponentWrapper
message={maybeWrappedMessage}
config={config}
details={details}
type={type}
/>
);
});
},
};
export default Toast;
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ class BoundingBox {
});
}

extend(other: BoundingBox): BoundingBox {
const newMin = V3.min(this.min, other.min);
const newMax = V3.max(this.max, other.max);
return new BoundingBox({
min: newMin,
max: newMax,
});
}

MichaelBuessemeyer marked this conversation as resolved.
Show resolved Hide resolved
getCenter(): Vector3 {
return V3.floor(V3.add(this.min, V3.scale(this.getSize(), 0.5)));
}
Expand Down
10 changes: 5 additions & 5 deletions frontend/javascripts/oxalis/store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createStore, applyMiddleware } from "redux";
import { enableBatching } from "redux-batched-actions";
import createSagaMiddleware, { Saga } from "redux-saga";
import createSagaMiddleware, { type Saga } from "redux-saga";
import type {
APIAllowedMode,
APIAnnotationType,
Expand Down Expand Up @@ -47,13 +47,13 @@ import type {
InterpolationMode,
TreeType,
} from "oxalis/constants";
import { BLEND_MODES, ControlModeEnum } from "oxalis/constants";
import type { BLEND_MODES, ControlModeEnum } from "oxalis/constants";
import type { Matrix4x4 } from "libs/mjs";
import type { UpdateAction } from "oxalis/model/sagas/update_actions";
import AnnotationReducer from "oxalis/model/reducers/annotation_reducer";
import DatasetReducer from "oxalis/model/reducers/dataset_reducer";
import DiffableMap from "libs/diffable_map";
import EdgeCollection from "oxalis/model/edge_collection";
import type DiffableMap from "libs/diffable_map";
import type EdgeCollection from "oxalis/model/edge_collection";
import FlycamReducer from "oxalis/model/reducers/flycam_reducer";
import SaveReducer from "oxalis/model/reducers/save_reducer";
import SettingsReducer from "oxalis/model/reducers/settings_reducer";
Expand All @@ -69,7 +69,7 @@ import overwriteActionMiddleware from "oxalis/model/helpers/overwrite_action_mid
import reduceReducers from "oxalis/model/helpers/reduce_reducers";
import ConnectomeReducer from "oxalis/model/reducers/connectome_reducer";
import OrganizationReducer from "./model/reducers/organization_reducer";
import { StartAIJobModalState } from "./view/action-bar/starting_job_modals";
import type { StartAIJobModalState } from "./view/action-bar/starting_job_modals";

export type MutableCommentType = {
content: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import _ from "lodash";
import Request from "libs/request";
import {
tokenUserA,
tokenUserC,
Expand All @@ -8,6 +7,7 @@ import {
replaceVolatileValues,
writeTypeCheckingFile,
} from "test/enzyme/e2e-setup";
import Request from "libs/request";
import * as foldersApi from "admin/api/folders";
import test from "ava";
test.before("Reset database and change token", async () => {
Expand Down
7 changes: 5 additions & 2 deletions frontend/javascripts/theme.tsx
philippotto marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ export function getAntdTheme(userTheme: Theme) {
return { algorithm, token: globalDesignToken, components };
}

export default function GlobalThemeProvider({ children }: { children?: React.ReactNode }) {
export default function GlobalThemeProvider({
children,
isMainProvider = true,
}: { children?: React.ReactNode; isMainProvider?: boolean }) {
const activeUser = useSelector((state: OxalisState) => state.activeUser);
const userTheme = getThemeFromUser(activeUser);
const antdTheme = getAntdTheme(userTheme);
Expand All @@ -82,7 +85,7 @@ export default function GlobalThemeProvider({ children }: { children?: React.Rea
className={isDarkMode ? "dark-theme" : undefined}
style={{
background: "var(--ant-color-bg-base)",
height: "calc(100vh - var(--navbar-height))",
height: isMainProvider ? "calc(100vh - var(--navbar-height))" : "auto",
}}
>
{children}
Expand Down
19 changes: 5 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@types/dagre": "^0.7.48",
"@types/lodash": "^4.14.181",
"@types/memoize-one": "^5.1.2",
"@types/merge-img": "^2.1.1",
"@types/mock-require": "^2.0.1",
"@types/ndarray": "^1.0.11",
"@types/ndarray-ops": "^1.2.4",
Expand Down Expand Up @@ -133,7 +134,6 @@
"@tanstack/react-query-persist-client": "^4.14.1",
"@types/file-saver": "^2.0.5",
"@types/lz-string": "^1.3.34",
"@types/merge-img": "^2.1.1",
philippotto marked this conversation as resolved.
Show resolved Hide resolved
"@types/pako": "^2.0.0",
"@types/pixelmatch": "^5.2.4",
"@types/pngjs": "^6.0.1",
Expand Down Expand Up @@ -221,23 +221,14 @@
"**/rc-tree": "^5.7.12"
},
"ava": {
"files": [
"./public-test/test-bundle/**/*.{js,jsx}"
],
"ignoredByWatcher": [
"./binaryData/**/*.*"
],
"require": [
"./frontend/javascripts/test/_ava_polyfill_provider.ts"
],
"files": ["./public-test/test-bundle/**/*.{js,jsx}"],
"ignoredByWatcher": ["./binaryData/**/*.*"],
"require": ["./frontend/javascripts/test/_ava_polyfill_provider.ts"],
"snapshotDir": "frontend/javascripts/test/snapshots",
"concurrency": 8
},
"c8": {
"exclude": [
"public-test/test-bundle/test/**/*.*",
"frontend/javascripts/test/**/*.*"
],
"exclude": ["public-test/test-bundle/test/**/*.*", "frontend/javascripts/test/**/*.*"],
"reporter": "lcov"
}
}
75 changes: 45 additions & 30 deletions tools/check-cyclic-dependencies.js
philippotto marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,57 +1,72 @@
const dpdm = require("dpdm")
const { parseDependencyTree, parseCircular } = dpdm
const dpdm = require("dpdm");
const { parseDependencyTree, parseCircular } = dpdm;

const KNOWN_CYCLES = [
[
'frontend/javascripts/oxalis/model/accessors/view_mode_accessor.ts',
'frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts'
"frontend/javascripts/oxalis/model/accessors/view_mode_accessor.ts",
"frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts",
],
[
'frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts',
'frontend/javascripts/oxalis/model/reducers/flycam_reducer.ts'
"frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts",
"frontend/javascripts/oxalis/model/reducers/flycam_reducer.ts",
],
[
'frontend/javascripts/oxalis/view/right-border-tabs/tree_hierarchy_view_helpers.ts',
'frontend/javascripts/oxalis/model/accessors/skeletontracing_accessor.ts'
"frontend/javascripts/oxalis/view/right-border-tabs/tree_hierarchy_view_helpers.ts",
"frontend/javascripts/oxalis/model/accessors/skeletontracing_accessor.ts",
],
["frontend/javascripts/libs/request.ts", "frontend/javascripts/admin/datastore_health_check.ts"],
[
'frontend/javascripts/libs/request.ts',
'frontend/javascripts/admin/datastore_health_check.ts'
"frontend/javascripts/admin/admin_rest_api.ts",
"frontend/javascripts/libs/request.ts",
"frontend/javascripts/admin/datastore_health_check.ts",
],
[
'frontend/javascripts/admin/admin_rest_api.ts',
'frontend/javascripts/libs/request.ts',
'frontend/javascripts/admin/datastore_health_check.ts'
"frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx",
"frontend/javascripts/oxalis/view/action-bar/starting_job_modals.tsx",
],
[
'frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx',
'frontend/javascripts/oxalis/view/action-bar/starting_job_modals.tsx'
"frontend/javascripts/admin/organization/upgrade_plan_modal.tsx",
"frontend/javascripts/admin/organization/organization_cards.tsx",
],
[
'frontend/javascripts/admin/organization/upgrade_plan_modal.tsx',
'frontend/javascripts/admin/organization/organization_cards.tsx'
"frontend/javascripts/admin/task/task_create_form_view.tsx",
"frontend/javascripts/admin/task/task_create_bulk_view.tsx",
],
[
'frontend/javascripts/admin/task/task_create_form_view.tsx',
'frontend/javascripts/admin/task/task_create_bulk_view.tsx'
"frontend/javascripts/admin/team/team_list_view.tsx",
"frontend/javascripts/admin/team/edit_team_modal_view.tsx",
],
[
'frontend/javascripts/admin/team/team_list_view.tsx',
'frontend/javascripts/admin/team/edit_team_modal_view.tsx'
"frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx",
"frontend/javascripts/dashboard/folders/folder_tree.tsx",
],
[
'frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx',
'frontend/javascripts/dashboard/folders/folder_tree.tsx'
"frontend/javascripts/oxalis/model_initialization.ts",
"frontend/javascripts/oxalis/controller/url_manager.ts",
],
[
'frontend/javascripts/oxalis/model_initialization.ts',
'frontend/javascripts/oxalis/controller/url_manager.ts'
"frontend/javascripts/oxalis/geometries/plane.ts",
"frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts",
"frontend/javascripts/oxalis/shaders/main_data_shaders.glsl.ts",
],
[
'frontend/javascripts/oxalis/geometries/plane.ts',
'frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts',
'frontend/javascripts/oxalis/shaders/main_data_shaders.glsl.ts'
]
"frontend/javascripts/libs/toast.tsx",
"frontend/javascripts/libs/render_independently.tsx ",
"frontend/javascripts/oxalis/throttled_store.ts ",
philippotto marked this conversation as resolved.
Show resolved Hide resolved
"frontend/javascripts/oxalis/store.ts ",
"frontend/javascripts/oxalis/model/reducers/annotation_reducer.ts ",
"frontend/javascripts/oxalis/model/accessors/view_mode_accessor.ts ",
"frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts ",
philippotto marked this conversation as resolved.
Show resolved Hide resolved
"frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts ",
"frontend/javascripts/libs/error_handling.ts",
],
[
"frontend/javascripts/libs/toast.tsx ",
"frontend/javascripts/libs/render_independently.tsx ",
"frontend/javascripts/oxalis/throttled_store.ts ",
"frontend/javascripts/oxalis/store.ts ",
"frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer.ts",
],
];
parseDependencyTree("frontend/javascripts/main.tsx", {
/* options, see below */
Expand All @@ -74,7 +89,7 @@ parseDependencyTree("frontend/javascripts/main.tsx", {
);
} else if (cyclicDependencies.length < knownCycleStrings.length) {
throw new Error(`Congratulations! Your admirable work removed at least one cyclic dependency from the TypeScript modules. To ensure
that this improvement is not undone accidentally in the future, please adapt the KNOWN_CYCLES variable in the check-cyclic-dependies.js
that this improvement is not undone accidentally in the future, please adapt the KNOWN_CYCLES variable in the check-cyclic-dependencies.js
script. Please set the variable to the following and commit it:
${JSON.stringify(cyclicDependencies, null, " ")}
`);
Expand Down