Skip to content

Commit

Permalink
feat: Allow to archive workflow from flyteconsole (#361)
Browse files Browse the repository at this point in the history
* feat: archive workflows base
* chore: test

Signed-off-by: Carina Ursu <[email protected]>
  • Loading branch information
ursucarina authored Apr 11, 2022
1 parent 4e501fa commit 1ed28c4
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,7 @@ export function getActionsCell(
</IconButton>
)}
{!!onArchiveClick && (
<IconButton
size="small"
title={t('archiveActionString', isArchived)}
onClick={onArchiveClick}
>
<IconButton size="small" title={t('archiveAction', isArchived)} onClick={onArchiveClick}>
{getArchiveIcon(isArchived)}
</IconButton>
)}
Expand Down
30 changes: 15 additions & 15 deletions src/components/Project/ProjectWorkflows.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { WaitForData } from 'components/common/WaitForData';
import { useWorkflowShowArchivedState } from 'components/Workflow/filters/useWorkflowShowArchivedState';
import { SearchableWorkflowNameList } from 'components/Workflow/SearchableWorkflowNameList';
import { Admin } from 'flyteidl';
import { limits } from 'models/AdminEntity/constants';
import { FilterOperationName, SortDirection } from 'models/AdminEntity/types';
import { SortDirection } from 'models/AdminEntity/types';
import { workflowSortFields } from 'models/Workflow/constants';
import * as React from 'react';
import { useWorkflowInfoList } from '../Workflow/useWorkflowInfoList';
Expand All @@ -12,33 +12,33 @@ export interface ProjectWorkflowsProps {
domainId: string;
}

const DEFAULT_SORT = {
direction: SortDirection.ASCENDING,
key: workflowSortFields.name,
};

/** A listing of the Workflows registered for a project */
export const ProjectWorkflows: React.FC<ProjectWorkflowsProps> = ({
domainId: domain,
projectId: project,
}) => {
const archivedFilter = useWorkflowShowArchivedState();
const workflows = useWorkflowInfoList(
{ domain, project },
{
limit: limits.NONE,
sort: {
direction: SortDirection.ASCENDING,
key: workflowSortFields.name,
},
// Hide archived workflows from the list
filter: [
{
key: 'state',
operation: FilterOperationName.EQ,
value: Admin.NamedEntityState.NAMED_ENTITY_ACTIVE,
},
],
sort: DEFAULT_SORT,
filter: [archivedFilter.getFilter()],
},
);

return (
<WaitForData {...workflows}>
<SearchableWorkflowNameList workflows={workflows.value} />
<SearchableWorkflowNameList
workflows={workflows.value}
showArchived={archivedFilter.showArchived}
onArchiveFilterChange={archivedFilter.setShowArchived}
/>
</WaitForData>
);
};
61 changes: 51 additions & 10 deletions src/components/Project/test/ProjectWorkflows.test.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import { render, waitFor } from '@testing-library/react';
import { fireEvent, render, waitFor } from '@testing-library/react';
import { APIContext } from 'components/data/apiContext';
import { mockAPIContextValue } from 'components/data/__mocks__/apiContext';
import { Admin } from 'flyteidl';
import { FilterOperationName } from 'models/AdminEntity/types';
import { listNamedEntities } from 'models/Common/api';
import { NamedEntity } from 'models/Common/types';
import { getUserProfile, listNamedEntities } from 'models/Common/api';
import { NamedEntity, UserProfile } from 'models/Common/types';
import * as React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { MemoryRouter } from 'react-router';
import { createWorkflowName } from 'test/modelUtils';
import { createTestQueryClient } from 'test/utils';
import { ProjectWorkflows } from '../ProjectWorkflows';

const sampleUserProfile: UserProfile = {
subject: 'subject',
} as UserProfile;

jest.mock('notistack', () => ({
useSnackbar: () => ({ enqueueSnackbar: jest.fn() }),
}));

describe('ProjectWorkflows', () => {
const project = 'TestProject';
const domain = 'TestDomain';
let workflowNames: NamedEntity[];
let queryClient: QueryClient;
let mockListNamedEntities: jest.Mock<ReturnType<typeof listNamedEntities>>;
let mockGetUserProfile: jest.Mock<ReturnType<typeof getUserProfile>>;

beforeEach(() => {
mockGetUserProfile = jest.fn().mockResolvedValue(null);
queryClient = createTestQueryClient();
workflowNames = ['MyWorkflow', 'MyOtherWorkflow'].map((name) =>
createWorkflowName({ domain, name, project }),
);
Expand All @@ -25,13 +39,16 @@ describe('ProjectWorkflows', () => {

const renderComponent = () =>
render(
<APIContext.Provider
value={mockAPIContextValue({
listNamedEntities: mockListNamedEntities,
})}
>
<ProjectWorkflows projectId={project} domainId={domain} />
</APIContext.Provider>,
<QueryClientProvider client={queryClient}>
<APIContext.Provider
value={mockAPIContextValue({
listNamedEntities: mockListNamedEntities,
getUserProfile: mockGetUserProfile,
})}
>
<ProjectWorkflows projectId={project} domainId={domain} />
</APIContext.Provider>
</QueryClientProvider>,
{ wrapper: MemoryRouter },
);

Expand All @@ -52,4 +69,28 @@ describe('ProjectWorkflows', () => {
}),
);
});

it('should display checkbox if user login', async () => {
mockGetUserProfile.mockResolvedValue(sampleUserProfile);
const { getAllByRole } = renderComponent();
await waitFor(() => {});
const checkboxes = getAllByRole(/checkbox/i) as HTMLInputElement[];
expect(checkboxes).toHaveLength(1);
expect(checkboxes[0]).toBeTruthy();
expect(checkboxes[0]?.checked).toEqual(false);
});

/** user doesn't have its own workflow */
it('clicking show archived should hide active workflows', async () => {
mockGetUserProfile.mockResolvedValue(sampleUserProfile);
const { getByText, queryByText, getAllByRole } = renderComponent();
await waitFor(() => {});
const checkboxes = getAllByRole(/checkbox/i) as HTMLInputElement[];
expect(checkboxes[0]).toBeTruthy();
expect(checkboxes[0]?.checked).toEqual(false);
await waitFor(() => expect(getByText('MyWorkflow')));
fireEvent.click(checkboxes[0]);
// when user selects checkbox, table should have no workflows to display
await waitFor(() => expect(queryByText('MyWorkflow')).not.toBeInTheDocument());
});
});
Loading

0 comments on commit 1ed28c4

Please sign in to comment.