diff --git a/.eslintrc b/.eslintrc
index 74f9766d204..b78b5466277 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -7,5 +7,18 @@
"Assets" : false,
"chrome" : false,
"jscolor" : false
- }
+ },
+ "plugins": ["react"],
+ "rules": {
+ "jsx-quotes": ["error", "prefer-single"],
+ "react/jsx-uses-react": "error",
+ "react/jsx-uses-vars": "error",
+ "react/jsx-no-undef": "error",
+ "react/jsx-fragments": ["error", "syntax"],
+ },
+ "settings": {
+ "react": {
+ "version": "detect",
+ },
+ },
}
diff --git a/app/setup-wizard/client/final.html b/app/setup-wizard/client/final.html
deleted file mode 100644
index 27480e459bc..00000000000
--- a/app/setup-wizard/client/final.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
- {{_ "Your_workspace_is_ready"}}
- {{_ "Your_server_link"}}
- {{siteUrl}}
-
-
-
-
-
diff --git a/app/setup-wizard/client/index.js b/app/setup-wizard/client/index.js
deleted file mode 100644
index 2b99b89e3ed..00000000000
--- a/app/setup-wizard/client/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import './setupWizard.html';
-import './setupWizard';
-import './final.html';
-import './final';
diff --git a/app/setup-wizard/client/setupWizard.html b/app/setup-wizard/client/setupWizard.html
deleted file mode 100644
index 9c77129d45e..00000000000
--- a/app/setup-wizard/client/setupWizard.html
+++ /dev/null
@@ -1,214 +0,0 @@
-
-
- {{> status}}
-
-
- {{> setupWizardInfo infoArgs}}
-
-
-
-
-
-
-
-
-
-
{{_ "Setup_Wizard"}}
-
{{_ "Setup_Wizard_Info"}}
-
- - {{_ (stepTitle 1)}}
- - {{_ (stepTitle 2)}}
- - {{_ (stepTitle 3)}}
- - {{_ (stepTitle 4)}}
-
-
-
-
-
-
-
-
-
-
-
-
{{_ "Register_Server_Info"}}
-
-
-
-
-
-
- {{#each settings}}
- {{#if $eq type 'string'}}
-
- {{/if}}
-
- {{#if $eq type 'select'}}
-
- {{/if}}
-
- {{#if $eq type 'language'}}
-
- {{/if}}
- {{/each}}
-
-
diff --git a/app/setup-wizard/server/index.js b/app/setup-wizard/server/index.js
deleted file mode 100644
index 43e790a126b..00000000000
--- a/app/setup-wizard/server/index.js
+++ /dev/null
@@ -1 +0,0 @@
-import './getSetupWizardParameters';
diff --git a/app/theme/client/imports/components/setup-wizard.css b/app/theme/client/imports/components/setup-wizard.css
deleted file mode 100644
index 7ab2448c63d..00000000000
--- a/app/theme/client/imports/components/setup-wizard.css
+++ /dev/null
@@ -1,574 +0,0 @@
-.setup-wizard {
- --step-color: var(--rc-color-button-primary);
- --highlight-color: var(--rc-color-button-primary);
-
- display: flex;
-
- width: 100%;
- height: 100%;
-
- background-color: #f7f8fa;
-
- justify-content: center;
-
- &-info {
-
- overflow: hidden;
- flex: 0 1 350px;
-
- margin: 55px 65px 30px 80px;
-
- &__header {
- display: flex;
-
- margin: 0 -0.375rem 3rem;
- align-items: center;
-
- &-logo {
- height: 1.5rem;
- margin: 0 0.375rem;
- }
-
- &-tag {
- margin: 0 0.375rem;
-
- padding: 4px 8px;
-
- letter-spacing: 0.05rem;
-
- text-transform: uppercase;
-
- color: #ffffff;
-
- border-radius: 50px;
- background: #2f343d;
-
- font-size: 10px;
-
- line-height: 1rem;
- }
- }
-
- &__content {
- &-title {
- margin-bottom: 1rem;
-
- letter-spacing: 0.03rem;
-
- color: #2f343d;
-
- font-size: 2rem;
-
- font-weight: 600;
-
- line-height: 2.6rem;
- }
-
- &-text {
- margin-bottom: 3rem;
-
- color: #9ea2a8;
-
- font-size: 1rem;
-
- font-weight: 500;
-
- line-height: 1.5rem;
- }
- }
-
- &__steps {
- counter-reset: steps;
-
- &-item {
- position: relative;
-
- margin: 0 -0.5rem;
-
- counter-increment: steps;
-
- color: #d3d5d9;
-
- font-size: 0.875rem;
- font-weight: 500;
-
- &:not(:last-child) {
- margin-bottom: 2rem;
-
- &::after {
- position: absolute;
- bottom: -1rem;
- left: 1.2rem;
-
- display: block;
-
- width: 1px;
- height: 1rem;
-
- content: "";
-
- background-color: #d3d5d9;
- }
- }
-
- &::before {
- display: inline-flex;
-
- width: 1.5rem;
- height: 1.5rem;
- margin: 0 0.5rem;
-
- content: counter(steps);
-
- color: #d3d5d9;
-
- border: 1px solid #d3d5d9;
- border-radius: 50px;
-
- font-size: 0.75rem;
- align-items: center;
- justify-content: center;
- }
-
- &--active {
- color: var(--rc-color-button-primary);
-
- &::before {
- color: var(--rc-color-button-primary);
- border-color: var(--rc-color-button-primary);
- background-color: transparent;
- }
- }
-
- &--past {
- color: var(--rc-color-primary);
-
- &::before {
- color: var(--rc-color-content);
- border-color: var(--rc-color-button-primary);
- background-color: var(--rc-color-button-primary);
- }
-
- &::after {
- background-color: var(--rc-color-button-primary) !important;
- }
-
- & .setup-wizard-info__steps-item-bonding {
- background-color: var(--rc-color-button-primary);
- }
- }
-
- &-bonding {
- position: absolute;
- top: -1rem;
- left: 1.2rem;
-
- display: block;
-
- width: 1px;
- height: 1rem;
-
- background-color: currentColor;
- }
- }
- }
- }
-
- &-forms {
- flex: 1 1 auto;
-
- &__wrapper {
- display: flex;
- overflow-y: auto;
-
- width: calc(100% - 1rem);
- height: calc(100% - 2rem);
- margin: 1rem 1rem 1rem 0;
-
- border-radius: 2px;
- background: #ffffff;
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
- justify-content: center;
- }
-
- &__box {
- display: flex;
-
- visibility: hidden;
- flex-direction: column;
-
- width: 350px;
- min-height: min-content;
- margin: 3rem;
-
- transition: opacity 1s linear;
-
- opacity: 0;
-
- &--loaded {
- visibility: visible;
-
- opacity: 1;
- }
- }
-
- &__header {
- margin-bottom: 2rem;
-
- &-step {
- display: block;
-
- margin-bottom: 3px;
-
- letter-spacing: 0.05rem;
-
- text-transform: uppercase;
-
- color: #caced1;
-
- font-size: 0.75rem;
-
- line-height: 1.125rem;
- }
-
- &-title {
- letter-spacing: 0.05rem;
-
- color: #1f2329;
-
- font-size: 1.25rem;
- font-weight: 500;
-
- line-height: 1.75rem;
- }
- }
-
- &__content {
- margin-bottom: 2rem;
-
- &-step {
- display: none;
-
- &--active {
- display: block;
- }
- }
-
- &-text {
-
- margin-bottom: 2rem;
-
- color: #9ea2a8;
-
- font-size: 1rem;
- font-weight: 500;
-
- line-height: 1.5rem;
- }
-
- &-register {
- display: flex;
- flex-direction: column;
-
- &-option {
-
- display: block;
-
- padding: 1.5rem;
-
- cursor: pointer;
-
- color: #2f343d;
- border: 2px solid #e7ebf2;
-
- border-radius: 2px;
-
- font-size: 0.875rem;
-
- line-height: 1.25rem;
-
- &--selected {
- border-color: var(--highlight-color);
- }
-
- &--disabled {
- opacity: 0.25;
- }
-
- &:first-child {
- margin-bottom: 1rem;
- }
- }
-
- &-radio {
- position: relative;
-
- display: flex;
-
- margin: 0 -0.5rem 1rem;
-
- &-element {
- position: absolute;
- z-index: -1;
- top: 0;
- left: 0;
-
- width: 0;
- height: 0;
-
- &:checked + .setup-wizard-forms__content-register-radio-fake {
-
- position: relative;
-
- border-color: var(--highlight-color);
-
- &::before {
-
- position: absolute;
-
- width: 100%;
- height: 100%;
-
- content: "";
-
- border: 2px solid transparent;
- border-radius: 50%;
-
- background-color: var(--highlight-color);
-
- background-clip: padding-box;
- }
- }
- }
-
- &-fake {
- display: block;
-
- width: 20px;
- height: 20px;
- margin: 0 0.5rem;
-
- border: 2px solid #cfd8e6;
- border-radius: 50px;
- }
-
- &-text {
- font-weight: 500;
- }
- }
-
- &-checkbox {
- position: relative;
-
- display: flex;
-
- margin: 0 -0.5rem 1rem;
-
- cursor: inherit;
-
- &-element {
- position: absolute;
- z-index: -1;
- top: 0;
- left: 0;
-
- width: 0;
- height: 0;
-
- &:checked + .setup-wizard-forms__content-register-checkbox-fake {
- position: relative;
-
- color: var(--rc-color-content);
-
- border-color: var(--highlight-color);
- background-color: var(--highlight-color);
-
- .setup-wizard-forms__content-register-checkbox-fake-icon {
- display: block;
- }
- }
- }
-
- &-fake {
- display: block;
-
- width: 16px;
- height: 16px;
- margin: 2px 0.5rem;
-
- border: 2px solid #cfd8e6;
- border-radius: 2px;
-
- &-icon {
-
- display: none;
-
- width: 100%;
- height: 100%;
- }
- }
-
- &-text {
- color: #666666;
- }
- }
-
- &-items + * {
- margin-top: 1rem;
- }
-
- &-item {
-
- display: flex;
-
- margin: 0 -0.5rem 0.5rem;
- align-items: center;
-
- &:last-child {
- margin-bottom: 0;
- }
-
- & .setup-wizard-forms__content-register-radio-icon {
- width: 20px;
- min-width: 20px;
- height: 20px;
- margin: 0 0.5rem;
- align-self: baseline;
-
- &--check {
- color: var(--highlight-color);
- }
-
- &--circle {
- height: 6px;
- margin: 7px 0.5rem;
- }
- }
- }
- }
- }
-
- &__footer {
- display: flex;
- flex-direction: row;
-
- margin: 0 -0.5rem 2rem;
-
- & .rc-button {
- margin: 0 0.5rem;
- }
- }
- }
-
- &-final {
- width: 930px;
- padding-top: 5rem;
-
- &__header {
- margin-bottom: 5rem;
- }
-
- &__box {
- padding: 5rem 6rem;
-
- border-radius: 2px;
- background: #ffffff;
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
-
- &-title {
- margin-bottom: 3.25rem;
- }
- }
-
- &__link {
- display: block;
-
- margin-bottom: 1.5rem;
-
- letter-spacing: 0;
-
- color: var(--highlight-color);
-
- font-size: 1rem;
-
- line-height: 1.5rem;
-
- &-text {
- display: block;
-
- letter-spacing: 0.03rem;
-
- text-transform: uppercase;
-
- color: #2f343d;
-
- font-size: 0.625rem;
- line-height: 1rem;
- }
- }
- }
-
- & .rc-input {
- &:not(:last-child) {
- margin-bottom: 1.5rem;
- }
-
- &__title {
- letter-spacing: 0.03rem;
-
- text-transform: uppercase;
-
- color: #9ea2a8;
-
- font-size: 0.625rem;
-
- line-height: 1rem;
- }
-
- &__element {
- color: #030c1a;
-
- font-weight: 500;
- }
- }
-
- & .rc-select {
- &__element {
- color: #030c1a;
-
- font-size: 0.875rem;
-
- font-weight: 500;
- }
- }
-}
-
-.rtl {
- & .setup-wizard-info {
- margin: 55px 80px 0 65px;
- }
-
- & .setup-wizard-forms__wrapper {
- margin: 1rem 0 1rem 1rem;
- }
-
- & .setup-wizard-info__steps-item {
- &:not(:last-child)::after,
- &-bonding {
- right: 1.2rem;
- left: auto;
- }
- }
-}
-
-@media (width <= 760px) {
- .setup-wizard {
- flex-direction: column;
- justify-content: initial;
-
- & .setup-wizard-forms__wrapper {
- width: 100%;
- margin: 0;
- }
- }
-}
diff --git a/app/theme/client/main.css b/app/theme/client/main.css
index d1b828f16b1..d768ec57c47 100644
--- a/app/theme/client/main.css
+++ b/app/theme/client/main.css
@@ -29,7 +29,6 @@
@import 'imports/components/sidebar/rooms-list.css';
/* Main */
-@import 'imports/components/setup-wizard.css';
@import 'imports/components/flex-nav.css';
@import 'imports/components/header.css';
@import 'imports/components/memberlist.css';
diff --git a/app/ui/client/index.js b/app/ui/client/index.js
index 3a134daf54c..80197cff270 100644
--- a/app/ui/client/index.js
+++ b/app/ui/client/index.js
@@ -8,7 +8,6 @@ import './lib/parentTemplate';
import './lib/codeMirror/codeMirror';
import './lib/textarea-cursor';
import './views/cmsPage.html';
-import './views/fxos.html';
import './views/modal.html';
import './views/404/roomNotFound.html';
import './views/404/invalidSecretURL.html';
@@ -30,7 +29,6 @@ import './views/app/videoCall/videoButtons.html';
import './views/app/videoCall/videoCall.html';
import './views/app/photoswipe.html';
import './views/cmsPage';
-import './views/fxos';
import './views/modal';
import './views/404/roomNotFound';
import './views/app/burger';
diff --git a/app/ui/client/views/fxos.html b/app/ui/client/views/fxos.html
deleted file mode 100644
index 3bdbcbf5502..00000000000
--- a/app/ui/client/views/fxos.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
{{_ "Install_FxOs"}}
-
{{_ "Install_FxOs_follow_instructions"}}
-
-
-
-
-
-
-
-
-
-
-
{{_ "Install_FxOs"}}
-
{{_ "Install_FxOs_done"}}
-
-
-
-
-
-
-
-
-
-
-
{{_ "Install_FxOs"}}
-
{{_ "Install_FxOs_error"}}
-
{{installError}}
-
-
-
-
diff --git a/app/ui/client/views/fxos.js b/app/ui/client/views/fxos.js
deleted file mode 100644
index 72847ba83a5..00000000000
--- a/app/ui/client/views/fxos.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { BlazeLayout } from 'meteor/kadira:blaze-layout';
-import { Template } from 'meteor/templating';
-
-Template.fxOsInstallPrompt.onRendered(function() {
- const showPrompt = function() {
- const request = window.navigator.mozApps.install(`http://${ location.host }/manifest.webapp`);
- request.onsuccess = function() {
- BlazeLayout.render('fxOsInstallDone');
- };
- request.onerror = function() {
- BlazeLayout.render('fxOsInstallError', {
- installError: this.error.name,
- });
- };
- };
- setTimeout(showPrompt, 2000);
- return $('#initial-page-loading').remove();
-});
-
-Template.fxOsInstallDone.onRendered(() => $('#initial-page-loading').remove());
-Template.fxOsInstallError.onRendered(() => $('#initial-page-loading').remove());
diff --git a/client/RocketChat.font.css b/client/RocketChat.font.css
new file mode 100644
index 00000000000..7b9074ad89b
--- /dev/null
+++ b/client/RocketChat.font.css
@@ -0,0 +1,14 @@
+@font-face {
+ font-family: 'RocketChat';
+ font-weight: 400;
+ font-style: normal;
+ font-display: auto;
+
+ src: url('/fonts/RocketChat.eot');
+ src:
+ url('/fonts/RocketChat.eot?#iefix') format('embedded-opentype'),
+ url('/fonts/RocketChat.woff2') format('woff2'),
+ url('/fonts/RocketChat.woff') format('woff'),
+ url('/fonts/RocketChat.ttf') format('truetype'),
+ url('/fonts/RocketChat.svg#RocketChat') format('svg');
+}
diff --git a/client/components/basic/Button.js b/client/components/basic/Button.js
new file mode 100644
index 00000000000..60cd9708a2e
--- /dev/null
+++ b/client/components/basic/Button.js
@@ -0,0 +1,23 @@
+import React from 'react';
+
+export const Button = ({
+ children,
+ className,
+ invisible,
+ primary,
+ secondary,
+ submit,
+ ...props
+}) => ;
diff --git a/client/components/basic/Icon.js b/client/components/basic/Icon.js
new file mode 100644
index 00000000000..2fc4eb3322c
--- /dev/null
+++ b/client/components/basic/Icon.js
@@ -0,0 +1,13 @@
+import React from 'react';
+
+export const Icon = ({ icon, block = '', baseUrl = '', className }) => ;
diff --git a/client/components/basic/Input.js b/client/components/basic/Input.js
new file mode 100644
index 00000000000..18136a344c2
--- /dev/null
+++ b/client/components/basic/Input.js
@@ -0,0 +1,67 @@
+import React, { useEffect, useRef } from 'react';
+
+import { Icon } from './Icon';
+
+export const Input = ({
+ error,
+ title,
+ icon,
+ type = 'text',
+ className,
+ placeholder,
+ options,
+ focused,
+ ...props
+}) => {
+ const ref = useRef(null);
+
+ useEffect(() => {
+ if (focused && ref.current) {
+ ref.current.focus();
+ }
+ }, [focused]);
+
+ return
+
+
;
+};
diff --git a/client/components/connectionStatus/ConnectionStatusAlert.css b/client/components/connectionStatus/ConnectionStatusAlert.css
new file mode 100644
index 00000000000..1d6931541a2
--- /dev/null
+++ b/client/components/connectionStatus/ConnectionStatusAlert.css
@@ -0,0 +1,19 @@
+.ConnectionStatusAlert {
+
+ position: fixed;
+ z-index: 1000000;
+ top: 0;
+
+ width: 100%;
+ padding: 2px;
+
+ text-align: center;
+
+ color: #916302;
+ border-bottom-width: 1px;
+ background-color: #fffdf9;
+}
+
+.ConnectionStatusAlert__link {
+ color: var(--color-blue);
+}
diff --git a/client/components/connectionStatus/ConnectionStatusAlert.js b/client/components/connectionStatus/ConnectionStatusAlert.js
new file mode 100644
index 00000000000..387ec9bc355
--- /dev/null
+++ b/client/components/connectionStatus/ConnectionStatusAlert.js
@@ -0,0 +1,69 @@
+import { Meteor } from 'meteor/meteor';
+import React, { useEffect, useRef, useState } from 'react';
+
+import { useReactiveValue } from '../../hooks/useReactiveValue';
+import { useTranslation } from '../../hooks/useTranslation';
+import { Icon } from '../basic/Icon';
+
+export function ConnectionStatusAlert() {
+ const {
+ connected,
+ retryTime,
+ status,
+ } = useReactiveValue(() => ({ ...Meteor.status() }));
+ const reconnectionTimerRef = useRef();
+ const [reconnectCountdown, setReconnectCountdown] = useState(0);
+ const t = useTranslation();
+
+ useEffect(() => {
+ if (status === 'waiting') {
+ if (reconnectionTimerRef.current) {
+ return;
+ }
+
+ reconnectionTimerRef.current = setInterval(() => {
+ const timeDiff = retryTime - Date.now();
+ setReconnectCountdown((timeDiff > 0 && Math.round(timeDiff / 1000)) || 0);
+ }, 500);
+ return;
+ }
+
+ clearInterval(reconnectionTimerRef.current);
+ reconnectionTimerRef.current = null;
+ }, [retryTime, status]);
+
+ useEffect(() => () => {
+ clearInterval(reconnectionTimerRef.current);
+ }, []);
+
+ if (connected) {
+ return null;
+ }
+
+ const handleRetryClick = (event) => {
+ event.preventDefault();
+ Meteor.reconnect();
+ };
+
+ return
+
+ {t('meteor_status', { context: status })}
+
+
+ {status === 'waiting' && <>
+ {' '}
+ {t('meteor_status_reconnect_in', { count: reconnectCountdown })}
+ >}
+
+ {['waiting', 'offline'].includes(status) && <>
+ {' '}
+
+ {t('meteor_status_try_now', { context: status })}
+
+ >}
+
;
+}
diff --git a/client/components/pageNotFound/PageNotFound.css b/client/components/pageNotFound/PageNotFound.css
new file mode 100644
index 00000000000..416b7523afb
--- /dev/null
+++ b/client/components/pageNotFound/PageNotFound.css
@@ -0,0 +1,44 @@
+.PageNotFound {
+ width: 100%;
+ min-height: 100vh;
+ padding: 10%;
+
+ text-align: center;
+
+ color: white;
+ background-color: var(--rc-color-primary);
+ background-image: url('/images/404.svg');
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: cover;
+}
+
+.PageNotFound__404 {
+ display: block;
+
+ padding: 10px;
+
+ font-size: 4em;
+ font-weight: bold;
+}
+
+.PageNotFound__message {
+ display: block;
+
+ padding: 10px;
+
+ font-size: 2em;
+ font-weight: bold;
+}
+
+.PageNotFound__description {
+ display: block;
+
+ padding: 10px;
+
+ font-size: 1em;
+}
+
+.PageNotFound__actions {
+ margin: 2rem;
+}
diff --git a/client/components/pageNotFound/PageNotFound.js b/client/components/pageNotFound/PageNotFound.js
new file mode 100644
index 00000000000..54e6237224f
--- /dev/null
+++ b/client/components/pageNotFound/PageNotFound.js
@@ -0,0 +1,37 @@
+import { Button, ButtonGroup } from '@rocket.chat/fuselage';
+import { FlowRouter } from 'meteor/kadira:flow-router';
+import React from 'react';
+
+import { useTranslation } from '../../hooks/useTranslation';
+import { useWipeInitialPageLoading } from '../../hooks/useWipeInitialPageLoading';
+import { ConnectionStatusAlert } from '../connectionStatus/ConnectionStatusAlert';
+
+export function PageNotFound() {
+ useWipeInitialPageLoading();
+
+ const t = useTranslation();
+
+ const handleGoToPreviousPageClick = () => {
+ window.history.back();
+ };
+
+ const handleGoHomeClick = () => {
+ FlowRouter.go('home');
+ };
+
+ return <>
+
+
+ 404
+ {t('Oops_page_not_found')}
+ {t('Sorry_page_you_requested_does_not_exists_or_was_deleted')}
+
+
+
+
+
+
+
+
+ >;
+}
diff --git a/client/components/setupWizard/Epilogue.css b/client/components/setupWizard/Epilogue.css
new file mode 100644
index 00000000000..32853de008b
--- /dev/null
+++ b/client/components/setupWizard/Epilogue.css
@@ -0,0 +1,81 @@
+.SetupWizard__Epilogue {
+ width: 930px;
+ padding-top: 5rem;
+}
+
+.SetupWizard__Epilogue-header {
+ display: flex;
+
+ margin: 0 -0.375rem 5rem;
+ align-items: center;
+}
+
+.SetupWizard__Epilogue-headerLogo {
+ height: 1.5rem;
+ margin: 0 0.375rem;
+}
+
+.SetupWizard__Epilogue-content {
+ padding: 5rem 6rem;
+
+ border-radius: 2px;
+ background: #ffffff;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+}
+
+.SetupWizard__Epilogue-runningHead {
+ display: block;
+
+ margin-bottom: 3px;
+
+ letter-spacing: 0.05rem;
+
+ text-transform: uppercase;
+
+ color: #caced1;
+
+ font-size: 0.75rem;
+
+ line-height: 1.125rem;
+}
+
+.SetupWizard__Epilogue-title {
+ margin-bottom: 3.25rem;
+
+ letter-spacing: 0.03rem;
+
+ color: #2f343d;
+
+ font-size: 2rem;
+
+ font-weight: 600;
+
+ line-height: 2.6rem;
+}
+
+.SetupWizard__Epilogue-link {
+ display: block;
+
+ margin-bottom: 1.5rem;
+
+ letter-spacing: 0;
+
+ color: var(--rc-color-button-primary);
+
+ font-size: 1rem;
+
+ line-height: 1.5rem;
+}
+
+.SetupWizard__Epilogue-linkLabel {
+ display: block;
+
+ letter-spacing: 0.03rem;
+
+ text-transform: uppercase;
+
+ color: var(--color-dark);
+
+ font-size: 0.625rem;
+ line-height: 1rem;
+}
diff --git a/client/components/setupWizard/Epilogue.js b/client/components/setupWizard/Epilogue.js
new file mode 100644
index 00000000000..1dd77db1556
--- /dev/null
+++ b/client/components/setupWizard/Epilogue.js
@@ -0,0 +1,32 @@
+import React from 'react';
+import { Button } from '@rocket.chat/fuselage';
+
+import { useTranslation } from '../../hooks/useTranslation';
+import { useSetting } from '../../hooks/useSetting';
+import { setSetting } from './functions';
+import './Epilogue.css';
+
+export function Epilogue() {
+ const t = useTranslation();
+ const siteUrl = useSetting('Site_Url');
+
+ const handleClick = () => {
+ setSetting('Show_Setup_Wizard', 'completed');
+ };
+
+ return
+
+
+
+
+
+ {t('Launched_successfully')}
+ {t('Your_workspace_is_ready')}
+ {t('Your_server_link')}
+ {siteUrl}
+
+
+ ;
+}
diff --git a/client/components/setupWizard/Pager.js b/client/components/setupWizard/Pager.js
new file mode 100644
index 00000000000..bd4d35e545b
--- /dev/null
+++ b/client/components/setupWizard/Pager.js
@@ -0,0 +1,17 @@
+import { Button, ButtonGroup } from '@rocket.chat/fuselage';
+import React from 'react';
+
+import { useTranslation } from '../../hooks/useTranslation';
+
+export function Pager({ disabled, onBackClick, isContinueEnabled = true }) {
+ const t = useTranslation();
+
+ return
+ {onBackClick ? : null}
+
+ ;
+}
diff --git a/client/components/setupWizard/ParametersProvider.js b/client/components/setupWizard/ParametersProvider.js
new file mode 100644
index 00000000000..7af9e4a8664
--- /dev/null
+++ b/client/components/setupWizard/ParametersProvider.js
@@ -0,0 +1,42 @@
+import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
+
+import { call } from '../../../app/ui-utils/client';
+
+const ParametersContext = createContext({
+ loaded: true,
+ settings: [],
+ canDeclineServerRegistration: false,
+});
+
+export const useSetupWizardParameters = () => useContext(ParametersContext);
+
+export function ParametersProvider({ children }) {
+ const [loaded, setLoaded] = useState(false);
+ const [settings, setSettings] = useState([]);
+ const [canDeclineServerRegistration, setCapableOfDeclineServerRegistration] = useState(false);
+
+ useEffect(() => {
+ const getParameters = async () => {
+ const {
+ settings,
+ allowStandaloneServer,
+ } = await call('getSetupWizardParameters') || {};
+
+ setLoaded(true);
+ setSettings(settings);
+ setCapableOfDeclineServerRegistration(allowStandaloneServer);
+ };
+
+ getParameters();
+ }, []);
+
+ const value = useMemo(() => ({
+ loaded,
+ settings,
+ canDeclineServerRegistration,
+ }), [loaded, settings, canDeclineServerRegistration]);
+
+ return
+ {children}
+ ;
+}
diff --git a/client/components/setupWizard/SetupWizard.css b/client/components/setupWizard/SetupWizard.css
new file mode 100644
index 00000000000..686744b0dd3
--- /dev/null
+++ b/client/components/setupWizard/SetupWizard.css
@@ -0,0 +1,18 @@
+.SetupWizard {
+ display: flex;
+
+ width: 100%;
+ height: 100vh;
+
+ background-color: var(--color-dark-05);
+ align-items: stretch;
+
+ justify-content: center;
+}
+
+@media (width <= 760px) {
+ .SetupWizard {
+ flex-direction: column;
+ justify-content: initial;
+ }
+}
diff --git a/client/components/setupWizard/SetupWizard.js b/client/components/setupWizard/SetupWizard.js
new file mode 100644
index 00000000000..cb326fe467c
--- /dev/null
+++ b/client/components/setupWizard/SetupWizard.js
@@ -0,0 +1,26 @@
+import React from 'react';
+
+import { useWipeInitialPageLoading } from '../../hooks/useWipeInitialPageLoading';
+import { ConnectionStatusAlert } from '../connectionStatus/ConnectionStatusAlert';
+import { ParametersProvider } from './ParametersProvider';
+import { StateChecker } from './StateChecker';
+import { Steps } from './Steps';
+import { StepsState } from './StepsState';
+import './SetupWizard.css';
+
+export function SetupWizard() {
+ useWipeInitialPageLoading();
+
+ return <>
+
+
+
+
+
+
+
+
+
+
+ >;
+}
diff --git a/client/components/setupWizard/SideBar.css b/client/components/setupWizard/SideBar.css
new file mode 100644
index 00000000000..d06ea2aeea6
--- /dev/null
+++ b/client/components/setupWizard/SideBar.css
@@ -0,0 +1,164 @@
+.SetupWizard__SideBar {
+ display: flex;
+ overflow: hidden;
+ flex: 0 1 350px;
+ flex-flow: column nowrap;
+}
+
+.SetupWizard__SideBar-header {
+ display: flex;
+
+ margin: 2rem 1.625rem;
+ align-items: center;
+ flex-flow: row wrap;
+}
+
+.SetupWizard__SideBar-headerLogo {
+ height: 1.5rem;
+ margin: 0.25rem 0.375rem;
+}
+
+.SetupWizard__SideBar-headerTag {
+ margin: 0.25rem 0.375rem;
+
+ padding: 4px 8px;
+
+ white-space: nowrap;
+
+ text-transform: uppercase;
+
+ color: var(--color-white);
+
+ border-radius: 50px;
+ background-color: var(--color-dark);
+
+ font-size: 10px;
+
+ line-height: 1rem;
+}
+
+.SetupWizard__SideBar-content {
+ overflow: auto;
+ flex: 1;
+
+ margin: 0 0 1rem;
+ padding: 0 2rem;
+}
+
+.SetupWizard__SideBar-title {
+ margin-bottom: 1rem;
+
+ letter-spacing: 0.03rem;
+
+ color: var(--color-dark);
+
+ font-size: 2rem;
+
+ font-weight: 600;
+
+ line-height: 2.6rem;
+}
+
+.SetupWizard__SideBar-text {
+ margin-bottom: 3rem;
+
+ color: var(--color-gray);
+
+ font-size: 1rem;
+
+ font-weight: 500;
+
+ line-height: 1.5rem;
+}
+
+.SetupWizard__SideBar-step {
+ position: relative;
+
+ margin: 0 -0.5rem 2rem;
+
+ color: var(--color-dark-10);
+
+ font-size: 0.875rem;
+ font-weight: 500;
+
+ &::before {
+ display: inline-flex;
+
+ width: 1.5rem;
+ height: 1.5rem;
+ margin: 0 0.5rem;
+
+ content: attr(data-number);
+
+ color: var(--color-dark-10);
+
+ border: 1px solid var(--color-dark-10);
+ border-radius: 9999px;
+
+ font-size: 0.75rem;
+ align-items: center;
+ justify-content: center;
+ }
+
+ &::after {
+ position: absolute;
+ bottom: -2rem;
+ left: 1.2rem;
+
+ display: block;
+
+ width: 0.0625rem;
+ height: 2rem;
+
+ content: '';
+
+ background-color: var(--color-dark-10);
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+
+ &::after {
+ display: none;
+ }
+ }
+
+ &--active {
+ color: var(--rc-color-button-primary);
+
+ &::before {
+ color: var(--rc-color-button-primary);
+ border-color: var(--rc-color-button-primary);
+ background-color: transparent;
+ }
+ }
+
+ &--past {
+ color: var(--rc-color-primary);
+
+ &::before {
+ color: var(--rc-color-content);
+ border-color: var(--rc-color-button-primary);
+ background-color: var(--rc-color-button-primary);
+ }
+
+ &::after {
+ background-color: var(--rc-color-button-primary);
+ }
+ }
+
+ .rtl &::after {
+ right: 1.2rem;
+ left: auto;
+ }
+}
+
+@media (width <= 760px) {
+ .SetupWizard__SideBar {
+ flex-basis: auto;
+ }
+
+ .SetupWizard__SideBar-content {
+ display: none;
+ }
+}
diff --git a/client/components/setupWizard/SideBar.js b/client/components/setupWizard/SideBar.js
new file mode 100644
index 00000000000..84511553290
--- /dev/null
+++ b/client/components/setupWizard/SideBar.js
@@ -0,0 +1,39 @@
+import React from 'react';
+
+import { useTranslation } from '../../hooks/useTranslation';
+import { useSetupWizardStepsState } from './StepsState';
+import './SideBar.css';
+
+export function SideBar({ steps = [] }) {
+ const { currentStep } = useSetupWizardStepsState();
+
+ const t = useTranslation();
+
+ return ;
+}
diff --git a/client/components/setupWizard/StateChecker.js b/client/components/setupWizard/StateChecker.js
new file mode 100644
index 00000000000..e4bd09467b4
--- /dev/null
+++ b/client/components/setupWizard/StateChecker.js
@@ -0,0 +1,47 @@
+import { FlowRouter } from 'meteor/kadira:flow-router';
+import React, { useEffect, useState } from 'react';
+
+import { hasRole } from '../../../app/authorization';
+import { Users } from '../../../app/models';
+import { useSetting } from '../../hooks/useSetting';
+import { useUserId } from '../../hooks/useUserId';
+import { useReactiveValue } from '../../hooks/useReactiveValue';
+
+export function StateChecker({ children }) {
+ const setupWizardState = useSetting('Show_Setup_Wizard');
+ const userId = useUserId();
+ const user = useReactiveValue(() => Users.findOne(userId, { fields: { status: true } }), [userId]);
+
+ const [renderAllowed, allowRender] = useState(false);
+
+ useEffect(() => {
+ if (!setupWizardState) {
+ return;
+ }
+
+ if (userId && (!user || !user.status)) {
+ return;
+ }
+
+ const isComplete = setupWizardState === 'completed';
+ const noUserLoggedInAndIsNotPending = !renderAllowed && !user && setupWizardState !== 'pending';
+ const userIsLoggedInButIsNotAdmin = !!user && !hasRole(user._id, 'admin');
+
+ const mustRedirect = isComplete || noUserLoggedInAndIsNotPending || userIsLoggedInButIsNotAdmin;
+
+ if (mustRedirect) {
+ FlowRouter.withReplaceState(() => {
+ FlowRouter.go('home');
+ });
+ return;
+ }
+
+ allowRender(true);
+ }, [setupWizardState, userId, user]);
+
+ if (!renderAllowed) {
+ return null;
+ }
+
+ return <>{children}>;
+}
diff --git a/client/components/setupWizard/Step.css b/client/components/setupWizard/Step.css
new file mode 100644
index 00000000000..5554bcb10c7
--- /dev/null
+++ b/client/components/setupWizard/Step.css
@@ -0,0 +1,26 @@
+.SetupWizard__Step {
+ display: none;
+
+ flex-direction: column;
+
+ max-width: 350px;
+ margin: 2rem auto;
+
+ transition: opacity 1s;
+
+ opacity: 1;
+
+ &--active {
+ display: flex;
+ }
+
+ &--working {
+ opacity: 0.5;
+ }
+}
+
+@media (width <= 760px) {
+ .SetupWizard__Step {
+ margin: 0 auto;
+ }
+}
diff --git a/client/components/setupWizard/Step.js b/client/components/setupWizard/Step.js
new file mode 100644
index 00000000000..fd2c6c85393
--- /dev/null
+++ b/client/components/setupWizard/Step.js
@@ -0,0 +1,14 @@
+import React from 'react';
+
+import './Step.css';
+
+export const Step = ({ active, working = false, ...props }) =>
+ ;
diff --git a/client/components/setupWizard/StepContent.css b/client/components/setupWizard/StepContent.css
new file mode 100644
index 00000000000..1af1de1f1a1
--- /dev/null
+++ b/client/components/setupWizard/StepContent.css
@@ -0,0 +1,3 @@
+.SetupWizard__StepContent {
+ margin-bottom: 2rem;
+}
diff --git a/client/components/setupWizard/StepContent.js b/client/components/setupWizard/StepContent.js
new file mode 100644
index 00000000000..910ce2e726f
--- /dev/null
+++ b/client/components/setupWizard/StepContent.js
@@ -0,0 +1,7 @@
+import React from 'react';
+
+import './StepContent.css';
+
+export function StepContent(props) {
+ return ;
+}
diff --git a/client/components/setupWizard/StepHeader.css b/client/components/setupWizard/StepHeader.css
new file mode 100644
index 00000000000..23065ee4d16
--- /dev/null
+++ b/client/components/setupWizard/StepHeader.css
@@ -0,0 +1,28 @@
+.SetupWizard__StepHeader {
+ margin-bottom: 2rem;
+}
+
+.SetupWizard__StepHeader-runningHead {
+ margin-bottom: 3px;
+
+ letter-spacing: 0.05rem;
+
+ text-transform: uppercase;
+
+ color: var(--color-dark-20);
+
+ font-size: 0.75rem;
+
+ line-height: 1.125rem;
+}
+
+.SetupWizard__StepHeader-title {
+ letter-spacing: 0.05rem;
+
+ color: var(--color-dark-90);
+
+ font-size: 1.25rem;
+ font-weight: 500;
+
+ line-height: 1.75rem;
+}
diff --git a/client/components/setupWizard/StepHeader.js b/client/components/setupWizard/StepHeader.js
new file mode 100644
index 00000000000..15a414fbb65
--- /dev/null
+++ b/client/components/setupWizard/StepHeader.js
@@ -0,0 +1,13 @@
+import React from 'react';
+
+import { useTranslation } from '../../hooks/useTranslation';
+import './StepHeader.css';
+
+export function StepHeader({ number, title }) {
+ const t = useTranslation();
+
+ return
+ {t('Step')} {number}
+ {title}
+ ;
+}
diff --git a/client/components/setupWizard/Steps.css b/client/components/setupWizard/Steps.css
new file mode 100644
index 00000000000..19d9938f84a
--- /dev/null
+++ b/client/components/setupWizard/Steps.css
@@ -0,0 +1,25 @@
+.SetupWizard__Steps {
+ flex: 1 1 auto;
+
+ height: 100vh;
+ padding: 1rem;
+}
+
+.SetupWizard__Steps-wrapper {
+ overflow: auto;
+
+ width: 100%;
+ height: 100%;
+ padding: 1rem 3rem;
+
+ border-radius: 2px;
+ background-color: var(--color-white);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ justify-content: center;
+}
+
+@media (width <= 760px) {
+ .SetupWizard__Steps {
+ padding: 0;
+ }
+}
diff --git a/client/components/setupWizard/Steps.js b/client/components/setupWizard/Steps.js
new file mode 100644
index 00000000000..3dab7fab351
--- /dev/null
+++ b/client/components/setupWizard/Steps.js
@@ -0,0 +1,49 @@
+import React from 'react';
+
+import { AdminUserInformationStep } from './steps/AdminUserInformationStep';
+import { SettingsBasedStep } from './steps/SettingsBasedStep';
+import { RegisterServerStep } from './steps/RegisterServerStep';
+import { useTranslation } from '../../hooks/useTranslation';
+import { Epilogue } from './Epilogue';
+import { SideBar } from './SideBar';
+import { useSetupWizardStepsState, finalStep } from './StepsState';
+
+export function Steps() {
+ const { currentStep } = useSetupWizardStepsState();
+ const t = useTranslation();
+
+ if (currentStep === finalStep) {
+ return ;
+ }
+
+ return <>
+
+
+ >;
+}
diff --git a/client/components/setupWizard/StepsState.js b/client/components/setupWizard/StepsState.js
new file mode 100644
index 00000000000..0dc6b08585c
--- /dev/null
+++ b/client/components/setupWizard/StepsState.js
@@ -0,0 +1,57 @@
+import { FlowRouter } from 'meteor/kadira:flow-router';
+import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
+
+import { useUserId } from '../../hooks/useUserId';
+
+const Context = createContext();
+
+export const useSetupWizardStepsState = () => useContext(Context);
+
+export const finalStep = 'final';
+
+const useStepRouting = () => {
+ const userId = useUserId();
+ const [currentStep, setCurrentStep] = useState(() => {
+ const param = FlowRouter.getParam('step');
+
+ if (param === finalStep) {
+ return finalStep;
+ }
+
+ const step = parseInt(param, 10);
+ if (Number.isFinite(step) && step >= 1) {
+ return step;
+ }
+
+ return 1;
+ });
+
+ useEffect(() => {
+ if (!userId) {
+ setCurrentStep(1);
+ } else if (currentStep === 1) {
+ setCurrentStep(2);
+ }
+
+ FlowRouter.withReplaceState(() => {
+ FlowRouter.go('setup-wizard', { step: String(currentStep) });
+ });
+ }, [userId, currentStep]);
+
+ return [currentStep, setCurrentStep];
+};
+
+export function StepsState({ children }) {
+ const [currentStep, setCurrentStep] = useStepRouting();
+
+ const value = useMemo(() => ({
+ currentStep,
+ goToPreviousStep: () => setCurrentStep(currentStep - 1),
+ goToNextStep: () => setCurrentStep(currentStep + 1),
+ goToFinalStep: () => setCurrentStep(finalStep),
+ }), [currentStep]);
+
+ return
+ {children}
+ ;
+}
diff --git a/client/components/setupWizard/functions.js b/client/components/setupWizard/functions.js
new file mode 100644
index 00000000000..d96e0a33e90
--- /dev/null
+++ b/client/components/setupWizard/functions.js
@@ -0,0 +1,20 @@
+import { Meteor } from 'meteor/meteor';
+
+import { settings } from '../../../app/settings/lib/settings';
+
+const withPromisifiedReturn = (f) => (...args) => new Promise((resolve, reject) => {
+ f(...args, (error, ...returnedValues) => {
+ if (error) {
+ reject(error);
+ return;
+ }
+
+ resolve(returnedValues);
+ });
+});
+
+export const loginWithPassword = withPromisifiedReturn(Meteor.loginWithPassword.bind(Meteor));
+
+export const batchSetSettings = withPromisifiedReturn(settings.batchSet.bind(settings));
+
+export const setSetting = withPromisifiedReturn(settings.set.bind(settings));
diff --git a/client/components/setupWizard/steps/AdminUserInformationStep.js b/client/components/setupWizard/steps/AdminUserInformationStep.js
new file mode 100644
index 00000000000..5d272dd3947
--- /dev/null
+++ b/client/components/setupWizard/steps/AdminUserInformationStep.js
@@ -0,0 +1,156 @@
+import { Input, InputGroup } from '@rocket.chat/fuselage';
+import { Session } from 'meteor/session';
+import React, { useMemo, useState } from 'react';
+import toastr from 'toastr';
+
+import { call } from '../../../../app/ui-utils/client';
+import { handleError } from '../../../../app/utils/client';
+import { callbacks } from '../../../../app/callbacks/client';
+import { useSetting } from '../../../hooks/useSetting';
+import { useTranslation } from '../../../hooks/useTranslation';
+import { useSetupWizardStepsState } from '../StepsState';
+import { Step } from '../Step';
+import { StepHeader } from '../StepHeader';
+import { Pager } from '../Pager';
+import { StepContent } from '../StepContent';
+import { loginWithPassword } from '../functions';
+import { useFocus } from '../../../hooks/useFocus';
+
+const registerAdminUser = async ({ name, username, email, password, onRegistrationEmailSent }) => {
+ await call('registerUser', { name, username, email, pass: password });
+ callbacks.run('userRegistered');
+
+ try {
+ await loginWithPassword(email, password);
+ } catch (error) {
+ if (error.error === 'error-invalid-email') {
+ onRegistrationEmailSent && onRegistrationEmailSent();
+ return;
+ }
+
+ throw error;
+ }
+
+ Session.set('forceLogin', false);
+
+ await call('setUsername', username);
+
+ callbacks.run('usernameSet');
+};
+
+export function AdminUserInformationStep({ step, title }) {
+ const { currentStep, goToNextStep } = useSetupWizardStepsState();
+ const active = step === currentStep;
+
+ const regexpForUsernameValidation = useSetting('UTF8_Names_Validation');
+ const usernameRegExp = useMemo(() => new RegExp(`^${ regexpForUsernameValidation }$`), [regexpForUsernameValidation]);
+ const emailRegExp = useMemo(() => /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+$/i, []);
+
+ const [name, setName] = useState('');
+ const [username, setUsername] = useState('');
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+
+ const [isNameValid, validateName] = useState(true);
+ const [isUsernameValid, validateUsername] = useState(true);
+ const [isEmailValid, validateEmail] = useState(true);
+ const [isPasswordValid, validatePassword] = useState(true);
+
+ const isContinueEnabled = useMemo(() => name && username && email && password, [name, username, email, password]);
+
+ const [commiting, setCommiting] = useState(false);
+
+ const validate = () => {
+ const isNameValid = !!name;
+ const isUsernameValid = !!username && usernameRegExp.test(username);
+ const isEmailValid = !!email && emailRegExp.test(email);
+ const isPasswordValid = !!password;
+
+ validateName(isNameValid);
+ validateUsername(isUsernameValid);
+ validateEmail(isEmailValid);
+ validatePassword(isPasswordValid);
+
+ return isNameValid && isUsernameValid && isEmailValid && isPasswordValid;
+ };
+
+ const t = useTranslation();
+
+ const autoFocusRef = useFocus(active);
+
+ const handleSubmit = async (event) => {
+ event.preventDefault();
+
+ const canRegisterAdminUser = validate();
+
+ if (!canRegisterAdminUser) {
+ return;
+ }
+
+ setCommiting(true);
+
+ try {
+ await registerAdminUser({
+ name,
+ username,
+ email,
+ password,
+ onRegistrationEmailSent: () => toastr.success(t('We_have_sent_registration_email')),
+ });
+ goToNextStep();
+ } catch (error) {
+ console.error(error);
+ handleError(error);
+ } finally {
+ setCommiting(false);
+ }
+ };
+
+ return
+
+
+
+
+ setName(value)}
+ error={!isNameValid}
+ />
+ setUsername(value)}
+ error={!isUsernameValid && t('Invalid_username')}
+ />
+ setEmail(value)}
+ error={!isEmailValid && t('Invalid_email')}
+ />
+ setPassword(value)}
+ error={!isPasswordValid}
+ />
+
+
+
+
+ ;
+}
diff --git a/client/components/setupWizard/steps/RegisterServerStep.css b/client/components/setupWizard/steps/RegisterServerStep.css
new file mode 100644
index 00000000000..5ff7379810f
--- /dev/null
+++ b/client/components/setupWizard/steps/RegisterServerStep.css
@@ -0,0 +1,81 @@
+.SetupWizard__RegisterServerStep-text {
+ margin-bottom: 3rem;
+
+ color: var(--color-gray);
+
+ font-size: 1rem;
+
+ font-weight: 500;
+
+ line-height: 1.5rem;
+}
+
+.SetupWizard__RegisterServerStep-content {
+ display: flex;
+ flex-direction: column;
+}
+
+.SetupWizard__RegisterServerStep-option {
+ display: block;
+
+ padding: 1.5rem;
+
+ cursor: pointer;
+
+ color: var(--color-dark);
+ border: 2px solid var(--color-dark-10);
+
+ border-radius: 2px;
+
+ font-size: 0.875rem;
+
+ line-height: 1.25rem;
+
+ &:first-child {
+ margin-bottom: 1rem;
+ }
+
+ &--selected {
+ border-color: var(--rc-color-button-primary);
+ }
+
+ &--disabled {
+ opacity: 0.25;
+ }
+}
+
+.SetupWizard__RegisterServerStep-items {
+ margin: 1rem 0;
+
+ & + * {
+ margin-top: 1rem;
+ }
+}
+
+.SetupWizard__RegisterServerStep-item {
+ display: flex;
+
+ margin: 0 -0.5rem 0.5rem;
+ align-items: center;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ & > .SetupWizard__RegisterServerStep-item-icon {
+ width: 20px;
+ min-width: 20px;
+ height: 20px;
+ margin: 0 0.5rem;
+ align-self: baseline;
+
+ &--check {
+ color: var(--rc-color-button-primary);
+ }
+
+ &--circle {
+ height: 6px;
+ margin: 7px 0.5rem;
+ }
+ }
+}
diff --git a/client/components/setupWizard/steps/RegisterServerStep.js b/client/components/setupWizard/steps/RegisterServerStep.js
new file mode 100644
index 00000000000..d45f658bd5f
--- /dev/null
+++ b/client/components/setupWizard/steps/RegisterServerStep.js
@@ -0,0 +1,152 @@
+import { CheckBox, RadioButton } from '@rocket.chat/fuselage';
+import React, { useState } from 'react';
+
+import { call } from '../../../../app/ui-utils/client';
+import { handleError } from '../../../../app/utils/client';
+import { useTranslation } from '../../../hooks/useTranslation';
+import { Icon } from '../../basic/Icon';
+import { Pager } from '../Pager';
+import { useSetupWizardParameters } from '../ParametersProvider';
+import { Step } from '../Step';
+import { StepContent } from '../StepContent';
+import { StepHeader } from '../StepHeader';
+import { useSetupWizardStepsState } from '../StepsState';
+import { batchSetSettings } from '../functions';
+import { useFocus } from '../../../hooks/useFocus';
+
+const Option = React.forwardRef(({ children, label, selected, disabled, ...props }, ref) =>
+
+);
+
+const Items = (props) => ;
+
+const Item = ({ children, icon, ...props }) =>
+
+
+ {children}
+ ;
+
+export function RegisterServerStep({ step, title }) {
+ const { canDeclineServerRegistration } = useSetupWizardParameters();
+ const { currentStep, goToPreviousStep, goToFinalStep } = useSetupWizardStepsState();
+
+ const active = step === currentStep;
+
+ const [registerServer, setRegisterServer] = useState(true);
+ const [optInMarketingEmails, setOptInMarketingEmails] = useState(true);
+
+ const t = useTranslation();
+
+ const [commiting, setComitting] = useState(false);
+
+ const handleBackClick = () => {
+ goToPreviousStep();
+ };
+
+ const handleSubmit = async (event) => {
+ event.preventDefault();
+
+ setComitting(true);
+
+ try {
+ await batchSetSettings([
+ {
+ _id: 'Statistics_reporting',
+ value: registerServer,
+ },
+ {
+ _id: 'Apps_Framework_enabled',
+ value: registerServer,
+ },
+ {
+ _id: 'Register_Server',
+ value: registerServer,
+ },
+ {
+ _id: 'Allow_Marketing_Emails',
+ value: optInMarketingEmails,
+ },
+ ]);
+
+ if (registerServer) {
+ await call('cloud:registerWorkspace');
+ }
+
+ setComitting(false);
+ goToFinalStep();
+ } catch (error) {
+ console.error(error);
+ handleError(error);
+ setComitting(false);
+ }
+ };
+
+ const autoFocusRef = useFocus(active);
+
+ return
+
+
+
+ {t('Register_Server_Info')}
+
+
+
+
+
+
+
+
+ ;
+}
diff --git a/client/components/setupWizard/steps/SettingsBasedStep.js b/client/components/setupWizard/steps/SettingsBasedStep.js
new file mode 100644
index 00000000000..1bc38d01c28
--- /dev/null
+++ b/client/components/setupWizard/steps/SettingsBasedStep.js
@@ -0,0 +1,141 @@
+import { Input, InputGroup } from '@rocket.chat/fuselage';
+import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
+import React, { Fragment, useEffect, useReducer, useState } from 'react';
+
+import { handleError } from '../../../../app/utils/client';
+import { useTranslation } from '../../../hooks/useTranslation';
+import { useReactiveValue } from '../../../hooks/useReactiveValue';
+import { Pager } from '../Pager';
+import { useSetupWizardParameters } from '../ParametersProvider';
+import { useSetupWizardStepsState } from '../StepsState';
+import { Step } from '../Step';
+import { StepHeader } from '../StepHeader';
+import { StepContent } from '../StepContent';
+import { batchSetSettings } from '../functions';
+import { useFocus } from '../../../hooks/useFocus';
+
+const useFields = () => {
+ const reset = 'RESET';
+ const setValue = 'SET_VALUE';
+
+ const [fields, dispatch] = useReducer((fields, { type, payload }) => {
+ if (type === reset) {
+ return payload;
+ }
+
+ if (type === setValue) {
+ const { _id, value } = payload;
+ return fields.map((field) => (field._id === _id ? { ...field, value } : field));
+ }
+
+ return fields;
+ }, []);
+
+ const resetFields = (fields) => dispatch({ type: reset, payload: fields });
+ const setFieldValue = (_id, value) => dispatch({ type: setValue, payload: { _id, value } });
+
+ return { fields, resetFields, setFieldValue };
+};
+
+export function SettingsBasedStep({ step, title }) {
+ const { settings } = useSetupWizardParameters();
+ const { currentStep, goToPreviousStep, goToNextStep } = useSetupWizardStepsState();
+ const { fields, resetFields, setFieldValue } = useFields();
+ const [commiting, setCommiting] = useState(false);
+
+ const active = step === currentStep;
+
+ const languages = useReactiveValue(() => TAPi18n.getLanguages(), []);
+
+ useEffect(() => {
+ resetFields(
+ settings
+ .filter(({ wizard }) => wizard.step === step)
+ .filter(({ type }) => ['string', 'select', 'language'].includes(type))
+ .sort(({ wizard: { order: a } }, { wizard: { order: b } }) => a - b)
+ .map(({ value, ...field }) => ({ ...field, value: value || '' }))
+ );
+ }, [settings, currentStep]);
+
+ const t = useTranslation();
+
+ const handleBackClick = () => {
+ goToPreviousStep();
+ };
+
+ const handleSubmit = async (event) => {
+ event.preventDefault();
+
+ setCommiting(true);
+
+ try {
+ await batchSetSettings(fields.map(({ _id, value }) => ({ _id, value })));
+ goToNextStep();
+ } catch (error) {
+ console.error(error);
+ handleError(error);
+ } finally {
+ setCommiting(false);
+ }
+ };
+
+ const autoFocusRef = useFocus(active);
+
+ return
+
+
+
+
+ {fields.map(({ _id, type, i18nLabel, value, values }, i) =>
+
+ {type === 'string'
+ && setFieldValue(_id, value)}
+ />}
+
+ {type === 'select'
+ && setFieldValue(_id, value)}
+ >
+ {values
+ .map(({ i18nLabel, key }) => ({ label: t(i18nLabel), value: key }))
+ .map(({ label, value }) => )}
+ }
+
+ {type === 'language'
+ && setFieldValue(_id, value)}
+ >
+ {Object.entries(languages)
+ .map(([key, { name }]) => ({ label: name, value: key }))
+ .sort((a, b) => a.key - b.key)
+ .map(({ label, value }) => )}
+ }
+
+ )}
+
+
+
+ 2 && handleBackClick}
+ />
+ ;
+}
diff --git a/client/hooks/useFocus.js b/client/hooks/useFocus.js
new file mode 100644
index 00000000000..74282ecdfae
--- /dev/null
+++ b/client/hooks/useFocus.js
@@ -0,0 +1,15 @@
+import { useEffect, useState } from 'react';
+
+export const useFocus = (isFocused) => {
+ const [element, setElement] = useState(null);
+
+ useEffect(() => {
+ if (isFocused && element) {
+ element.focus();
+ }
+ }, [element, isFocused]);
+
+ return (ref) => {
+ setElement(ref);
+ };
+};
diff --git a/client/hooks/useReactiveValue.js b/client/hooks/useReactiveValue.js
new file mode 100644
index 00000000000..00e63cad57c
--- /dev/null
+++ b/client/hooks/useReactiveValue.js
@@ -0,0 +1,19 @@
+import { Tracker } from 'meteor/tracker';
+import { useEffect, useState } from 'react';
+
+export const useReactiveValue = (getValue, deps = []) => {
+ const [value, setValue] = useState(getValue);
+
+ useEffect(() => {
+ const computation = Tracker.autorun(() => {
+ const newValue = getValue();
+ setValue(() => newValue);
+ });
+
+ return () => {
+ computation.stop();
+ };
+ }, deps);
+
+ return value;
+};
diff --git a/client/hooks/useSession.js b/client/hooks/useSession.js
new file mode 100644
index 00000000000..731d2226510
--- /dev/null
+++ b/client/hooks/useSession.js
@@ -0,0 +1,5 @@
+import { Session } from 'meteor/session';
+
+import { useReactiveValue } from './useReactiveValue';
+
+export const useSession = (variableName) => useReactiveValue(() => Session.get(variableName));
diff --git a/client/hooks/useSetting.js b/client/hooks/useSetting.js
new file mode 100644
index 00000000000..1d287c2e819
--- /dev/null
+++ b/client/hooks/useSetting.js
@@ -0,0 +1,4 @@
+import { settings } from '../../app/settings/client';
+import { useReactiveValue } from './useReactiveValue';
+
+export const useSetting = (settingName) => useReactiveValue(() => settings.get(settingName));
diff --git a/client/hooks/useTranslation.js b/client/hooks/useTranslation.js
new file mode 100644
index 00000000000..efeb945795f
--- /dev/null
+++ b/client/hooks/useTranslation.js
@@ -0,0 +1,21 @@
+import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
+import { Tracker } from 'meteor/tracker';
+
+import { useReactiveValue } from './useReactiveValue';
+
+const translator = (key, ...replaces) => Tracker.nonreactive(() => {
+ if (typeof replaces[0] === 'object') {
+ return TAPi18n.__(key, ...replaces);
+ }
+
+ return TAPi18n.__(key, {
+ postProcess: 'sprintf',
+ sprintf: replaces,
+ });
+});
+
+export const useTranslation = () => {
+ useReactiveValue(() => TAPi18n.getLanguage());
+
+ return translator;
+};
diff --git a/client/hooks/useUserId.js b/client/hooks/useUserId.js
new file mode 100644
index 00000000000..600efa45f51
--- /dev/null
+++ b/client/hooks/useUserId.js
@@ -0,0 +1,5 @@
+import { Meteor } from 'meteor/meteor';
+
+import { useReactiveValue } from './useReactiveValue';
+
+export const useUserId = () => useReactiveValue(() => Meteor.userId());
diff --git a/client/hooks/useWipeInitialPageLoading.js b/client/hooks/useWipeInitialPageLoading.js
new file mode 100644
index 00000000000..2c8ec5a6afd
--- /dev/null
+++ b/client/hooks/useWipeInitialPageLoading.js
@@ -0,0 +1,17 @@
+import { useLayoutEffect } from 'react';
+
+export const useWipeInitialPageLoading = () => {
+ useLayoutEffect(() => {
+ const initialPageLoadingElement = document.getElementById('initial-page-loading');
+
+ if (!initialPageLoadingElement) {
+ return;
+ }
+
+ initialPageLoadingElement.style.display = 'none';
+
+ return () => {
+ initialPageLoadingElement.style.display = 'flex';
+ };
+ }, []);
+};
diff --git a/client/importPackages.js b/client/importPackages.js
index a2a44dfe298..14f6e227977 100644
--- a/client/importPackages.js
+++ b/client/importPackages.js
@@ -54,7 +54,6 @@ import '../app/oembed/client';
import '../app/otr/client';
import '../app/push-notifications/client';
import '../app/apps/client';
-import '../app/setup-wizard/client';
import '../app/slackbridge/client';
import '../app/slashcommands-archiveroom/client';
import '../app/slashcommand-asciiarts/client';
diff --git a/client/importsCss.js b/client/importsCss.js
index 9b3b49c4fd6..34cf7a0a1c0 100644
--- a/client/importsCss.js
+++ b/client/importsCss.js
@@ -1,4 +1,4 @@
-
+import './RocketChat.font.css';
import '../app/chatpal-search/client/style.css';
import '../app/theme/client/main.css';
import '../app/theme/client/vendor/photoswipe.css';
diff --git a/client/main.js b/client/main.js
index 7b0799357d6..4f58796f67c 100644
--- a/client/main.js
+++ b/client/main.js
@@ -21,7 +21,6 @@ import './notifications/updateAvatar';
import './notifications/updateUserState';
import './notifications/UsersNameChanged';
import './routes/adminRouter';
-import './routes/pageNotFound';
import './routes/roomRoute';
import './routes/router';
import './startup/emailVerification';
diff --git a/client/routes/pageNotFound.html b/client/routes/pageNotFound.html
deleted file mode 100644
index 6a5bfffbeb6..00000000000
--- a/client/routes/pageNotFound.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
- 404
- {{_ "Oops_page_not_found"}}
- {{_ "Sorry_page_you_requested_does_not_exists_or_was_deleted"}}
-
-
-
-
diff --git a/client/routes/pageNotFound.js b/client/routes/pageNotFound.js
deleted file mode 100644
index e83fe3f0271..00000000000
--- a/client/routes/pageNotFound.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Template } from 'meteor/templating';
-import { FlowRouter } from 'meteor/kadira:flow-router';
-
-import './pageNotFound.html';
-
-Template.pageNotFound.onRendered(function() {
- const parent = document.querySelector('.page-loading');
- const child = document.querySelector('.loading-animation');
- parent.removeChild(child);
-});
-
-Template.pageNotFound.events({
- 'click .page-not-found-button-home'(e) {
- e.preventDefault();
- FlowRouter.go('home');
- },
-
- 'click .page-not-found-button-previous'(e) {
- e.preventDefault();
- window.history.back();
- },
-});
diff --git a/client/routes/router.js b/client/routes/router.js
index 4df791c5cf8..3159fc618c5 100644
--- a/client/routes/router.js
+++ b/client/routes/router.js
@@ -3,8 +3,10 @@ import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Tracker } from 'meteor/tracker';
import { Blaze } from 'meteor/blaze';
+import { HTML } from 'meteor/htmljs';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { BlazeLayout } from 'meteor/kadira:blaze-layout';
+import { Template } from 'meteor/templating';
import { Session } from 'meteor/session';
import { KonchatNotification } from '../../app/ui';
@@ -15,6 +17,42 @@ Blaze.registerHelper('pathFor', function(path, kw) {
BlazeLayout.setRoot('body');
+const createTemplateForComponent = async (
+ component,
+ props = {},
+ // eslint-disable-next-line new-cap
+ renderContainerView = () => HTML.DIV()
+) => {
+ const React = await import('react');
+ const ReactDOM = await import('react-dom');
+
+ const name = component.displayName || component.name;
+
+ if (!name) {
+ throw new Error('the component must have a name');
+ }
+
+ Template[name] = new Blaze.Template(name, renderContainerView);
+
+ Template[name].onRendered(() => {
+ Template.instance().autorun((computation) => {
+ if (computation.firstRun) {
+ Template.instance().container = Template.instance().firstNode;
+ }
+
+ ReactDOM.render(React.createElement(component, props), Template.instance().firstNode);
+ });
+ });
+
+ Template[name].onDestroyed(() => {
+ if (Template.instance().container) {
+ ReactDOM.unmountComponentAtNode(Template.instance().container);
+ }
+ });
+
+ return name;
+};
+
FlowRouter.subscriptions = function() {
Tracker.autorun(() => {
if (Meteor.userId()) {
@@ -137,14 +175,6 @@ FlowRouter.route('/room-not-found/:type/:name', {
},
});
-FlowRouter.route('/fxos', {
- name: 'firefox-os-install',
-
- action() {
- BlazeLayout.render('fxOsInstallPrompt');
- },
-});
-
FlowRouter.route('/register/:hash', {
name: 'register-secret-url',
@@ -164,24 +194,17 @@ FlowRouter.route('/register/:hash', {
},
});
-FlowRouter.route('/setup-wizard', {
+FlowRouter.route('/setup-wizard/:step?', {
name: 'setup-wizard',
-
- action() {
- BlazeLayout.render('setupWizard');
- },
-});
-
-FlowRouter.route('/setup-wizard/final', {
- name: 'setup-wizard-final',
-
- action() {
- BlazeLayout.render('setupWizardFinal');
+ action: async () => {
+ const { SetupWizard } = await import('../components/setupWizard/SetupWizard');
+ BlazeLayout.render(await createTemplateForComponent(SetupWizard));
},
});
FlowRouter.notFound = {
- action() {
- BlazeLayout.render('pageNotFound');
+ action: async () => {
+ const { PageNotFound } = await import('../components/pageNotFound/PageNotFound');
+ BlazeLayout.render(await createTemplateForComponent(PageNotFound));
},
};
diff --git a/client/routes/stylesheets/pageNotFound.css b/client/routes/stylesheets/pageNotFound.css
deleted file mode 100644
index 6e0aae972be..00000000000
--- a/client/routes/stylesheets/pageNotFound.css
+++ /dev/null
@@ -1,48 +0,0 @@
-.page-not-found-container {
- width: 100%;
- height: 100%;
- padding: 10%;
-
- text-align: center;
-
- color: white;
- background-image: url("/images/404.svg");
- background-repeat: no-repeat;
- background-position: center;
- background-size: cover;
-
- .error-404 {
- display: block;
-
- padding: 10px;
-
- font-size: 4em;
- font-weight: bold;
- }
-
- .page-not-found-message {
- display: block;
-
- padding: 10px;
-
- font-size: 2em;
- font-weight: bold;
- }
-
- .page-not-found-description {
- display: block;
-
- padding: 10px;
-
- font-size: 1em;
- }
-
- .page-not-found-button {
- display: inline-block;
-
- margin: 20px 10px 0;
- padding: 8px 16px;
-
- font-size: 1em;
- }
-}
diff --git a/package-lock.json b/package-lock.json
index e125255c262..ff9de5e8246 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -702,6 +702,19 @@
"eslint-plugin-import": "^2.17.2"
}
},
+ "@rocket.chat/fuselage": {
+ "version": "0.2.0-alpha.2",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage/-/fuselage-0.2.0-alpha.2.tgz",
+ "integrity": "sha512-fAGRMPGvluQAxwUCWmgn28anFT0NPsKEzM1yYOdo1xPbYbs48QKg6f9aUgNEAAqpviw58AKq8d/re8KPjzEYLw==",
+ "requires": {
+ "@rocket.chat/icons": "^0.2.0-alpha.0"
+ }
+ },
+ "@rocket.chat/icons": {
+ "version": "0.2.0-alpha.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/icons/-/icons-0.2.0-alpha.0.tgz",
+ "integrity": "sha512-7bzc7frrOfSypD/QvJ+eBfiD5XZSpxzN8taaOB2g0AHDUYcS/yIDpZLRH0Eq0fVe4A4gXsg0MRgcU0cJzuXQ+g=="
+ },
"@rocket.chat/livechat": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@rocket.chat/livechat/-/livechat-1.1.6.tgz",
@@ -882,7 +895,7 @@
},
"@types/events": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA=="
},
"@types/express": {
@@ -1859,7 +1872,7 @@
},
"axios": {
"version": "0.18.0",
- "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
"requires": {
"follow-redirects": "^1.3.0",
@@ -2197,7 +2210,7 @@
},
"babel-plugin-add-module-exports": {
"version": "0.2.1",
- "resolved": "http://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz",
"integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=",
"dev": true
},
@@ -2218,79 +2231,79 @@
},
"babel-plugin-syntax-async-functions": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
"dev": true
},
"babel-plugin-syntax-async-generators": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
"integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
"dev": true
},
"babel-plugin-syntax-class-constructor-call": {
"version": "6.18.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
"integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=",
"dev": true
},
"babel-plugin-syntax-class-properties": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
"integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
"dev": true
},
"babel-plugin-syntax-decorators": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
"integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
"dev": true
},
"babel-plugin-syntax-do-expressions": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
"integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=",
"dev": true
},
"babel-plugin-syntax-dynamic-import": {
"version": "6.18.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
"integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
"dev": true
},
"babel-plugin-syntax-exponentiation-operator": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
"integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
"dev": true
},
"babel-plugin-syntax-export-extensions": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
"integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=",
"dev": true
},
"babel-plugin-syntax-flow": {
"version": "6.18.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
"integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=",
"dev": true
},
"babel-plugin-syntax-function-bind": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
"integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=",
"dev": true
},
"babel-plugin-syntax-jsx": {
"version": "6.18.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=",
"dev": true
},
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
"dev": true
},
@@ -2687,7 +2700,7 @@
},
"babel-preset-es2015": {
"version": "6.3.13",
- "resolved": "http://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.3.13.tgz",
+ "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.3.13.tgz",
"integrity": "sha1-l9zn7ykuGMubK3VF2AxZPCjZUX8=",
"dev": true,
"requires": {
@@ -2715,7 +2728,7 @@
},
"babel-preset-react": {
"version": "6.3.13",
- "resolved": "http://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.3.13.tgz",
+ "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.3.13.tgz",
"integrity": "sha1-E9VeBqZfqqoHw5v2Op2DbgMhFvo=",
"dev": true,
"requires": {
@@ -2729,7 +2742,7 @@
},
"babel-preset-stage-0": {
"version": "6.3.13",
- "resolved": "http://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.3.13.tgz",
+ "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.3.13.tgz",
"integrity": "sha1-eKN8VvCzmI8qeZMtywzrj/N3sNE=",
"dev": true,
"requires": {
@@ -3636,7 +3649,7 @@
},
"bl": {
"version": "1.2.2",
- "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"requires": {
"readable-stream": "^2.3.5",
@@ -4020,7 +4033,7 @@
},
"readable-stream": {
"version": "1.1.14",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
@@ -4386,7 +4399,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
@@ -4489,7 +4502,7 @@
},
"chimp": {
"version": "0.51.1",
- "resolved": "http://registry.npmjs.org/chimp/-/chimp-0.51.1.tgz",
+ "resolved": "https://registry.npmjs.org/chimp/-/chimp-0.51.1.tgz",
"integrity": "sha1-6hIbzfJsidV/jvNBlUDPPCeaPMU=",
"dev": true,
"requires": {
@@ -4535,7 +4548,7 @@
"dependencies": {
"async": {
"version": "0.9.2",
- "resolved": "http://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
"dev": true
},
@@ -4607,7 +4620,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -4659,7 +4672,7 @@
},
"progress": {
"version": "1.1.8",
- "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
"integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
"dev": true
},
@@ -4682,7 +4695,7 @@
},
"chokidar": {
"version": "1.6.1",
- "resolved": "http://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz",
"integrity": "sha1-L0RHq16W5Q+z14n9kNTHLg5McMI=",
"dev": true,
"requires": {
@@ -5448,7 +5461,7 @@
"dependencies": {
"core-js": {
"version": "1.2.7",
- "resolved": "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
}
}
@@ -5848,7 +5861,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
- "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
@@ -5878,7 +5891,7 @@
},
"deprecate": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/deprecate/-/deprecate-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/deprecate/-/deprecate-1.0.0.tgz",
"integrity": "sha1-ZhSQ7SQokWpsiIPYg05WRvTkpKg="
},
"deprecated-decorator": {
@@ -5936,7 +5949,7 @@
},
"readable-stream": {
"version": "1.1.14",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
@@ -6003,7 +6016,7 @@
"dependencies": {
"domelementtype": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
}
}
@@ -6381,7 +6394,7 @@
},
"es6-promisify": {
"version": "5.0.0",
- "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"requires": {
"es6-promise": "^4.0.3"
@@ -6717,6 +6730,67 @@
}
}
},
+ "eslint-plugin-react": {
+ "version": "7.14.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz",
+ "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==",
+ "dev": true,
+ "requires": {
+ "array-includes": "^3.0.3",
+ "doctrine": "^2.1.0",
+ "has": "^1.0.3",
+ "jsx-ast-utils": "^2.1.0",
+ "object.entries": "^1.1.0",
+ "object.fromentries": "^2.0.0",
+ "object.values": "^1.1.0",
+ "prop-types": "^15.7.2",
+ "resolve": "^1.10.1"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "object.entries": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz",
+ "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.12.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3"
+ }
+ },
+ "object.values": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz",
+ "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.12.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3"
+ }
+ },
+ "resolve": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
+ "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ }
+ }
+ },
"eslint-scope": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
@@ -6822,7 +6896,7 @@
},
"events": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
},
"evp_bytestokey": {
@@ -7240,7 +7314,7 @@
},
"external-editor": {
"version": "2.2.0",
- "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"dev": true,
"requires": {
@@ -7410,13 +7484,13 @@
"dependencies": {
"lodash": {
"version": "2.4.2",
- "resolved": "http://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
"integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
"dev": true
},
"underscore.string": {
"version": "2.3.3",
- "resolved": "http://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
"integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
"dev": true
}
@@ -8597,7 +8671,7 @@
"dependencies": {
"minimist": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
"integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=",
"dev": true
}
@@ -9452,7 +9526,7 @@
},
"hapi": {
"version": "8.8.0",
- "resolved": "http://registry.npmjs.org/hapi/-/hapi-8.8.0.tgz",
+ "resolved": "https://registry.npmjs.org/hapi/-/hapi-8.8.0.tgz",
"integrity": "sha1-h+N6Bum0meiXkOLcERqpZotuYX8=",
"dev": true,
"requires": {
@@ -9522,7 +9596,7 @@
},
"catbox": {
"version": "4.3.0",
- "resolved": "http://registry.npmjs.org/catbox/-/catbox-4.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/catbox/-/catbox-4.3.0.tgz",
"integrity": "sha1-IiN3vWfxKRrA4l0AAC0GWp3385o=",
"dev": true,
"requires": {
@@ -9619,7 +9693,7 @@
},
"joi": {
"version": "6.4.1",
- "resolved": "http://registry.npmjs.org/joi/-/joi-6.4.1.tgz",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-6.4.1.tgz",
"integrity": "sha1-9Q9CRTVgBo5jg9oVrC0w3Xzra24=",
"dev": true,
"requires": {
@@ -9631,7 +9705,7 @@
"dependencies": {
"isemail": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/isemail/-/isemail-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.1.1.tgz",
"integrity": "sha1-4Mj23D9HCX53dzlcaJYnGqJWw7U=",
"dev": true
},
@@ -9664,7 +9738,7 @@
"dependencies": {
"mime-db": {
"version": "1.14.0",
- "resolved": "http://registry.npmjs.org/mime-db/-/mime-db-1.14.0.tgz",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.14.0.tgz",
"integrity": "sha1-1WHxC27mbbUflK5leilRp0IX7YM=",
"dev": true
}
@@ -10405,7 +10479,7 @@
},
"readable-stream": {
"version": "1.1.14",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
@@ -10757,7 +10831,7 @@
},
"is-builtin-module": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
"dev": true,
"requires": {
@@ -10924,7 +10998,7 @@
},
"is-obj": {
"version": "1.0.1",
- "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
},
"is-object": {
@@ -11097,7 +11171,7 @@
},
"isemail": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz",
"integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo="
},
"isexe": {
@@ -11133,7 +11207,7 @@
},
"jasmine-core": {
"version": "2.99.1",
- "resolved": "http://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
+ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
"integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
"dev": true
},
@@ -11215,8 +11289,7 @@
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"js-yaml": {
"version": "3.12.0",
@@ -11339,7 +11412,7 @@
},
"jsonfile": {
"version": "2.4.0",
- "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
"dev": true,
"requires": {
@@ -11402,6 +11475,16 @@
"resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.12.tgz",
"integrity": "sha1-Iqu5ZW00owuVMENnIINeicLlwxY="
},
+ "jsx-ast-utils": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz",
+ "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==",
+ "dev": true,
+ "requires": {
+ "array-includes": "^3.0.3",
+ "object.assign": "^4.1.0"
+ }
+ },
"juice": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/juice/-/juice-5.2.0.tgz",
@@ -11632,7 +11715,7 @@
},
"promise": {
"version": "6.1.0",
- "resolved": "http://registry.npmjs.org/promise/-/promise-6.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz",
"integrity": "sha1-LOcp9rlLRcJoka0GAsXJDgTG7vY=",
"optional": true,
"requires": {
@@ -12095,7 +12178,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dev": true,
"requires": {
"js-tokens": "^3.0.0 || ^4.0.0"
}
@@ -12304,7 +12386,7 @@
},
"media-typer": {
"version": "0.3.0",
- "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"mem": {
@@ -12813,14 +12895,14 @@
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
},
"minimist-options": {
@@ -12908,7 +12990,7 @@
},
"mkdirp": {
"version": "0.5.1",
- "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": {
"minimist": "0.0.8"
@@ -13345,7 +13427,7 @@
},
"ncp": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
"integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=",
"optional": true
},
@@ -13715,7 +13797,7 @@
},
"npm-install-package": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz",
"integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=",
"dev": true
},
@@ -13730,7 +13812,7 @@
"npmlog": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
- "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=",
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
@@ -13840,6 +13922,18 @@
"has": "^1.0.1"
}
},
+ "object.fromentries": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz",
+ "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.11.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.1"
+ }
+ },
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
@@ -13969,7 +14063,7 @@
},
"os-locale": {
"version": "1.4.0",
- "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"requires": {
"lcid": "^1.0.0"
@@ -14302,7 +14396,7 @@
},
"es6-promise": {
"version": "4.0.5",
- "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz",
"integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=",
"dev": true
},
@@ -14358,7 +14452,7 @@
},
"progress": {
"version": "1.1.8",
- "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
"integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
"dev": true
},
@@ -15352,6 +15446,16 @@
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
"dev": true
},
+ "prop-types": {
+ "version": "15.7.2",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+ "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.8.1"
+ }
+ },
"protobufjs": {
"version": "6.8.8",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz",
@@ -15596,11 +15700,38 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
}
}
},
+ "react": {
+ "version": "16.8.6",
+ "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz",
+ "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1",
+ "prop-types": "^15.6.2",
+ "scheduler": "^0.13.6"
+ }
+ },
+ "react-dom": {
+ "version": "16.8.6",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz",
+ "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1",
+ "prop-types": "^15.6.2",
+ "scheduler": "^0.13.6"
+ }
+ },
+ "react-is": {
+ "version": "16.8.6",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
+ "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
+ },
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -15612,7 +15743,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
- "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
@@ -15646,7 +15777,7 @@
},
"pify": {
"version": "2.3.0",
- "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
@@ -15709,7 +15840,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -15847,7 +15978,7 @@
},
"regjsgen": {
"version": "0.2.0",
- "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
"dev": true
},
@@ -16039,7 +16170,7 @@
},
"requestretry": {
"version": "1.5.0",
- "resolved": "http://registry.npmjs.org/requestretry/-/requestretry-1.5.0.tgz",
+ "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.5.0.tgz",
"integrity": "sha1-7RV7ulNSbt6z7DKo5wSkmYvs5ic=",
"dev": true,
"requires": {
@@ -16171,7 +16302,7 @@
},
"rimraf": {
"version": "2.4.5",
- "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
"integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=",
"requires": {
"glob": "^6.0.1"
@@ -16266,7 +16397,7 @@
},
"safe-regex": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"requires": {
"ret": "~0.1.10"
@@ -16297,7 +16428,7 @@
},
"sax": {
"version": "1.2.1",
- "resolved": "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
"integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
},
"scandirectory": {
@@ -16311,6 +16442,15 @@
"taskgroup": "^4.0.5"
}
},
+ "scheduler": {
+ "version": "0.13.6",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz",
+ "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1"
+ }
+ },
"schema-inspector": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/schema-inspector/-/schema-inspector-1.6.8.tgz",
@@ -16321,7 +16461,7 @@
"dependencies": {
"async": {
"version": "1.5.2",
- "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
}
}
@@ -16406,7 +16546,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -17148,7 +17288,7 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
@@ -17725,7 +17865,7 @@
},
"through": {
"version": "2.3.8",
- "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
@@ -18521,7 +18661,7 @@
"dependencies": {
"semver": {
"version": "5.3.0",
- "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
}
}
@@ -19190,7 +19330,7 @@
},
"wrap-ansi": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"requires": {
"string-width": "^1.0.1",
@@ -19294,7 +19434,7 @@
},
"xolvio-ddp": {
"version": "0.12.3",
- "resolved": "http://registry.npmjs.org/xolvio-ddp/-/xolvio-ddp-0.12.3.tgz",
+ "resolved": "https://registry.npmjs.org/xolvio-ddp/-/xolvio-ddp-0.12.3.tgz",
"integrity": "sha1-NqarlhKyQLWg0cCoNJCK8XwLjwI=",
"dev": true,
"requires": {
@@ -19319,7 +19459,7 @@
},
"async": {
"version": "0.9.2",
- "resolved": "http://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
"dev": true
},
@@ -19331,7 +19471,7 @@
},
"bl": {
"version": "0.9.5",
- "resolved": "http://registry.npmjs.org/bl/-/bl-0.9.5.tgz",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz",
"integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=",
"dev": true,
"requires": {
@@ -19340,7 +19480,7 @@
},
"bluebird": {
"version": "2.11.0",
- "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=",
"dev": true
},
@@ -19352,7 +19492,7 @@
},
"combined-stream": {
"version": "0.0.7",
- "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
"integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
"dev": true,
"requires": {
@@ -19373,7 +19513,7 @@
},
"form-data": {
"version": "0.2.0",
- "resolved": "http://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
"integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=",
"dev": true,
"requires": {
@@ -19413,13 +19553,13 @@
},
"mime-db": {
"version": "1.12.0",
- "resolved": "http://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
"integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=",
"dev": true
},
"mime-types": {
"version": "2.0.14",
- "resolved": "http://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
"integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
"dev": true,
"requires": {
@@ -19446,7 +19586,7 @@
},
"readable-stream": {
"version": "1.0.34",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"dev": true,
"requires": {
@@ -19458,7 +19598,7 @@
},
"request": {
"version": "2.53.0",
- "resolved": "http://registry.npmjs.org/request/-/request-2.53.0.tgz",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.53.0.tgz",
"integrity": "sha1-GAo66St7Y5gC5PlUXdj83rcddgw=",
"dev": true,
"requires": {
@@ -19497,7 +19637,7 @@
},
"xolvio-fiber-utils": {
"version": "2.0.3",
- "resolved": "http://registry.npmjs.org/xolvio-fiber-utils/-/xolvio-fiber-utils-2.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/xolvio-fiber-utils/-/xolvio-fiber-utils-2.0.3.tgz",
"integrity": "sha1-vsjXDHQGGjFjFbun0w0lyz6C3FA=",
"dev": true,
"requires": {
@@ -19515,7 +19655,7 @@
},
"xolvio-jasmine-expect": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/xolvio-jasmine-expect/-/xolvio-jasmine-expect-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/xolvio-jasmine-expect/-/xolvio-jasmine-expect-1.1.0.tgz",
"integrity": "sha1-vCud1ghCMR8EV59agtzqaisxnH0=",
"dev": true,
"requires": {
@@ -19582,7 +19722,7 @@
},
"yargs": {
"version": "3.32.0",
- "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
"integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
"requires": {
"camelcase": "^2.0.1",
diff --git a/package.json b/package.json
index 67801442083..14e79a8b878 100644
--- a/package.json
+++ b/package.json
@@ -104,12 +104,13 @@
"chimp": "^0.51.1",
"emojione-assets": "^4.5.0",
"eslint": "^5.9.0",
+ "eslint-plugin-react": "^7.14.3",
"fast-glob": "^2.2.6",
"husky": "^1.2.0",
"mocha": "^5.2.0",
"mock-require": "^3.0.2",
- "node-sprite-generator": "^0.10.2",
"mongo-unit": "^1.4.4",
+ "node-sprite-generator": "^0.10.2",
"postcss": "^7.0.6",
"postcss-custom-properties": "^8.0.9",
"postcss-easy-import": "^3.0.0",
@@ -135,6 +136,8 @@
"@google-cloud/storage": "^2.3.1",
"@google-cloud/vision": "^0.23.0",
"@rocket.chat/apps-engine": "^1.5.2",
+ "@rocket.chat/fuselage": "^0.2.0-alpha.2",
+ "@rocket.chat/icons": "^0.2.0-alpha.0",
"@slack/client": "^4.8.0",
"adm-zip": "^0.4.13",
"apollo-server-express": "^1.3.6",
@@ -214,6 +217,8 @@
"prom-client": "^11.2.0",
"querystring": "^0.2.0",
"queue-fifo": "^0.2.5",
+ "react": "^16.8.6",
+ "react-dom": "^16.8.6",
"redis": "^2.8.0",
"semver": "^5.6.0",
"sharp": "^0.22.1",
diff --git a/public/fonts/RocketChat.eot b/public/fonts/RocketChat.eot
new file mode 120000
index 00000000000..25d326d7e00
--- /dev/null
+++ b/public/fonts/RocketChat.eot
@@ -0,0 +1 @@
+../../node_modules/@rocket.chat/icons/dist/font/RocketChat.eot
\ No newline at end of file
diff --git a/public/fonts/RocketChat.svg b/public/fonts/RocketChat.svg
new file mode 120000
index 00000000000..6360397c7a6
--- /dev/null
+++ b/public/fonts/RocketChat.svg
@@ -0,0 +1 @@
+../../node_modules/@rocket.chat/icons/dist/font/RocketChat.svg
\ No newline at end of file
diff --git a/public/fonts/RocketChat.ttf b/public/fonts/RocketChat.ttf
new file mode 120000
index 00000000000..4a2797b73b6
--- /dev/null
+++ b/public/fonts/RocketChat.ttf
@@ -0,0 +1 @@
+../../node_modules/@rocket.chat/icons/dist/font/RocketChat.ttf
\ No newline at end of file
diff --git a/public/fonts/RocketChat.woff b/public/fonts/RocketChat.woff
new file mode 120000
index 00000000000..5530527154c
--- /dev/null
+++ b/public/fonts/RocketChat.woff
@@ -0,0 +1 @@
+../../node_modules/@rocket.chat/icons/dist/font/RocketChat.woff
\ No newline at end of file
diff --git a/public/fonts/RocketChat.woff2 b/public/fonts/RocketChat.woff2
new file mode 120000
index 00000000000..85ba5007685
--- /dev/null
+++ b/public/fonts/RocketChat.woff2
@@ -0,0 +1 @@
+../../node_modules/@rocket.chat/icons/dist/font/RocketChat.woff2
\ No newline at end of file
diff --git a/server/importPackages.js b/server/importPackages.js
index 2c5b7ad7430..a8981a90f60 100644
--- a/server/importPackages.js
+++ b/server/importPackages.js
@@ -61,7 +61,6 @@ import '../app/otr/server';
import '../app/push-notifications/server';
import '../app/retention-policy';
import '../app/apps/server';
-import '../app/setup-wizard/server';
import '../app/slackbridge/server';
import '../app/slashcommands-archiveroom/server';
import '../app/slashcommand-asciiarts/server';
diff --git a/server/main.js b/server/main.js
index 2e682195f09..2d7e2e97270 100644
--- a/server/main.js
+++ b/server/main.js
@@ -30,6 +30,7 @@ import './methods/getAvatarSuggestion';
import './methods/getRoomById';
import './methods/getRoomIdByNameOrId';
import './methods/getRoomNameById';
+import './methods/getSetupWizardParameters';
import './methods/getTotalChannels';
import './methods/getUsersOfRoom';
import './methods/hideRoom';
diff --git a/app/setup-wizard/server/getSetupWizardParameters.js b/server/methods/getSetupWizardParameters.js
similarity index 52%
rename from app/setup-wizard/server/getSetupWizardParameters.js
rename to server/methods/getSetupWizardParameters.js
index b2a178e4be3..22e018e8765 100644
--- a/app/setup-wizard/server/getSetupWizardParameters.js
+++ b/server/methods/getSetupWizardParameters.js
@@ -1,17 +1,9 @@
import { Meteor } from 'meteor/meteor';
-import { hasRole } from '../../authorization';
-import { Settings } from '../../models';
+import { Settings } from '../../app/models';
Meteor.methods({
getSetupWizardParameters() {
- const userId = Meteor.userId();
- const userHasAdminRole = userId && hasRole(userId, 'admin');
-
- if (!userHasAdminRole) {
- throw new Meteor.Error('error-not-allowed');
- }
-
const settings = Settings.findSetupWizardSettings().fetch();
const allowStandaloneServer = process.env.DEPLOY_PLATFORM !== 'rocket-cloud';
diff --git a/tests/pageobjects/setup-wizard.page.js b/tests/pageobjects/setup-wizard.page.js
index 296f178bfc2..5d791b023f7 100644
--- a/tests/pageobjects/setup-wizard.page.js
+++ b/tests/pageobjects/setup-wizard.page.js
@@ -3,9 +3,9 @@ import { adminEmail, adminPassword } from '../data/user';
class SetupWizard extends Page {
- get nextButton() { return browser.element('.setup-wizard-forms__footer-next:enabled'); }
+ get nextButton() { return browser.element('.SetupWizard .SetupWizard__Step--active .SetupWizard__continue'); }
- get goToWorkspace() { return browser.element('button.js-finish'); }
+ get goToWorkspace() { return browser.element('.SetupWizard .SetupWizard__Epilogue__goToWorkspace'); }
get organizationType() { return browser.element('select[name="Organization_Type"]'); }