Skip to content

Commit bd306bf

Browse files
committed
added new data source
1 parent 4de68b1 commit bd306bf

108 files changed

Lines changed: 658 additions & 352 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lasso/docs/datastructures/lsl.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ Configures runtime context (typically docker/image for Java analysis and builds)
161161

162162
### 4. Actions
163163

164+
(Note: A list of available actions on LASSO's playground service is available [here](/web/lasso/actions))
165+
164166
`action` and Action Types
165167

166168
An action represents a step or task in the LSL pipeline. They can create SMs, execute code, generate code/tests, perform search/filtering, integrate external tools etc.
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import React, { useEffect, useState } from 'react';
2+
import {
3+
Accordion,
4+
AccordionSummary,
5+
AccordionDetails,
6+
Typography,
7+
Table,
8+
TableBody,
9+
TableCell,
10+
TableContainer,
11+
TableHead,
12+
TableRow,
13+
Paper,
14+
Box,
15+
Chip,
16+
CircularProgress,
17+
Alert,
18+
Container,
19+
} from '@mui/material';
20+
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
21+
import LassoService from '@site/src/services/LassoService';
22+
23+
// --- Types ---
24+
25+
type ActionConfig = {
26+
[key: string]: {
27+
description: string;
28+
optional: boolean;
29+
type: string;
30+
};
31+
};
32+
type Action = {
33+
distributable: boolean;
34+
disablePartitioning: boolean;
35+
configuration: ActionConfig;
36+
description: string;
37+
state: string;
38+
type: string;
39+
};
40+
type ActionsResponse = {
41+
actions: {
42+
[actionName: string]: Action;
43+
};
44+
};
45+
46+
// --- Component ---
47+
48+
const ActionList: React.FC = () => {
49+
const [data, setData] = useState<ActionsResponse | null>(null);
50+
const [error, setError] = useState<string | null>(null);
51+
const [loading, setLoading] = useState(true);
52+
53+
useEffect(() => {
54+
LassoService.getActions()
55+
.then(response => setData(response.data))
56+
.catch((e) => setError('Failed to load actions'))
57+
.finally(() => setLoading(false));
58+
}, []);
59+
60+
if (loading) return <Box display="flex" justifyContent="center" mt={4}><CircularProgress /></Box>;
61+
if (error) return <Alert severity="error">{error}</Alert>;
62+
if (!data) return null;
63+
64+
return (
65+
<Container maxWidth="md" sx={{ mt: 4, mb: 4 }}>
66+
<Box>
67+
{/* <Typography variant="h4" mb={2}>
68+
Available Actions
69+
</Typography> */}
70+
{Object.entries(data.actions).map(([actionName, action]) => (
71+
<Accordion key={actionName}>
72+
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
73+
<Box sx={{ flexGrow: 1 }}>
74+
<Typography variant="h6">{actionName}</Typography>
75+
<Typography variant="body2" color="text.secondary">
76+
{action.description}
77+
</Typography>
78+
</Box>
79+
<Box ml={2}>
80+
<Chip
81+
label={action.state}
82+
color={action.state === 'stable' ? 'success' : 'default'}
83+
size="small"
84+
sx={{ mr: 1 }}
85+
/>
86+
{action.distributable && (
87+
<Chip label="Distributable" color="primary" size="small" sx={{ mr: 1 }} />
88+
)}
89+
{action.disablePartitioning && (
90+
<Chip label="No Partitioning" color="warning" size="small" />
91+
)}
92+
</Box>
93+
</AccordionSummary>
94+
<AccordionDetails>
95+
<Typography variant="subtitle1" mb={1}>
96+
Configuration
97+
</Typography>
98+
{Object.keys(action.configuration).length === 0 ? (
99+
<Typography color="text.secondary">
100+
No configuration required.
101+
</Typography>
102+
) : (
103+
<TableContainer component={Paper} variant="outlined">
104+
<Table size="small">
105+
<TableHead>
106+
<TableRow>
107+
<TableCell>Key</TableCell>
108+
<TableCell>Description</TableCell>
109+
<TableCell>Type</TableCell>
110+
<TableCell>Optional</TableCell>
111+
</TableRow>
112+
</TableHead>
113+
<TableBody>
114+
{Object.entries(action.configuration).map(
115+
([key, conf]) => (
116+
<TableRow key={key}>
117+
<TableCell>{key}</TableCell>
118+
<TableCell>{conf.description}</TableCell>
119+
<TableCell>
120+
<Chip label={conf.type} size="small" variant="outlined" />
121+
</TableCell>
122+
<TableCell>
123+
{conf.optional ? (
124+
<Chip label="Yes" size="small" color="success" />
125+
) : (
126+
<Chip label="No" size="small" color="error" />
127+
)}
128+
</TableCell>
129+
</TableRow>
130+
)
131+
)}
132+
</TableBody>
133+
</Table>
134+
</TableContainer>
135+
)}
136+
</AccordionDetails>
137+
</Accordion>
138+
))}
139+
</Box>
140+
</Container>
141+
);
142+
};
143+
144+
export default ActionList;

lasso/src/pages/lasso/actions.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, { useEffect, useRef, useState } from 'react';
2+
3+
import Layout from '@theme/Layout';
4+
import Head from '@docusaurus/Head';
5+
import { Typography } from '@mui/material';
6+
import ActionList from '@site/src/components/actions/actions';
7+
8+
const ActionsPage = () => {
9+
10+
11+
return (
12+
<Layout>
13+
<Head>
14+
<title>LASSO Actions</title>
15+
<meta name="description" content="LSL Editor" />
16+
</Head>
17+
18+
<Typography sx={{ margin: 2 }} variant="h5" component="div">Actions<Typography variant="h6" component="div">Explore available Actions and their configuration parameters</Typography>
19+
20+
</Typography>
21+
22+
<ActionList/>
23+
24+
</Layout>
25+
);
26+
}
27+
28+
export default ActionsPage;

lasso/src/pages/lasso/search.tsx

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ import {
1313
InputAdornment,
1414
Pagination,
1515
Stack,
16-
Link
16+
Link,
17+
List,
18+
ListItem,
19+
ListItemButton,
20+
Dialog,
21+
DialogTitle,
22+
DialogContent,
23+
ListItemText,
24+
DialogActions
1725
} from '@mui/material';
1826
import SearchIcon from '@mui/icons-material/Search';
1927
import { CodeSnippet, SearchQueryRequest, SearchQueryResponse, TextualSearch } from '@site/src/services/models';
@@ -23,9 +31,17 @@ import Head from '@docusaurus/Head';
2331
import Layout from '@theme/Layout';
2432
import { TDSExamples } from '@site/src/components/HubFeatures/HubFeatures';
2533
import AuthService from '@site/src/services/AuthService';
34+
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
2635

2736
const RESULTS_PER_PAGE = 10;
2837

38+
interface DataSource {
39+
id: string;
40+
name: string;
41+
description?: string;
42+
url?: string;
43+
}
44+
2945
const CodeSearchPage: React.FC = () => {
3046
// Only run in browser context
3147
let filterString = ""
@@ -69,6 +85,13 @@ const CodeSearchPage: React.FC = () => {
6985
const [page, setPage] = useState(1);
7086
const [total, setTotal] = useState(0);
7187

88+
// New state for dialog and datasources:
89+
const [dsDialogOpen, setDsDialogOpen] = useState(false);
90+
const [availableDataSources, setAvailableDataSources] = useState<DataSource[]>([]);
91+
const [dataSourcesLoading, setDataSourcesLoading] = useState(false);
92+
93+
94+
7295
const sortImplementationsToArray = (implementations: any): any[] => {
7396
const jsonArray = Array.from(Object.values(implementations));
7497

@@ -82,6 +105,31 @@ const CodeSearchPage: React.FC = () => {
82105
return jsonArray;
83106
};
84107

108+
// Helper to open dialog and fetch datasources on-open:
109+
const handleOpenDatasourceDialog = async () => {
110+
setDsDialogOpen(true);
111+
setDataSourcesLoading(true);
112+
try {
113+
const response = await LassoService.getDataSources();
114+
115+
// Now extract: response.data.dataSources, convert to array:
116+
const dsMap = response.data.dataSources;
117+
const dsArray = Object.values(dsMap) as DataSource[];
118+
setAvailableDataSources(dsArray);
119+
} catch (error) {
120+
// Handle error as you wish (alert, etc)
121+
setAvailableDataSources([]);
122+
}
123+
setDataSourcesLoading(false);
124+
};
125+
const handleCloseDatasourceDialog = () => setDsDialogOpen(false);
126+
127+
// When a datasource is selected:
128+
const handleSelectDatasource = (selectedId: string) => {
129+
setUrlDataSource(selectedId); // This changes which is used for searching
130+
setDsDialogOpen(false);
131+
};
132+
85133
const handleSearch = async () => {
86134
// do a textual search
87135
let textualSearch = new TextualSearch()
@@ -109,24 +157,24 @@ const CodeSearchPage: React.FC = () => {
109157
console.log(JSON.stringify(request))
110158

111159
await AuthService.loginDefault().then(
112-
(response) => {
160+
(response) => {
113161
// login successful
114162
console.log("Successfully logged in")
115163

116-
117-
},
118-
(error) => {
164+
165+
},
166+
(error) => {
119167
const resMessage =
120-
(error.response &&
121-
error.response.data &&
122-
error.response.data.message) ||
123-
error.message ||
124-
error.toString();
125-
168+
(error.response &&
169+
error.response.data &&
170+
error.response.data.message) ||
171+
error.message ||
172+
error.toString();
173+
126174
// FIXME
127175
console.log("Login attempt failed " + error)
128-
}
129-
)
176+
}
177+
)
130178

131179
await LassoService.queryImplementationsForDataSource(lassoDataSource, request).then(
132180
(response) => {
@@ -226,6 +274,20 @@ const CodeSearchPage: React.FC = () => {
226274
Search
227275
</Button>
228276
</Grid>
277+
278+
{/* NEW: Datasource selector button */}
279+
<Grid item>
280+
<Button
281+
variant="outlined"
282+
color="secondary"
283+
onClick={handleOpenDatasourceDialog}
284+
endIcon={<ArrowDropDownIcon />}
285+
>
286+
Datasource: {urlDataSource}
287+
</Button>
288+
</Grid>
289+
290+
<Grid item>
229291
<Stack direction="row" spacing={1} alignItems="center" sx={{ mt: 1, mb: 3 }}>
230292
<Typography variant="body2" color="text.secondary">
231293
Learn more about the <b>LQL Query Language</b>:
@@ -239,9 +301,44 @@ const CodeSearchPage: React.FC = () => {
239301
Documentation
240302
</Link>
241303
</Stack>
242-
</Grid>
304+
</Grid>
305+
243306

307+
</Grid>
244308

309+
{/* Datasource selection dialog */}
310+
<Dialog open={dsDialogOpen} onClose={handleCloseDatasourceDialog} fullWidth>
311+
<DialogTitle>Select a Datasource</DialogTitle>
312+
<DialogContent dividers>
313+
{dataSourcesLoading ? (
314+
<CircularProgress />
315+
) : (
316+
<List>
317+
{availableDataSources.map(ds => (
318+
<ListItem key={ds.id} disablePadding>
319+
<ListItemButton onClick={() => handleSelectDatasource(ds.id)}>
320+
<ListItemText
321+
primary={ds.name}
322+
secondary={ds.description}
323+
style={ds.id === urlDataSource ? { fontWeight: 'bold' } : {}}
324+
/>
325+
</ListItemButton>
326+
</ListItem>
327+
))}
328+
{availableDataSources.length === 0 && (
329+
<Typography color="text.secondary">
330+
No datasources found.
331+
</Typography>
332+
)}
333+
</List>
334+
)}
335+
</DialogContent>
336+
<DialogActions>
337+
<Button onClick={handleCloseDatasourceDialog} color="primary">
338+
Close
339+
</Button>
340+
</DialogActions>
341+
</Dialog>
245342

246343
<div style={{ minHeight: 320, marginTop: 40 }}>
247344
{!loading && searched && total > 0 && (

0 commit comments

Comments
 (0)