{
- $timeout: ng.ITimeoutService;
- /** Passed through templates */
- application!: WebApplication;
- state: S = {} as any;
- private unsubApp: any;
- private unsubState: any;
- private stateTimeout?: ng.IPromise {
+ private unsubApp!: () => void;
+ private unsubState!: () => void;
private reactionDisposers: IReactionDisposer[] = [];
- /* @ngInject */
- constructor($timeout: ng.ITimeoutService, public props: P = {} as any) {
- this.$timeout = $timeout;
+ constructor(props: P, protected application: WebApplication) {
+ super(props);
}
- $onInit(): void {
- this.state = {
- ...this.getInitialState(),
- ...this.state,
- };
+ componentDidMount() {
this.addAppEventObserver();
this.addAppStateObserver();
- this.templateReady = true;
}
deinit(): void {
@@ -43,63 +32,38 @@ export class PureViewCtrl {
disposer();
}
this.reactionDisposers.length = 0;
- this.unsubApp = undefined;
- this.unsubState = undefined;
- if (this.stateTimeout) {
- this.$timeout.cancel(this.stateTimeout);
- }
+ (this.unsubApp as unknown) = undefined;
+ (this.unsubState as unknown) = undefined;
}
- $onDestroy(): void {
+ protected dismissModal(): void {
+ const elem = this.getElement();
+ if (!elem) {
+ return;
+ }
+
+ const parent = elem.parentElement;
+ if (!parent) {
+ return;
+ }
+ parent.remove();
+ unmountComponentAtNode(parent);
+ }
+
+ componentWillUnmount(): void {
this.deinit();
}
+ render() {
+ return {
/** @override */
async onAppStart() {
- await this.resetState();
+ /** Optional override */
}
onLocalDataLoaded() {
diff --git a/app/assets/javascripts/components/AccountMenu/AdvancedOptions.tsx b/app/assets/javascripts/components/AccountMenu/AdvancedOptions.tsx
index eb16d545c..1a75878df 100644
--- a/app/assets/javascripts/components/AccountMenu/AdvancedOptions.tsx
+++ b/app/assets/javascripts/components/AccountMenu/AdvancedOptions.tsx
@@ -1,9 +1,8 @@
import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';
-import { isDev } from '@/utils';
import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
-import { useEffect, useState } from 'preact/hooks';
+import { useState } from 'preact/hooks';
import { Checkbox } from '../Checkbox';
import { Icon } from '../Icon';
import { InputWithIcon } from '../InputWithIcon';
diff --git a/app/assets/javascripts/components/AccountMenu/index.tsx b/app/assets/javascripts/components/AccountMenu/index.tsx
index 12f6a12b0..36bc5cae0 100644
--- a/app/assets/javascripts/components/AccountMenu/index.tsx
+++ b/app/assets/javascripts/components/AccountMenu/index.tsx
@@ -1,8 +1,8 @@
import { observer } from 'mobx-react-lite';
-import { toDirective } from '@/components/utils';
+import { useCloseOnClickOutside } from '@/components/utils';
import { AppState } from '@/ui_models/app_state';
import { WebApplication } from '@/ui_models/application';
-import { useState } from 'preact/hooks';
+import { useRef, useState } from 'preact/hooks';
import { GeneralAccountMenu } from './GeneralAccountMenu';
import { FunctionComponent } from 'preact';
import { SignInPane } from './SignIn';
@@ -21,9 +21,12 @@ export enum AccountMenuPane {
type Props = {
appState: AppState;
application: WebApplication;
+ onClickOutside: () => void;
};
-type PaneSelectorProps = Props & {
+type PaneSelectorProps = {
+ appState: AppState;
+ application: WebApplication;
menuPane: AccountMenuPane;
setMenuPane: (pane: AccountMenuPane) => void;
closeMenu: () => void;
@@ -79,8 +82,8 @@ const MenuPaneSelector: FunctionComponent): Promise