Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor components and views to Storybook compatibility #17800

Merged
merged 23 commits into from Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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