Skip to content

Commit

Permalink
feat: archive/unarchive workflow's execution (#271)
Browse files Browse the repository at this point in the history
* feat: archive/unarchive workflow's execution

Signed-off-by: Nastya Rusina <[email protected]>

* chore: fix tests

Signed-off-by: Nastya Rusina <[email protected]>

* chore: pr feedback

Signed-off-by: Nastya Rusina <[email protected]>
  • Loading branch information
anrusina authored Feb 3, 2022
1 parent 54272a3 commit 2c6c041
Show file tree
Hide file tree
Showing 39 changed files with 937 additions and 432 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@date-io/moment": "1.3.9",
"@flyteorg/flyteidl": "0.21.16",
"@flyteorg/flyteidl": "0.21.24",
"@material-ui/core": "^4.0.0",
"@material-ui/icons": "^4.0.0",
"@material-ui/pickers": "^3.2.2",
Expand Down Expand Up @@ -171,6 +171,7 @@
"moment": "^2.18.1",
"moment-timezone": "^0.5.28",
"msw": "^0.24.1",
"notistack": "^1.0.10",
"object-hash": "^1.3.1",
"prettier": "1.19.1",
"protobufjs": "~6.8.0",
Expand Down
6 changes: 3 additions & 3 deletions src/basics/FeatureFlags/FeatureFlags.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { render, screen, waitFor, act } from '@testing-library/react';

