Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Implement updated open dialog method of the Module API (#11395)
Browse files Browse the repository at this point in the history
* Implement updated open dialog method

Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>

* Apply the review comments

Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>

* Add unit tests for the module system dialog

Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>

* Bump @matrix-org/react-sdk-module-api from 1.0.0 to 2.0.0

Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>

* Run prettier

Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>

* Apply review comments

Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>

---------

Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>
  • Loading branch information
dhenneke committed Aug 21, 2023
1 parent 3a64722 commit 5c43054
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 129 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"@babel/runtime": "^7.12.5",
"@matrix-org/analytics-events": "^0.6.0",
"@matrix-org/matrix-wysiwyg": "^2.4.1",
"@matrix-org/react-sdk-module-api": "^1.0.0",
"@matrix-org/react-sdk-module-api": "^2.0.0",
"@matrix-org/spec": "^1.7.0",
"@sentry/browser": "^7.0.0",
"@sentry/tracing": "^7.0.0",
Expand Down
38 changes: 27 additions & 11 deletions src/components/views/dialogs/ModuleUiDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@ limitations under the License.
import React, { createRef } from "react";
import { DialogContent, DialogProps } from "@matrix-org/react-sdk-module-api/lib/components/DialogContent";
import { logger } from "matrix-js-sdk/src/logger";
import { ModuleApi } from "@matrix-org/react-sdk-module-api/lib/ModuleApi";
import { ModuleUiDialogOptions } from "@matrix-org/react-sdk-module-api/lib/types/ModuleUiDialogOptions";

import ScrollableBaseModal, { IScrollableBaseState } from "./ScrollableBaseModal";
import { _t } from "../../../languageHandler";

interface IProps<P extends DialogProps, C extends DialogContent<P>> {
contentFactory: (props: P, ref: React.RefObject<C>) => React.ReactNode;
contentProps: P;
title: string;
onFinished(ok?: boolean, model?: Awaited<ReturnType<DialogContent<P>["trySubmit"]>>): void;
additionalContentProps: Omit<P, keyof DialogProps> | undefined;
initialOptions: ModuleUiDialogOptions;
moduleApi: ModuleApi;
onFinished(ok?: boolean, model?: Awaited<ReturnType<DialogContent<P & DialogProps>["trySubmit"]>>): void;
}

interface IState extends IScrollableBaseState {
Expand All @@ -42,9 +45,10 @@ export class ModuleUiDialog<P extends DialogProps, C extends DialogContent<P>> e
super(props);

this.state = {
title: this.props.title,
canSubmit: true,
actionLabel: _t("OK"),
title: this.props.initialOptions.title,
actionLabel: this.props.initialOptions.actionLabel ?? _t("OK"),
cancelLabel: this.props.initialOptions.cancelLabel,
canSubmit: this.props.initialOptions.canSubmit ?? true,
};
}

Expand All @@ -61,11 +65,23 @@ export class ModuleUiDialog<P extends DialogProps, C extends DialogContent<P>> e
this.props.onFinished(false);
}

private setOptions(options: ModuleUiDialogOptions): void {
this.setState((state) => ({ ...state, ...options }));
}

protected renderContent(): React.ReactNode {
return (
<div className="mx_ModuleUiDialog">
{this.props.contentFactory(this.props.contentProps, this.contentRef)}
</div>
);
const dialogProps: DialogProps = {
moduleApi: this.props.moduleApi,
setOptions: this.setOptions.bind(this),
cancel: this.cancel.bind(this),
};

// Typescript isn't very happy understanding that `contentProps` satisfies `P`
const contentProps: P = {
...this.props.additionalContentProps,
...dialogProps,
} as unknown as P;

return <div className="mx_ModuleUiDialog">{this.props.contentFactory(contentProps, this.contentRef)}</div>;
}
}
3 changes: 2 additions & 1 deletion src/components/views/dialogs/ScrollableBaseModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface IScrollableBaseState {
canSubmit: boolean;
title: string;
actionLabel: string;
cancelLabel?: string;
}

/**
Expand Down Expand Up @@ -103,7 +104,7 @@ export default abstract class ScrollableBaseModal<
<div className="mx_CompoundDialog_content">{this.renderContent()}</div>
<div className="mx_CompoundDialog_footer">
<AccessibleButton onClick={this.onCancel} kind="primary_outline">
{_t("Cancel")}
{this.state.cancelLabel ?? _t("Cancel")}
</AccessibleButton>
<AccessibleButton
onClick={this.onSubmit}
Expand Down
15 changes: 8 additions & 7 deletions src/modules/ProxiedModuleApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import React from "react";
import { AccountAuthInfo } from "@matrix-org/react-sdk-module-api/lib/types/AccountAuthInfo";
import * as Matrix from "matrix-js-sdk/src/matrix";
import { IRegisterRequestParams } from "matrix-js-sdk/src/matrix";
import { ModuleUiDialogOptions } from "@matrix-org/react-sdk-module-api/lib/types/ModuleUiDialogOptions";

import Modal from "../Modal";
import { _t } from "../languageHandler";
Expand Down Expand Up @@ -81,21 +82,21 @@ export class ProxiedModuleApi implements ModuleApi {
* @override
*/
public openDialog<M extends object, P extends DialogProps, C extends DialogContent<P>>(
title: string,
initialTitleOrOptions: string | ModuleUiDialogOptions,
body: (props: P, ref: React.RefObject<C>) => React.ReactNode,
props?: Omit<P, keyof DialogProps>,
): Promise<{ didOkOrSubmit: boolean; model: M }> {
const initialOptions: ModuleUiDialogOptions =
typeof initialTitleOrOptions === "string" ? { title: initialTitleOrOptions } : initialTitleOrOptions;

return new Promise<{ didOkOrSubmit: boolean; model: M }>((resolve) => {
Modal.createDialog(
ModuleUiDialog<P, C>,
{
title: title,
initialOptions,
contentFactory: body,
// Typescript isn't very happy understanding that `props` satisfies `Omit<P, keyof DialogProps>`
contentProps: {
...props,
moduleApi: this,
} as unknown as P,
moduleApi: this,
additionalContentProps: props,
},
"mx_CompoundDialog",
).finished.then(([didOkOrSubmit, model]) => {
Expand Down
105 changes: 0 additions & 105 deletions test/modules/ProxiedModuleApi-test.ts

This file was deleted.

Loading

0 comments on commit 5c43054

Please sign in to comment.