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(Marketplace): Install private apps page to TypeScript #31404

Merged
merged 12 commits into from
Jan 19, 2024
15 changes: 0 additions & 15 deletions apps/meteor/client/views/marketplace/AccordionLoading.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { ReactElement } from 'react';
import React from 'react';

import { useFormatDateAndTime } from '../../../../../hooks/useFormatDateAndTime';
import AccordionLoading from '../../../AccordionLoading';
import AccordionLoading from '../../../components/AccordionLoading';
import { useLogs } from '../../../hooks/useLogs';
import AppLogsItem from './AppLogsItem';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { useQuery } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React from 'react';

import AccordionLoading from '../../../AccordionLoading';
import AccordionLoading from '../../../components/AccordionLoading';
import AppReleasesItem from './AppReleasesItem';

// TODO: replace useEndpointData
const AppReleases = ({ id }: { id: App['id'] }): ReactElement => {
const getVersions = useEndpoint('GET', '/apps/:id/versions', { id });
const dispatchToastMessage = useToastMessageDispatch();
Expand Down
250 changes: 0 additions & 250 deletions apps/meteor/client/views/marketplace/AppInstallPage.js

This file was deleted.

94 changes: 94 additions & 0 deletions apps/meteor/client/views/marketplace/AppInstallPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Button, ButtonGroup, Icon, Field, FieldGroup, FieldLabel, FieldRow, TextInput, Callout } from '@rocket.chat/fuselage';
import { useUniqueId } from '@rocket.chat/fuselage-hooks';
import { useTranslation, useRouter, useSearchParameter } from '@rocket.chat/ui-contexts';
import React, { useCallback } from 'react';
import { useForm, Controller } from 'react-hook-form';

import { Page, PageHeader, PageScrollableContent } from '../../components/Page';
import { useSingleFileInput } from '../../hooks/useSingleFileInput';
import { useInstallApp } from './hooks/useInstallApp';

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

const AppInstallPage = () => {
const t = useTranslation();
const router = useRouter();

const queryUrl = useSearchParameter('url');

const { control, setValue, watch } = useForm<{ file: File; url: string }>({ defaultValues: { url: queryUrl || '' } });
const { file, url } = watch();
const { install, isInstalling } = useInstallApp(file, url);

const [handleUploadButtonClick] = useSingleFileInput((value) => setValue('file', value), 'app');

const handleCancel = useCallback(() => {
router.navigate({
name: 'marketplace',
params: {
context: 'private',
page: 'list',
},
});
}, [router]);

const urlField = useUniqueId();
const fileField = useUniqueId();

return (
<Page flexDirection='column'>
<PageHeader title={t('App_Installation')} />
<PageScrollableContent>
<FieldGroup display='flex' flexDirection='column' alignSelf='center' maxWidth='x600' w='full'>
<Field>
<FieldLabel htmlFor={urlField}>{t('App_Url_to_Install_From')}</FieldLabel>
<Callout type='warning' title={t('App_Installation_Deprecation_Title')}>
{t('App_Installation_Deprecation')}
</Callout>
<FieldRow>
<Controller
name='url'
control={control}
render={({ field }) => (
<TextInput id={urlField} placeholder={PLACEHOLDER_URL} addon={<Icon name='permalink' size='x20' />} {...field} />
)}
/>
</FieldRow>
</Field>
<Field>
<FieldLabel htmlFor={fileField}>{t('App_Url_to_Install_From_File')}</FieldLabel>
<FieldRow>
<Controller
name='file'
control={control}
render={({ field }) => (
<TextInput
id={fileField}
readOnly
{...field}
value={field.value?.name || ''}
addon={
<Button icon='upload' small primary onClick={handleUploadButtonClick} mb='neg-x4' mie='neg-x8'>
{t('Browse_Files')}
</Button>
}
/>
)}
/>
</FieldRow>
</Field>
<Field>
<ButtonGroup>
<Button disabled={!url && !file?.name} loading={isInstalling} onClick={install}>
{t('Install')}
</Button>
<Button onClick={handleCancel}>{t('Cancel')}</Button>
</ButtonGroup>
</Field>
</FieldGroup>
</PageScrollableContent>
</Page>
);
};

export default AppInstallPage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Skeleton } from '@rocket.chat/fuselage';
import React from 'react';

const SKELETON_ITEMS = 3;

const AccordionLoading = () => (
<>
{Array.from({ length: SKELETON_ITEMS }, (_v, k) => (
<Skeleton key={k} variant='rect' height='80px' m='2px' />
))}
</>
);

export default AccordionLoading;
Loading
Loading