Skip to content

Commit e3ec37f

Browse files
Persist created resources; clean up unused tabs (#135) (#136)
(cherry picked from commit 16a0967) Co-authored-by: Tyler Ohlsen <ohltyler@amazon.com>
1 parent c452485 commit e3ec37f

File tree

14 files changed

+169
-104
lines changed

14 files changed

+169
-104
lines changed

common/interfaces.ts

+16
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ export type Workflow = WorkflowTemplate & {
119119
lastLaunched?: number;
120120
// won't exist until launched/provisioned in backend
121121
state?: WORKFLOW_STATE;
122+
// won't exist until launched/provisioned in backend
123+
resourcesCreated?: WorkflowResource[];
122124
};
123125

124126
export enum USE_CASE {
@@ -152,6 +154,20 @@ export enum WORKFLOW_STATE {
152154
COMPLETED = 'Completed',
153155
}
154156

157+
export type WorkflowResource = {
158+
id: string;
159+
type: WORKFLOW_RESOURCE_TYPE;
160+
};
161+
162+
// Based off of https://github.com/opensearch-project/flow-framework/blob/main/src/main/java/org/opensearch/flowframework/common/WorkflowResources.java
163+
export enum WORKFLOW_RESOURCE_TYPE {
164+
PIPELINE_ID = 'Ingest pipeline',
165+
INDEX_NAME = 'Index',
166+
MODEL_ID = 'Model',
167+
MODEL_GROUP_ID = 'Model group',
168+
CONNECTOR_ID = 'Connector',
169+
}
170+
155171
export type WorkflowDict = {
156172
[workflowId: string]: Workflow;
157173
};

public/app.tsx

+5-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { Route, RouteComponentProps, Switch } from 'react-router-dom';
88
import { EuiPageSideBar, EuiSideNav, EuiPageTemplate } from '@elastic/eui';
99
import { Navigation, APP_PATH } from './utils';
1010
import {
11-
Overview,
1211
Workflows,
1312
WorkflowDetail,
1413
WorkflowDetailRouterProps,
@@ -27,15 +26,9 @@ export const FlowFrameworkDashboardsApp = (props: Props) => {
2726
name: Navigation.FlowFramework,
2827
id: 0,
2928
items: [
30-
{
31-
name: Navigation.Overview,
32-
id: 1,
33-
href: `#${APP_PATH.OVERVIEW}`,
34-
isSelected: props.location.pathname === APP_PATH.OVERVIEW,
35-
},
3629
{
3730
name: Navigation.Workflows,
38-
id: 2,
31+
id: 1,
3932
href: `#${APP_PATH.WORKFLOWS}`,
4033
isSelected: props.location.pathname === APP_PATH.WORKFLOWS,
4134
},
@@ -69,10 +62,12 @@ export const FlowFrameworkDashboardsApp = (props: Props) => {
6962
<Workflows {...routeProps} />
7063
)}
7164
/>
72-
{/* Defaulting to Overview page */}
65+
{/* Defaulting to Workflows page */}
7366
<Route
7467
path={`${APP_PATH.HOME}`}
75-
render={(routeProps: RouteComponentProps) => <Overview />}
68+
render={(routeProps: RouteComponentProps<WorkflowsRouterProps>) => (
69+
<Workflows {...routeProps} />
70+
)}
7671
/>
7772
</Switch>
7873
</EuiPageTemplate>

public/pages/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44
*/
55

66
export * from './workflows';
7-
export * from './overview';
87
export * from './workflow_detail';

public/pages/overview/overview.tsx

-44
This file was deleted.

public/pages/workflow_detail/prototype/index.ts

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
export const columns = [
7+
{
8+
field: 'id',
9+
name: 'ID',
10+
sortable: true,
11+
},
12+
{
13+
field: 'type',
14+
name: 'Type',
15+
sortable: true,
16+
},
17+
];

public/pages/overview/index.ts public/pages/workflow_detail/resources/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
export { Overview } from './overview';
6+
export { Resources } from './resources';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import React, { useState, useEffect } from 'react';
7+
import {
8+
EuiInMemoryTable,
9+
Direction,
10+
EuiFlexGroup,
11+
EuiFlexItem,
12+
} from '@elastic/eui';
13+
import { Workflow, WorkflowResource } from '../../../../common';
14+
import { columns } from './columns';
15+
16+
interface ResourceListProps {
17+
workflow?: Workflow;
18+
}
19+
20+
/**
21+
* The searchable list of resources for a particular workflow.
22+
*/
23+
export function ResourceList(props: ResourceListProps) {
24+
const [allResources, setAllResources] = useState<WorkflowResource[]>([]);
25+
26+
// Hook to initialize all resources
27+
useEffect(() => {
28+
if (props.workflow?.resourcesCreated) {
29+
setAllResources(props.workflow.resourcesCreated);
30+
}
31+
}, [props.workflow?.resourcesCreated]);
32+
33+
const sorting = {
34+
sort: {
35+
field: 'id',
36+
direction: 'asc' as Direction,
37+
},
38+
};
39+
40+
return (
41+
<EuiFlexGroup direction="column">
42+
<EuiFlexItem>
43+
<EuiInMemoryTable<WorkflowResource>
44+
items={allResources}
45+
rowHeader="id"
46+
columns={columns}
47+
sorting={sorting}
48+
pagination={true}
49+
message={'No existing resources found'}
50+
/>
51+
</EuiFlexItem>
52+
</EuiFlexGroup>
53+
);
54+
}

public/pages/workflow_detail/prototype/prototype.tsx public/pages/workflow_detail/resources/resources.tsx

+11-10
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,34 @@
55

66
import React from 'react';
77
import {
8+
EuiFlexGroup,
89
EuiFlexItem,
910
EuiPageContent,
1011
EuiSpacer,
11-
EuiText,
1212
EuiTitle,
1313
} from '@elastic/eui';
1414
import { Workflow } from '../../../../common';
15+
import { ResourceList } from './resource_list';
1516

16-
interface PrototypeProps {
17+
interface ResourcesProps {
1718
workflow?: Workflow;
1819
}
1920

2021
/**
21-
* The prototype page. Dedicated for testing out a launched workflow.
22-
* Will have default simple interfaces for common application types, such as
23-
* conversational chatbots.
22+
* A simple resources page to browse created resources for a given Workflow.
2423
*/
25-
export function Prototype(props: PrototypeProps) {
24+
export function Resources(props: ResourcesProps) {
2625
return (
2726
<EuiPageContent>
2827
<EuiTitle>
29-
<h2>Prototype</h2>
28+
<h2>Resources</h2>
3029
</EuiTitle>
3130
<EuiSpacer size="m" />
32-
<EuiFlexItem>
33-
<EuiText>TODO: add prototype page</EuiText>
34-
</EuiFlexItem>
31+
<EuiFlexGroup direction="row">
32+
<EuiFlexItem>
33+
<ResourceList workflow={props.workflow} />
34+
</EuiFlexItem>
35+
</EuiFlexGroup>
3536
</EuiPageContent>
3637
);
3738
}

public/pages/workflow_detail/workflow_detail.tsx

+12-21
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ import {
1919
useAppDispatch,
2020
} from '../../store';
2121
import { ResizableWorkspace } from './workspace';
22-
import { Launches } from './launches';
23-
import { Prototype } from './prototype';
2422
import {
2523
DEFAULT_NEW_WORKFLOW_NAME,
2624
FETCH_ALL_QUERY_BODY,
2725
NEW_WORKFLOW_ID_URL,
2826
} from '../../../common';
27+
import { Resources } from './resources';
2928

3029
// styling
3130
import './workflow-detail-styles.scss';
@@ -39,8 +38,10 @@ interface WorkflowDetailProps
3938

4039
enum WORKFLOW_DETAILS_TAB {
4140
EDITOR = 'editor',
42-
LAUNCHES = 'launches',
43-
PROTOTYPE = 'prototype',
41+
// TODO: temporarily adding a resources tab until UX is finalized.
42+
// This gives clarity into what has been done on the cluster on behalf
43+
// of the frontend provisioning workflows.
44+
RESOURCES = 'resources',
4445
}
4546

4647
const ACTIVE_TAB_PARAM = 'tab';
@@ -133,21 +134,12 @@ export function WorkflowDetail(props: WorkflowDetailProps) {
133134
},
134135
},
135136
{
136-
id: WORKFLOW_DETAILS_TAB.LAUNCHES,
137-
label: 'Launches',
138-
isSelected: selectedTabId === WORKFLOW_DETAILS_TAB.LAUNCHES,
137+
id: WORKFLOW_DETAILS_TAB.RESOURCES,
138+
label: 'Resources',
139+
isSelected: selectedTabId === WORKFLOW_DETAILS_TAB.RESOURCES,
139140
onClick: () => {
140-
setSelectedTabId(WORKFLOW_DETAILS_TAB.LAUNCHES);
141-
replaceActiveTab(WORKFLOW_DETAILS_TAB.LAUNCHES, props);
142-
},
143-
},
144-
{
145-
id: WORKFLOW_DETAILS_TAB.PROTOTYPE,
146-
label: 'Prototype',
147-
isSelected: selectedTabId === WORKFLOW_DETAILS_TAB.PROTOTYPE,
148-
onClick: () => {
149-
setSelectedTabId(WORKFLOW_DETAILS_TAB.PROTOTYPE);
150-
replaceActiveTab(WORKFLOW_DETAILS_TAB.PROTOTYPE, props);
141+
setSelectedTabId(WORKFLOW_DETAILS_TAB.RESOURCES);
142+
replaceActiveTab(WORKFLOW_DETAILS_TAB.RESOURCES, props);
151143
},
152144
},
153145
];
@@ -169,9 +161,8 @@ export function WorkflowDetail(props: WorkflowDetailProps) {
169161
/>
170162
</ReactFlowProvider>
171163
)}
172-
{selectedTabId === WORKFLOW_DETAILS_TAB.LAUNCHES && <Launches />}
173-
{selectedTabId === WORKFLOW_DETAILS_TAB.PROTOTYPE && (
174-
<Prototype workflow={workflow} />
164+
{selectedTabId === WORKFLOW_DETAILS_TAB.RESOURCES && (
165+
<Resources workflow={workflow} />
175166
)}
176167
</EuiPageBody>
177168
</EuiPage>

public/store/reducers/workflows_reducer.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,13 @@ const workflowsSlice = createSlice({
235235
state.errorMessage = '';
236236
})
237237
.addCase(getWorkflowState.fulfilled, (state, action) => {
238-
const { workflowId, workflowState } = action.payload;
238+
const { workflowId, workflowState, resourcesCreated } = action.payload;
239239
state.workflows = {
240240
...state.workflows,
241241
[workflowId]: {
242242
...state.workflows[workflowId],
243243
state: workflowState,
244+
resourcesCreated,
244245
},
245246
};
246247
state.loading = false;

public/utils/constants.ts

-3
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,17 @@
55

66
export enum Navigation {
77
FlowFramework = 'Flow Framework',
8-
Overview = 'Overview',
98
Workflows = 'Workflows',
109
}
1110

1211
export enum APP_PATH {
1312
HOME = '/',
14-
OVERVIEW = '/overview',
1513
WORKFLOWS = '/workflows',
1614
WORKFLOW_DETAIL = '/workflows/:workflowId',
1715
}
1816

1917
export const BREADCRUMBS = Object.freeze({
2018
FLOW_FRAMEWORK: { text: 'Flow Framework', href: '#/' },
21-
OVERVIEW: { text: 'Overview', href: `#${APP_PATH.OVERVIEW}` },
2219
WORKFLOWS: { text: 'Workflows', href: `#${APP_PATH.WORKFLOWS}` },
2320
});
2421

0 commit comments

Comments
 (0)