Skip to content

Commit

Permalink
feat: add comparison tool to execution list V1 (flyteorg#234)
Browse files Browse the repository at this point in the history
* feat: add comparison tool to execution list V1

Signed-off-by: Pianist038801 <[email protected]>

* fix: fix failing tests

Signed-off-by: Pianist038801 <[email protected]>

* feat: use opacity instead of dot

Signed-off-by: Pianist038801 <[email protected]>

Co-authored-by: Pianist038801 <[email protected]>
  • Loading branch information
Pianist038801 and Pianist038801 authored Oct 26, 2021
1 parent 2a95fb0 commit df4f7e7
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 14 deletions.
16 changes: 14 additions & 2 deletions src/components/Entities/EntityDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { contentMarginGridUnits } from 'common/layout';
import { WaitForData } from 'components/common/WaitForData';
import { EntityDescription } from 'components/Entities/EntityDescription';
import { useProject } from 'components/hooks/useProjects';
import { useChartState } from 'components/hooks/useChartState';
import { LaunchForm } from 'components/Launch/LaunchForm/LaunchForm';
import { ResourceIdentifier, ResourceType } from 'models/Common/types';
import * as React from 'react';
Expand Down Expand Up @@ -82,6 +83,7 @@ export const EntityDetails: React.FC<EntityDetailsProps> = ({
const [showLaunchForm, setShowLaunchForm] = React.useState(false);
const onLaunch = () => setShowLaunchForm(true);
const onCancelLaunch = () => setShowLaunchForm(false);
const { chartIds, onToggle, clearCharts } = useChartState();

return (
<WaitForData {...project}>
Expand Down Expand Up @@ -120,10 +122,20 @@ export const EntityDetails: React.FC<EntityDetailsProps> = ({
</div>
</>
) : null}
{!versionView && <EntityExecutionsBarChart id={id} />}
{!versionView && (
<EntityExecutionsBarChart
onToggle={onToggle}
chartIds={chartIds}
id={id}
/>
)}
{sections.executions && !versionView ? (
<div className={styles.executionsContainer}>
<EntityExecutions id={id} />
<EntityExecutions
chartIds={chartIds}
id={id}
clearCharts={clearCharts}
/>
</div>
) : null}
{sections.launch ? (
Expand Down
18 changes: 16 additions & 2 deletions src/components/Entities/EntityExecutions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ const useStyles = makeStyles((theme: Theme) => ({

export interface EntityExecutionsProps {
id: ResourceIdentifier;
chartIds: string[];
clearCharts: () => void;
}

/** The tab/page content for viewing a workflow's executions */
export const EntityExecutions: React.FC<EntityExecutionsProps> = ({ id }) => {
export const EntityExecutions: React.FC<EntityExecutionsProps> = ({
id,
chartIds,
clearCharts
}) => {
const { domain, project, resourceType } = id;
const styles = useStyles();
const filtersState = useWorkflowExecutionFiltersState();
Expand All @@ -50,6 +56,10 @@ export const EntityExecutions: React.FC<EntityExecutionsProps> = ({ id }) => {
}
);

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') {
return null;
Expand All @@ -61,7 +71,11 @@ export const EntityExecutions: React.FC<EntityExecutionsProps> = ({ id }) => {
All Executions in the Workflow
</Typography>
<div className={styles.filtersContainer}>
<ExecutionFilters {...filtersState} />
<ExecutionFilters
{...filtersState}
chartIds={chartIds}
clearCharts={clearCharts}
/>
</div>
<WaitForData {...executions}>
<WorkflowExecutionsTable
Expand Down
8 changes: 7 additions & 1 deletion src/components/Entities/EntityExecutionsBarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const useStyles = makeStyles((theme: Theme) => ({

export interface EntityExecutionsBarChartProps {
id: ResourceIdentifier;
onToggle: (id: string) => void;
chartIds: string[];
}

const getExecutionTimeData = (executions: Execution[], fillSize = 100) => {
Expand Down Expand Up @@ -88,7 +90,9 @@ const getStartExecutionTime = (executions: Execution[]) => {
* @constructor
*/
export const EntityExecutionsBarChart: React.FC<EntityExecutionsBarChartProps> = ({
id
id,
onToggle,
chartIds
}) => {
const styles = useStyles();
const { domain, project, resourceType } = id;
Expand Down Expand Up @@ -116,6 +120,7 @@ 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));
}
Expand All @@ -133,6 +138,7 @@ export const EntityExecutionsBarChart: React.FC<EntityExecutionsBarChartProps> =
</Typography>
<div className={styles.body}>
<BarChart
chartIds={chartIds}
data={getExecutionTimeData(executions.value)}
startDate={getStartExecutionTime(executions.value)}
onClickItem={handleClickItem}
Expand Down
24 changes: 23 additions & 1 deletion src/components/Executions/ExecutionFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,20 @@ const RenderFilter: React.FC<{ filter: FilterState }> = ({ filter }) => {
*/
export const ExecutionFilters: React.FC<{
filters: (FilterState | BooleanFilterState)[];
}> = ({ filters }) => {
chartIds?: string[];
clearCharts?: () => void;
}> = ({ filters, chartIds, clearCharts }) => {
const styles = useStyles();

filters = filters.map(filter => {
const onChangeFunc = filter.onChange;
filter.onChange = value => {
if (clearCharts) clearCharts();
if (onChangeFunc) onChangeFunc(value);
};
return filter;
});

return (
<div className={styles.container}>
{filters.map((filter: any) => {
Expand Down Expand Up @@ -102,6 +113,17 @@ export const ExecutionFilters: React.FC<{
/>
);
})}
{chartIds && chartIds.length > 0 && (
<FilterPopoverButton
open={false}
active={true}
renderContent={() => <></>}
className={styles.filterButton}
buttonText="Clear Manually Selected Executions"
onReset={clearCharts}
key="charts"
/>
)}
</div>
);
};
1 change: 1 addition & 0 deletions src/components/Executions/filters/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface FilterState {
status?: string;
getFilter: () => FilterOperation[];
onReset: () => void;
onChange?: (value) => void;
}

export interface SingleFilterState<FilterKey extends string>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Executions/filters/useSingleFilterState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function useSingleFilterState<FilterKey extends string>({

useEffect(() => {
const { value } = selectedOption;
const queryValue = value === defaultValue.value ? undefined : value;
const queryValue = value;
setQueryStateValue(queryStateKey, queryValue);
}, [selectedOption, queryStateKey]);

Expand Down
33 changes: 26 additions & 7 deletions src/components/common/BarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const useStyles = makeStyles((theme: Theme) => ({
item: {
flex: 1,
display: 'flex',
alignItems: 'flex-end',
flexDirection: 'column',
alignItems: 'center',
'&:last-child': {
marginRight: 0
}
Expand All @@ -37,7 +38,9 @@ const useStyles = makeStyles((theme: Theme) => ({
flex: 1,
marginRight: theme.spacing(0.25),
minHeight: theme.spacing(0.75),
cursor: 'pointer'
cursor: 'pointer',
width: '80%',
marginLeft: '10%'
}
}));

Expand All @@ -50,12 +53,14 @@ interface BarChartData {

interface BarChartItemProps extends BarChartData {
onClick?: () => void;
isSelected: boolean;
}

interface BarChartProps {
data: BarChartData[];
startDate?: string;
onClickItem?: (item: any) => void;
chartIds: string[];
}

/**
Expand All @@ -67,18 +72,25 @@ interface BarChartProps {
const BarChartItem: React.FC<BarChartItemProps> = ({
value,
color,
isSelected,
tooltip,
onClick
}) => {
const styles = useStyles();
const [position, setPosition] = React.useState({ x: 0, y: 0 });

const content = (
<div
className={styles.itemBar}
style={{ backgroundColor: color, height: `${value}%` }}
onClick={onClick}
/>
<>
<div
className={styles.itemBar}
style={{
backgroundColor: color,
height: `${value}%`,
opacity: isSelected ? '100%' : '50%'
}}
onClick={onClick}
/>
</>
);

return (
Expand Down Expand Up @@ -121,6 +133,7 @@ const BarChartItem: React.FC<BarChartItemProps> = ({
* @constructor
*/
export const BarChart: React.FC<BarChartProps> = ({
chartIds,
data,
startDate,
onClickItem
Expand Down Expand Up @@ -154,6 +167,12 @@ export const BarChart: React.FC<BarChartProps> = ({
tooltip={item.tooltip}
onClick={handleClickItem(item)}
key={`bar-chart-item-${index}`}
isSelected={
chartIds.length === 0
? true
: item.metadata &&
chartIds.includes(item.metadata.name)
}
/>
))}
</div>
Expand Down
27 changes: 27 additions & 0 deletions src/components/hooks/useChartState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useState } from 'react';

export function useChartState() {
const [chartIds, setChartIds] = useState<string[]>([]);
const onToggle = (id: string) => {
setChartIds(curIds => {
const newChartIds = [...curIds];
if (newChartIds.includes(id)) {
const index = newChartIds.indexOf(id);
newChartIds.splice(index, 1);
} else {
newChartIds.push(id);
}
return newChartIds;
});
};

const clearCharts = () => {
setChartIds([]);
};

return {
onToggle,
clearCharts,
chartIds
};
}

0 comments on commit df4f7e7

Please sign in to comment.