-
Notifications
You must be signed in to change notification settings - Fork 13.5k
feat: new App instances page & mixed app status #36359
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
Merged
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
06902cc
feat: new App instances page & mixed app status
MartinSchoeler 0382c22
Test: add tests
MartinSchoeler 2b33af6
test: Adjust snapshot
MartinSchoeler 4b14a04
Prevent /api/apps/installed from throwing when no cluster information
d-gubert 04db8b6
Create mean-apricots-confess.md
MartinSchoeler 7e65dc4
chore: use GenericMenu
MartinSchoeler bed84e8
fix: instance pages with no cluster
MartinSchoeler 3a3c449
Merge remote-tracking branch 'origin/develop' into feat/app-instances…
MartinSchoeler de31b3a
chore: remove unused rule
MartinSchoeler af698f6
Update Jest snapshot
tassoevan 1f0732b
chore: reviews
MartinSchoeler ccf9d6a
Merge branch 'develop' into feat/app-instances-page
MartinSchoeler 9695cca
nitpick: remove inline type
MartinSchoeler e86aed9
Merge remote-tracking branch 'origin/develop' into feat/app-instances…
MartinSchoeler 1de5a33
fix: translation key typo
MartinSchoeler 8644e16
Merge branch 'develop' into feat/app-instances-page
d-gubert 4160a58
Merge branch 'develop' into feat/app-instances-page
d-gubert 4526ddc
Return the local instance when querying the app status across a cluster
d-gubert a11c4d7
Sort cluster status by instance in alphabetical order
d-gubert 0f58503
Merge branch 'develop' into feat/app-instances-page
d-gubert 70aea8a
Fix unit tests
d-gubert a044772
chore: prettier :)
MartinSchoeler 62e5c06
Merge branch 'develop' into feat/app-instances-page
MartinSchoeler de8840f
chore: update storybook
MartinSchoeler 9b9bd74
Merge remote-tracking branch 'origin/develop' into feat/app-instances…
MartinSchoeler b26d269
Rearrange story declarations
tassoevan cc28fb9
Merge branch 'develop' into feat/app-instances-page
kodiakhq[bot] 1c8d1ac
Merge branch 'develop' into feat/app-instances-page
kodiakhq[bot] 36e9e70
Merge branch 'develop' into feat/app-instances-page
kodiakhq[bot] 3fd05ad
Merge branch 'develop' into feat/app-instances-page
kodiakhq[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| "@rocket.chat/meteor": minor | ||
| "@rocket.chat/i18n": minor | ||
| --- | ||
|
|
||
| Adds a new tab on App Details page to see all instances and it's statuses. | ||
| Adds a new variant to the status tag, mixed status. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppInstances/AppInstances.spec.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import { mockAppRoot } from '@rocket.chat/mock-providers'; | ||
| import { composeStories } from '@storybook/react'; | ||
| import { render } from '@testing-library/react'; | ||
| import { axe } from 'jest-axe'; | ||
|
|
||
| import * as stories from './AppInstances.stories'; | ||
|
|
||
| const testCases = Object.values(composeStories(stories)).map((Story) => [Story.storyName || 'Story', Story]); | ||
|
|
||
| test.each(testCases)(`renders AppInstances without crashing`, async (_storyname, Story) => { | ||
| const view = render(<Story />, { wrapper: mockAppRoot().build() }); | ||
|
|
||
| expect(view.baseElement).toMatchSnapshot(); | ||
| }); | ||
|
|
||
| test.each(testCases)('AppInstances should have no a11y violations', async (_storyname, Story) => { | ||
| const { container } = render(<Story />, { wrapper: mockAppRoot().build() }); | ||
|
|
||
| // Today we do not have exactly a pattern to handle menu cells that don't have a header | ||
| const results = await axe(container, { rules: { 'empty-table-header': { enabled: false } } }); | ||
|
|
||
| expect(results).toHaveNoViolations(); | ||
| }); |
71 changes: 71 additions & 0 deletions
71
...meteor/client/views/marketplace/AppDetailsPage/tabs/AppInstances/AppInstances.stories.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| import { mockAppRoot } from '@rocket.chat/mock-providers'; | ||
| import type { Meta, StoryObj } from '@storybook/react'; | ||
|
|
||
| import AppInstances from './AppInstances'; | ||
|
|
||
| const statusPossibleStates = [ | ||
| 'unknown', | ||
| 'constructed', | ||
| 'initialized', | ||
| 'auto_enabled', | ||
| 'manually_enabled', | ||
| 'compiler_error_disabled', | ||
| 'invalid_license_disabled', | ||
| 'invalid_installation_disabled', | ||
| 'error_disabled', | ||
| 'manually_disabled', | ||
| 'invalid_settings_disabled', | ||
| 'disabled', | ||
| ]; | ||
|
|
||
| const statusTranslations = { | ||
| App_status_auto_enabled: 'Enabled', | ||
| App_status_constructed: 'Constructed', | ||
| App_status_disabled: 'Disabled', | ||
| App_status_error_disabled: 'Disabled: Uncaught Error', | ||
| App_status_initialized: 'Initialized', | ||
| App_status_invalid_license_disabled: 'Disabled: Invalid License', | ||
| App_status_invalid_settings_disabled: 'Disabled: Configuration Needed', | ||
| App_status_manually_disabled: 'Disabled: Manually', | ||
| App_status_manually_enabled: 'Enabled', | ||
| App_status_unknown: 'Unknown', | ||
| App_status_invalid_installation_disabled: 'Disabled: Invalid Installation', | ||
| Workspace_instance: 'Workspace instance', | ||
| }; | ||
|
|
||
| export default { | ||
| title: 'Components/AppInstances', | ||
| component: AppInstances, | ||
| } satisfies Meta<typeof AppInstances>; | ||
|
|
||
| type Story = StoryObj<typeof AppInstances>; | ||
|
|
||
| export const Default: Story = { | ||
| decorators: [ | ||
| mockAppRoot() | ||
| .withEndpoint('GET', '/apps/:id/status', () => ({ | ||
| status: 'disabled', | ||
| // Using any since the actual values from the AppStatus Enum cannot be used because it was exported as a type | ||
| clusterStatus: statusPossibleStates.map((status, i) => ({ instanceId: `instance-id-${i}`, status })) as any, | ||
| })) | ||
| .withTranslations('en', 'core', statusTranslations) | ||
| .buildStoryDecorator(), | ||
| ], | ||
| args: { | ||
| id: 'app-id', | ||
| }, | ||
| }; | ||
|
|
||
| export const NoResults: Story = { | ||
| decorators: [ | ||
| mockAppRoot() | ||
| .withEndpoint('GET', '/apps/:id/status', () => ({ | ||
| status: 'disabled', | ||
| clusterStatus: [], | ||
| })) | ||
| .buildStoryDecorator(), | ||
| ], | ||
| args: { | ||
| id: 'app-id', | ||
| }, | ||
| }; |
105 changes: 105 additions & 0 deletions
105
apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppInstances/AppInstances.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| import type { AppStatus } from '@rocket.chat/apps'; | ||
| import { AppStatusUtils } from '@rocket.chat/apps-engine/definition/AppStatus'; | ||
| import { Box, Palette, Tag } from '@rocket.chat/fuselage'; | ||
| import { GenericMenu } from '@rocket.chat/ui-client'; | ||
| import { useRouter } from '@rocket.chat/ui-contexts'; | ||
| import type { ReactElement } from 'react'; | ||
| import { useTranslation } from 'react-i18next'; | ||
|
|
||
| import { CustomScrollbars } from '../../../../../components/CustomScrollbars'; | ||
| import GenericNoResults from '../../../../../components/GenericNoResults'; | ||
| import { | ||
| GenericTable, | ||
| GenericTableBody, | ||
| GenericTableCell, | ||
| GenericTableHeader, | ||
| GenericTableHeaderCell, | ||
| GenericTableRow, | ||
| } from '../../../../../components/GenericTable'; | ||
| import AccordionLoading from '../../../components/AccordionLoading'; | ||
| import { useAppInstances } from '../../../hooks/useAppInstances'; | ||
|
|
||
| type AppInstanceProps = { | ||
| id: string; | ||
| }; | ||
|
|
||
| const AppInstances = ({ id }: AppInstanceProps): ReactElement => { | ||
| const { t } = useTranslation(); | ||
| const { data, isSuccess, isError, isLoading } = useAppInstances({ appId: id }); | ||
|
|
||
| const getStatusColor = (status: AppStatus) => { | ||
| if (AppStatusUtils.isDisabled(status) || AppStatusUtils.isError(status)) { | ||
| return Palette.text['font-danger'].toString(); | ||
| } | ||
|
|
||
| return Palette.text['font-default'].toString(); | ||
| }; | ||
|
|
||
| const router = useRouter(); | ||
|
|
||
| const handleSelectLogs = () => { | ||
| router.navigate( | ||
| { | ||
| name: 'marketplace', | ||
| params: { ...router.getRouteParameters(), tab: 'logs' }, | ||
| }, | ||
| { replace: true }, | ||
| ); | ||
| }; | ||
|
|
||
| return ( | ||
| <Box h='full' w='full' marginInline='auto' color='default' pbs={24}> | ||
| {isLoading && <AccordionLoading />} | ||
| {isError && ( | ||
| <Box maxWidth='x600' alignSelf='center'> | ||
| {t('App_not_found')} | ||
| </Box> | ||
| )} | ||
| {isSuccess && data.clusterStatus && data.clusterStatus.length > 0 && ( | ||
| <CustomScrollbars> | ||
| <GenericTable w='full'> | ||
| <GenericTableHeader> | ||
| <GenericTableHeaderCell key='instanceId'>{t('Workspace_instance')}</GenericTableHeaderCell> | ||
| <GenericTableHeaderCell key='status'>{t('Status')}</GenericTableHeaderCell> | ||
| <GenericTableHeaderCell key='actions' width={64} /> | ||
| </GenericTableHeader> | ||
| <GenericTableBody> | ||
| {data?.clusterStatus?.map((instance) => ( | ||
| <GenericTableRow key={instance.instanceId}> | ||
| <GenericTableCell>{instance.instanceId}</GenericTableCell> | ||
| <GenericTableCell> | ||
| <Box justifyContent='flex-start' display='flex'> | ||
| <Tag medium color={getStatusColor(instance.status)}> | ||
| {t(`App_status_${instance.status}`)} | ||
| </Tag> | ||
| </Box> | ||
| </GenericTableCell> | ||
| <GenericTableCell> | ||
| <GenericMenu | ||
| title='Actions' | ||
| items={[ | ||
| { | ||
| content: t('View_Logs'), | ||
| onClick: handleSelectLogs, | ||
| id: 'view-logs', | ||
| icon: 'desktop-text', | ||
| }, | ||
| ]} | ||
| /> | ||
| </GenericTableCell> | ||
| </GenericTableRow> | ||
| ))} | ||
| </GenericTableBody> | ||
| </GenericTable> | ||
| </CustomScrollbars> | ||
| )} | ||
| {isSuccess && (!data.clusterStatus || data.clusterStatus.length === 0) && ( | ||
| <CustomScrollbars> | ||
| <GenericNoResults /> | ||
| </CustomScrollbars> | ||
| )} | ||
| </Box> | ||
| ); | ||
| }; | ||
|
|
||
| export default AppInstances; | ||
41 changes: 41 additions & 0 deletions
41
...ews/marketplace/AppDetailsPage/tabs/AppInstances/__snapshots__/AppInstances.spec.tsx.snap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing | ||
|
|
||
| exports[`renders AppInstances without crashing 1`] = ` | ||
| <body> | ||
| <div> | ||
| <div | ||
| class="rcx-box rcx-box--full rcx-css-vkstbu" | ||
| > | ||
| <span | ||
| class="rcx-skeleton rcx-skeleton--rect rcx-css-jti8fm" | ||
| /> | ||
| <span | ||
| class="rcx-skeleton rcx-skeleton--rect rcx-css-jti8fm" | ||
| /> | ||
| <span | ||
| class="rcx-skeleton rcx-skeleton--rect rcx-css-jti8fm" | ||
| /> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| `; | ||
|
|
||
| exports[`renders AppInstances without crashing 2`] = ` | ||
| <body> | ||
| <div> | ||
| <div | ||
| class="rcx-box rcx-box--full rcx-css-vkstbu" | ||
| > | ||
| <span | ||
| class="rcx-skeleton rcx-skeleton--rect rcx-css-jti8fm" | ||
| /> | ||
| <span | ||
| class="rcx-skeleton rcx-skeleton--rect rcx-css-jti8fm" | ||
| /> | ||
| <span | ||
| class="rcx-skeleton rcx-skeleton--rect rcx-css-jti8fm" | ||
| /> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| `; |
1 change: 1 addition & 0 deletions
1
apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppInstances/index.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { default } from './AppInstances'; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.