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

Chore: Presence cap tweaks #28058

Merged
merged 19 commits into from
Feb 23, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions apps/meteor/client/sidebar/header/UserAvatarButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { css } from '@rocket.chat/css-in-js';
import { Box, Dropdown } from '@rocket.chat/fuselage';
import { useUser } from '@rocket.chat/ui-contexts';
import { useSetting, useUser } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React, { memo, useRef } from 'react';
import { createPortal } from 'react-dom';
Expand All @@ -22,6 +22,7 @@ const UserAvatarButton = (): ReactElement => {
const user = useUser();

const { status = !user ? 'online' : 'offline', username, avatarETag, statusText } = user || anon;
const presenceDisabled = useSetting<boolean>('Presence_broadcast_disabled');

// const allowAnonymousRead = useSetting('Accounts_AllowAnonymousRead');

Expand Down Expand Up @@ -59,7 +60,7 @@ const UserAvatarButton = (): ReactElement => {
mie='neg-x2'
mbe='neg-x2'
>
<UserStatus small status={status} statusText={statusText} />
<UserStatus small status={presenceDisabled ? 'disabled' : status} statusText={statusText} />
</Box>
</Box>
{user &&
Expand Down
47 changes: 5 additions & 42 deletions apps/meteor/client/sidebar/header/UserDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ import {
} from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { useLayout, useRole, useRoute, useLogout, useSetting, useTranslation, useSetModal } from '@rocket.chat/ui-contexts';
import { useLayout, useRoute, useLogout, useSetting, useTranslation } from '@rocket.chat/ui-contexts';
import { useThemeMode } from '@rocket.chat/ui-theming/src/hooks/useThemeMode';
import type { ReactElement } from 'react';
import React from 'react';

import { AccountBox } from '../../../app/ui-utils/client';
import { userStatus } from '../../../app/user-status/client';
import { callbacks } from '../../../lib/callbacks';
import GenericModal from '../../components/GenericModal';
import MarkdownText from '../../components/MarkdownText';
import { UserStatus } from '../../components/UserStatus';
import UserAvatar from '../../components/avatar/UserAvatar';
import { useUserDisplayName } from '../../hooks/useUserDisplayName';
import { imperativeModal } from '../../lib/imperativeModal';
import { useStatusDisabledModal } from '../../views/admin/customUserStatus/hooks/useStatusDisabledModal';
import EditStatusModal from './EditStatusModal';

const isDefaultStatus = (id: string): boolean => (Object.values(UserStatusEnum) as string[]).includes(id);
Expand Down Expand Up @@ -54,19 +54,11 @@ type UserDropdownProps = {
const UserDropdown = ({ user, onClose }: UserDropdownProps): ReactElement => {
const t = useTranslation();
const accountRoute = useRoute('account-index');
const userStatusRoute = useRoute('user-status');
const logout = useLogout();
const { isMobile } = useLayout();
const presenceDisabled = useSetting<boolean>('Presence_broadcast_disabled');
const isAdmin = useRole('admin');
const handleStatusDisabledModal = useStatusDisabledModal();

const setModal = useSetModal();
const closeModal = useMutableCallback(() => setModal());
const handleGoToSettings = useMutableCallback(() => {
userStatusRoute.push({});
closeModal();
onClose();
});
const [selectedTheme, setTheme] = useThemeMode();

const { username, avatarETag, status, statusText } = user;
Expand Down Expand Up @@ -105,7 +97,7 @@ const UserDropdown = ({ user, onClose }: UserDropdownProps): ReactElement => {
<Box mis='x4' display='flex' overflow='hidden' flexDirection='column' fontScale='p2' mb='neg-x4' flexGrow={1} flexShrink={1}>
<Box withTruncatedText w='full' display='flex' alignItems='center' flexDirection='row'>
<Margins inline='x4'>
<UserStatus status={status} />
<UserStatus status={presenceDisabled ? 'disabled' : status} />
<Box is='span' withTruncatedText display='inline-block' fontWeight='700'>
{displayName}
</Box>
Expand All @@ -126,36 +118,7 @@ const UserDropdown = ({ user, onClose }: UserDropdownProps): ReactElement => {
{presenceDisabled && (
<Box fontScale='p2' mi='x12' mb='x4'>
<Box mbe='x4'>{t('User_status_disabled')}</Box>
<Box
is='a'
color='status-font-on-info'
onClick={() =>
setModal(
isAdmin ? (
<GenericModal
title={t('User_status_disabled_learn_more')}
cancelText={t('Close')}
confirmText={t('Go_to_workspace_settings')}
children={t('User_status_disabled_learn_more_description')}
onConfirm={handleGoToSettings}
onClose={closeModal}
onCancel={closeModal}
icon={null}
variant='warning'
/>
) : (
<GenericModal
title={t('User_status_disabled_learn_more')}
confirmText={t('Close')}
children={t('User_status_disabled_learn_more_description')}
onConfirm={closeModal}
onClose={closeModal}
icon={null}
/>
),
)
}
>
<Box is='a' color='status-font-on-info' onClick={handleStatusDisabledModal}>
{t('Learn_more')}
</Box>
</Box>
Expand Down
41 changes: 4 additions & 37 deletions apps/meteor/client/sidebar/sections/StatusDisabledSection.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,19 @@
import { SidebarBanner } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useRole, useRoute, useSetModal, useTranslation } from '@rocket.chat/ui-contexts';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';

import GenericModal from '../../components/GenericModal';
import { useStatusDisabledModal } from '../../views/admin/customUserStatus/hooks/useStatusDisabledModal';

const StatusDisabledSection = ({ onDismiss }: { onDismiss: () => void }) => {
const t = useTranslation();
const userStatusRoute = useRoute('user-status');
const setModal = useSetModal();
const closeModal = useMutableCallback(() => setModal());
const handleGoToSettings = useMutableCallback(() => {
userStatusRoute.push({});
closeModal();
});
const isAdmin = useRole('admin');
const handleStatusDisabledModal = useStatusDisabledModal();

return (
<SidebarBanner
text={t('User_status_temporarily_disabled')}
description={t('Learn_more')}
onClose={onDismiss}
onClick={() =>
setModal(
isAdmin ? (
<GenericModal
title={t('User_status_disabled_learn_more')}
cancelText={t('Close')}
confirmText={t('Go_to_workspace_settings')}
children={t('User_status_disabled_learn_more_description')}
onConfirm={handleGoToSettings}
onClose={closeModal}
onCancel={closeModal}
icon={null}
variant='warning'
/>
) : (
<GenericModal
title={t('User_status_disabled_learn_more')}
confirmText={t('Close')}
children={t('User_status_disabled_learn_more_description')}
onConfirm={closeModal}
onClose={closeModal}
icon={null}
/>
),
)
}
onClick={handleStatusDisabledModal}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';

import GenericModal from '../../../components/GenericModal';

type CustomUserStatusDisabledModalProps = { isAdmin: boolean; onConfirm: () => void; onClose: () => void };

const CustomUserStatusDisabledModal = ({ isAdmin, onConfirm, onClose }: CustomUserStatusDisabledModalProps) => {
const t = useTranslation();
return isAdmin ? (
<GenericModal
title={t('User_status_disabled_learn_more')}
cancelText={t('Close')}
confirmText={t('Go_to_workspace_settings')}
children={t('User_status_disabled_learn_more_description')}
onConfirm={onConfirm}
onClose={onClose}
onCancel={onClose}
icon={null}
variant='warning'
/>
) : (
<GenericModal
title={t('User_status_disabled_learn_more')}
confirmText={t('Close')}
children={t('User_status_disabled_learn_more_description')}
onConfirm={onConfirm}
onClose={onClose}
icon={null}
/>
);
};

export default CustomUserStatusDisabledModal;
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Button, ButtonGroup } from '@rocket.chat/fuselage';
import { useRoute, useRouteParameter, usePermission, useTranslation } from '@rocket.chat/ui-contexts';
import { useRoute, useRouteParameter, usePermission, useTranslation, useSetting } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React, { useCallback, useRef } from 'react';
import React, { useCallback, useRef, useEffect } from 'react';

import Page from '../../../components/Page';
import VerticalBar from '../../../components/VerticalBar';
import { useIsEnterprise } from '../../../hooks/useIsEnterprise';
import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage';
import CustomUserActiveConnections from './CustomUserActiveConnections';
import CustomUserStatusFormWithData from './CustomUserStatusFormWithData';
Expand All @@ -17,6 +18,12 @@ const CustomUserStatusRoute = (): ReactElement => {
const context = useRouteParameter('context');
const id = useRouteParameter('id');
const canManageUserStatus = usePermission('manage-user-status');
const { data: license } = useIsEnterprise();
const presenceDisabled = useSetting<boolean>('Presence_broadcast_disabled');

useEffect(() => {
presenceDisabled && route.push({ context: 'presence-service' });
}, [presenceDisabled, route]);

const handleItemClick = (id: string): void => {
route.push({
Expand Down Expand Up @@ -51,7 +58,7 @@ const CustomUserStatusRoute = (): ReactElement => {
<Page flexDirection='row'>
<Page name='admin-user-status'>
<Page.Header title={t('User_Status')}>
<CustomUserActiveConnections />
{!license?.isEnterprise && <CustomUserActiveConnections />}
<ButtonGroup>
<Button onClick={handlePresenceServiceClick}>{t('Presence_service')}</Button>
<Button onClick={handleNewButtonClick}>{t('New_custom_status')}</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,18 @@ const CustomUserStatusService = () => {
const presenceDisabled = useSetting<boolean>('Presence_broadcast_disabled');
const togglePresenceServiceEndpoint = useEndpoint('POST', '/v1/presence.enableBroadcast');
const disablePresenceService = useMutation(() => togglePresenceServiceEndpoint());
const isEnterprise = useIsEnterprise();
const { data: license, isLoading: licenseIsLoading } = useIsEnterprise();

if (result.isLoading || disablePresenceService.isLoading) {
return <Skeleton />;
if (result.isLoading || disablePresenceService.isLoading || licenseIsLoading) {
return (
<Box pi='x16' pb='x8'>
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
</Box>
);
}
if (result.isError || disablePresenceService.isError) {
return (
Expand All @@ -54,18 +62,14 @@ const CustomUserStatusService = () => {
<ToggleSwitch
disabled={disablePresenceService.isLoading || !presenceDisabled || percentage === 100}
checked={!presenceDisabled}
onClick={
!(disablePresenceService.isLoading || !presenceDisabled || percentage === 100)
? () => disablePresenceService.mutate()
: undefined
}
onChange={() => disablePresenceService.mutate()}
/>
</Box>
<Box display='flex' fontScale='c1' justifyContent='space-between' mb='x16'>
<Box>{t('Active_connections')}</Box>
<Box>{isEnterprise ? current : `${current}/${max}`}</Box>
<Box>{license?.isEnterprise ? current : `${current}/${max}`}</Box>
</Box>
{!isEnterprise && <ProgressBar percentage={percentage} variant={percentage > 80 ? 'danger' : 'success'} />}
{!license?.isEnterprise && <ProgressBar percentage={percentage} variant={percentage > 80 ? 'danger' : 'success'} />}
{presenceDisabled && (
<Margins block='x16'>
<Callout type='danger' title={t('Service_disabled')}>
Expand All @@ -75,14 +79,14 @@ const CustomUserStatusService = () => {
)}
</div>
<Box display='flex' flexDirection='column' mb='x16'>
{isEnterprise ? (
{license?.isEnterprise ? (
<>
<Box fontScale='p2' mb='x8'>
{t('Enterprise_cap_description')}
</Box>
<Box fontScale='p2' mb='x8'>
{t('Larger_amounts_of_active_connections')}{' '}
<Box is='a' href='https://go.rocket.chat/i/presence-cap-learn-more' target='_blank' color='status-font-on-info'>
<Box is='a' href='https://docs.rocket.chat/deploy/scaling-rocket.chat' target='_blank' color='info'>
{t('multiple_instance_solutions')}
</Box>
</Box>
Expand All @@ -99,10 +103,10 @@ const CustomUserStatusService = () => {
)}
</Box>
</VerticalBar.Content>
{!isEnterprise && (
{!license?.isEnterprise && (
<VerticalBar.Footer borderBlockStartWidth='default' borderBlockColor='extra-light'>
<ButtonGroup stretch vertical>
<Button primary width='100%' is='a' href='https://go.rocket.chat/i/presence-cap-learn-more' target='_blank'>
<Button primary width='100%' is='a' href='https://www.rocket.chat/enterprise' target='_blank'>
{t('More_about_Enterprise_Edition')}
</Button>
</ButtonGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useRole, useRoute, useSetModal } from '@rocket.chat/ui-contexts';
import React from 'react';

import CustomUserStatusDisabledModal from '../CustomUserStatusDisabledModal';

export const useStatusDisabledModal = () => {
const userStatusRoute = useRoute('user-status');
const setModal = useSetModal();
const closeModal = useMutableCallback(() => setModal());
const handleGoToSettings = useMutableCallback(() => {
userStatusRoute.push({ context: 'presence-service' });
closeModal();
});
const isAdmin = useRole('admin');

const handleSetModal = () => {
setModal(<CustomUserStatusDisabledModal isAdmin={isAdmin} onConfirm={handleGoToSettings} onClose={closeModal} />);
};

return handleSetModal;
};
2 changes: 1 addition & 1 deletion apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -5686,7 +5686,7 @@
"Service_disabled": "The service is now disabled",
"Service_disabled_description": "You can't reenable it again until there's less than 200 active connections at the same time",
"User_status_disabled": "User status temporarily disabled to maintain performance.",
"User_status_disabled_learn_more": "Keeping performance in mind",
"User_status_disabled_learn_more": "User status disabled",
"User_status_disabled_learn_more_description": "Due to high volume of active connections, the service that handles user status is temporarily disabled. Administrators can re-enable this manually in the workspace settings.",
"Go_to_workspace_settings": "Go to workspace settings",
"User_status_temporarily_disabled": "User status temporarily disabled",
Expand Down