Skip to content

Commit 593c1a8

Browse files
tcnichollmarini
andauthored
260 show extractor metadata (#274)
* fixing uvicorn, this got overwritten with local (i think by me) * new tab, placeholder * gets metadata with listeners nothing shows yet * adding separate component for each listener metadata entry, currently does not display anything * adding component for contents and listener agent very basic, only works for non-nested metadata * working on nested metadata, only displays top level correctly * json displays properly, need to put each metadata in a box and make metadata collapsible * toggle. can hide or view metadata now * formatting. pipenv run black app * adding new tab to dataset for extractor metadata * changing tab order, tab names, and setting metadata json open by default * metadata from extractors appears in solid boxes. change in font for listener agent. * changing tab order, names for dataset * Added card to extracted metadata entries and fixed grid around them. Co-authored-by: Luigi Marini <[email protected]>
1 parent 7436860 commit 593c1a8

File tree

7 files changed

+229
-7
lines changed

7 files changed

+229
-7
lines changed

.run/uvicorn.run.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
<option name="INPUT_FILE" value="" />
2222
<method v="2" />
2323
</configuration>
24-
</component>
24+
</component>

frontend/src/components/datasets/Dataset.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import FilesTable from "../files/FilesTable";
1313
import config from "../../app.config";
1414
import {DatasetIn, MetadataIn} from "../../openapi/v2";
1515
import {DisplayMetadata} from "../metadata/DisplayMetadata";
16+
import {DisplayListenerMetadata} from "../metadata/DisplayListenerMetadata";
1617
import {EditMetadata} from "../metadata/EditMetadata";
1718
import {
1819
deleteDatasetMetadata as deleteDatasetMetadataAction,
@@ -185,9 +186,12 @@ export const Dataset = (): JSX.Element => {
185186
<Tabs value={selectedTabIndex} onChange={handleTabChange} aria-label="dataset tabs">
186187
<Tab icon={<InsertDriveFile/>} iconPosition="start" sx={tab} label="Files" {...a11yProps(0)} />
187188
<Tab icon={<FormatListBulleted/>} iconPosition="start" sx={tab}
188-
label="Metadata" {...a11yProps(1)} disabled={false}/>
189+
label="User Metadata" {...a11yProps(1)} disabled={false}/>
189190
<Tab icon={<AssessmentIcon/>} iconPosition="start" sx={tab}
190-
label="Extractors" {...a11yProps(2)} disabled={false}/>
191+
label="Extracted Metadata" {...a11yProps(2)} disabled={false}/>
192+
<Tab icon={<AssessmentIcon/>} iconPosition="start" sx={tab}
193+
label="Extractors" {...a11yProps(3)} disabled={false}/>
194+
191195
</Tabs>
192196
<TabPanel value={selectedTabIndex} index={0}>
193197
<FilesTable datasetId={datasetId} folderId={folderId}/>
@@ -225,11 +229,15 @@ export const Dataset = (): JSX.Element => {
225229
}
226230
</TabPanel>
227231
<TabPanel value={selectedTabIndex} index={2}>
232+
<DisplayListenerMetadata updateMetadata={updateDatasetMetadata}
233+
deleteMetadata={deleteDatasetMetadata}
234+
resourceType="dataset" resourceId={datasetId}/>
235+
</TabPanel>
236+
<TabPanel value={selectedTabIndex} index={3}>
228237
<Listeners
229238
datasetId={datasetId}
230239
/>
231240
</TabPanel>
232-
<TabPanel value={selectedTabIndex} index={3}/>
233241
<TabPanel value={selectedTabIndex} index={4}/>
234242
</Grid>
235243
<Grid item>

frontend/src/components/files/File.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {MainBreadcrumbs} from "../navigation/BreadCrumb";
1313
import {ActionModal} from "../dialog/ActionModal";
1414
import {FileVersionHistory} from "../versions/FileVersionHistory";
1515
import {DisplayMetadata} from "../metadata/DisplayMetadata";
16+
import {DisplayListenerMetadata} from "../metadata/DisplayListenerMetadata";
1617
import {
1718
deleteFileMetadata as deleteFileMetadataAction,
1819
fetchFileMetadata,
@@ -132,6 +133,8 @@ export const File = (): JSX.Element => {
132133

133134
const setMetadata = (metadata: any) => {
134135
// TODO wrap this in to a function
136+
console.log('metadata in file component');
137+
console.log(metadata);
135138
setMetadataRequestForms(prevState => {
136139
// merge the contents field; e.g. lat lon
137140
if (metadata.definition in prevState) {
@@ -228,8 +231,9 @@ export const File = (): JSX.Element => {
228231
<Tabs value={selectedTabIndex} onChange={handleTabChange} aria-label="file tabs">
229232
{/*<Tab label="Previews" {...a11yProps(0)} />*/}
230233
<Tab label="Version History" {...a11yProps(0)} />
231-
<Tab label="Metadata" {...a11yProps(1)} disabled={false}/>
232-
<Tab label="Extractors" {...a11yProps(2)} disabled={false}/>
234+
<Tab label="User Metadata" {...a11yProps(1)} disabled={false}/>
235+
<Tab label="Extracted Metadata" {...a11yProps(2)} disabled={false}/>
236+
<Tab label="Extractors" {...a11yProps(3)} disabled={false}/>
233237
</Tabs>
234238
{/*Preview Tab*/}
235239
{/*<TabPanel value={selectedTabIndex} index={0}>*/}
@@ -283,11 +287,16 @@ export const File = (): JSX.Element => {
283287
}
284288
</TabPanel>
285289
<TabPanel value={selectedTabIndex} index={2}>
290+
<DisplayListenerMetadata updateMetadata={updateFileMetadata}
291+
deleteMetadata={deleteFileMetadata}
292+
resourceType="file" resourceId={fileId}/>
293+
</TabPanel>
294+
<TabPanel value={selectedTabIndex} index={3}>
286295
<Listeners fileId={fileId}
287296
datasetId={datasetId}
288297
/>
289298
</TabPanel>
290-
<TabPanel value={selectedTabIndex} index={3}>
299+
<TabPanel value={selectedTabIndex} index={4}>
291300
Comments
292301
</TabPanel>
293302
</Grid>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import React, {useEffect, useState} from "react";
2+
import {Box, Grid, Typography} from "@mui/material";
3+
import {metadataConfig} from "../../metadata.config";
4+
import {useSelector, useDispatch} from "react-redux";
5+
import {RootState} from "../../types/data";
6+
import {fetchDatasetMetadata, fetchFileMetadata, fetchMetadataDefinitions} from "../../actions/metadata";
7+
import {Agent} from "./Agent";
8+
import {MetadataDeleteButton} from "./widgets/MetadataDeleteButton";
9+
import {ListenerMetadataEntry} from "../metadata/ListenerMetadataEntry";
10+
import Card from "@mui/material/Card";
11+
import CardContent from "@mui/material/CardContent";
12+
13+
type MetadataType = {
14+
updateMetadata: any,
15+
deleteMetadata: any,
16+
resourceType: string | undefined,
17+
resourceId: string | undefined,
18+
}
19+
20+
/*
21+
This is the interface displayed already created metadata and allow eidts
22+
Uses only the list of metadata
23+
*/
24+
export const DisplayListenerMetadata = (props: MetadataType) => {
25+
26+
const {updateMetadata, deleteMetadata, resourceType, resourceId} = props;
27+
28+
const dispatch = useDispatch();
29+
30+
const getMetadatDefinitions = (name: string | null, skip: number, limit: number) => dispatch(fetchMetadataDefinitions(name, skip, limit));
31+
const metadataDefinitionList = useSelector((state: RootState) => state.metadata.metadataDefinitionList);
32+
const listDatasetMetadata = (datasetId: string | undefined) => dispatch(fetchDatasetMetadata(datasetId));
33+
const listFileMetadata = (fileId: string | undefined) => dispatch(fetchFileMetadata(fileId));
34+
const datasetMetadataList = useSelector((state: RootState) => state.metadata.datasetMetadataList);
35+
const fileMetadataList = useSelector((state: RootState) => state.metadata.fileMetadataList);
36+
37+
useEffect(() => {
38+
getMetadatDefinitions(null, 0, 100);
39+
}, []);
40+
41+
// complete metadata list with both definition and values
42+
useEffect(() => {
43+
if (resourceType === "dataset") {
44+
listDatasetMetadata(resourceId);
45+
} else if (resourceType === "file") {
46+
listFileMetadata(resourceId);
47+
}
48+
}, [resourceType, resourceId]);
49+
50+
return (
51+
<>
52+
{
53+
(() => {
54+
let metadataList = [];
55+
if (resourceType === "dataset") metadataList = datasetMetadataList;
56+
else if (resourceType === "file") metadataList = fileMetadataList;
57+
let listenerMetadataList = [];
58+
let listenerMetadataContent = [];
59+
60+
return (<Grid container spacing={2}>
61+
{metadataList.map((metadata, idx) => {
62+
if (metadata.agent.listener !== null) {
63+
return (<Grid item xs={12}><Card key={idx}>
64+
<CardContent>
65+
<ListenerMetadataEntry agent={metadata.agent}
66+
contents={metadata.contents}
67+
context={metadata.context}
68+
context_url={metadata.context_url}
69+
created={metadata.created}
70+
/>
71+
</CardContent>
72+
</Card></Grid>);
73+
}
74+
})}
75+
</Grid>);
76+
})()
77+
}
78+
</>
79+
)
80+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from "react";
2+
import {Box, Typography} from "@mui/material";
3+
import {theme} from "../../theme";
4+
import {parseDate} from "../../utils/common";
5+
6+
const textStyle = {
7+
fontWeight: "normal",
8+
fontSize: "16x",
9+
color: theme.palette.primary,
10+
};
11+
12+
13+
export const ListenerAgent = (props) => {
14+
const {created, agent} = props;
15+
const id = `agent-${agent.id}`;
16+
const listener = agent.listener;
17+
18+
return (
19+
<>
20+
<Box key={id}>
21+
<Typography sx={textStyle}>Listener name: {agent.listener.name}</Typography>
22+
<Typography sx={textStyle}>Version: {agent.listener.version}</Typography>
23+
<Typography sx={textStyle}>Created at: {parseDate(created)}</Typography>
24+
<Typography sx={textStyle}>Created by: {agent.creator.first_name} {agent.creator.last_name}</Typography>
25+
</Box>
26+
</>
27+
)
28+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from "react";
2+
import {Box, Typography} from "@mui/material";
3+
import {theme} from "../../theme";
4+
import {parseDate} from "../../utils/common";
5+
6+
const textStyle = {
7+
fontWeight: "normal",
8+
fontSize: "16x",
9+
color: theme.palette.primary,
10+
};
11+
12+
type ListenerContentsEntry = {
13+
contents: any,
14+
}
15+
16+
17+
18+
export const ListenerContents = (props: ListenerContentsEntry) => {
19+
const {contents} = props;
20+
21+
return <div><pre>{JSON.stringify(contents, null, 2)}</pre></div>
22+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, {useEffect, useState} from "react";
2+
import {Box, Grid, Typography, Divider, Button} from "@mui/material";
3+
import {metadataConfig} from "../../metadata.config";
4+
import {useSelector, useDispatch} from "react-redux";
5+
import {RootState} from "../../types/data";
6+
import {fetchDatasetMetadata, fetchFileMetadata, fetchMetadataDefinitions} from "../../actions/metadata";
7+
import {ListenerAgent} from "./ListenerAgent";
8+
import {ListenerContents} from "./ListenerContents";
9+
import {MetadataDeleteButton} from "./widgets/MetadataDeleteButton";
10+
11+
12+
type ListenerMetadata = {
13+
agent: any,
14+
contents: any,
15+
context: any,
16+
context_url: any,
17+
created: string,
18+
}
19+
20+
/*
21+
This is the interface displayed already created metadata and allow eidts
22+
Uses only the list of metadata
23+
*/
24+
export const ListenerMetadataEntry = (props: ListenerMetadata) => {
25+
26+
const {agent, contents, context, context_url, created} = props;
27+
28+
const dispatch = useDispatch();
29+
30+
const [isOpened, setIsOpened] = useState(true);
31+
const buttonTextClosed = "View Metadata";
32+
const buttonTextOpened = "Hide Metadata";
33+
const [buttonText, setButtonText] = useState(buttonTextOpened);
34+
35+
function toggle() {
36+
setIsOpened(wasOpened => !wasOpened);
37+
if (buttonText == buttonTextClosed){
38+
setButtonText(buttonTextOpened)
39+
} else {
40+
setButtonText(buttonTextClosed)
41+
}
42+
43+
}
44+
45+
46+
return (
47+
<>
48+
{
49+
(() => {
50+
return <Grid container spacing={2}>
51+
<Grid item xs={11} sm={11} md={11} lg={11} xl={11}>
52+
<div>
53+
<ListenerAgent created={created} agent={agent} />
54+
</div>
55+
<Divider></Divider>
56+
<Button
57+
onClick={toggle}
58+
>
59+
{buttonText}
60+
</Button>
61+
{isOpened && (
62+
<ListenerContents
63+
contents={contents}/>
64+
)}
65+
66+
67+
</Grid>
68+
</Grid>
69+
70+
71+
})()
72+
}
73+
</>
74+
)
75+
}

0 commit comments

Comments
 (0)