Skip to content

Commit

Permalink
Refactor components and views to Storybook compatibility (#17800)
Browse files Browse the repository at this point in the history
  • Loading branch information
tassoevan committed Jun 9, 2020
1 parent 6828007 commit 6be2861
Show file tree
Hide file tree
Showing 92 changed files with 1,578 additions and 1,301 deletions.
20 changes: 15 additions & 5 deletions .storybook/mocks/decorators.js → .storybook/decorators.js
@@ -1,21 +1,21 @@
import React from 'react';

import { MeteorProviderMock } from './providers';
import { MeteorProviderMock } from './mocks/providers';

export const rocketChatDecorator = (fn) => {
const linkElement = document.getElementById('theme-styles') || document.createElement('link');
if (linkElement.id !== 'theme-styles') {
require('../../app/theme/client/main.css');
require('../../app/theme/client/vendor/fontello/css/fontello.css');
require('../../app/theme/client/rocketchat.font.css');
require('../app/theme/client/main.css');
require('../app/theme/client/vendor/fontello/css/fontello.css');
require('../app/theme/client/rocketchat.font.css');
linkElement.setAttribute('id', 'theme-styles');
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('href', 'https://open.rocket.chat/theme.css');
document.head.appendChild(linkElement);
}

// eslint-disable-next-line import/no-unresolved
const { default: icons } = require('!!raw-loader!../../private/public/icons.svg');
const { default: icons } = require('!!raw-loader!../private/public/icons.svg');

return <MeteorProviderMock>
<style>{`
Expand All @@ -29,3 +29,13 @@ export const rocketChatDecorator = (fn) => {
</div>
</MeteorProviderMock>;
};

export const fullHeightDecorator = (storyFn) =>
<div style={{ display: 'flex', flexDirection: 'column', maxHeight: '100vh' }}>
{storyFn()}
</div>;

export const centeredDecorator = (storyFn) =>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh' }}>
{storyFn()}
</div>;
15 changes: 15 additions & 0 deletions .storybook/hooks.js
@@ -0,0 +1,15 @@
import { useEffect, useState } from 'react';

export const useAutoToggle = (initialValue = false, ms = 1000) => {
const [value, setValue] = useState(initialValue);

useEffect(() => {
const timer = setInterval(() => setValue((value) => !value), ms);

return () => {
clearInterval(timer);
};
}, []);

return value;
};
1 change: 1 addition & 0 deletions .storybook/main.js
Expand Up @@ -7,5 +7,6 @@ module.exports = {
addons: [
'@storybook/addon-actions',
'@storybook/addon-knobs',
'@storybook/addon-viewport',
],
};
10 changes: 8 additions & 2 deletions .storybook/preview.js
@@ -1,7 +1,13 @@
import { withKnobs } from '@storybook/addon-knobs';
import { addDecorator } from '@storybook/react';
import { addDecorator, addParameters } from '@storybook/react';

import { rocketChatDecorator } from './mocks/decorators';
import { rocketChatDecorator } from './decorators';

addDecorator(rocketChatDecorator);
addDecorator(withKnobs);

addParameters({
options: {
showRoots: true,
},
});
4 changes: 1 addition & 3 deletions .storybook/webpack.config.js
Expand Up @@ -42,9 +42,7 @@ module.exports = async ({ config }) => {
},
},
},
{
loader: 'react-docgen-typescript-loader',
},
'react-docgen-typescript-loader',
],
});

Expand Down
2 changes: 1 addition & 1 deletion app/2fa/server/code/EmailCheck.ts
Expand Up @@ -99,7 +99,7 @@ ${ t('If_you_didnt_try_to_login_in_your_account_please_ignore_this_email') }
const random = Random._randomString(6, '0123456789');
const encryptedRandom = bcrypt.hashSync(random, Accounts._bcryptRounds());
const expire = new Date();
const expirationInSeconds = parseInt(settings.get('Accounts_TwoFactorAuthentication_By_Email_Code_Expiration'));
const expirationInSeconds = parseInt(settings.get('Accounts_TwoFactorAuthentication_By_Email_Code_Expiration') as string, 10);

expire.setSeconds(expire.getSeconds() + expirationInSeconds);

Expand Down
2 changes: 1 addition & 1 deletion app/2fa/server/code/index.ts
Expand Up @@ -95,7 +95,7 @@ export function isAuthorizedForToken(connection: IMethodConnection, user: IUser,
export function rememberAuthorization(connection: IMethodConnection, user: IUser): void {
const currentToken = Accounts._getLoginToken(connection.id);

const rememberFor = parseInt(settings.get('Accounts_TwoFactorAuthentication_RememberFor'));
const rememberFor = parseInt(settings.get('Accounts_TwoFactorAuthentication_RememberFor') as string, 10);

if (rememberFor <= 0) {
return;
Expand Down
2 changes: 1 addition & 1 deletion app/authorization/server/functions/hasPermission.js
Expand Up @@ -12,7 +12,7 @@ const rolesHasPermission = mem(async (permission, roles) => {
return !!result;
}, {
cacheKey: JSON.stringify,
...process.env.TEST_MODE === 'true' && { maxAge: 0 },
...process.env.TEST_MODE === 'true' && { maxAge: 1 },
});

const getRoles = mem(async (uid, scope) => {
Expand Down
20 changes: 16 additions & 4 deletions app/livechat/server/lib/stream/agentStatus.ts
Expand Up @@ -9,19 +9,31 @@ let actionTimeout = 60000;
let action = 'none';
let comment = '';

settings.get('Livechat_agent_leave_action_timeout', function(_key: string, value: number) {
settings.get('Livechat_agent_leave_action_timeout', (_key, value) => {
if (typeof value !== 'number') {
return;
}
actionTimeout = value * 1000;
});

settings.get('Livechat_agent_leave_action', function(_key: string, value: boolean) {
settings.get('Livechat_agent_leave_action', (_key, value) => {
if (typeof value !== 'boolean') {
return;
}
monitorAgents = value;
});

settings.get('Livechat_agent_leave_action', function(_key: string, value: string) {
settings.get('Livechat_agent_leave_action', (_key, value) => {
if (typeof value !== 'string') {
return;
}
action = value;
});

settings.get('Livechat_agent_leave_comment', function(_key: string, value: string) {
settings.get('Livechat_agent_leave_comment', (_key, value) => {
if (typeof value !== 'string') {
return;
}
comment = value;
});

Expand Down
3 changes: 1 addition & 2 deletions app/ui-message/client/blocks/MessageBlock.js
Expand Up @@ -2,7 +2,6 @@ import { UIKitIncomingInteractionContainerType } from '@rocket.chat/apps-engine/
import { UiKitMessage, UiKitComponent, kitContext, messageParser } from '@rocket.chat/fuselage-ui-kit';
import React, { useRef, useEffect } from 'react';

import RawText from '../../../../client/components/basic/RawText';
import { renderMessageBody } from '../../../ui-utils/client';
import * as ActionManager from '../ActionManager';

Expand All @@ -12,7 +11,7 @@ messageParser.text = ({ text, type } = {}) => {
return text;
}

return <RawText>{renderMessageBody({ msg: text })}</RawText>;
return <span dangerouslySetInnerHTML={{ __html: renderMessageBody({ msg: text }) }} />;
};

export function MessageBlock({ mid: _mid, rid, blocks, appId }) {
Expand Down
3 changes: 1 addition & 2 deletions app/ui-message/client/blocks/ModalBlock.js
Expand Up @@ -5,7 +5,6 @@ import { kitContext, UiKitComponent, UiKitModal, modalParser } from '@rocket.cha
import { uiKitText } from '@rocket.chat/ui-kit';
import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';

import RawText from '../../../../client/components/basic/RawText';
import { renderMessageBody } from '../../../ui-utils/client';
import { getURL } from '../../../utils/lib/getURL';
import * as ActionManager from '../ActionManager';
Expand All @@ -16,7 +15,7 @@ modalParser.text = ({ text, type } = {}) => {
return text;
}

return <RawText>{renderMessageBody({ msg: text })}</RawText>;
return <span dangerouslySetInnerHTML={{ __html: renderMessageBody({ msg: text }) }} />;
};

const textParser = uiKitText({
Expand Down
2 changes: 1 addition & 1 deletion app/ui/client/components/GenericTable.stories.js
Expand Up @@ -5,7 +5,7 @@ import { GenericTable, Th } from './GenericTable';


export default {
title: 'directory/table',
title: 'uncategorized/GenericTable',
component: GenericTable,
decorators: [(fn) => <div children={fn()} style={{ height: '100vh' }} />],
};
Expand Down
4 changes: 1 addition & 3 deletions app/ui/client/views/app/components/Directory/ChannelsTab.js
Expand Up @@ -88,9 +88,7 @@ export function ChannelsTab() {
<Box display='flex' alignItems='center'>
<Icon name={roomTypes.getIcon(room)} color='hint' /> <Box fontScale='p2' mi='x4'>{fname || name}</Box><RoomTags room={room} style={style} />
</Box>
{topic && <Box fontScale='p1' color='hint' style={style}>
<MarkdownText>{topic}</MarkdownText>
</Box>}
{topic && <MarkdownText fontScale='p1' color='hint' style={style} content={topic} />}
</Box>
</Box>
</Table.Cell>
Expand Down
6 changes: 1 addition & 5 deletions client/admin/cloud/ManualWorkspaceRegistrationModal.js
Expand Up @@ -67,11 +67,7 @@ function CopyStep({ onNextButtonClick }) {
<Icon name='copy' /> {t('Copy')}
</Button>
</Box>
<Box withRichContent>
<p>
<MarkdownText>{t('Cloud_click_here', { cloudConsoleUrl })}</MarkdownText>
</p>
</Box>
<MarkdownText is='p' withRichContent content={t('Cloud_click_here', { cloudConsoleUrl })} />
</Modal.Content>
<Modal.Footer>
<ButtonGroup>
Expand Down
2 changes: 1 addition & 1 deletion client/admin/invites/InvitesPage.js
Expand Up @@ -9,9 +9,9 @@ import React, { useState, useEffect } from 'react';
import moment from 'moment';

import Page from '../../components/basic/Page';
import { useModal } from '../../contexts/ModalContext';
import { useTranslation } from '../../contexts/TranslationContext';
import { useEndpoint } from '../../contexts/ServerContext';
import { useModal } from '../../hooks/useModal';
import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext';
import { GenericTable } from '../../../app/ui/client/components/GenericTable';
import { useFormatDateAndTime } from '../../hooks/useFormatDateAndTime';
Expand Down
5 changes: 1 addition & 4 deletions client/admin/mailer/Mailer.js
Expand Up @@ -4,7 +4,6 @@ import { TextInput, TextAreaInput, Field, FieldGroup, CheckBox, Button, Icon, Bu
import { isEmail } from '../../../app/utils/lib/isEmail.js';
import { isJSON } from '../../../app/utils/lib/isJSON.js';
import Page from '../../components/basic/Page';
import RawText from '../../components/basic/RawText';
import { useTranslation } from '../../contexts/TranslationContext';

export function Mailer({ sendMail = () => {} }) {
Expand Down Expand Up @@ -95,9 +94,7 @@ export function Mailer({ sendMail = () => {} }) {
onChange={(e) => setEmailBody(e.currentTarget.value)}
/>
</Field.Row>
<Field.Hint>
<RawText>{t('Mailer_body_tags')}</RawText>
</Field.Hint>
<Field.Hint dangerouslySetInnerHTML={{ __html: t('Mailer_body_tags') }} />
</Field>
</FieldGroup>
</Page.ScrollableContentWithShadow>
Expand Down
2 changes: 1 addition & 1 deletion client/admin/settings/GroupPage.js
@@ -1,9 +1,9 @@
import { Accordion, Box, Button, ButtonGroup, Skeleton } from '@rocket.chat/fuselage';
import React, { useMemo } from 'react';

import Page from '../../components/basic/Page';
import { useTranslation } from '../../contexts/TranslationContext';
import { Section } from './Section';
import Page from '../../components/basic/Page';

export function GroupPage({ children, headerButtons, save, cancel, _id, i18nLabel, i18nDescription, changed }) {
const t = useTranslation();
Expand Down
6 changes: 0 additions & 6 deletions client/admin/settings/GroupPage.stories.js
@@ -1,16 +1,10 @@
import React from 'react';

import { GroupPage } from './GroupPage';
import { SettingsState } from './SettingsState';

export default {
title: 'admin/settings/GroupPage',
component: GroupPage,
decorators: [
(storyFn) => <SettingsState>
{storyFn()}
</SettingsState>,
],
};

export const _default = () =>
Expand Down
4 changes: 2 additions & 2 deletions client/admin/settings/GroupSelector.js
@@ -1,13 +1,13 @@
import React from 'react';

import { usePrivateSettingsGroup } from '../../contexts/PrivateSettingsContext';
import { AssetsGroupPage } from './groups/AssetsGroupPage';
import { OAuthGroupPage } from './groups/OAuthGroupPage';
import { GenericGroupPage } from './groups/GenericGroupPage';
import { GroupPage } from './GroupPage';
import { useGroup } from './SettingsState';

export function GroupSelector({ groupId }) {
const group = useGroup(groupId);
const group = usePrivateSettingsGroup(groupId);

if (!group) {
return <GroupPage.Skeleton />;
Expand Down
4 changes: 0 additions & 4 deletions client/admin/settings/GroupSelector.stories.js
@@ -1,14 +1,10 @@
import React from 'react';

import { GroupSelector } from './GroupSelector';
import { SettingsState } from './SettingsState';

export default {
title: 'admin/settings/GroupSelector',
component: GroupSelector,
decorators: [
(storyFn) => <SettingsState>{storyFn()}</SettingsState>,
],
};

export const _default = () => <GroupSelector />;
9 changes: 6 additions & 3 deletions client/admin/settings/Section.js
@@ -1,13 +1,16 @@
import { Accordion, Box, Button, FieldGroup, Skeleton } from '@rocket.chat/fuselage';
import React from 'react';

import {
usePrivateSettingsSection,
usePrivateSettingsSectionChangedState,
} from '../../contexts/PrivateSettingsContext';
import { useTranslation } from '../../contexts/TranslationContext';
import { Setting } from './Setting';
import { useSection, useSectionChangedState } from './SettingsState';

export function Section({ children, groupId, hasReset = true, help, sectionName, solo }) {
const section = useSection(groupId, sectionName);
const changed = useSectionChangedState(groupId, sectionName);
const section = usePrivateSettingsSection(groupId, sectionName);
const changed = usePrivateSettingsSectionChangedState(groupId, sectionName);

const t = useTranslation();

Expand Down
4 changes: 0 additions & 4 deletions client/admin/settings/Section.stories.js
@@ -1,14 +1,10 @@
import React from 'react';

import { Section } from './Section';
import { SettingsState } from './SettingsState';

export default {
title: 'admin/settings/Section',
component: Section,
decorators: [
(storyFn) => <SettingsState>{storyFn()}</SettingsState>,
],
};

export const _default = () => <Section groupId='General' />;
Expand Down
9 changes: 4 additions & 5 deletions client/admin/settings/Setting.js
Expand Up @@ -2,7 +2,7 @@ import { Callout, Field, Flex, InputBox, Margins, Skeleton } from '@rocket.chat/
import React, { memo, useEffect, useMemo, useState, useCallback } from 'react';

import MarkdownText from '../../components/basic/MarkdownText';
import RawText from '../../components/basic/RawText';
import { usePrivateSetting } from '../../contexts/PrivateSettingsContext';
import { useTranslation } from '../../contexts/TranslationContext';
import { GenericSettingInput } from './inputs/GenericSettingInput';
import { BooleanSettingInput } from './inputs/BooleanSettingInput';
Expand All @@ -19,7 +19,6 @@ import { CodeSettingInput } from './inputs/CodeSettingInput';
import { ActionSettingInput } from './inputs/ActionSettingInput';
import { AssetSettingInput } from './inputs/AssetSettingInput';
import { RoomPickSettingInput } from './inputs/RoomPickSettingInput';
import { useSetting } from './SettingsState';

export const MemoizedSetting = memo(function MemoizedSetting({
type,
Expand Down Expand Up @@ -71,7 +70,7 @@ export function Setting({ settingId, sectionChanged }) {
update,
reset,
...setting
} = useSetting(settingId);
} = usePrivateSetting(settingId);


const t = useTranslation();
Expand Down Expand Up @@ -116,8 +115,8 @@ export function Setting({ settingId, sectionChanged }) {
} = setting;

const label = (i18nLabel && t(i18nLabel)) || (_id || t(_id));
const hint = useMemo(() => t.has(i18nDescription) && <MarkdownText>{t(i18nDescription)}</MarkdownText>, [i18nDescription]);
const callout = useMemo(() => alert && <RawText>{t(alert)}</RawText>, [alert]);
const hint = useMemo(() => t.has(i18nDescription) && <MarkdownText content={t(i18nDescription)} />, [i18nDescription]);
const callout = useMemo(() => alert && <span dangerouslySetInnerHTML={{ __html: t(alert) }} />, [alert]);
const hasResetButton = !disableReset && !readonly && type !== 'asset' && (JSON.stringify(packageEditor) !== JSON.stringify(editor) || JSON.stringify(value) !== JSON.stringify(packageValue)) && !disabled;

return <MemoizedSetting
Expand Down

0 comments on commit 6be2861

Please sign in to comment.