Skip to content

Commit

Permalink
gant chart selection
Browse files Browse the repository at this point in the history
  • Loading branch information
salazarm committed Dec 20, 2024
1 parent ecba546 commit 7262f1e
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {FeatureFlag} from 'shared/app/FeatureFlags.oss';

import {AntlrAssetSelectionVisitor} from './AntlrAssetSelectionVisitor';
import {AssetGraphQueryItem} from '../asset-graph/useAssetGraphData';
import {weakMapMemoize} from '../util/weakMapMemoize';
import {AssetSelectionLexer} from './generated/AssetSelectionLexer';
import {AssetSelectionParser} from './generated/AssetSelectionParser';
import {featureEnabled} from '../app/Flags';
Expand Down Expand Up @@ -65,17 +66,17 @@ export const parseAssetSelectionQuery = (
}
};

export const filterAssetSelectionByQuery = (
all_assets: AssetGraphQueryItem[],
query: string,
): AssetSelectionQueryResult => {
if (featureEnabled(FeatureFlag.flagAssetSelectionSyntax)) {
const result = parseAssetSelectionQuery(all_assets, query);
if (result instanceof Error) {
// fall back to old behavior
return filterByQuery(all_assets, query);
export const filterAssetSelectionByQuery = weakMapMemoize(
(all_assets: AssetGraphQueryItem[], query: string): AssetSelectionQueryResult => {
if (featureEnabled(FeatureFlag.flagAssetSelectionSyntax)) {
const result = parseAssetSelectionQuery(all_assets, query);
if (result instanceof Error) {
// fall back to old behavior
return filterByQuery(all_assets, query);
}
return result;
}
return result;
}
return filterByQuery(all_assets, query);
};
return filterByQuery(all_assets, query);
},
{maxEntries: 20},
);
27 changes: 19 additions & 8 deletions js_modules/dagster-ui/packages/ui-core/src/gantt/GanttChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import isEqual from 'lodash/isEqual';
import * as React from 'react';
import {useMemo} from 'react';
import {Link} from 'react-router-dom';
import {FeatureFlag} from 'shared/app/FeatureFlags.oss';
import styled from 'styled-components';

import {
Expand Down Expand Up @@ -48,13 +49,15 @@ import {
interestingQueriesFor,
} from './GanttChartLayout';
import {GanttChartModeControl} from './GanttChartModeControl';
import {GanttChartSelectionInput} from './GanttChartSelectionInput';
import {GanttChartTimescale} from './GanttChartTimescale';
import {GanttStatusPanel} from './GanttStatusPanel';
import {OptionsContainer, OptionsSpacer} from './VizComponents';
import {ZoomSlider} from './ZoomSlider';
import {RunGraphQueryItem} from './toGraphQueryItems';
import {useGanttChartMode} from './useGanttChartMode';
import {AppContext} from '../app/AppContext';
import {featureEnabled} from '../app/Flags';
import {GraphQueryItem} from '../app/GraphQueryImpl';
import {withMiddleTruncation} from '../app/Util';
import {WebSocketContext} from '../app/WebSocketProvider';
Expand Down Expand Up @@ -411,14 +414,22 @@ const GanttChartInner = React.memo((props: GanttChartInnerProps) => {
</WebsocketWarning>
) : null}
<FilterInputsBackgroundBox flex={{direction: 'row', alignItems: 'center', gap: 12}}>
<GraphQueryInput
items={props.graph}
value={props.selection.query}
placeholder="Type a step subset"
onChange={props.onUpdateQuery}
presets={presets}
className={selection.keys.length > 0 ? 'has-step' : ''}
/>
{featureEnabled(FeatureFlag.flagRunSelectionSyntax) ? (
<GanttChartSelectionInput
items={props.graph}
value={props.selection.query}
onChange={props.onUpdateQuery}
/>
) : (
<GraphQueryInput
items={props.graph}
value={props.selection.query}
placeholder="Type a step subset"
onChange={props.onUpdateQuery}
presets={presets}
className={selection.keys.length > 0 ? 'has-step' : ''}
/>
)}
<Checkbox
checked={options.hideUnselectedSteps}
label="Hide unselected steps"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {useMemo} from 'react';
import styled from 'styled-components';

import {RunGraphQueryItem} from './toGraphQueryItems';
import {SelectionAutoCompleteInput} from '../../../../../../../internal/dagster-cloud/js_modules/app-cloud/dagster/js_modules/dagster-ui/packages/ui-core/src/selection/SelectionAutoCompleteInput';
import {NO_STATE} from '../run-selection/AntlrRunSelectionVisitor';
import {RunSelectionLexer} from '../run-selection/generated/RunSelectionLexer';
import {RunSelectionParser} from '../run-selection/generated/RunSelectionParser';
import {InputDiv} from '../selection/SelectionAutoCompleteInput';
import {createSelectionLinter} from '../selection/createSelectionLinter';
import {weakMapMemoize} from '../util/weakMapMemoize';

export const GanttChartSelectionInput = ({
items,
value,
onChange,
}: {
items: RunGraphQueryItem[];
value: string;
onChange: (value: string) => void;
}) => {
const attributesMap = useMemo(() => {
const statuses = new Set<string>();
const names = new Set<string>();

items.forEach((item) => {
if (item.metadata?.state) {
statuses.add(item.metadata.state);
} else {
statuses.add(NO_STATE);
}
names.add(item.name);
});
return {name: Array.from(names), status: Array.from(statuses)};
}, [items]);

return (
<Wrapper>
<SelectionAutoCompleteInput
nameBase="name"
attributesMap={attributesMap}
placeholder="Type a step subset"
functions={FUNCTIONS}
linter={getLinter()}
value={value}
onChange={onChange}
/>
</Wrapper>
);
};

const getLinter = weakMapMemoize(() =>
createSelectionLinter({Lexer: RunSelectionLexer, Parser: RunSelectionParser}),
);

const FUNCTIONS = ['sinks', 'roots'];

const Wrapper = styled.div`
${InputDiv} {
width: 24vw;
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import {RunSelectionLexer} from './generated/RunSelectionLexer';
import {RunSelectionParser} from './generated/RunSelectionParser';
import {featureEnabled} from '../app/Flags';
import {filterByQuery} from '../app/GraphQueryImpl';
import {weakMapMemoize} from '../util/weakMapMemoize';

type RunSelectionQueryResult = {
export type RunSelectionQueryResult = {
all: RunGraphQueryItem[];
focus: RunGraphQueryItem[];
};
Expand Down Expand Up @@ -44,17 +45,17 @@ export const parseRunSelectionQuery = (
}
};

export const filterRunSelectionByQuery = (
all_runs: RunGraphQueryItem[],
query: string,
): RunSelectionQueryResult => {
if (featureEnabled(FeatureFlag.flagRunSelectionSyntax)) {
const result = parseRunSelectionQuery(all_runs, query);
if (result instanceof Error) {
// fall back to old behavior
return filterByQuery(all_runs, query);
export const filterRunSelectionByQuery = weakMapMemoize(
(all_runs: RunGraphQueryItem[], query: string): RunSelectionQueryResult => {
if (featureEnabled(FeatureFlag.flagRunSelectionSyntax)) {
const result = parseRunSelectionQuery(all_runs, query);
if (result instanceof Error) {
// fall back to old behavior
return filterByQuery(all_runs, query);
}
return result;
}
return result;
}
return filterByQuery(all_runs, query);
};
return filterByQuery(all_runs, query);
},
{maxEntries: 20},
);
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ export class AntlrRunSelectionVisitor

visitStatusAttributeExpr(ctx: StatusAttributeExprContext) {
const state: string = getValue(ctx.value()).toLowerCase();
return new Set([...this.all_runs].filter((i) => i.metadata?.state === state));
return new Set(
[...this.all_runs].filter(
(i) => i.metadata?.state === state || (state === NO_STATE && !i.metadata?.state),
),
);
}
}

export const NO_STATE = 'none';
Loading

0 comments on commit 7262f1e

Please sign in to comment.