mirror of
https://github.com/astuto/astuto.git
synced 2025-12-15 03:07:52 +01:00
Form refactoring (#142)
This commit is contained in:
committed by
GitHub
parent
d078e659c6
commit
9592ac3d1d
@@ -47,6 +47,18 @@ class TenantsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Given a new_subdomain
|
||||||
|
# Returns true if it is available, false otherwise
|
||||||
|
def is_available
|
||||||
|
subdomain = params[:new_subdomain]
|
||||||
|
|
||||||
|
return unless subdomain.present?
|
||||||
|
return if RESERVED_SUBDOMAINS.include?(subdomain)
|
||||||
|
return if Tenant.exists?(subdomain: subdomain)
|
||||||
|
|
||||||
|
render json: { is_available: 'true' }
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def tenant_create_params
|
def tenant_create_params
|
||||||
|
|||||||
@@ -76,7 +76,11 @@ export const submitTenant = (
|
|||||||
} else {
|
} else {
|
||||||
dispatch(tenantSubmitFailure(json.error));
|
dispatch(tenantSubmitFailure(json.error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dispatch(tenantSubmitFailure(e));
|
dispatch(tenantSubmitFailure(e));
|
||||||
|
|
||||||
|
return Promise.resolve(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
export const TENANT_SIGN_UP_TOGGLE_EMAIL_AUTH = 'TENANT_SIGN_UP_TOGGLE_EMAIL_AUTH';
|
|
||||||
|
|
||||||
interface TenantSignUpToggleEmailAuth {
|
|
||||||
type: typeof TENANT_SIGN_UP_TOGGLE_EMAIL_AUTH,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const toggleEmailAuthTenantSignUp = (
|
|
||||||
|
|
||||||
): TenantSignUpToggleEmailAuth => ({
|
|
||||||
type: TENANT_SIGN_UP_TOGGLE_EMAIL_AUTH,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// User full name
|
|
||||||
export const TENANT_SIGN_UP_CHANGE_USER_FULL_NAME = 'TENANT_SIGN_UP_CHANGE_USER_FULL_NAME';
|
|
||||||
|
|
||||||
interface TenantSignUpChangeUserFullName {
|
|
||||||
type: typeof TENANT_SIGN_UP_CHANGE_USER_FULL_NAME,
|
|
||||||
fullName: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeUserFullNameTenantSignUp = (
|
|
||||||
fullName: string
|
|
||||||
): TenantSignUpChangeUserFullName => ({
|
|
||||||
type: TENANT_SIGN_UP_CHANGE_USER_FULL_NAME,
|
|
||||||
fullName,
|
|
||||||
});
|
|
||||||
|
|
||||||
// User email
|
|
||||||
export const TENANT_SIGN_UP_CHANGE_USER_EMAIL = 'TENANT_SIGN_UP_CHANGE_USER_EMAIL';
|
|
||||||
|
|
||||||
interface TenantSignUpChangeUserEmail {
|
|
||||||
type: typeof TENANT_SIGN_UP_CHANGE_USER_EMAIL,
|
|
||||||
email: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeUserEmailTenantSignUp = (
|
|
||||||
email: string
|
|
||||||
): TenantSignUpChangeUserEmail => ({
|
|
||||||
type: TENANT_SIGN_UP_CHANGE_USER_EMAIL,
|
|
||||||
email,
|
|
||||||
});
|
|
||||||
|
|
||||||
// User password
|
|
||||||
export const TENANT_SIGN_UP_CHANGE_USER_PASSWORD = 'TENANT_SIGN_UP_CHANGE_USER_PASSWORD';
|
|
||||||
|
|
||||||
interface TenantSignUpChangeUserPassword {
|
|
||||||
type: typeof TENANT_SIGN_UP_CHANGE_USER_PASSWORD,
|
|
||||||
password: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeUserPasswordTenantSignUp = (
|
|
||||||
password: string
|
|
||||||
): TenantSignUpChangeUserPassword => ({
|
|
||||||
type: TENANT_SIGN_UP_CHANGE_USER_PASSWORD,
|
|
||||||
password,
|
|
||||||
});
|
|
||||||
|
|
||||||
// User password confirmation
|
|
||||||
export const TENANT_SIGN_UP_CHANGE_USER_PASSWORD_CONFIRMATION = 'TENANT_SIGN_UP_CHANGE_USER_PASSWORD_CONFIRMATION';
|
|
||||||
|
|
||||||
interface TenantSignUpChangeUserPasswordConfirmation {
|
|
||||||
type: typeof TENANT_SIGN_UP_CHANGE_USER_PASSWORD_CONFIRMATION,
|
|
||||||
passwordConfirmation: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeUserPasswordConfirmationTenantSignUp = (
|
|
||||||
passwordConfirmation: string
|
|
||||||
): TenantSignUpChangeUserPasswordConfirmation => ({
|
|
||||||
type: TENANT_SIGN_UP_CHANGE_USER_PASSWORD_CONFIRMATION,
|
|
||||||
passwordConfirmation,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Confirm user data, proceed to step 2
|
|
||||||
export const TENANT_SIGN_UP_CONFIRM_USER_FORM = 'TENANT_SIGN_UP_CONFIRM_USER_FORM';
|
|
||||||
|
|
||||||
interface TenantSignUpConfirmUserForm {
|
|
||||||
type: typeof TENANT_SIGN_UP_CONFIRM_USER_FORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const confirmUserFormTenantSignUp = (): TenantSignUpConfirmUserForm => ({
|
|
||||||
type: TENANT_SIGN_UP_CONFIRM_USER_FORM,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Tenant site name
|
|
||||||
export const TENANT_SIGN_UP_CHANGE_TENANT_SITE_NAME = 'TENANT_SIGN_UP_CHANGE_TENANT_SITE_NAME';
|
|
||||||
|
|
||||||
interface TenantSignUpChangeTenantSiteName {
|
|
||||||
type: typeof TENANT_SIGN_UP_CHANGE_TENANT_SITE_NAME,
|
|
||||||
siteName: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeTenantSiteNameTenantSignUp = (
|
|
||||||
siteName: string
|
|
||||||
): TenantSignUpChangeTenantSiteName => ({
|
|
||||||
type: TENANT_SIGN_UP_CHANGE_TENANT_SITE_NAME,
|
|
||||||
siteName,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Tenant site name
|
|
||||||
export const TENANT_SIGN_UP_CHANGE_TENANT_SUBDOMAIN = 'TENANT_SIGN_UP_CHANGE_TENANT_SUBDOMAIN';
|
|
||||||
|
|
||||||
interface TenantSignUpChangeTenantSubdomain {
|
|
||||||
type: typeof TENANT_SIGN_UP_CHANGE_TENANT_SUBDOMAIN,
|
|
||||||
subdomain: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeTenantSubdomainTenantSignUp = (
|
|
||||||
subdomain: string
|
|
||||||
): TenantSignUpChangeTenantSubdomain => ({
|
|
||||||
type: TENANT_SIGN_UP_CHANGE_TENANT_SUBDOMAIN,
|
|
||||||
subdomain,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export type TenantSignUpFormActions =
|
|
||||||
TenantSignUpToggleEmailAuth |
|
|
||||||
TenantSignUpChangeUserFullName |
|
|
||||||
TenantSignUpChangeUserEmail |
|
|
||||||
TenantSignUpChangeUserPassword |
|
|
||||||
TenantSignUpChangeUserPasswordConfirmation |
|
|
||||||
TenantSignUpConfirmUserForm |
|
|
||||||
TenantSignUpChangeTenantSiteName |
|
|
||||||
TenantSignUpChangeTenantSubdomain;
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
// siteName
|
|
||||||
export const SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME = 'SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME';
|
|
||||||
|
|
||||||
interface SiteSettingsChangeGeneralFormSiteName {
|
|
||||||
type: typeof SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME,
|
|
||||||
siteName: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeSiteSettingsGeneralFormSiteName = (
|
|
||||||
siteName: string
|
|
||||||
): SiteSettingsChangeGeneralFormSiteName => ({
|
|
||||||
type: SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME,
|
|
||||||
siteName,
|
|
||||||
});
|
|
||||||
|
|
||||||
// siteLogo
|
|
||||||
export const SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO = 'SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO';
|
|
||||||
|
|
||||||
interface SiteSettingsChangeGeneralFormSiteLogo {
|
|
||||||
type: typeof SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO,
|
|
||||||
siteLogo: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeSiteSettingsGeneralFormSiteLogo = (
|
|
||||||
siteLogo: string
|
|
||||||
): SiteSettingsChangeGeneralFormSiteLogo => ({
|
|
||||||
type: SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO,
|
|
||||||
siteLogo,
|
|
||||||
});
|
|
||||||
|
|
||||||
// brandDisplaySetting
|
|
||||||
export const SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING = 'SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING';
|
|
||||||
|
|
||||||
interface SiteSettingsChangeGeneralFormBrandSetting {
|
|
||||||
type: typeof SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING,
|
|
||||||
brandDisplaySetting: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeSiteSettingsGeneralFormBrandSetting = (
|
|
||||||
brandDisplaySetting: string
|
|
||||||
): SiteSettingsChangeGeneralFormBrandSetting => ({
|
|
||||||
type: SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING,
|
|
||||||
brandDisplaySetting,
|
|
||||||
});
|
|
||||||
|
|
||||||
// locale
|
|
||||||
export const SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE = 'SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE';
|
|
||||||
|
|
||||||
interface SiteSettingsChangeGeneralFormLocale {
|
|
||||||
type: typeof SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE,
|
|
||||||
locale: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const changeSiteSettingsGeneralFormLocale = (
|
|
||||||
locale: string
|
|
||||||
): SiteSettingsChangeGeneralFormLocale => ({
|
|
||||||
type: SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE,
|
|
||||||
locale,
|
|
||||||
});
|
|
||||||
|
|
||||||
export type ChangeSiteSettingsGeneralFormActionTypes =
|
|
||||||
SiteSettingsChangeGeneralFormSiteName |
|
|
||||||
SiteSettingsChangeGeneralFormSiteLogo |
|
|
||||||
SiteSettingsChangeGeneralFormBrandSetting |
|
|
||||||
SiteSettingsChangeGeneralFormLocale;
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
import I18n from 'i18n-js';
|
import I18n from 'i18n-js';
|
||||||
|
|
||||||
import Button from '../../common/Button';
|
import Button from '../../common/Button';
|
||||||
@@ -10,7 +11,7 @@ interface Props {
|
|||||||
name?: string;
|
name?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
handleSubmit?(
|
handleCreate?(
|
||||||
name: string,
|
name: string,
|
||||||
description: string,
|
description: string,
|
||||||
onSuccess: Function,
|
onSuccess: Function,
|
||||||
@@ -22,101 +23,75 @@ interface Props {
|
|||||||
): void;
|
): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface IBoardForm {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BoardForm extends React.Component<Props, State> {
|
const BoardForm = ({
|
||||||
initialState: State = {
|
mode,
|
||||||
name: '',
|
id,
|
||||||
description: '',
|
name,
|
||||||
};
|
description,
|
||||||
|
handleCreate,
|
||||||
|
handleUpdate,
|
||||||
|
}: Props) => {
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
reset,
|
||||||
|
formState: { isValid },
|
||||||
|
} = useForm<IBoardForm>({
|
||||||
|
mode: 'onChange',
|
||||||
|
defaultValues: {
|
||||||
|
name: name || '',
|
||||||
|
description: description || '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
constructor(props: Props) {
|
const onSubmit: SubmitHandler<IBoardForm> = data => {
|
||||||
super(props);
|
if (mode === 'create') {
|
||||||
|
handleCreate(
|
||||||
this.state = this.props.mode === 'create' ?
|
data.name,
|
||||||
this.initialState
|
data.description,
|
||||||
:
|
() => reset({ name: '', description: '' })
|
||||||
{
|
|
||||||
name: this.props.name,
|
|
||||||
description: this.props.description,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.onSubmit = this.onSubmit.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
isFormValid() {
|
|
||||||
return this.state.name && this.state.name.length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
onNameChange(nameText: string) {
|
|
||||||
this.setState({
|
|
||||||
name: nameText,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onDescriptionChange(descriptionText: string) {
|
|
||||||
this.setState({
|
|
||||||
description: descriptionText,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
if (this.props.mode === 'create') {
|
|
||||||
this.props.handleSubmit(
|
|
||||||
this.state.name,
|
|
||||||
this.state.description,
|
|
||||||
() => this.setState({...this.initialState}),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.props.handleUpdate(this.props.id, this.state.name, this.state.description);
|
handleUpdate(id, data.name, data.description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const {mode} = this.props;
|
<form onSubmit={handleSubmit(onSubmit)} className="boardForm">
|
||||||
const {name, description} = this.state;
|
<div className="boardMandatoryForm">
|
||||||
|
<input
|
||||||
return (
|
{...register('name', { required: true })}
|
||||||
<form className="boardForm">
|
placeholder={I18n.t('site_settings.boards.form.name')}
|
||||||
<div className="boardMandatoryForm">
|
autoFocus
|
||||||
<input
|
className="formControl"
|
||||||
type="text"
|
|
||||||
placeholder={I18n.t('site_settings.boards.form.name')}
|
|
||||||
value={name}
|
|
||||||
onChange={e => this.onNameChange(e.target.value)}
|
|
||||||
autoFocus
|
|
||||||
className="form-control"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
onClick={e => {
|
|
||||||
e.preventDefault();
|
|
||||||
this.onSubmit();
|
|
||||||
}}
|
|
||||||
className="newBoardButton"
|
|
||||||
disabled={!this.isFormValid()}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
mode === 'create' ?
|
|
||||||
I18n.t('common.buttons.create')
|
|
||||||
:
|
|
||||||
I18n.t('common.buttons.update')
|
|
||||||
}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<textarea
|
|
||||||
placeholder={I18n.t('site_settings.boards.form.description')}
|
|
||||||
value={description}
|
|
||||||
onChange={e => this.onDescriptionChange(e.target.value)}
|
|
||||||
className="form-control"
|
|
||||||
/>
|
/>
|
||||||
</form>
|
|
||||||
);
|
<Button
|
||||||
}
|
onClick={() => null}
|
||||||
|
className="newBoardButton"
|
||||||
|
disabled={!isValid}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
mode === 'create' ?
|
||||||
|
I18n.t('common.buttons.create')
|
||||||
|
:
|
||||||
|
I18n.t('common.buttons.update')
|
||||||
|
}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
{...register('description')}
|
||||||
|
placeholder={I18n.t('site_settings.boards.form.description')}
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BoardForm;
|
export default BoardForm;
|
||||||
@@ -130,7 +130,7 @@ class BoardsSiteSettingsP extends React.Component<Props> {
|
|||||||
<Box>
|
<Box>
|
||||||
<h2>{I18n.t('site_settings.boards.new')}</h2>
|
<h2>{I18n.t('site_settings.boards.new')}</h2>
|
||||||
|
|
||||||
<BoardForm mode='create' handleSubmit={this.handleSubmit} />
|
<BoardForm mode='create' handleCreate={this.handleSubmit} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<SiteSettingsInfoBox areUpdating={settingsAreUpdating || boards.areLoading} error={settingsError} />
|
<SiteSettingsInfoBox areUpdating={settingsAreUpdating || boards.areLoading} error={settingsError} />
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
import I18n from 'i18n-js';
|
import I18n from 'i18n-js';
|
||||||
|
|
||||||
import Box from '../../common/Box';
|
import Box from '../../common/Box';
|
||||||
import SiteSettingsInfoBox from '../../common/SiteSettingsInfoBox';
|
import SiteSettingsInfoBox from '../../common/SiteSettingsInfoBox';
|
||||||
import { ISiteSettingsGeneralForm } from '../../../reducers/SiteSettings/generalReducer';
|
|
||||||
import Button from '../../common/Button';
|
import Button from '../../common/Button';
|
||||||
import HttpStatus from '../../../constants/http_status';
|
import HttpStatus from '../../../constants/http_status';
|
||||||
import {
|
import {
|
||||||
@@ -12,18 +12,22 @@ import {
|
|||||||
TENANT_BRAND_LOGO_ONLY,
|
TENANT_BRAND_LOGO_ONLY,
|
||||||
TENANT_BRAND_NONE,
|
TENANT_BRAND_NONE,
|
||||||
} from '../../../interfaces/ITenant';
|
} from '../../../interfaces/ITenant';
|
||||||
|
import { DangerText } from '../../common/CustomTexts';
|
||||||
|
|
||||||
|
export interface ISiteSettingsGeneralForm {
|
||||||
|
siteName: string;
|
||||||
|
siteLogo: string;
|
||||||
|
brandDisplaySetting: string;
|
||||||
|
locale: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
originForm: ISiteSettingsGeneralForm;
|
originForm: ISiteSettingsGeneralForm;
|
||||||
authenticityToken: string;
|
authenticityToken: string;
|
||||||
|
|
||||||
form: ISiteSettingsGeneralForm;
|
|
||||||
areDirty: boolean;
|
|
||||||
areLoading: boolean;
|
|
||||||
areUpdating: boolean;
|
areUpdating: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
|
|
||||||
requestTenant(): void;
|
|
||||||
updateTenant(
|
updateTenant(
|
||||||
siteName: string,
|
siteName: string,
|
||||||
siteLogo: string,
|
siteLogo: string,
|
||||||
@@ -31,136 +35,118 @@ interface Props {
|
|||||||
locale: string,
|
locale: string,
|
||||||
authenticityToken: string
|
authenticityToken: string
|
||||||
): Promise<any>;
|
): Promise<any>;
|
||||||
|
|
||||||
handleChangeSiteName(siteName: string): void;
|
|
||||||
handleChangeSiteLogo(siteLogo: string): void;
|
|
||||||
handleChangeBrandDisplaySetting(brandDisplaySetting: string)
|
|
||||||
handleChangeLocale(locale: string): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class GeneralSiteSettingsP extends React.Component<Props> {
|
const GeneralSiteSettingsP = ({
|
||||||
constructor(props: Props) {
|
originForm,
|
||||||
super(props);
|
authenticityToken,
|
||||||
|
|
||||||
this._handleUpdateTenant = this._handleUpdateTenant.bind(this);
|
areUpdating,
|
||||||
}
|
error,
|
||||||
|
updateTenant,
|
||||||
|
}: Props) => {
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { isDirty, isSubmitSuccessful, errors }
|
||||||
|
} = useForm<ISiteSettingsGeneralForm>({
|
||||||
|
defaultValues: {
|
||||||
|
siteName: originForm.siteName,
|
||||||
|
siteLogo: originForm.siteLogo,
|
||||||
|
brandDisplaySetting: originForm.brandDisplaySetting,
|
||||||
|
locale: originForm.locale,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
componentDidMount() {
|
const onSubmit: SubmitHandler<ISiteSettingsGeneralForm> = data => {
|
||||||
this.props.requestTenant();
|
updateTenant(
|
||||||
}
|
data.siteName,
|
||||||
|
data.siteLogo,
|
||||||
_handleUpdateTenant() {
|
data.brandDisplaySetting,
|
||||||
const { siteName, siteLogo, brandDisplaySetting, locale } = this.props.form;
|
data.locale,
|
||||||
|
authenticityToken,
|
||||||
this.props.updateTenant(
|
|
||||||
siteName,
|
|
||||||
siteLogo,
|
|
||||||
brandDisplaySetting,
|
|
||||||
locale,
|
|
||||||
this.props.authenticityToken,
|
|
||||||
).then(res => {
|
).then(res => {
|
||||||
if (res?.status !== HttpStatus.OK) return;
|
if (res?.status !== HttpStatus.OK) return;
|
||||||
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const {
|
<>
|
||||||
originForm,
|
<Box>
|
||||||
form,
|
<h2>{ I18n.t('site_settings.general.title') }</h2>
|
||||||
areDirty,
|
|
||||||
areLoading,
|
|
||||||
areUpdating,
|
|
||||||
error,
|
|
||||||
|
|
||||||
handleChangeSiteName,
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
handleChangeSiteLogo,
|
<div className="formRow">
|
||||||
handleChangeBrandDisplaySetting,
|
<div className="formGroup col-4">
|
||||||
handleChangeLocale,
|
<label htmlFor="siteName">{ I18n.t('site_settings.general.site_name') }</label>
|
||||||
} = this.props;
|
<input
|
||||||
|
{...register('siteName', { required: true })}
|
||||||
return (
|
id="siteName"
|
||||||
<>
|
className="formControl"
|
||||||
<Box>
|
/>
|
||||||
<h2>{ I18n.t('site_settings.general.title') }</h2>
|
<DangerText>{errors.siteName && I18n.t('site_settings.general.validations.site_name')}</DangerText>
|
||||||
|
|
||||||
<form>
|
|
||||||
<div className="formRow">
|
|
||||||
<div className="formGroup col-4">
|
|
||||||
<label htmlFor="siteName">{ I18n.t('site_settings.general.site_name') }</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={areLoading ? originForm.siteName : form.siteName}
|
|
||||||
onChange={e => handleChangeSiteName(e.target.value)}
|
|
||||||
id="siteName"
|
|
||||||
className="formControl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="formGroup col-4">
|
|
||||||
<label htmlFor="siteLogo">{ I18n.t('site_settings.general.site_logo') }</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={areLoading ? originForm.siteLogo : form.siteLogo}
|
|
||||||
onChange={e => handleChangeSiteLogo(e.target.value)}
|
|
||||||
id="siteLogo"
|
|
||||||
className="formControl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="formGroup col-4">
|
|
||||||
<label htmlFor="brandSetting">{ I18n.t('site_settings.general.brand_setting') }</label>
|
|
||||||
<select
|
|
||||||
value={form.brandDisplaySetting || originForm.brandDisplaySetting}
|
|
||||||
onChange={e => handleChangeBrandDisplaySetting(e.target.value)}
|
|
||||||
id="brandSetting"
|
|
||||||
className="selectPicker"
|
|
||||||
>
|
|
||||||
<option value={TENANT_BRAND_NAME_AND_LOGO}>
|
|
||||||
{ I18n.t('site_settings.general.brand_setting_both') }
|
|
||||||
</option>
|
|
||||||
<option value={TENANT_BRAND_NAME_ONLY}>
|
|
||||||
{ I18n.t('site_settings.general.brand_setting_name') }
|
|
||||||
</option>
|
|
||||||
<option value={TENANT_BRAND_LOGO_ONLY}>
|
|
||||||
{ I18n.t('site_settings.general.brand_setting_logo') }
|
|
||||||
</option>
|
|
||||||
<option value={TENANT_BRAND_NONE}>
|
|
||||||
{ I18n.t('site_settings.general.brand_setting_none') }
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="formGroup">
|
<div className="formGroup col-4">
|
||||||
<label htmlFor="locale">{ I18n.t('site_settings.general.locale') }</label>
|
<label htmlFor="siteLogo">{ I18n.t('site_settings.general.site_logo') }</label>
|
||||||
|
<input
|
||||||
|
{...register('siteLogo')}
|
||||||
|
id="siteLogo"
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="formGroup col-4">
|
||||||
|
<label htmlFor="brandSetting">{ I18n.t('site_settings.general.brand_setting') }</label>
|
||||||
<select
|
<select
|
||||||
value={form.locale || originForm.locale}
|
{...register('brandDisplaySetting')}
|
||||||
onChange={e => handleChangeLocale(e.target.value)}
|
id="brandSetting"
|
||||||
id="locale"
|
|
||||||
className="selectPicker"
|
className="selectPicker"
|
||||||
>
|
>
|
||||||
<option value="en">🇬🇧 English</option>
|
<option value={TENANT_BRAND_NAME_AND_LOGO}>
|
||||||
<option value="it">🇮🇹 Italiano</option>
|
{ I18n.t('site_settings.general.brand_setting_both') }
|
||||||
|
</option>
|
||||||
|
<option value={TENANT_BRAND_NAME_ONLY}>
|
||||||
|
{ I18n.t('site_settings.general.brand_setting_name') }
|
||||||
|
</option>
|
||||||
|
<option value={TENANT_BRAND_LOGO_ONLY}>
|
||||||
|
{ I18n.t('site_settings.general.brand_setting_logo') }
|
||||||
|
</option>
|
||||||
|
<option value={TENANT_BRAND_NONE}>
|
||||||
|
{ I18n.t('site_settings.general.brand_setting_none') }
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
|
|
||||||
|
<div className="formGroup">
|
||||||
|
<label htmlFor="locale">{ I18n.t('site_settings.general.locale') }</label>
|
||||||
|
<select
|
||||||
|
{...register('locale')}
|
||||||
|
id="locale"
|
||||||
|
className="selectPicker"
|
||||||
|
>
|
||||||
|
<option value="en">🇬🇧 English</option>
|
||||||
|
<option value="it">🇮🇹 Italiano</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<Button
|
<Button onClick={() => null} disabled={!isDirty}>
|
||||||
onClick={this._handleUpdateTenant}
|
{I18n.t('common.buttons.update')}
|
||||||
disabled={!areDirty}
|
|
||||||
>
|
|
||||||
{ I18n.t('common.buttons.update') }
|
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</form>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<SiteSettingsInfoBox areUpdating={areLoading || areUpdating} error={error} areDirty={areDirty} />
|
<SiteSettingsInfoBox
|
||||||
</>
|
areUpdating={areUpdating}
|
||||||
);
|
error={error}
|
||||||
}
|
areDirty={isDirty && !isSubmitSuccessful}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GeneralSiteSettingsP;
|
export default GeneralSiteSettingsP;
|
||||||
@@ -5,7 +5,7 @@ import { Store } from 'redux';
|
|||||||
import GeneralSiteSettings from '../../../containers/GeneralSiteSettings';
|
import GeneralSiteSettings from '../../../containers/GeneralSiteSettings';
|
||||||
import createStoreHelper from '../../../helpers/createStore';
|
import createStoreHelper from '../../../helpers/createStore';
|
||||||
import { State } from '../../../reducers/rootReducer';
|
import { State } from '../../../reducers/rootReducer';
|
||||||
import { ISiteSettingsGeneralForm } from '../../../reducers/SiteSettings/generalReducer';
|
import { ISiteSettingsGeneralForm } from './GeneralSiteSettingsP';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
originForm: ISiteSettingsGeneralForm;
|
originForm: ISiteSettingsGeneralForm;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
import I18n from 'i18n-js';
|
import I18n from 'i18n-js';
|
||||||
|
|
||||||
import Button from '../../common/Button';
|
import Button from '../../common/Button';
|
||||||
@@ -12,7 +13,7 @@ interface Props {
|
|||||||
name?: string;
|
name?: string;
|
||||||
color?: string;
|
color?: string;
|
||||||
|
|
||||||
handleSubmit?(
|
handleCreate?(
|
||||||
name: string,
|
name: string,
|
||||||
color: string,
|
color: string,
|
||||||
onSuccess: Function,
|
onSuccess: Function,
|
||||||
@@ -24,104 +25,76 @@ interface Props {
|
|||||||
): void;
|
): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface IPostStatusForm {
|
||||||
name: string;
|
name: string;
|
||||||
color: string;
|
color: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostStatusForm extends React.Component<Props, State> {
|
const PostStatusForm = ({
|
||||||
initialState: State = {
|
mode,
|
||||||
name: '',
|
id,
|
||||||
color: this.getRandomColor(),
|
name,
|
||||||
};
|
color,
|
||||||
|
handleCreate,
|
||||||
|
handleUpdate,
|
||||||
|
}: Props) => {
|
||||||
|
const getRandomColor = () =>
|
||||||
|
'#' + padStart((Math.random() * 0xFFFFFF << 0).toString(16), 6, '0');
|
||||||
|
|
||||||
constructor(props: Props) {
|
const {
|
||||||
super(props);
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
reset,
|
||||||
|
formState: { isValid },
|
||||||
|
} = useForm<IPostStatusForm>({
|
||||||
|
mode: 'onChange',
|
||||||
|
defaultValues: {
|
||||||
|
name: name || '',
|
||||||
|
color: color || getRandomColor(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
this.state = this.props.mode === 'create' ?
|
const onSubmit: SubmitHandler<IPostStatusForm> = data => {
|
||||||
this.initialState
|
if (mode === 'create') {
|
||||||
:
|
handleCreate(
|
||||||
{
|
data.name,
|
||||||
name: this.props.name,
|
data.color,
|
||||||
color: this.props.color,
|
() => reset({ name: '', color: getRandomColor() })
|
||||||
};
|
|
||||||
|
|
||||||
this.onSubmit = this.onSubmit.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
getRandomColor() {
|
|
||||||
return '#' + padStart((Math.random() * 0xFFFFFF << 0).toString(16), 6, '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
isFormValid() {
|
|
||||||
return this.state.name && this.state.name.length > 0 &&
|
|
||||||
this.state.color && this.state.color.length === 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
onNameChange(nameText: string) {
|
|
||||||
this.setState({
|
|
||||||
name: nameText,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onColorChange(colorText: string) {
|
|
||||||
this.setState({
|
|
||||||
color: colorText,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
if (this.props.mode === 'create') {
|
|
||||||
this.props.handleSubmit(
|
|
||||||
this.state.name,
|
|
||||||
this.state.color,
|
|
||||||
() => this.setState({...this.initialState, color: this.getRandomColor()}),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.props.handleUpdate(this.props.id, this.state.name, this.state.color);
|
handleUpdate(id, data.name, data.color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const {mode} = this.props;
|
<form onSubmit={handleSubmit(onSubmit)} className="postStatusForm">
|
||||||
const {name, color} = this.state;
|
<input
|
||||||
|
{...register('name', { required: true })}
|
||||||
|
placeholder={I18n.t('site_settings.post_statuses.form.name')}
|
||||||
|
autoFocus
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
|
||||||
return (
|
<input
|
||||||
<form className="postStatusForm">
|
{...register('color', { required: true })}
|
||||||
<input
|
type="color"
|
||||||
type="text"
|
className="formControl postStatusColorInput"
|
||||||
placeholder={I18n.t('site_settings.post_statuses.form.name')}
|
/>
|
||||||
value={name}
|
|
||||||
onChange={e => this.onNameChange(e.target.value)}
|
|
||||||
autoFocus
|
|
||||||
className="form-control"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
<Button
|
||||||
type="color"
|
onClick={() => null}
|
||||||
value={color}
|
className="newPostStatusButton"
|
||||||
onChange={e => this.onColorChange(e.target.value)}
|
disabled={!isValid}
|
||||||
className="form-control postStatusColorInput"
|
>
|
||||||
/>
|
{
|
||||||
|
mode === 'create' ?
|
||||||
<Button
|
I18n.t('common.buttons.create')
|
||||||
onClick={e => {
|
:
|
||||||
e.preventDefault();
|
I18n.t('common.buttons.update')
|
||||||
this.onSubmit();
|
}
|
||||||
}}
|
</Button>
|
||||||
className="newPostStatusButton"
|
</form>
|
||||||
disabled={!this.isFormValid()}
|
);
|
||||||
>
|
|
||||||
{
|
|
||||||
mode === 'create' ?
|
|
||||||
I18n.t('common.buttons.create')
|
|
||||||
:
|
|
||||||
I18n.t('common.buttons.update')
|
|
||||||
}
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PostStatusForm;
|
export default PostStatusForm;
|
||||||
@@ -125,7 +125,7 @@ class PostStatusesSiteSettingsP extends React.Component<Props> {
|
|||||||
<Box>
|
<Box>
|
||||||
<h2>{I18n.t('site_settings.post_statuses.new')}</h2>
|
<h2>{I18n.t('site_settings.post_statuses.new')}</h2>
|
||||||
|
|
||||||
<PostStatusForm mode='create' handleSubmit={this.handleSubmit} />
|
<PostStatusForm mode='create' handleCreate={this.handleSubmit} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<SiteSettingsInfoBox areUpdating={settingsAreUpdating || postStatuses.areLoading} error={settingsError} />
|
<SiteSettingsInfoBox areUpdating={settingsAreUpdating || postStatuses.areLoading} error={settingsError} />
|
||||||
|
|||||||
@@ -1,92 +1,83 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { SubmitHandler, useForm } from 'react-hook-form';
|
||||||
import I18n from 'i18n-js';
|
import I18n from 'i18n-js';
|
||||||
|
|
||||||
import Box from '../common/Box';
|
import Box from '../common/Box';
|
||||||
import { TenantSignUpTenantFormState } from '../../reducers/tenantSignUpReducer';
|
|
||||||
import Button from '../common/Button';
|
import Button from '../common/Button';
|
||||||
import Spinner from '../common/Spinner';
|
import Spinner from '../common/Spinner';
|
||||||
import { DangerText } from '../common/CustomTexts';
|
import { DangerText } from '../common/CustomTexts';
|
||||||
|
import { ITenantSignUpTenantForm } from './TenantSignUpP';
|
||||||
|
import HttpStatus from '../../constants/http_status';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
tenantForm: TenantSignUpTenantFormState;
|
|
||||||
handleChangeTenantSiteName(siteName: string): void;
|
|
||||||
handleChangeTenantSubdomain(subdomain: string): void;
|
|
||||||
|
|
||||||
isSubmitting: boolean;
|
isSubmitting: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
handleSubmit(): void;
|
handleSignUpSubmit(siteName: string, subdomain: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TenantSignUpForm extends React.Component<Props> {
|
const TenantSignUpForm = ({
|
||||||
form: any;
|
isSubmitting,
|
||||||
|
error,
|
||||||
constructor(props: Props) {
|
handleSignUpSubmit,
|
||||||
super(props);
|
}: Props) => {
|
||||||
|
const { register, handleSubmit, formState: { errors } } = useForm<ITenantSignUpTenantForm>();
|
||||||
this.form = React.createRef();
|
const onSubmit: SubmitHandler<ITenantSignUpTenantForm> = data => {
|
||||||
|
handleSignUpSubmit(data.siteName, data.subdomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const {
|
<Box customClass="tenantSignUpStep2">
|
||||||
tenantForm,
|
<h3>{ I18n.t('signup.step2.title') }</h3>
|
||||||
handleChangeTenantSiteName,
|
|
||||||
handleChangeTenantSubdomain,
|
|
||||||
|
|
||||||
isSubmitting,
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
error,
|
<div className="formRow">
|
||||||
handleSubmit,
|
<input
|
||||||
} = this.props;
|
{...register('siteName', { required: true })}
|
||||||
|
autoFocus
|
||||||
|
placeholder={I18n.t('signup.step2.site_name')}
|
||||||
|
id="tenantSiteName"
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
<DangerText>{errors.siteName && I18n.t('signup.step2.validations.site_name')}</DangerText>
|
||||||
|
</div>
|
||||||
|
|
||||||
return (
|
<div className="formRow">
|
||||||
<Box customClass="tenantSignUpStep2">
|
<div className="input-group">
|
||||||
<h3>{ I18n.t('signup.step2.title') }</h3>
|
|
||||||
|
|
||||||
<form ref={this.form}>
|
|
||||||
<div className="formRow">
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
{...register('subdomain', {
|
||||||
autoFocus
|
required: true,
|
||||||
value={tenantForm.siteName}
|
validate: async (newSubdomain) => {
|
||||||
onChange={e => handleChangeTenantSiteName(e.target.value)}
|
const res = await fetch(`/is_available?new_subdomain=${newSubdomain}`);
|
||||||
placeholder={I18n.t('signup.step2.site_name')}
|
return res.status === HttpStatus.OK;
|
||||||
required
|
},
|
||||||
id="tenantSiteName"
|
})}
|
||||||
|
placeholder={I18n.t('signup.step2.subdomain')}
|
||||||
|
id="tenantSubdomain"
|
||||||
className="formControl"
|
className="formControl"
|
||||||
/>
|
/>
|
||||||
</div>
|
<div className="input-group-append">
|
||||||
|
<div className="input-group-text">.astuto.io</div>
|
||||||
<div className="formRow">
|
|
||||||
<div className="input-group">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={tenantForm.subdomain}
|
|
||||||
onChange={e => handleChangeTenantSubdomain(e.target.value)}
|
|
||||||
placeholder={I18n.t('signup.step2.subdomain')}
|
|
||||||
required
|
|
||||||
id="tenantSubdomain"
|
|
||||||
className="formControl"
|
|
||||||
/>
|
|
||||||
<div className="input-group-append">
|
|
||||||
<div className="input-group-text">.astuto.io</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<DangerText>
|
||||||
|
{errors.subdomain?.type === 'required' && I18n.t('signup.step2.validations.subdomain')}
|
||||||
|
</DangerText>
|
||||||
|
<DangerText>
|
||||||
|
{errors.subdomain?.type === 'validate' && I18n.t('signup.step2.validations.subdomain_already_taken')}
|
||||||
|
</DangerText>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={e => {
|
onClick={() => null}
|
||||||
e.preventDefault();
|
className="tenantConfirm"
|
||||||
handleSubmit();
|
>
|
||||||
}}
|
{ isSubmitting ? <Spinner /> : I18n.t('signup.step2.create_button') }
|
||||||
className="tenantConfirm"
|
</Button>
|
||||||
>
|
|
||||||
{ isSubmitting ? <Spinner /> : I18n.t('signup.step2.create_button') }
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{ error !== '' && <DangerText>{ error }</DangerText> }
|
{ error !== '' && <DangerText>{ error }</DangerText> }
|
||||||
</form>
|
</form>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TenantSignUpForm;
|
export default TenantSignUpForm;
|
||||||
@@ -1,31 +1,15 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { TenantSignUpTenantFormState, TenantSignUpUserFormState } from '../../reducers/tenantSignUpReducer';
|
import { useState } from 'react';
|
||||||
|
import HttpStatus from '../../constants/http_status';
|
||||||
import ConfirmSignUpPage from './ConfirmSignUpPage';
|
import ConfirmSignUpPage from './ConfirmSignUpPage';
|
||||||
|
|
||||||
import TenantSignUpForm from './TenantSignUpForm';
|
import TenantSignUpForm from './TenantSignUpForm';
|
||||||
import UserSignUpForm from './UserSignUpForm';
|
import UserSignUpForm from './UserSignUpForm';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
authenticityToken: string;
|
|
||||||
|
|
||||||
currentStep: number;
|
|
||||||
emailAuth: boolean;
|
|
||||||
isSubmitting: boolean;
|
isSubmitting: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
|
|
||||||
toggleEmailAuth(): void;
|
|
||||||
|
|
||||||
userForm: TenantSignUpUserFormState;
|
|
||||||
handleChangeUserFullName(fullName: string): void;
|
|
||||||
handleChangeUserEmail(email: string): void;
|
|
||||||
handleChangeUserPassword(password: string): void;
|
|
||||||
handleChangeUserPasswordConfirmation(passwordConfirmation: string): void;
|
|
||||||
handleUserFormConfirm(): void;
|
|
||||||
|
|
||||||
tenantForm: TenantSignUpTenantFormState;
|
|
||||||
handleChangeTenantSiteName(siteName: string): void;
|
|
||||||
handleChangeTenantSubdomain(subdomain: string): void;
|
|
||||||
|
|
||||||
handleSubmit(
|
handleSubmit(
|
||||||
userFullName: string,
|
userFullName: string,
|
||||||
userEmail: string,
|
userEmail: string,
|
||||||
@@ -33,92 +17,92 @@ interface Props {
|
|||||||
siteName: string,
|
siteName: string,
|
||||||
subdomain: string,
|
subdomain: string,
|
||||||
authenticityToken: string,
|
authenticityToken: string,
|
||||||
): void;
|
): Promise<any>;
|
||||||
|
|
||||||
|
authenticityToken: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TenantSignUpP extends React.Component<Props> {
|
export interface ITenantSignUpUserForm {
|
||||||
constructor(props: Props) {
|
fullName: string;
|
||||||
super(props);
|
email: string;
|
||||||
|
password: string;
|
||||||
|
passwordConfirmation: string;
|
||||||
|
}
|
||||||
|
|
||||||
this._handleSubmit = this._handleSubmit.bind(this);
|
export interface ITenantSignUpTenantForm {
|
||||||
}
|
siteName: string;
|
||||||
|
subdomain: string;
|
||||||
|
}
|
||||||
|
|
||||||
_handleSubmit() {
|
const TenantSignUpP = ({
|
||||||
const { userForm, tenantForm, handleSubmit } = this.props;
|
isSubmitting,
|
||||||
|
error,
|
||||||
|
handleSubmit,
|
||||||
|
authenticityToken
|
||||||
|
}: Props) => {
|
||||||
|
const [userData, setUserData] = useState({
|
||||||
|
fullName: '',
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
passwordConfirmation: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const [tenantData, setTenantData] = useState({
|
||||||
|
siteName: '',
|
||||||
|
subdomain: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const [currentStep, setCurrentStep] = useState(1);
|
||||||
|
const [emailAuth, setEmailAuth] = useState(false);
|
||||||
|
|
||||||
|
const handleSignUpSubmit = (siteName: string, subdomain: string) => {
|
||||||
handleSubmit(
|
handleSubmit(
|
||||||
userForm.fullName,
|
userData.fullName,
|
||||||
userForm.email,
|
userData.email,
|
||||||
userForm.password,
|
userData.password,
|
||||||
tenantForm.siteName,
|
siteName,
|
||||||
tenantForm.subdomain,
|
subdomain,
|
||||||
this.props.authenticityToken,
|
authenticityToken,
|
||||||
);
|
).then(res => {
|
||||||
|
if (res?.status !== HttpStatus.Created) return;
|
||||||
|
|
||||||
|
setTenantData({ siteName, subdomain });
|
||||||
|
setCurrentStep(currentStep + 1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const {
|
<div className="tenantSignUpContainer">
|
||||||
currentStep,
|
{
|
||||||
emailAuth,
|
(currentStep === 1 || currentStep === 2) &&
|
||||||
toggleEmailAuth,
|
<UserSignUpForm
|
||||||
|
currentStep={currentStep}
|
||||||
|
setCurrentStep={setCurrentStep}
|
||||||
|
emailAuth={emailAuth}
|
||||||
|
setEmailAuth={setEmailAuth}
|
||||||
|
userData={userData}
|
||||||
|
setUserData={setUserData}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
userForm,
|
{
|
||||||
handleChangeUserFullName,
|
currentStep === 2 &&
|
||||||
handleChangeUserEmail,
|
<TenantSignUpForm
|
||||||
handleChangeUserPassword,
|
isSubmitting={isSubmitting}
|
||||||
handleChangeUserPasswordConfirmation,
|
error={error}
|
||||||
handleUserFormConfirm,
|
handleSignUpSubmit={handleSignUpSubmit}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
tenantForm,
|
{
|
||||||
handleChangeTenantSiteName,
|
currentStep === 3 &&
|
||||||
handleChangeTenantSubdomain,
|
<ConfirmSignUpPage
|
||||||
|
subdomain={tenantData.subdomain}
|
||||||
isSubmitting,
|
userEmail={userData.email}
|
||||||
error,
|
/>
|
||||||
} = this.props;
|
}
|
||||||
|
</div>
|
||||||
return (
|
);
|
||||||
<div className="tenantSignUpContainer">
|
|
||||||
{
|
|
||||||
(currentStep === 1 || currentStep === 2) &&
|
|
||||||
<UserSignUpForm
|
|
||||||
currentStep={currentStep}
|
|
||||||
|
|
||||||
emailAuth={emailAuth}
|
|
||||||
toggleEmailAuth={toggleEmailAuth}
|
|
||||||
userForm={userForm}
|
|
||||||
|
|
||||||
handleChangeUserFullName={handleChangeUserFullName}
|
|
||||||
handleChangeUserEmail={handleChangeUserEmail}
|
|
||||||
handleChangeUserPassword={handleChangeUserPassword}
|
|
||||||
handleChangeUserPasswordConfirmation={handleChangeUserPasswordConfirmation}
|
|
||||||
handleUserFormConfirm={handleUserFormConfirm}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
currentStep === 2 &&
|
|
||||||
<TenantSignUpForm
|
|
||||||
tenantForm={tenantForm}
|
|
||||||
handleChangeTenantSiteName={handleChangeTenantSiteName}
|
|
||||||
handleChangeTenantSubdomain={handleChangeTenantSubdomain}
|
|
||||||
|
|
||||||
isSubmitting={isSubmitting}
|
|
||||||
error={error}
|
|
||||||
handleSubmit={this._handleSubmit}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
currentStep === 3 &&
|
|
||||||
<ConfirmSignUpPage
|
|
||||||
subdomain={tenantForm.subdomain}
|
|
||||||
userEmail={userForm.email}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TenantSignUpP;
|
export default TenantSignUpP;
|
||||||
@@ -1,147 +1,115 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { SubmitHandler, useForm } from 'react-hook-form';
|
||||||
import I18n from 'i18n-js';
|
import I18n from 'i18n-js';
|
||||||
|
|
||||||
import Box from '../common/Box';
|
import Box from '../common/Box';
|
||||||
import Button from '../common/Button';
|
import Button from '../common/Button';
|
||||||
import { TenantSignUpUserFormState } from '../../reducers/tenantSignUpReducer';
|
import { ITenantSignUpUserForm } from './TenantSignUpP';
|
||||||
|
import { DangerText } from '../common/CustomTexts';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currentStep: number;
|
currentStep: number;
|
||||||
|
setCurrentStep(step: number): void;
|
||||||
emailAuth: boolean;
|
emailAuth: boolean;
|
||||||
toggleEmailAuth(): void;
|
setEmailAuth(enabled: boolean): void;
|
||||||
userForm: TenantSignUpUserFormState;
|
userData: ITenantSignUpUserForm;
|
||||||
|
setUserData({}: ITenantSignUpUserForm): void;
|
||||||
handleChangeUserFullName(fullName: string): void;
|
|
||||||
handleChangeUserEmail(email: string): void;
|
|
||||||
handleChangeUserPassword(password: string): void;
|
|
||||||
handleChangeUserPasswordConfirmation(passwordConfirmation: string): void;
|
|
||||||
handleUserFormConfirm(): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserSignUpForm extends React.Component<Props> {
|
const UserSignUpForm = ({
|
||||||
form: any;
|
currentStep,
|
||||||
|
setCurrentStep,
|
||||||
|
emailAuth,
|
||||||
|
setEmailAuth,
|
||||||
|
userData,
|
||||||
|
setUserData,
|
||||||
|
}: Props) => {
|
||||||
|
const { register, handleSubmit, setError, formState: { errors } } = useForm<ITenantSignUpUserForm>();
|
||||||
|
const onSubmit: SubmitHandler<ITenantSignUpUserForm> = data => {
|
||||||
|
if (data.password !== data.passwordConfirmation) {
|
||||||
|
setError('passwordConfirmation', I18n.t('signup.step1.validations.password_mismatch'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props: Props) {
|
setUserData({...data});
|
||||||
super(props);
|
setCurrentStep(currentStep + 1);
|
||||||
|
|
||||||
this.form = React.createRef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validateUserForm(): boolean {
|
return (
|
||||||
let isValid: boolean = this.form.current.reportValidity();
|
<Box customClass="tenantSignUpStep1">
|
||||||
if (this.validateUserPasswordConfirmation() === false)
|
<h3>{ I18n.t('signup.step1.title') }</h3>
|
||||||
isValid = false;
|
|
||||||
|
|
||||||
return isValid;
|
{
|
||||||
}
|
currentStep === 1 && !emailAuth &&
|
||||||
|
<Button className="emailAuth" onClick={() => setEmailAuth(true)}>
|
||||||
|
{ I18n.t('signup.step1.email_auth') }
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
|
||||||
validateUserPasswordConfirmation(): boolean {
|
{
|
||||||
const isValid = this.props.userForm.password === this.props.userForm.passwordConfirmation;
|
currentStep === 1 && emailAuth &&
|
||||||
return isValid;
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
}
|
<div className="formRow">
|
||||||
|
<input
|
||||||
|
{...register('fullName', { required: true, minLength: 2 })}
|
||||||
|
autoFocus
|
||||||
|
placeholder={I18n.t('common.forms.auth.full_name')}
|
||||||
|
id="userFullName"
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
<DangerText>{ errors.fullName && I18n.t('signup.step1.validations.full_name') }</DangerText>
|
||||||
|
</div>
|
||||||
|
|
||||||
render() {
|
<div className="formRow">
|
||||||
const {
|
<input
|
||||||
currentStep,
|
{...register('email', { required: true, pattern: /(.+)@(.+){2,}\.(.+){2,}/ })}
|
||||||
emailAuth,
|
type="email"
|
||||||
toggleEmailAuth,
|
placeholder={I18n.t('common.forms.auth.email')}
|
||||||
userForm,
|
id="userEmail"
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
<DangerText>{ errors.email && I18n.t('signup.step1.validations.email') }</DangerText>
|
||||||
|
</div>
|
||||||
|
|
||||||
handleChangeUserFullName,
|
<div className="formRow">
|
||||||
handleChangeUserEmail,
|
<div className="formGroup col-6">
|
||||||
handleChangeUserPassword,
|
<input
|
||||||
handleChangeUserPasswordConfirmation,
|
{...register('password', { required: true, minLength: 6, maxLength: 128 })}
|
||||||
handleUserFormConfirm,
|
type="password"
|
||||||
} = this.props;
|
placeholder={I18n.t('common.forms.auth.password')}
|
||||||
|
id="userPassword"
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
<DangerText>{ errors.password && I18n.t('signup.step1.validations.password', { n: 6 }) }</DangerText>
|
||||||
|
</div>
|
||||||
|
|
||||||
return (
|
<div className="formGroup col-6">
|
||||||
<Box customClass="tenantSignUpStep1">
|
<input
|
||||||
<h3>{ I18n.t('signup.step1.title') }</h3>
|
{...register('passwordConfirmation')}
|
||||||
|
type="password"
|
||||||
|
placeholder={I18n.t('common.forms.auth.password_confirmation')}
|
||||||
|
id="userPasswordConfirmation"
|
||||||
|
className="formControl"
|
||||||
|
/>
|
||||||
|
<DangerText>{ errors.passwordConfirmation && I18n.t('signup.step1.validations.password_mismatch') }</DangerText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{
|
<Button
|
||||||
currentStep === 1 && !emailAuth &&
|
onClick={() => null}
|
||||||
<Button className="emailAuth" onClick={toggleEmailAuth}>
|
className="userConfirm"
|
||||||
{ I18n.t('signup.step1.email_auth') }
|
>
|
||||||
|
{ I18n.t('common.buttons.confirm') }
|
||||||
</Button>
|
</Button>
|
||||||
}
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
currentStep === 1 && emailAuth &&
|
currentStep === 2 &&
|
||||||
<form ref={this.form}>
|
<p><b>{userData.fullName}</b> ({userData.email})</p>
|
||||||
<div className="formRow">
|
}
|
||||||
<input
|
</Box>
|
||||||
type="text"
|
);
|
||||||
autoFocus
|
|
||||||
value={userForm.fullName}
|
|
||||||
onChange={e => handleChangeUserFullName(e.target.value)}
|
|
||||||
placeholder={I18n.t('common.forms.auth.full_name')}
|
|
||||||
required
|
|
||||||
id="userFullName"
|
|
||||||
className="formControl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="formRow">
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
value={userForm.email}
|
|
||||||
onChange={e => handleChangeUserEmail(e.target.value)}
|
|
||||||
placeholder={I18n.t('common.forms.auth.email')}
|
|
||||||
required
|
|
||||||
id="userEmail"
|
|
||||||
className="formControl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="formRow">
|
|
||||||
<div className="formGroup col-6">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
value={userForm.password}
|
|
||||||
onChange={e => handleChangeUserPassword(e.target.value)}
|
|
||||||
placeholder={I18n.t('common.forms.auth.password')}
|
|
||||||
required
|
|
||||||
minLength={6}
|
|
||||||
maxLength={128}
|
|
||||||
id="userPassword"
|
|
||||||
className="formControl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="formGroup col-6">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
value={userForm.passwordConfirmation}
|
|
||||||
onChange={e => handleChangeUserPasswordConfirmation(e.target.value)}
|
|
||||||
placeholder={I18n.t('common.forms.auth.password_confirmation')}
|
|
||||||
required
|
|
||||||
minLength={6}
|
|
||||||
maxLength={128}
|
|
||||||
id="userPasswordConfirmation"
|
|
||||||
className={`formControl${userForm.passwordConfirmationError ? ' invalid' : ''}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
onClick={e => {
|
|
||||||
e.preventDefault();
|
|
||||||
this.validateUserForm() && handleUserFormConfirm();
|
|
||||||
}}
|
|
||||||
className="userConfirm"
|
|
||||||
>
|
|
||||||
{ I18n.t('common.buttons.confirm') }
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
currentStep === 2 &&
|
|
||||||
<p><b>{userForm.fullName}</b> ({userForm.email})</p>
|
|
||||||
}
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UserSignUpForm;
|
export default UserSignUpForm;
|
||||||
@@ -1,29 +1,15 @@
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
import { requestTenant } from "../actions/Tenant/requestTenant";
|
|
||||||
import {
|
|
||||||
changeSiteSettingsGeneralFormBrandSetting,
|
|
||||||
changeSiteSettingsGeneralFormLocale,
|
|
||||||
changeSiteSettingsGeneralFormSiteLogo,
|
|
||||||
changeSiteSettingsGeneralFormSiteName
|
|
||||||
} from "../actions/changeSiteSettingsGeneralForm";
|
|
||||||
import GeneralSiteSettingsP from "../components/SiteSettings/General/GeneralSiteSettingsP";
|
import GeneralSiteSettingsP from "../components/SiteSettings/General/GeneralSiteSettingsP";
|
||||||
import { State } from "../reducers/rootReducer";
|
|
||||||
import { updateTenant } from "../actions/Tenant/updateTenant";
|
import { updateTenant } from "../actions/Tenant/updateTenant";
|
||||||
|
import { State } from "../reducers/rootReducer";
|
||||||
|
|
||||||
const mapStateToProps = (state: State) => ({
|
const mapStateToProps = (state: State) => ({
|
||||||
form: state.siteSettings.general.form,
|
|
||||||
areDirty: state.siteSettings.general.areDirty,
|
|
||||||
areLoading: state.siteSettings.general.areLoading,
|
|
||||||
areUpdating: state.siteSettings.general.areUpdating,
|
areUpdating: state.siteSettings.general.areUpdating,
|
||||||
error: state.siteSettings.general.error,
|
error: state.siteSettings.general.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: any) => ({
|
const mapDispatchToProps = (dispatch: any) => ({
|
||||||
requestTenant() {
|
|
||||||
dispatch(requestTenant());
|
|
||||||
},
|
|
||||||
|
|
||||||
updateTenant(
|
updateTenant(
|
||||||
siteName: string,
|
siteName: string,
|
||||||
siteLogo: string,
|
siteLogo: string,
|
||||||
@@ -39,22 +25,6 @@ const mapDispatchToProps = (dispatch: any) => ({
|
|||||||
authenticityToken,
|
authenticityToken,
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
handleChangeSiteName(siteName: string) {
|
|
||||||
dispatch(changeSiteSettingsGeneralFormSiteName(siteName));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeSiteLogo(siteLogo: string) {
|
|
||||||
dispatch(changeSiteSettingsGeneralFormSiteLogo(siteLogo));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeBrandDisplaySetting(brandDisplaySetting: string) {
|
|
||||||
dispatch(changeSiteSettingsGeneralFormBrandSetting(brandDisplaySetting));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeLocale(locale: string) {
|
|
||||||
dispatch(changeSiteSettingsGeneralFormLocale(locale));
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
|||||||
@@ -3,60 +3,14 @@ import { connect } from "react-redux";
|
|||||||
import TenantSignUpP from "../components/TenantSignUp/TenantSignUpP";
|
import TenantSignUpP from "../components/TenantSignUp/TenantSignUpP";
|
||||||
|
|
||||||
import { State } from "../reducers/rootReducer";
|
import { State } from "../reducers/rootReducer";
|
||||||
import {
|
|
||||||
changeTenantSiteNameTenantSignUp,
|
|
||||||
changeTenantSubdomainTenantSignUp,
|
|
||||||
changeUserEmailTenantSignUp,
|
|
||||||
changeUserFullNameTenantSignUp,
|
|
||||||
changeUserPasswordConfirmationTenantSignUp,
|
|
||||||
changeUserPasswordTenantSignUp,
|
|
||||||
confirmUserFormTenantSignUp,
|
|
||||||
toggleEmailAuthTenantSignUp
|
|
||||||
} from "../actions/Tenant/tenantSignUpFormActions";
|
|
||||||
import { submitTenant } from "../actions/Tenant/submitTenant";
|
import { submitTenant } from "../actions/Tenant/submitTenant";
|
||||||
|
|
||||||
const mapStateToProps = (state: State) => ({
|
const mapStateToProps = (state: State) => ({
|
||||||
currentStep: state.tenantSignUp.currentStep,
|
|
||||||
emailAuth: state.tenantSignUp.emailAuth,
|
|
||||||
isSubmitting: state.tenantSignUp.isSubmitting,
|
isSubmitting: state.tenantSignUp.isSubmitting,
|
||||||
error: state.tenantSignUp.error,
|
error: state.tenantSignUp.error,
|
||||||
userForm: state.tenantSignUp.userForm,
|
|
||||||
tenantForm: state.tenantSignUp.tenantForm,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: any) => ({
|
const mapDispatchToProps = (dispatch: any) => ({
|
||||||
toggleEmailAuth() {
|
|
||||||
dispatch(toggleEmailAuthTenantSignUp());
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeUserFullName(fullName: string) {
|
|
||||||
dispatch(changeUserFullNameTenantSignUp(fullName));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeUserEmail(email: string) {
|
|
||||||
dispatch(changeUserEmailTenantSignUp(email));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeUserPassword(password: string) {
|
|
||||||
dispatch(changeUserPasswordTenantSignUp(password));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeUserPasswordConfirmation(passwordConfirmation: string) {
|
|
||||||
dispatch(changeUserPasswordConfirmationTenantSignUp(passwordConfirmation));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleUserFormConfirm() {
|
|
||||||
dispatch(confirmUserFormTenantSignUp());
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeTenantSiteName(siteName: string) {
|
|
||||||
dispatch(changeTenantSiteNameTenantSignUp(siteName));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChangeTenantSubdomain(subdomain: string) {
|
|
||||||
dispatch(changeTenantSubdomainTenantSignUp(subdomain));
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSubmit(
|
handleSubmit(
|
||||||
userFullName: string,
|
userFullName: string,
|
||||||
userEmail: string,
|
userEmail: string,
|
||||||
@@ -64,8 +18,8 @@ const mapDispatchToProps = (dispatch: any) => ({
|
|||||||
siteName: string,
|
siteName: string,
|
||||||
subdomain: string,
|
subdomain: string,
|
||||||
authenticityToken: string,
|
authenticityToken: string,
|
||||||
) {
|
): Promise<any> {
|
||||||
dispatch(submitTenant(
|
return dispatch(submitTenant(
|
||||||
userFullName,
|
userFullName,
|
||||||
userEmail,
|
userEmail,
|
||||||
userPassword,
|
userPassword,
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
import {
|
|
||||||
TenantRequestActionTypes,
|
|
||||||
TENANT_REQUEST_START,
|
|
||||||
TENANT_REQUEST_SUCCESS,
|
|
||||||
TENANT_REQUEST_FAILURE,
|
|
||||||
} from "../../actions/Tenant/requestTenant";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TenantUpdateActionTypes,
|
TenantUpdateActionTypes,
|
||||||
TENANT_UPDATE_START,
|
TENANT_UPDATE_START,
|
||||||
@@ -12,38 +5,13 @@ import {
|
|||||||
TENANT_UPDATE_FAILURE,
|
TENANT_UPDATE_FAILURE,
|
||||||
} from '../../actions/Tenant/updateTenant';
|
} from '../../actions/Tenant/updateTenant';
|
||||||
|
|
||||||
import {
|
|
||||||
ChangeSiteSettingsGeneralFormActionTypes,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE,
|
|
||||||
} from '../../actions/changeSiteSettingsGeneralForm';
|
|
||||||
|
|
||||||
export interface ISiteSettingsGeneralForm {
|
|
||||||
siteName: string;
|
|
||||||
siteLogo: string;
|
|
||||||
brandDisplaySetting: string;
|
|
||||||
locale: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SiteSettingsGeneralState {
|
export interface SiteSettingsGeneralState {
|
||||||
form: ISiteSettingsGeneralForm,
|
|
||||||
areDirty: boolean;
|
|
||||||
areLoading: boolean;
|
|
||||||
areUpdating: boolean;
|
areUpdating: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: SiteSettingsGeneralState = {
|
const initialState: SiteSettingsGeneralState = {
|
||||||
form: {
|
|
||||||
siteName: '',
|
|
||||||
siteLogo: '',
|
|
||||||
brandDisplaySetting: '',
|
|
||||||
locale: '',
|
|
||||||
},
|
|
||||||
areDirty: false,
|
|
||||||
areLoading: false,
|
|
||||||
areUpdating: false,
|
areUpdating: false,
|
||||||
error: '',
|
error: '',
|
||||||
};
|
};
|
||||||
@@ -51,52 +19,22 @@ const initialState: SiteSettingsGeneralState = {
|
|||||||
const siteSettingsGeneralReducer = (
|
const siteSettingsGeneralReducer = (
|
||||||
state = initialState,
|
state = initialState,
|
||||||
action:
|
action:
|
||||||
TenantRequestActionTypes |
|
TenantUpdateActionTypes
|
||||||
TenantUpdateActionTypes |
|
|
||||||
ChangeSiteSettingsGeneralFormActionTypes
|
|
||||||
) => {
|
) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case TENANT_REQUEST_START:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
areLoading: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_UPDATE_START:
|
case TENANT_UPDATE_START:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
areUpdating: true,
|
areUpdating: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
case TENANT_REQUEST_SUCCESS:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
form: {
|
|
||||||
siteName: action.tenant.site_name,
|
|
||||||
siteLogo: action.tenant.site_logo,
|
|
||||||
brandDisplaySetting: action.tenant.brand_display_setting,
|
|
||||||
locale: action.tenant.locale,
|
|
||||||
},
|
|
||||||
areDirty: false,
|
|
||||||
areLoading: false,
|
|
||||||
error: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_UPDATE_SUCCESS:
|
case TENANT_UPDATE_SUCCESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
areDirty: false,
|
|
||||||
areUpdating: false,
|
areUpdating: false,
|
||||||
error: '',
|
error: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
case TENANT_REQUEST_FAILURE:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
areLoading: false,
|
|
||||||
error: action.error,
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_UPDATE_FAILURE:
|
case TENANT_UPDATE_FAILURE:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -104,34 +42,6 @@ const siteSettingsGeneralReducer = (
|
|||||||
error: action.error,
|
error: action.error,
|
||||||
};
|
};
|
||||||
|
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
form: { ...state.form, siteName: action.siteName },
|
|
||||||
areDirty: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
form: { ...state.form, siteLogo: action.siteLogo },
|
|
||||||
areDirty: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
form: { ...state.form, brandDisplaySetting: action.brandDisplaySetting },
|
|
||||||
areDirty: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
form: { ...state.form, locale: action.locale },
|
|
||||||
areDirty: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,6 @@ import {
|
|||||||
TENANT_UPDATE_FAILURE,
|
TENANT_UPDATE_FAILURE,
|
||||||
} from '../actions/Tenant/updateTenant';
|
} from '../actions/Tenant/updateTenant';
|
||||||
|
|
||||||
import {
|
|
||||||
ChangeSiteSettingsGeneralFormActionTypes,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING,
|
|
||||||
SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE,
|
|
||||||
} from '../actions/changeSiteSettingsGeneralForm';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BoardsRequestActionTypes,
|
BoardsRequestActionTypes,
|
||||||
BOARDS_REQUEST_START,
|
BOARDS_REQUEST_START,
|
||||||
@@ -131,7 +123,6 @@ const siteSettingsReducer = (
|
|||||||
action:
|
action:
|
||||||
TenantRequestActionTypes |
|
TenantRequestActionTypes |
|
||||||
TenantUpdateActionTypes |
|
TenantUpdateActionTypes |
|
||||||
ChangeSiteSettingsGeneralFormActionTypes |
|
|
||||||
BoardsRequestActionTypes |
|
BoardsRequestActionTypes |
|
||||||
BoardSubmitActionTypes |
|
BoardSubmitActionTypes |
|
||||||
BoardUpdateActionTypes |
|
BoardUpdateActionTypes |
|
||||||
@@ -146,16 +137,9 @@ const siteSettingsReducer = (
|
|||||||
UserUpdateActionTypes
|
UserUpdateActionTypes
|
||||||
): SiteSettingsState => {
|
): SiteSettingsState => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case TENANT_REQUEST_START:
|
|
||||||
case TENANT_REQUEST_SUCCESS:
|
|
||||||
case TENANT_REQUEST_FAILURE:
|
|
||||||
case TENANT_UPDATE_START:
|
case TENANT_UPDATE_START:
|
||||||
case TENANT_UPDATE_SUCCESS:
|
case TENANT_UPDATE_SUCCESS:
|
||||||
case TENANT_UPDATE_FAILURE:
|
case TENANT_UPDATE_FAILURE:
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_NAME:
|
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_SITE_LOGO:
|
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_BRAND_SETTING:
|
|
||||||
case SITE_SETTINGS_CHANGE_GENERAL_FORM_LOCALE:
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
general: siteSettingsGeneralReducer(state.general, action),
|
general: siteSettingsGeneralReducer(state.general, action),
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
import {
|
|
||||||
TenantSignUpFormActions,
|
|
||||||
TENANT_SIGN_UP_TOGGLE_EMAIL_AUTH,
|
|
||||||
TENANT_SIGN_UP_CHANGE_USER_FULL_NAME,
|
|
||||||
TENANT_SIGN_UP_CHANGE_USER_EMAIL,
|
|
||||||
TENANT_SIGN_UP_CHANGE_USER_PASSWORD,
|
|
||||||
TENANT_SIGN_UP_CHANGE_USER_PASSWORD_CONFIRMATION,
|
|
||||||
TENANT_SIGN_UP_CONFIRM_USER_FORM,
|
|
||||||
TENANT_SIGN_UP_CHANGE_TENANT_SITE_NAME,
|
|
||||||
TENANT_SIGN_UP_CHANGE_TENANT_SUBDOMAIN,
|
|
||||||
} from '../actions/Tenant/tenantSignUpFormActions';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TenantSubmitActionTypes,
|
TenantSubmitActionTypes,
|
||||||
TENANT_SUBMIT_START,
|
TENANT_SUBMIT_START,
|
||||||
@@ -17,105 +5,21 @@ import {
|
|||||||
TENANT_SUBMIT_FAILURE,
|
TENANT_SUBMIT_FAILURE,
|
||||||
} from '../actions/Tenant/submitTenant';
|
} from '../actions/Tenant/submitTenant';
|
||||||
|
|
||||||
export interface TenantSignUpUserFormState {
|
|
||||||
fullName: string;
|
|
||||||
email: string;
|
|
||||||
password: string;
|
|
||||||
passwordConfirmation: string;
|
|
||||||
passwordConfirmationError: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TenantSignUpTenantFormState {
|
|
||||||
siteName: string;
|
|
||||||
subdomain: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TenantSignUpState {
|
export interface TenantSignUpState {
|
||||||
currentStep: number;
|
|
||||||
emailAuth: boolean;
|
|
||||||
isSubmitting: boolean;
|
isSubmitting: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
|
|
||||||
userForm: TenantSignUpUserFormState;
|
|
||||||
tenantForm: TenantSignUpTenantFormState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: TenantSignUpState = {
|
const initialState: TenantSignUpState = {
|
||||||
currentStep: 1,
|
|
||||||
emailAuth: false,
|
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
error: '',
|
error: '',
|
||||||
|
|
||||||
userForm: {
|
|
||||||
fullName: '',
|
|
||||||
email: '',
|
|
||||||
password: '',
|
|
||||||
passwordConfirmation: '',
|
|
||||||
passwordConfirmationError: false,
|
|
||||||
},
|
|
||||||
tenantForm: {
|
|
||||||
siteName: '',
|
|
||||||
subdomain: '',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const tenantSignUpReducer = (
|
const tenantSignUpReducer = (
|
||||||
state = initialState,
|
state = initialState,
|
||||||
action: TenantSignUpFormActions | TenantSubmitActionTypes,
|
action: TenantSubmitActionTypes,
|
||||||
) => {
|
) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case TENANT_SIGN_UP_TOGGLE_EMAIL_AUTH:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
emailAuth: !state.emailAuth,
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SIGN_UP_CHANGE_USER_FULL_NAME:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
userForm: { ...state.userForm, fullName: action.fullName },
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SIGN_UP_CHANGE_USER_EMAIL:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
userForm: { ...state.userForm, email: action.email },
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SIGN_UP_CHANGE_USER_PASSWORD:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
userForm: { ...state.userForm, password: action.password },
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SIGN_UP_CHANGE_USER_PASSWORD_CONFIRMATION:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
userForm: {
|
|
||||||
...state.userForm,
|
|
||||||
passwordConfirmation: action.passwordConfirmation,
|
|
||||||
passwordConfirmationError: state.userForm.password !== action.passwordConfirmation,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SIGN_UP_CONFIRM_USER_FORM:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentStep: 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SIGN_UP_CHANGE_TENANT_SITE_NAME:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
tenantForm: { ...state.tenantForm, siteName: action.siteName },
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SIGN_UP_CHANGE_TENANT_SUBDOMAIN:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
tenantForm: { ...state.tenantForm, subdomain: action.subdomain },
|
|
||||||
};
|
|
||||||
|
|
||||||
case TENANT_SUBMIT_START:
|
case TENANT_SUBMIT_START:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -125,7 +29,6 @@ const tenantSignUpReducer = (
|
|||||||
case TENANT_SUBMIT_SUCCESS:
|
case TENANT_SUBMIT_SUCCESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
currentStep: 3,
|
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
error: '',
|
error: '',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,11 +55,20 @@ en:
|
|||||||
step1:
|
step1:
|
||||||
title: '1. Create user account'
|
title: '1. Create user account'
|
||||||
email_auth: 'Register with email'
|
email_auth: 'Register with email'
|
||||||
|
validations:
|
||||||
|
full_name: 'Full name is required'
|
||||||
|
email: 'Email is invalid'
|
||||||
|
password: 'Password must have at least %{n} characters'
|
||||||
|
password_mismatch: 'Password and password confirmation must match'
|
||||||
step2:
|
step2:
|
||||||
title: '2. Create feedback space'
|
title: '2. Create feedback space'
|
||||||
site_name: 'Site name'
|
site_name: 'Site name'
|
||||||
subdomain: 'Subdomain'
|
subdomain: 'Subdomain'
|
||||||
create_button: 'Create feedback space'
|
create_button: 'Create feedback space'
|
||||||
|
validations:
|
||||||
|
site_name: 'Site name is required'
|
||||||
|
subdomain: 'Subdomain is required'
|
||||||
|
subdomain_already_taken: 'Sorry, this subdomain is not available'
|
||||||
step3:
|
step3:
|
||||||
title: "You're almost done!"
|
title: "You're almost done!"
|
||||||
message: "Check your email %{email} to activate your new feedback space %{subdomain}!"
|
message: "Check your email %{email} to activate your new feedback space %{subdomain}!"
|
||||||
@@ -141,6 +150,8 @@ en:
|
|||||||
brand_setting_logo: 'Logo only'
|
brand_setting_logo: 'Logo only'
|
||||||
brand_setting_none: 'None'
|
brand_setting_none: 'None'
|
||||||
locale: 'Language'
|
locale: 'Language'
|
||||||
|
validations:
|
||||||
|
site_name: 'Site name is required'
|
||||||
boards:
|
boards:
|
||||||
title: 'Boards'
|
title: 'Boards'
|
||||||
empty: 'There are no boards. Create one below!'
|
empty: 'There are no boards. Create one below!'
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ Rails.application.routes.draw do
|
|||||||
|
|
||||||
constraints subdomain: 'login' do
|
constraints subdomain: 'login' do
|
||||||
get '/signup', to: 'tenants#new'
|
get '/signup', to: 'tenants#new'
|
||||||
|
get '/is_available', to: 'tenants#is_available'
|
||||||
|
|
||||||
resource :tenants, only: [:create]
|
resource :tenants, only: [:create]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -21,15 +21,16 @@
|
|||||||
"react-beautiful-dnd": "^13.1.0",
|
"react-beautiful-dnd": "^13.1.0",
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.9.0",
|
||||||
"react-gravatar": "^2.6.3",
|
"react-gravatar": "^2.6.3",
|
||||||
|
"react-hook-form": "7.33.1",
|
||||||
"react-infinite-scroller": "^1.2.4",
|
"react-infinite-scroller": "^1.2.4",
|
||||||
"react-markdown": "^5.0.3",
|
"react-markdown": "^5.0.3",
|
||||||
"react-redux": "^7.1.1",
|
"react-redux": "^7.1.1",
|
||||||
"react_ujs": "^2.6.0",
|
"react_ujs": "^2.6.0",
|
||||||
"redux": "^4.0.4",
|
"redux": "^4.0.4",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"ts-loader": "^6.0.4",
|
"ts-loader": "8.1.0",
|
||||||
"turbolinks": "^5.2.0",
|
"turbolinks": "^5.2.0",
|
||||||
"typescript": "^3.5.3"
|
"typescript": "4.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react-redux": "^7.1.3",
|
"@types/react-redux": "^7.1.3",
|
||||||
|
|||||||
86
yarn.lock
86
yarn.lock
@@ -1192,6 +1192,13 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^1.9.0"
|
color-convert "^1.9.0"
|
||||||
|
|
||||||
|
ansi-styles@^4.1.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||||
|
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||||
|
dependencies:
|
||||||
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
anymatch@^2.0.0:
|
anymatch@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
|
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
|
||||||
@@ -1795,7 +1802,7 @@ caseless@~0.12.0:
|
|||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||||
|
|
||||||
chalk@2.4.2, chalk@^2.0, chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
|
chalk@2.4.2, chalk@^2.0, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||||
@@ -1815,6 +1822,14 @@ chalk@^1.1.1:
|
|||||||
strip-ansi "^3.0.0"
|
strip-ansi "^3.0.0"
|
||||||
supports-color "^2.0.0"
|
supports-color "^2.0.0"
|
||||||
|
|
||||||
|
chalk@^4.1.0:
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||||
|
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.1.0"
|
||||||
|
supports-color "^7.1.0"
|
||||||
|
|
||||||
character-entities-legacy@^1.0.0:
|
character-entities-legacy@^1.0.0:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
|
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
|
||||||
@@ -1941,12 +1956,19 @@ color-convert@^1.9.0, color-convert@^1.9.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-name "1.1.3"
|
color-name "1.1.3"
|
||||||
|
|
||||||
|
color-convert@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||||
|
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||||
|
dependencies:
|
||||||
|
color-name "~1.1.4"
|
||||||
|
|
||||||
color-name@1.1.3:
|
color-name@1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||||
|
|
||||||
color-name@^1.0.0:
|
color-name@^1.0.0, color-name@~1.1.4:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
@@ -2710,6 +2732,11 @@ emojis-list@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
||||||
integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
|
integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
|
||||||
|
|
||||||
|
emojis-list@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
|
||||||
|
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
|
||||||
|
|
||||||
encodeurl@~1.0.2:
|
encodeurl@~1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||||
@@ -3393,6 +3420,11 @@ has-flag@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||||
|
|
||||||
|
has-flag@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||||
|
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||||
|
|
||||||
has-symbols@^1.0.0, has-symbols@^1.0.1:
|
has-symbols@^1.0.0, has-symbols@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
|
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
|
||||||
@@ -4206,6 +4238,11 @@ json5@^2.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
|
|
||||||
|
json5@^2.1.2:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
|
||||||
|
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
|
||||||
|
|
||||||
jsprim@^1.2.2:
|
jsprim@^1.2.2:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||||
@@ -4290,6 +4327,15 @@ loader-utils@1.2.3, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.
|
|||||||
emojis-list "^2.0.0"
|
emojis-list "^2.0.0"
|
||||||
json5 "^1.0.1"
|
json5 "^1.0.1"
|
||||||
|
|
||||||
|
loader-utils@^2.0.0:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
|
||||||
|
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
|
||||||
|
dependencies:
|
||||||
|
big.js "^5.2.2"
|
||||||
|
emojis-list "^3.0.0"
|
||||||
|
json5 "^2.1.2"
|
||||||
|
|
||||||
locate-path@^3.0.0:
|
locate-path@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
|
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
|
||||||
@@ -6337,6 +6383,11 @@ react-gravatar@^2.6.3:
|
|||||||
md5 "^2.1.0"
|
md5 "^2.1.0"
|
||||||
query-string "^4.2.2"
|
query-string "^4.2.2"
|
||||||
|
|
||||||
|
react-hook-form@7.33.1:
|
||||||
|
version "7.33.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.33.1.tgz#8c4410e3420788d3b804d62cc4c142915c2e46d0"
|
||||||
|
integrity sha512-ydTfTxEJdvgjCZBj5DDXRc58oTEfnFupEwwTAQ9FSKzykEJkX+3CiAkGtAMiZG7IPWHuzgT6AOBfogiKhUvKgg==
|
||||||
|
|
||||||
react-infinite-scroller@^1.2.4:
|
react-infinite-scroller@^1.2.4:
|
||||||
version "1.2.4"
|
version "1.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-infinite-scroller/-/react-infinite-scroller-1.2.4.tgz#f67eaec4940a4ce6417bebdd6e3433bfc38826e9"
|
resolved "https://registry.yarnpkg.com/react-infinite-scroller/-/react-infinite-scroller-1.2.4.tgz#f67eaec4940a4ce6417bebdd6e3433bfc38826e9"
|
||||||
@@ -6853,7 +6904,7 @@ semver@^6.0.0, semver@^6.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||||
|
|
||||||
semver@^7.3.5:
|
semver@^7.3.4, semver@^7.3.5:
|
||||||
version "7.3.7"
|
version "7.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
||||||
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
|
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
|
||||||
@@ -7389,6 +7440,13 @@ supports-color@^5.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^3.0.0"
|
has-flag "^3.0.0"
|
||||||
|
|
||||||
|
supports-color@^7.1.0:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||||
|
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||||
|
dependencies:
|
||||||
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
svgo@^1.0.0:
|
svgo@^1.0.0:
|
||||||
version "1.3.2"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167"
|
resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167"
|
||||||
@@ -7579,16 +7637,16 @@ trough@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.1.2"
|
glob "^7.1.2"
|
||||||
|
|
||||||
ts-loader@^6.0.4:
|
ts-loader@8.1.0:
|
||||||
version "6.2.1"
|
version "8.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.1.tgz#67939d5772e8a8c6bdaf6277ca023a4812da02ef"
|
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.1.0.tgz#d6292487df279c7cc79b6d3b70bb9d31682b693e"
|
||||||
integrity sha512-Dd9FekWuABGgjE1g0TlQJ+4dFUfYGbYcs52/HQObE0ZmUNjQlmLAS7xXsSzy23AMaMwipsx5sNHvoEpT2CZq1g==
|
integrity sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk "^2.3.0"
|
chalk "^4.1.0"
|
||||||
enhanced-resolve "^4.0.0"
|
enhanced-resolve "^4.0.0"
|
||||||
loader-utils "^1.0.2"
|
loader-utils "^2.0.0"
|
||||||
micromatch "^4.0.0"
|
micromatch "^4.0.0"
|
||||||
semver "^6.0.0"
|
semver "^7.3.4"
|
||||||
|
|
||||||
ts-pnp@^1.1.2:
|
ts-pnp@^1.1.2:
|
||||||
version "1.1.5"
|
version "1.1.5"
|
||||||
@@ -7635,10 +7693,10 @@ typedarray@^0.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
typescript@^3.5.3:
|
typescript@4.3.2:
|
||||||
version "3.7.3"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.3.tgz#b36840668a16458a7025b9eabfad11b66ab85c69"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805"
|
||||||
integrity sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==
|
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==
|
||||||
|
|
||||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
|
|||||||
Reference in New Issue
Block a user