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

feat: archive/unarchive workflow's execution #271

Merged
merged 3 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something we want to establish as a pattern? Currently we don't have plans for localized strings?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern will not require you to localize strings, but will keep all strings in file sections, which make them easier to change, and makes easier to switch to localization if we would have such plan in future.
Most problems with localizations are usually come from struggle to find all strings and get developer used to t("string") notation.
Proper localization will require files to be located in folders per language - but we won't go there until we will start to really discuss localization.

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') {
anrusina marked this conversation as resolved.
Show resolved Hide resolved
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