Skip to content

Commit

Permalink
feat(onboarding-ui): Remove standalone and introduce offline server r…
Browse files Browse the repository at this point in the history
…egistration (#1184)
  • Loading branch information
tiagoevanp authored Oct 4, 2023
1 parent 3386202 commit 695d42a
Show file tree
Hide file tree
Showing 24 changed files with 437 additions and 233 deletions.
5 changes: 5 additions & 0 deletions .changeset/popular-adults-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/onboarding-ui": patch
---

feat(onboarding-ui): Remove standalone and introduce offline server registration
27 changes: 19 additions & 8 deletions packages/onboarding-ui/.i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
"back": "Back",
"next": "Next",
"skip": "Skip this step",
"registerWorkspace": "Register workspace",
"register": "Register",
"registerNow": "Register now",
"confirm": "Confirm"
"registerOffline": "Register offline",
"confirm": "Confirm",
"pasteHere": "Paste here...",
"completeRegistration": "Complete registration"
},
"termsAndConditions": "I agree with <1>Terms and Conditions</1> and <3>Privacy Policy</3>"
},
Expand Down Expand Up @@ -184,12 +187,6 @@
"notConnectedToInternet": "The server is not connected to the internet, so you’ll have to do an offline registration for this workspace.",
"registrationEngagement": "Registration allows automatic license updates, notifications of critical vulnerabilities and access to Rocket.Chat Cloud services. No sensitive workspace data is shared; statistics sent to Rocket.Chat are made visible to you within the administration area."
},
"standaloneServerForm": {
"title": "Standalone Server Confirmation",
"servicesUnavailable": "Some of the services will be unavailable or will require manual setup",
"publishOwnApp": "In order to send push notitications you need to compile and publish your own app to Google Play and App Store",
"manuallyIntegrate": "Need to manually integrate with external services"
},
"createCloudWorkspace": {
"title": "New Cloud Workspace",
"fields": {
Expand All @@ -216,6 +213,20 @@
"keepMeInformed": "Keep me informed about news and events"
}
},
"registerOfflineForm": {
"title": "Register Offline",
"copyStep": {
"description": "If for any reason your workspace can’t be connected to the internet, follow these steps:<1></1>1. Go to: <2>cloud.rocket.chat > Workspaces</2> and click “<3>Register self-managed</3>”<4></4>2. Click “<5>Continue offline</5>”<6></6>3. In the <7>Register offline workspace</7> dialog in cloud.rocket.chat, paste the token in the box below"
},
"pasteStep": {
"description": "1. In <1>cloud.rocket.chat</1> get the generated text and paste below to complete your registration process"
},
"fields": {
"registrationToken": {
"inputLabel": "Registration token"
}
}
},
"requestTrialForm": {
"fields": {
"emailAddress": {
Expand Down
41 changes: 29 additions & 12 deletions packages/onboarding-ui/src/flows/SelfHostedRegistration/stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { useState } from 'react';

import type { AdminInfoPayload } from '../../forms/AdminInfoForm/AdminInfoForm';
import type { OrganizationInfoPayload } from '../../forms/OrganizationInfoForm/OrganizationInfoForm';
import type { RegisterOfflinePayload } from '../../forms/RegisterOfflineForm/RegisterOfflineForm';
import type { RegisterServerPayload } from '../../forms/RegisterServerForm/RegisterServerForm';
import AdminInfoPage from '../../pages/AdminInfoPage';
import AwaitingConfirmationPage from '../../pages/AwaitingConfirmationPage';
import ConfirmationProcessPage from '../../pages/ConfirmationProcessPage';
import EmailConfirmedPage from '../../pages/EmailConfirmedPage';
import OrganizationInfoPage from '../../pages/OrganizationInfoPage';
import RegisterOfflinePage from '../../pages/RegisterOfflinePage';
import RegisteredServerPage from '../../pages/RegisterServerPage';
import StandaloneServerPage from '../../pages/StandaloneServerPage';
import {
countryOptions,
logSubmit,
Expand All @@ -36,7 +37,7 @@ export const SelfHostedRegistration: Story = ({ offline }) => {
| 'admin-info'
| 'org-info'
| 'register-server'
| 'standalone-confirmation'
| 'register-offline'
| 'cloud-email'
| 'awaiting'
| 'home'
Expand All @@ -57,6 +58,11 @@ export const SelfHostedRegistration: Story = ({ offline }) => {
securityCode?: string;
}>();

const [offlineRegistration, setOfflineRegistration] = useState<{
agreement?: boolean;
token?: string;
}>();

const handleAdminInfoSubmit = logSubmit((data: AdminInfoPayload) => {
setAdminInfo(data);
navigateTo('/org-info');
Expand All @@ -82,6 +88,17 @@ export const SelfHostedRegistration: Story = ({ offline }) => {
}
);

const handleRegisterOfflineSubmit = logSubmit(
(data: RegisterOfflinePayload) => {
setOfflineRegistration((offlineRegistration) => ({
...offlineRegistration,
agreement: data.agreement,
token: data.token,
}));
navigateTo('/awaiting');
}
);

if (path === '/admin-info') {
return (
<AdminInfoPage
Expand Down Expand Up @@ -126,30 +143,30 @@ export const SelfHostedRegistration: Story = ({ offline }) => {
}),
}}
onSubmit={handleRegisterServerSubmit}
onClickRegisterOffline={() => navigateTo('/register-offline')}
offline={offline}
onClickRegisterLater={() => navigateTo('/standalone-confirmation')}
/>
);
}

if (path === '/standalone-confirmation') {
if (path === '/register-offline') {
return (
<StandaloneServerPage
currentStep={4}
stepCount={4}
initialValues={{}}
<RegisterOfflinePage
termsHref=''
policyHref=''
clientKey=''
onBackButtonClick={() => navigateTo('/register-server')}
onSubmit={() => navigateTo('/home')}
onSubmit={handleRegisterOfflineSubmit}
/>
);
}

if (path === '/awaiting') {
if (!serverRegistration?.cloudAccountEmail) {
throw new Error('missing cloud account email');
if (!serverRegistration?.cloudAccountEmail || !offlineRegistration?.token) {
throw new Error('missing cloud account email or token');
}

if (!serverRegistration?.securityCode) {
if (!serverRegistration?.securityCode || !offlineRegistration?.token) {
throw new Error('missing verification code');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import ReactDOM from 'react-dom';

import StandaloneServerPage from './StandaloneServerPage';
import RegisterOfflineForm from './RegisterOfflineForm';

it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(
<StandaloneServerPage
currentStep={1}
stepCount={1}
onSubmit={() => undefined}
<RegisterOfflineForm
termsHref=''
policyHref=''
clientKey=''
onBackButtonClick={() => undefined}
onSubmit={() => undefined}
/>,
div
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Meta, Story } from '@storybook/react';
import type { ComponentProps } from 'react';

import RegisterOfflineForm from './RegisterOfflineForm';

type Args = ComponentProps<typeof RegisterOfflineForm>;

export default {
title: 'forms/RegisterOfflineForm',
component: RegisterOfflineForm,
parameters: {
layout: 'centered',
actions: { argTypesRegex: '^on.*' },
},
args: {
clientKey:
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
},
} as Meta<Args>;

export const _RegisterOfflineForm: Story<Args> = (args) => (
<RegisterOfflineForm {...args} />
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Form } from '@rocket.chat/layout';
import { useState, type ReactElement } from 'react';
import type { SubmitHandler } from 'react-hook-form';
import { useForm, FormProvider } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

import CopyStep from './steps/CopyStep';
import PasteStep from './steps/PasteStep';

export type RegisterOfflinePayload = {
token: string;
agreement: boolean;
};

type RegisterOfflineFormProps = {
termsHref: string;
policyHref: string;
clientKey: string;
onSubmit: SubmitHandler<RegisterOfflinePayload>;
onBackButtonClick: () => void;
};

export const Steps = {
COPY: 'copy',
PASTE: 'paste',
};

const RegisterOfflineForm = ({
termsHref,
policyHref,
clientKey,
onSubmit,
onBackButtonClick,
}: RegisterOfflineFormProps): ReactElement => {
const { t } = useTranslation();

const [step, setStep] = useState(Steps.COPY);

const form = useForm<RegisterOfflinePayload>({
mode: 'onChange',
defaultValues: {
token: '',
agreement: false,
},
});

const { handleSubmit } = form;

return (
<FormProvider {...form}>
<Form onSubmit={handleSubmit(onSubmit)}>
<Form.Header>
<Form.Title>{t('form.registerOfflineForm.title')}</Form.Title>
</Form.Header>
{step === Steps.COPY ? (
<CopyStep
termsHref={termsHref}
policyHref={policyHref}
clientKey={clientKey}
setStep={setStep}
onBackButtonClick={onBackButtonClick}
/>
) : (
<PasteStep setStep={setStep} />
)}
</Form>
</FormProvider>
);
};

export default RegisterOfflineForm;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './RegisterOfflineForm';
Loading

0 comments on commit 695d42a

Please sign in to comment.