Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ee9ae97
fix: :bug: Marketplace app details page back-button behavior
rique223 Oct 13, 2022
e4a0771
Lock
rique223 Oct 13, 2022
b3f4771
test: :white_check_mark: Update AppsModelList tests to work with new …
rique223 Oct 13, 2022
700e67a
Fix admin menu tests
rique223 Oct 14, 2022
9c9ad6d
Merge branch 'develop' into fix/marketplace-back-button
rique223 Oct 15, 2022
6b021fa
Solve upload app page cancel button behavior
rique223 Oct 18, 2022
61b3174
Merge remote-tracking branch 'origin' into fix/marketplace-back-button
rique223 Nov 1, 2022
9e31fc3
Typecheck
rique223 Nov 1, 2022
99f6749
Merge remote-tracking branch 'origin' into fix/marketplace-back-button
rique223 Nov 7, 2022
a9c7ca7
Merge branch 'develop' into fix/marketplace-back-button
dougfabris Nov 10, 2022
cc33f3e
fix: review
dougfabris Nov 10, 2022
99105f5
review
juliajforesti Nov 10, 2022
3349abd
Solve wrong types review
rique223 Nov 10, 2022
cd17f32
Merge branch 'fix/marketplace-back-button' of github.com:RocketChat/R…
rique223 Nov 10, 2022
9aa9b74
Merge branch 'develop' into fix/marketplace-back-button
rique223 Nov 10, 2022
1adf60b
Merge remote-tracking branch 'origin' into fix/marketplace-back-button
rique223 Nov 11, 2022
715c5b0
Merge branch 'fix/marketplace-back-button' of github.com:RocketChat/R…
rique223 Nov 11, 2022
04d090c
Merge origin and add divider to AppMenu
rique223 Nov 11, 2022
815f0b7
Merge branch 'develop' into fix/marketplace-back-button
rique223 Nov 11, 2022
990496f
Merge branch 'develop' into fix/marketplace-back-button
rique223 Nov 14, 2022
270e70e
Merge branch 'develop' into fix/marketplace-back-button
rique223 Nov 16, 2022
30cc797
Merge branch 'develop' into fix/marketplace-back-button
rique223 Nov 16, 2022
3f8d269
Merge branch 'develop' into fix/marketplace-back-button
rique223 Nov 17, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type AppsModelListProps = {
const AppsModelList: FC<AppsModelListProps> = ({ appBoxItems, showManageApps, closeList }) => {
Comment thread
rique223 marked this conversation as resolved.
Outdated
const t = useTranslation();
const marketplaceRoute = useRoute('admin-marketplace');
const page = 'list';

return (
<>
Expand All @@ -26,15 +27,15 @@ const AppsModelList: FC<AppsModelListProps> = ({ appBoxItems, showManageApps, cl
icon='store'
text={t('Marketplace')}
action={(): void => {
marketplaceRoute.push();
marketplaceRoute.push({ context: 'all', page });
closeList();
}}
/>
<ListItem
icon='cube'
text={t('Installed')}
action={(): void => {
marketplaceRoute.push({ context: 'installed' });
marketplaceRoute.push({ context: 'installed', page });
closeList();
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@ const AppDetailsPage = ({ id }: { id: App['id'] }): ReactElement => {
const settingsRef = useRef<Record<string, ISetting['value']>>({});
const appData = useAppInfo(id);

const [routeName, urlParams] = useCurrentRoute();
const appsRoute = useRoute('admin-apps');
const marketplaceRoute = useRoute('admin-marketplace');
const tab = useRouteParameter('tab');

const [currentRouteName] = useCurrentRoute();
if (!currentRouteName) {
throw new Error('No current route name');
}

const router = useRoute(currentRouteName);
const handleReturn = useMutableCallback((): void => router.push({}));

const [, urlParams] = useCurrentRoute();
const tab = useRouteParameter('tab');
const context = useRouteParameter('context');

const handleReturn = useMutableCallback((): void => {
context && router.push({ context, page: 'list' });
});

const { installed, settings, privacyPolicySummary, permissions, tosLink, privacyLink, marketplace } = appData || {};
const isSecurityVisible = privacyPolicySummary || permissions || tosLink || privacyLink;
Expand All @@ -61,13 +62,7 @@ const AppDetailsPage = ({ id }: { id: App['id'] }): ReactElement => {
}, [id, settings]);

const handleTabClick = (tab: 'details' | 'security' | 'releases' | 'settings' | 'logs'): void => {
if (routeName === 'admin-marketplace') {
marketplaceRoute.replace({ ...urlParams, tab });
}

if (routeName === 'admin-apps') {
appsRoute.replace({ ...urlParams, tab });
}
router.replace({ ...urlParams, tab });
};

return (
Expand Down
43 changes: 24 additions & 19 deletions apps/meteor/client/views/admin/apps/AppInstallPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
useEndpoint,
useUpload,
useTranslation,
useToastMessageDispatch,
useCurrentRoute,
useRouteParameter,
} from '@rocket.chat/ui-contexts';
import React, { useCallback, useEffect, useState } from 'react';

Expand All @@ -16,16 +17,25 @@ import { useFileInput } from '../../../hooks/useFileInput';
import { useForm } from '../../../hooks/useForm';
import AppPermissionsReviewModal from './AppPermissionsReviewModal';
import AppUpdateModal from './AppUpdateModal';
import { handleInstallError } from './helpers';
import { useAppsReload } from './AppsContext';
import { handleAPIError, handleInstallError } from './helpers';
import { getManifestFromZippedApp } from './lib/getManifestFromZippedApp';

const placeholderUrl = 'https://rocket.chat/apps/package.zip';

function AppInstallPage() {
const t = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();

const appsRoute = useRoute('admin-apps');
const reload = useAppsReload();

const [currentRouteName] = useCurrentRoute();
if (!currentRouteName) {
throw new Error('No current route name');
}
const router = useRoute(currentRouteName);

const context = useRouteParameter('context');

const setModal = useSetModal();

const appId = useQueryStringParameter('id');
Expand Down Expand Up @@ -61,25 +71,20 @@ function AppInstallPage() {
fileData.append('app', appFile, appFile.name);
fileData.append('permissions', JSON.stringify(permissionsGranted));

if (appId) {
try {
try {
if (appId) {
await uploadUpdateApp(fileData);
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
} finally {
setModal(null);
}
} else {
try {
} else {
app = await uploadApp(fileData);
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
} finally {
setModal(null);
}
} catch (e) {
handleAPIError(e);
}

appsRoute.push({ context: 'details', id: appId || app.app.id });
router.push({ context: 'installed', page: 'info', id: appId || app.app.id });

reload();

setModal(null);
};

Expand Down Expand Up @@ -140,7 +145,7 @@ function AppInstallPage() {
};

const handleCancel = () => {
appsRoute.push();
router.push({ context, page: 'list' });
};

return (
Expand Down
22 changes: 18 additions & 4 deletions apps/meteor/client/views/admin/apps/AppMenu.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Box, Icon, Menu } from '@rocket.chat/fuselage';
import { useSetModal, useMethod, useEndpoint, useTranslation, useRoute, useRouteParameter } from '@rocket.chat/ui-contexts';
import {
useSetModal,
useMethod,
useEndpoint,
useTranslation,
useRoute,
useRouteParameter,
useCurrentRoute,
} from '@rocket.chat/ui-contexts';
import React, { useMemo, useCallback } from 'react';

import WarningModal from '../../../components/WarningModal';
Expand All @@ -11,7 +19,13 @@ function AppMenu({ app, ...props }) {
const t = useTranslation();
const setModal = useSetModal();
const checkUserLoggedIn = useMethod('cloud:checkUserLoggedIn');
const appsRoute = useRoute('admin-apps');

const [currentRouteName] = useCurrentRoute();
if (!currentRouteName) {
throw new Error('No current route name');
}
const router = useRoute(currentRouteName);

const context = useRouteParameter('context');

const setAppStatus = useEndpoint('POST', `/apps/${app.id}/status`);
Expand Down Expand Up @@ -67,8 +81,8 @@ function AppMenu({ app, ...props }) {
}, [checkUserLoggedIn, setModal, closeModal, buildExternalUrl, app.id, app.purchaseType, syncApp]);

const handleViewLogs = useCallback(() => {
appsRoute.push({ context: 'details', id: app.id, version: app.version, tab: 'logs' });
}, [app.id, app.version, appsRoute]);
router.push({ context, page: 'info', id: app.id, version: app.version, tab: 'logs' });
}, [app.id, app.version, context, router]);

const handleDisable = useCallback(() => {
const confirm = async () => {
Expand Down
40 changes: 18 additions & 22 deletions apps/meteor/client/views/admin/apps/AppsList/AppRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { css } from '@rocket.chat/css-in-js';
import { Box } from '@rocket.chat/fuselage';
import { useBreakpoints } from '@rocket.chat/fuselage-hooks';
import colors from '@rocket.chat/fuselage-tokens/colors';
import { useRoute } from '@rocket.chat/ui-contexts';
import React, { FC, memo, KeyboardEvent, MouseEvent } from 'react';
import { useCurrentRoute, useRoute, useRouteParameter } from '@rocket.chat/ui-contexts';
import React, { memo, KeyboardEvent, MouseEvent, ReactElement } from 'react';

import AppAvatar from '../../../../components/avatar/AppAvatar';
import AppStatus from '../AppDetailsPage/tabs/AppStatus/AppStatus';
Expand All @@ -13,40 +13,36 @@ import BundleChips from '../BundleChips';

type AppRowProps = App & { isMarketplace: boolean };

// TODO: org props
const AppRow: FC<AppRowProps> = (props) => {
const { name, id, description, iconFileData, marketplaceVersion, iconFileContent, installed, isSubscribed, isMarketplace, bundledIn } =
props;
const AppRow = (props: AppRowProps): ReactElement => {
const { name, id, description, iconFileData, marketplaceVersion, iconFileContent, installed, isSubscribed, bundledIn } = props;

const breakpoints = useBreakpoints();
const isDescriptionVisible = breakpoints.includes('xl');

const appsRoute = useRoute('admin-apps');
const marketplaceRoute = useRoute('admin-marketplace');
const [currentRouteName] = useCurrentRoute();
if (!currentRouteName) {
throw new Error('No current route name');
}
const router = useRoute(currentRouteName);

const handleClick = (): void => {
if (isMarketplace) {
marketplaceRoute.push({
context: 'details',
const context = useRouteParameter('context');

const handleNavigateToAppInfo = (): void => {
context &&
router.push({
context,
page: 'info',
version: marketplaceVersion,
id,
});
return;
}

appsRoute.push({
context: 'details',
version: marketplaceVersion,
id,
});
};

const handleKeyDown = (e: KeyboardEvent<HTMLOrSVGElement>): void => {
if (!['Enter', 'Space'].includes(e.nativeEvent.code)) {
return;
}

handleClick();
handleNavigateToAppInfo();
};

const preventClickPropagation = (e: MouseEvent<HTMLOrSVGElement>): void => {
Expand All @@ -67,7 +63,7 @@ const AppRow: FC<AppRowProps> = (props) => {
key={id}
role='link'
tabIndex={0}
onClick={handleClick}
onClick={handleNavigateToAppInfo}
onKeyDown={handleKeyDown}
display='flex'
flexDirection='row'
Expand Down
30 changes: 17 additions & 13 deletions apps/meteor/client/views/admin/apps/AppsPage/AppsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button, ButtonGroup, Icon, Skeleton, Tabs } from '@rocket.chat/fuselage';
import { useRoute, useSetting, useMethod, useTranslation } from '@rocket.chat/ui-contexts';
import { useRoute, useSetting, useMethod, useTranslation, useCurrentRoute, useRouteParameter } from '@rocket.chat/ui-contexts';
import React, { useEffect, useState, ReactElement } from 'react';

import Page from '../../../../components/Page';
Expand All @@ -13,11 +13,17 @@ const AppsPage = ({ isMarketplace }: AppsPageProps): ReactElement => {
const t = useTranslation();

const isDevelopmentMode = useSetting('Apps_Framework_Development_Mode');
const marketplaceRoute = useRoute('admin-marketplace');
const appsRoute = useRoute('admin-apps');
const cloudRoute = useRoute('cloud');
const checkUserLoggedIn = useMethod('cloud:checkUserLoggedIn');

const [currentRouteName] = useCurrentRoute();
if (!currentRouteName) {
throw new Error('No current route name');
}
const router = useRoute(currentRouteName);

const context = useRouteParameter('context');

const [isLoggedInCloud, setIsLoggedInCloud] = useState();

useEffect(() => {
Expand All @@ -32,9 +38,13 @@ const AppsPage = ({ isMarketplace }: AppsPageProps): ReactElement => {
};

const handleUploadButtonClick = (): void => {
appsRoute.push({ context: 'install' });
context && router.push({ context, page: 'install' });
};

const handleMarketplaceTabClick = (): void => router.push({ context: 'all', page: 'list' });

const handleInstalledTabClick = (): void => router.push({ context: 'installed', page: 'list' });

return (
<Page background='tint'>
<Page.Header title={t('Apps')}>
Expand All @@ -58,21 +68,15 @@ const AppsPage = ({ isMarketplace }: AppsPageProps): ReactElement => {
</ButtonGroup>
</Page.Header>
<Tabs>
<Tabs.Item onClick={(): void => marketplaceRoute.push({ context: '' })} selected={isMarketplace}>
<Tabs.Item onClick={handleMarketplaceTabClick} selected={context === 'all'}>
{t('Marketplace')}
</Tabs.Item>
<Tabs.Item
onClick={(): void => marketplaceRoute.push({ context: 'installed' })}
selected={!isMarketplace}
mbe='neg-x4'
borderWidth='0'
borderBlockWidth='x4'
>
<Tabs.Item onClick={handleInstalledTabClick} selected={context === 'installed'}>
{t('Installed')}
</Tabs.Item>
</Tabs>
<Page.Content overflowY='auto'>
<AppsPageContent isMarketplace={isMarketplace} />
<AppsPageContent />
</Page.Content>
</Page>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Pagination, Divider } from '@rocket.chat/fuselage';
import { useDebouncedState } from '@rocket.chat/fuselage-hooks';
import { useRoute, useTranslation } from '@rocket.chat/ui-contexts';
import { useCurrentRoute, useRoute, useRouteParameter, useTranslation } from '@rocket.chat/ui-contexts';
import React, { ReactElement, useMemo, useState } from 'react';

import { usePagination } from '../../../../components/GenericTable/hooks/usePagination';
Expand All @@ -19,14 +19,21 @@ import NoInstalledAppMatchesEmptyState from './NoInstalledAppMatchesEmptyState';
import NoInstalledAppsFoundEmptyState from './NoInstalledAppsFoundEmptyState';
import NoMarketplaceOrInstalledAppMatchesEmptyState from './NoMarketplaceOrInstalledAppMatchesEmptyState';

const AppsPageContent = ({ isMarketplace }: { isMarketplace: boolean }): ReactElement => {
const AppsPageContent = (): ReactElement => {
const t = useTranslation();
const { marketplaceApps, installedApps } = useAppsResult();
const [text, setText] = useDebouncedState('', 500);
const reload = useAppsReload();
const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination();

const marketplaceRoute = useRoute('admin-marketplace');
const [currentRouteName] = useCurrentRoute();
if (!currentRouteName) {
throw new Error('No current route name');
}
const router = useRoute(currentRouteName);

const context = useRouteParameter('context');
const isMarketplace = context === 'all';

const [freePaidFilterStructure, setFreePaidFilterStructure] = useState({
label: t('Filter_By_Price'),
Expand Down Expand Up @@ -85,6 +92,10 @@ const AppsPageContent = ({ isMarketplace }: { isMarketplace: boolean }): ReactEl
sortFilterStructure.items.find((item) => item.checked)?.id !== 'mru' ||
selectedCategories.length > 0;

const handleBack = (): void => {
router.push({ context: 'all', page: 'list' });
};

return (
<>
<AppsFilters
Expand Down Expand Up @@ -130,10 +141,10 @@ const AppsPageContent = ({ isMarketplace }: { isMarketplace: boolean }): ReactEl
<NoInstalledAppMatchesEmptyState
shouldShowSearchText={appsResult.value.shouldShowSearchText}
text={text}
onButtonClick={(): void => marketplaceRoute.push({ context: '' })}
onButtonClick={handleBack}
/>
)}
{noInstalledAppsFound && <NoInstalledAppsFoundEmptyState onButtonClick={(): void => marketplaceRoute.push({ context: '' })} />}
{noInstalledAppsFound && <NoInstalledAppsFoundEmptyState onButtonClick={handleBack} />}
{appsResult.phase === AsyncStatePhase.REJECTED && <AppsPageConnectionError onButtonClick={reload} />}
</>
);
Expand Down
Loading