import { FeatureFlagsProvider, useFeatureFlag } from '.';
import { FeatureFlag } from './defaultConfig';
Expand Down Expand Up @@ -46,7 +46,7 @@ describe('FeatureFlags', () => {
window.getFeatureFlag(FeatureFlag.TestFlagUndefined)
).toBeFalsy();

window.setFeatureFlag(FeatureFlag.TestFlagUndefined, true);
act(() => window.setFeatureFlag(FeatureFlag.TestFlagUndefined, true));
await waitFor(() => {
// check that flag cghanged value
expect(
Expand All @@ -60,7 +60,7 @@ describe('FeatureFlags', () => {
expect(screen.getByText(/Disabled/i)).toBeTruthy();

// Enable flag
window.setFeatureFlag(FeatureFlag.TestFlagUndefined, true);
act(() => window.setFeatureFlag(FeatureFlag.TestFlagUndefined, true));
await waitFor(() => {
// check that component was updated accordingly
expect(screen.getByText(/Enabled/i)).toBeTruthy();
Expand Down
8 changes: 8 additions & 0 deletions src/basics/Locale/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const createLocalizedString = (strings = {}) => (key, ...rest) => {
const value = strings[key];
return typeof value === 'function' ? value(...rest) : value;
};

export const patternKey = (parent: string, pattern: string) => {
return `${parent}_${pattern}`;
};
62 changes: 35 additions & 27 deletions src/components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CssBaseline } from '@material-ui/core';
import { CssBaseline, Collapse } from '@material-ui/core';
import { ThemeProvider } from '@material-ui/styles';
import { SnackbarProvider } from 'notistack';
import { FeatureFlagsProvider } from 'basics/FeatureFlags';
import { env } from 'common/env';
import { debug, debugPrefix } from 'common/log';
Expand Down Expand Up @@ -35,32 +36,39 @@ export const AppComponent: React.FC = () => {
return (
<FeatureFlagsProvider>
<ThemeProvider theme={muiTheme}>
<QueryClientProvider client={queryClient}>
<APIContext.Provider value={apiState}>
<QueryAuthorizationObserver />
<SkeletonTheme
color={skeletonColor}
highlightColor={skeletonHighlightColor}
>
<CssBaseline />
<Helmet>
<title>Flyte Console</title>
<meta
name="viewport"
content="width=device-width"
/>
</Helmet>
<Router history={history}>
<ErrorBoundary fixed={true}>
<NavBarRouter />
<ApplicationRouter />
</ErrorBoundary>
</Router>
<SystemStatusBanner />
</SkeletonTheme>
</APIContext.Provider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
<SnackbarProvider
// Notifications provider https://iamhosseindhv.com/notistack/demos
maxSnack={2}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
TransitionComponent={Collapse}
>
<QueryClientProvider client={queryClient}>
<APIContext.Provider value={apiState}>
<QueryAuthorizationObserver />
<SkeletonTheme
color={skeletonColor}
highlightColor={skeletonHighlightColor}
>
<CssBaseline />
<Helmet>
<title>Flyte Console</title>
<meta
name="viewport"
content="width=device-width"
/>
</Helmet>
<Router history={history}>
<ErrorBoundary fixed={true}>
<NavBarRouter />
<ApplicationRouter />
</ErrorBoundary>
</Router>
<SystemStatusBanner />
</SkeletonTheme>
</APIContext.Provider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</SnackbarProvider>
</ThemeProvider>
</FeatureFlagsProvider>
);
Expand Down
23 changes: 19 additions & 4 deletions src/components/Entities/EntityExecutions.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import * as React from 'react';
import { Typography } from '@material-ui/core';
import { makeStyles, Theme } from '@material-ui/core/styles';
import { contentMarginGridUnits } from 'common/layout';
import { fetchStates } from 'components/hooks/types';
import { WaitForData } from 'components/common/WaitForData';
import { ExecutionFilters } from 'components/Executions/ExecutionFilters';
import { useExecutionShowArchivedState } from 'components/Executions/filters/useExecutionArchiveState';
import { useWorkflowExecutionFiltersState } from 'components/Executions/filters/useExecutionFiltersState';
import { WorkflowExecutionsTable } from 'components/Executions/Tables/WorkflowExecutionsTable';
import { isLoadingState } from 'components/hooks/fetchMachine';
import { useWorkflowExecutions } from 'components/hooks/useWorkflowExecutions';
import { SortDirection } from 'models/AdminEntity/types';
import { ResourceIdentifier } from 'models/Common/types';
import { executionSortFields } from 'models/Execution/constants';
import * as React from 'react';
import { executionFilterGenerator } from './generators';
import { compact } from 'lodash';

const useStyles = makeStyles((theme: Theme) => ({
filtersContainer: {
Expand All @@ -38,6 +41,8 @@ export const EntityExecutions: React.FC<EntityExecutionsProps> = ({
const { domain, project, resourceType } = id;
const styles = useStyles();
const filtersState = useWorkflowExecutionFiltersState();
const archivedFilter = useExecutionShowArchivedState();

const sort = {
key: executionSortFields.createdAt,
direction: SortDirection.DESCENDING
Expand All @@ -48,21 +53,29 @@ export const EntityExecutions: React.FC<EntityExecutionsProps> = ({
[id, resourceType]
);

const allFilters = compact([
...baseFilters,
...filtersState.appliedFilters,
archivedFilter.getFilter()
]);
const executions = useWorkflowExecutions(
{ domain, project },
{
sort,
filter: [...baseFilters, ...filtersState.appliedFilters],
filter: allFilters,
limit: 100
}
);

if (chartIds.length > 0)
if (chartIds.length > 0) {
executions.value = executions.value.filter(item =>
chartIds.includes(item.id.name)
);
}

/** Don't render component until finish fetching user profile */
if (filtersState.filters[4].status !== 'LOADED') {
const lastIndex = filtersState.filters.length - 1;
if (filtersState.filters[lastIndex].status !== fetchStates.LOADED) {
return null;
}

Expand All @@ -76,6 +89,8 @@ export const EntityExecutions: React.FC<EntityExecutionsProps> = ({
{...filtersState}
chartIds={chartIds}
clearCharts={clearCharts}
showArchived={archivedFilter.showArchived}
onArchiveFilterChange={archivedFilter.setShowArchived}
/>
</div>
<WaitForData {...executions}>
Expand Down
25 changes: 14 additions & 11 deletions src/components/Entities/EntityExecutionsBarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Typography from '@material-ui/core/Typography';
import { makeStyles, Theme } from '@material-ui/core/styles';
import { formatDateUTC, millisecondsToHMS } from 'common/formatters';
import { timestampToDate } from 'common/utils';
import { fetchStates } from 'components/hooks/types';
import { BarChart } from 'components/common/BarChart';
import { WaitForData } from 'components/common/WaitForData';
import { useWorkflowExecutionFiltersState } from 'components/Executions/filters/useExecutionFiltersState';
Expand Down Expand Up @@ -53,9 +54,9 @@ export const getExecutionTimeData = (
<span>Running time: {millisecondsToHMS(duration)}</span>
<span>
Started at:{' '}
{execution.closure.startedAt != null &&
{execution.closure.startedAt &&
formatDateUTC(
timestampToDate(execution.closure.startedAt!)
timestampToDate(execution.closure.startedAt)
)}
</span>
</div>
Expand Down Expand Up @@ -105,7 +106,7 @@ export const EntityExecutionsBarChart: React.FC<EntityExecutionsBarChartProps> =

const baseFilters = React.useMemo(
() => executionFilterGenerator[resourceType](id),
[id]
[id, resourceType]
);

const executions = useWorkflowExecutions(
Expand All @@ -117,16 +118,18 @@ export const EntityExecutionsBarChart: React.FC<EntityExecutionsBarChartProps> =
}
);

const handleClickItem = React.useCallback(item => {
if (item.metadata) {
onToggle(item.metadata.name);
// const executionId = item.metadata as WorkflowExecutionIdentifier;
// history.push(Routes.ExecutionDetails.makeUrl(executionId));
}
}, []);
const handleClickItem = React.useCallback(
item => {
if (item.metadata) {
onToggle(item.metadata.name);
}
},
[onToggle]
);

/** Don't render component until finish fetching user profile */
if (filtersState.filters[4].status !== 'LOADED') {
const lastIndex = filtersState.filters.length - 1;
if (filtersState.filters[lastIndex].status !== fetchStates.LOADED) {
return null;
}

Expand Down
1 change: 0 additions & 1 deletion src/components/Entities/EntityVersions.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Typography from '@material-ui/core/Typography';
import { makeStyles, Theme } from '@material-ui/core/styles';
import { WaitForData } from 'components/common/WaitForData';
import { useWorkflowExecutionFiltersState } from 'components/Executions/filters/useExecutionFiltersState';
import { WorkflowVersionsTable } from 'components/Executions/Tables/WorkflowVersionsTable';
import { isLoadingState } from 'components/hooks/fetchMachine';
import { useWorkflowVersions } from 'components/hooks/useWorkflowVersions';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as React from 'react';
import { Tab, Tabs } from '@material-ui/core';
import { makeStyles, Theme } from '@material-ui/core/styles';

import { WaitForQuery } from 'components/common/WaitForQuery';
import { DataError } from 'components/Errors/DataError';
import { useTabState } from 'components/hooks/useTabState';
import { secondaryBackgroundColor } from 'components/Theme/constants';
import { Execution, NodeExecution } from 'models/Execution/types';
import * as React from 'react';
import { useState, useEffect } from 'react';
import { NodeExecutionsRequestConfigContext } from '../contexts';
import { ExecutionFilters } from '../ExecutionFilters';
import { useNodeExecutionFiltersState } from '../filters/useExecutionFiltersState';
Expand Down Expand Up @@ -43,7 +43,7 @@ export const ExecutionNodeViews: React.FC<ExecutionNodeViewsProps> = ({
const styles = useStyles();
const filterState = useNodeExecutionFiltersState();
const tabState = useTabState(tabs, tabs.nodes.id);
const [graphStateReady, setGraphStateReady] = useState(false);

const {
closure: { abortMetadata }
} = execution;
Expand Down
30 changes: 27 additions & 3 deletions src/components/Executions/ExecutionFilters.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { FormControlLabel, Checkbox } from '@material-ui/core';
import * as React from 'react';
import { FormControlLabel, Checkbox, FormGroup } from '@material-ui/core';
import { makeStyles, Theme } from '@material-ui/core/styles';
import { MultiSelectForm } from 'components/common/MultiSelectForm';
import { SearchInputForm } from 'components/common/SearchInputForm';
import { SingleSelectForm } from 'components/common/SingleSelectForm';
import { FilterPopoverButton } from 'components/Tables/filters/FilterPopoverButton';
import * as React from 'react';
import {
FilterState,
MultiFilterState,
Expand Down Expand Up @@ -62,7 +62,15 @@ export const ExecutionFilters: React.FC<{
filters: (FilterState | BooleanFilterState)[];
chartIds?: string[];
clearCharts?: () => void;
}> = ({ filters, chartIds, clearCharts }) => {
showArchived?: boolean;
onArchiveFilterChange?: (showArchievedItems: boolean) => void;
}> = ({
filters,
chartIds,
clearCharts,
showArchived,
onArchiveFilterChange
}) => {
const styles = useStyles();

filters = filters.map(filter => {
Expand Down Expand Up @@ -124,6 +132,22 @@ export const ExecutionFilters: React.FC<{
key="charts"
/>
)}
{!!onArchiveFilterChange && (
<FormGroup>
<FormControlLabel
control={
<Checkbox
value={showArchived}
onChange={(_, checked) =>
onArchiveFilterChange(checked)
}
/>
}
className={styles.checkbox}
label="Show archived executions"
/>
</FormGroup>
)}
</div>
);
};
12 changes: 9 additions & 3 deletions src/components/Executions/ExecutionStatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { makeStyles, Theme } from '@material-ui/core/styles';
import * as classnames from 'classnames';
import { bodyFontFamily, smallFontSize } from 'components/Theme/constants';
import {
bodyFontFamily,
smallFontSize,
statusColors
} from 'components/Theme/constants';
import {
NodeExecutionPhase,
TaskExecutionPhase,
Expand Down Expand Up @@ -41,6 +45,7 @@ const useStyles = makeStyles((theme: Theme) => ({

interface BaseProps {
variant?: 'default' | 'text';
disabled?: boolean;
}

interface WorkflowExecutionStatusBadgeProps extends BaseProps {
Expand Down Expand Up @@ -83,15 +88,16 @@ function getPhaseConstants(
export const ExecutionStatusBadge: React.FC<ExecutionStatusBadgeProps> = ({
phase,
type,
variant = 'default'
variant = 'default',
disabled = false
}) => {
const styles = useStyles();
const style: React.CSSProperties = {};
const { badgeColor, text, textColor } = getPhaseConstants(type, phase);
if (variant === 'text') {
style.color = textColor;
} else {
style.backgroundColor = badgeColor;
style.backgroundColor = disabled ? statusColors.UNKNOWN : badgeColor;
}

return (
Expand Down
Loading

0 comments on commit 2c6c041

Please sign in to comment.