feat: New account menu and text input with icon & toggle (#665)

* feat: Add new icons

* Revert "feat: Add new icons"

This reverts commit 0acb403fe846dbb2e48fd22de35c3568c3cb4453.

* feat: Add new icons for account menu

* feat: Add new Icons

* feat: Add "currentPane" state to prefs view

* feat: Update account menu to new design

* feat: Add input component with icon & toggle

* fix: sync icon & function

* fix: Fix eye icon

* feat: Create re-usable checkbox

feat: Add "merge local" option

* feat: Allow using className on IconButton

* feat: Add disabled state on input

feat: Make toggle circle

* refactor: Move checkbox to components

* feat: Handle invalid email/password error

* feat: Implement new design for Create Account

* feat: Implement new account menu design

* feat: Add disabled option to IconButton

* feat: Set account menu pane from other component

* feat: Add 2fa account menu pane

feat: Add lock icon

* feat: Remove unnecessary 2FA menu pane

feat: Reset current menu pane on clickOutside

* feat: Change "Log in" to "Sign in"

* feat: Remove sync from footer

* feat: Change "Login" to "Sign in"

feat: Add spinner to "Syncing..."

refactor: Use then-catch-finally for sync

* feat: Use common enableCustomServer state

* feat: Animate account menu closing

* fix: Reset menu pane only after it's closed

* feat: Add keyDown handler to InputWithIcon

* feat: Handle Enter press in inputs

* Update app/assets/javascripts/components/InputWithIcon.tsx

Co-authored-by: Antonella Sgarlatta <antsgar@gmail.com>

* Update app/assets/javascripts/components/InputWithIcon.tsx

Co-authored-by: Antonella Sgarlatta <antsgar@gmail.com>

* refactor: Use server state from AccountMenuState

* Update app/assets/javascripts/components/AccountMenu/CreateAccount.tsx

Co-authored-by: Antonella Sgarlatta <antsgar@gmail.com>

* Update app/assets/javascripts/components/AccountMenu/ConfirmPassword.tsx

Co-authored-by: Antonella Sgarlatta <antsgar@gmail.com>

* feat: Use common AdvancedOptions

* feat: Add "eye-off" icon and toggle state

* feat: Allow undefined values

* refactor: Remove enableCustomServer state

* feat: Persist server option state

* feat: Add bottom-100 and cursor-auto util classes

refactor: Use bottom-100 and cursor-auto classes

* refactor: Invert ternary operator

* refactor: Remove unused imports

* refactor: Use toggled as prop instead of state

* refactor: Change "Log in/out" to "Sign in/out"

* refactor: Change "Login" to "Sign in"

* refactor: Remove hardcoded width/height

* refactor: Use success class

* feat: Remove hardcoded width & height from svg

* fix: Fix chevron-down icon

Co-authored-by: Antonella Sgarlatta <antsgar@gmail.com>
Co-authored-by: Antonella Sgarlatta <antonella@standardnotes.org>
This commit is contained in:
Aman Harwara
2021-10-08 21:48:31 +05:30
committed by GitHub
parent 7b6c99d188
commit f1122f292e
51 changed files with 1566 additions and 407 deletions

View File

@@ -1,48 +1,52 @@
import { WebApplication } from '@/ui_models/application';
import { PasswordWizardScope, PasswordWizardType, WebDirective } from './../../types';
import {
PasswordWizardScope,
PasswordWizardType,
WebDirective,
} from './../../types';
import template from '%/directives/password-wizard.pug';
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
const DEFAULT_CONTINUE_TITLE = "Continue";
const DEFAULT_CONTINUE_TITLE = 'Continue';
enum Steps {
PasswordStep = 1,
FinishStep = 2
FinishStep = 2,
}
type FormData = {
currentPassword?: string,
newPassword?: string,
newPasswordConfirmation?: string,
status?: string
}
currentPassword?: string;
newPassword?: string;
newPasswordConfirmation?: string;
status?: string;
};
type State = {
lockContinue: boolean
formData: FormData,
continueTitle: string,
step: Steps,
title: string,
showSpinner: boolean
processing: boolean
}
lockContinue: boolean;
formData: FormData;
continueTitle: string;
step: Steps;
title: string;
showSpinner: boolean;
processing: boolean;
};
type Props = {
type: PasswordWizardType,
changePassword: boolean,
securityUpdate: boolean
}
type: PasswordWizardType;
changePassword: boolean;
securityUpdate: boolean;
};
class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordWizardScope {
$element: JQLite
application!: WebApplication
type!: PasswordWizardType
isContinuing = false
class PasswordWizardCtrl
extends PureViewCtrl<Props, State>
implements PasswordWizardScope
{
$element: JQLite;
application!: WebApplication;
type!: PasswordWizardType;
isContinuing = false;
/* @ngInject */
constructor(
$element: JQLite,
$timeout: ng.ITimeoutService,
) {
constructor($element: JQLite, $timeout: ng.ITimeoutService) {
super($timeout);
this.$element = $element;
this.registerWindowUnloadStopper();
@@ -53,13 +57,13 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
this.initProps({
type: this.type,
changePassword: this.type === PasswordWizardType.ChangePassword,
securityUpdate: this.type === PasswordWizardType.AccountUpgrade
securityUpdate: this.type === PasswordWizardType.AccountUpgrade,
});
this.setState({
formData: {},
continueTitle: DEFAULT_CONTINUE_TITLE,
step: Steps.PasswordStep,
title: this.props.changePassword ? 'Change Password' : 'Account Update'
title: this.props.changePassword ? 'Change Password' : 'Account Update',
});
}
@@ -78,7 +82,7 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
resetContinueState() {
this.setState({
showSpinner: false,
continueTitle: DEFAULT_CONTINUE_TITLE
continueTitle: DEFAULT_CONTINUE_TITLE,
});
this.isContinuing = false;
}
@@ -95,7 +99,7 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
this.isContinuing = true;
await this.setState({
showSpinner: true,
continueTitle: "Generating Keys..."
continueTitle: 'Generating Keys...',
});
const valid = await this.validateCurrentPassword();
if (!valid) {
@@ -110,8 +114,8 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
this.isContinuing = false;
this.setState({
showSpinner: false,
continueTitle: "Finish",
step: Steps.FinishStep
continueTitle: 'Finish',
step: Steps.FinishStep,
});
}
@@ -119,43 +123,43 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
return this.setState({
formData: {
...this.state.formData,
...formData
}
...formData,
},
});
}
async validateCurrentPassword() {
const currentPassword = this.state.formData.currentPassword;
const newPass = this.props.securityUpdate ? currentPassword : this.state.formData.newPassword;
const newPass = this.props.securityUpdate
? currentPassword
: this.state.formData.newPassword;
if (!currentPassword || currentPassword.length === 0) {
this.application.alertService!.alert(
"Please enter your current password."
'Please enter your current password.'
);
return false;
}
if (this.props.changePassword) {
if (!newPass || newPass.length === 0) {
this.application.alertService!.alert(
"Please enter a new password."
);
this.application.alertService!.alert('Please enter a new password.');
return false;
}
if (newPass !== this.state.formData.newPasswordConfirmation) {
this.application.alertService!.alert(
"Your new password does not match its confirmation."
'Your new password does not match its confirmation.'
);
this.setFormDataState({
status: undefined
status: undefined,
});
return false;
}
}
if (!this.application.getUser()?.email) {
this.application.alertService!.alert(
"We don't have your email stored. Please log out then log back in to fix this issue."
"We don't have your email stored. Please sign out then log back in to fix this issue."
);
this.setFormDataState({
status: undefined
status: undefined,
});
return false;
}
@@ -166,7 +170,7 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
);
if (!success) {
this.application.alertService!.alert(
"The current password you entered is not correct. Please try again."
'The current password you entered is not correct. Please try again.'
);
}
return success;
@@ -176,10 +180,10 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
await this.application.downloadBackup();
await this.setState({
lockContinue: true,
processing: true
processing: true,
});
await this.setFormDataState({
status: "Processing encryption keys…"
status: 'Processing encryption keys…',
});
const newPassword = this.props.securityUpdate
? this.state.formData.currentPassword
@@ -195,16 +199,16 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
});
if (!success) {
this.setFormDataState({
status: "Unable to process your password. Please try again."
status: 'Unable to process your password. Please try again.',
});
} else {
this.setState({
formData: {
...this.state.formData,
status: this.props.changePassword
? "Successfully changed password."
: "Successfully performed account update."
}
? 'Successfully changed password.'
: 'Successfully performed account update.',
},
});
}
return success;
@@ -213,7 +217,7 @@ class PasswordWizardCtrl extends PureViewCtrl<Props, State> implements PasswordW
dismiss() {
if (this.state.lockContinue) {
this.application.alertService!.alert(
"Cannot close window until pending tasks are complete."
'Cannot close window until pending tasks are complete.'
);
} else {
const elem = this.$element;
@@ -234,7 +238,7 @@ export class PasswordWizard extends WebDirective {
this.bindToController = true;
this.scope = {
type: '=',
application: '='
application: '=',
};
}
}