Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions src/api/endpoints/apiService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React from "react";
import { createPostRequest, createGetRequest } from "./apiActions";
import { API_CONFIG } from "../../config";
import { GlobalDataContext } from "../../contexts/DataContext";

export interface LoginRequest {
username: string
Expand All @@ -17,6 +15,19 @@ export interface RegisterRequest {
organization: string
}

type LabelType =
| string
| { '@value': string; '@language'?: string }
| Array<string | { '@value': string; '@language'?: string }>;

interface GraphNode {
'rdfs:label'?: LabelType;
}

interface JsonLdResponse {
'@graph'?: GraphNode[];
}

export const login = createPostRequest<any, LoginRequest>(API_CONFIG.REAL_API.SIGNIN, "application/x-www-form-urlencoded")

export const register = createPostRequest<any, RegisterRequest>(API_CONFIG.REAL_API.NEWUSER_ILX, "application/x-www-form-urlencoded")
Expand All @@ -27,7 +38,7 @@ export const getUserSettings = (group: string) => {
return createGetRequest<any, any>(endpoint, "application/json")();
};

export const createNewOrganization = ({group, data} : {group: string, data: any}) => {
export const createNewOrganization = ({ group, data }: { group: string, data: any }) => {
const endpoint = `/${group}${API_CONFIG.REAL_API.CREATE_NEW_ORGANIZATION}`;
return createPostRequest<any, any>(endpoint, "application/json")(data);
};
Expand All @@ -41,3 +52,29 @@ export const userLogout = (group: string) => {
const endpoint = `/${group}${API_CONFIG.REAL_API.LOGOUT}`;
return createGetRequest<any, any>(endpoint, "application/json")();
};

export const getSelectedTermLabel = async (searchTerm: string): Promise<string | undefined> => {
try {
const res = await fetch(`https://uri.olympiangods.org/base/${searchTerm}.jsonld`);
if (!res.ok) throw new Error(`Response status: ${res.status}`);

const data: JsonLdResponse = await res.json();
const label = data['@graph']?.[0]?.['rdfs:label'];

const getLabelValue = (label: LabelType): string => {
if (typeof label === 'string') return label;
if (Array.isArray(label)) {
const en = label.find(
l => typeof l === 'string' || (typeof l === 'object' && l?.['@language'] === 'en')
);
return typeof en === 'string' ? en : en?.['@value'] || '';
}
return label?.['@value'] || '';
};

return label ? getLabelValue(label) : undefined
} catch (err: any) {
console.error(err.message);
return undefined;
}
};
20 changes: 10 additions & 10 deletions src/components/Header/Search.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import {
} from "@mui/material";
import { debounce } from 'lodash';
import PropTypes from 'prop-types';
import { useQuery } from "../../helpers";
import BasicTabs from "../common/CustomTabs";
import { useNavigate } from "react-router-dom";
import { GlobalDataContext } from "../../contexts/DataContext";
import { SEARCH_TYPES } from "../../constants/types";
import { searchAll, elasticSearch } from "../../api/endpoints";
import FolderOutlinedIcon from '@mui/icons-material/FolderOutlined';
import { useEffect, useState, useCallback, forwardRef } from 'react';
import { useEffect, useState, useCallback, forwardRef, useContext } from 'react';
import { CloseIcon, ForwardIcon, SearchIcon, TermsIcon } from '../../Icons';
import CorporateFareOutlinedIcon from '@mui/icons-material/CorporateFareOutlined';

Expand Down Expand Up @@ -87,26 +87,26 @@ const Search = () => {
const [openList, setOpenList] = useState(false);
const [tabValue, setTabValue] = useState(0);
const navigate = useNavigate();
const query = useQuery();
const storedSearchTerm = query.get('searchTerm');
const [terms, setTerms] = useState([]);
const [organizations, setOrganizations] = useState([]);
const [ontologies, setOntologies] = useState([]);
const { storedSearchTerm, updateStoredSearchTerm} = useContext(GlobalDataContext)

const handleOpenList = () => setOpenList(true);
const handleCloseList = () => setOpenList(false);
const handleInputChange = (event) => setSearchTerm(event.target.value);

const handleSelectTerm = (event, newInputValue) => {
if (!newInputValue) return;

handleCloseList();
navigate(`/view?searchTerm=${newInputValue?.ilx}`);
updateStoredSearchTerm(newInputValue?.label)
};

const handleSearchTermClick = () => {
navigate(`/search?searchTerm=${searchTerm}`);
handleCloseList();
navigate(`/search?searchTerm=${searchTerm}`);
};

const handleInputFocus = (event) => {
Expand Down Expand Up @@ -139,7 +139,7 @@ const Search = () => {
setTerms([])
setOntologies([])
setOrganizations([])
},[]);
}, []);

const handleKeyDown = useCallback(event => {
if (event.ctrlKey && event.key === 'k') {
Expand Down Expand Up @@ -179,7 +179,7 @@ const Search = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [storedSearchTerm]);

// eslint-disable-next-line no-unused-vars
//eslint-disable-next-line no-unused-vars
const ListboxComponent = forwardRef(function ListboxComponent(props, ref) {
return (
<>
Expand Down Expand Up @@ -305,7 +305,7 @@ const Search = () => {
getOptionLabel={(option) => option?.hidden ? '' : (option.label || option.name || '')}
renderOption={(props, option, { selected }) => {
if (option?.hidden) return null;

const { key, ...otherProps } = props;
return (
<ListItem
Expand All @@ -330,7 +330,7 @@ const Search = () => {
</Button>
</ListItem>
);
}}
}}
renderInput={(params) => (
<TextField
{...params}
Expand Down
6 changes: 5 additions & 1 deletion src/components/SearchResults/ListView.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import PropTypes from "prop-types";
import { useContext } from "react";
import { useNavigate } from "react-router-dom";
import CustomButton from '../common/CustomButton';
import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined';
import CreateNewFolderOutlinedIcon from '@mui/icons-material/CreateNewFolderOutlined';
import { Box, Typography, Grid, Stack, Chip, CircularProgress } from '@mui/material';
import { GlobalDataContext } from "../../contexts/DataContext";

import { vars } from '../../theme/variables';
const { gray200, gray500, gray700, brand50, brand200, brand600, brand700, error50, error300, error700 } = vars;
Expand Down Expand Up @@ -129,9 +131,11 @@ const InfoSection = ({ searchResult }) => {

const ListView = ({ searchResults, loading }) => {
const navigate = useNavigate();
const { updateStoredSearchTerm } = useContext(GlobalDataContext);

const handleClick = (searchResult) => {
navigate(`/view?searchTerm=${searchResult?.label}`);
updateStoredSearchTerm(searchResult?.label)
navigate(`/view?searchTerm=${searchResult?.ilx}`);
};


Expand Down
6 changes: 2 additions & 4 deletions src/components/SingleTermView/OverView/OverView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ import { debounce } from 'lodash';
import PropTypes from 'prop-types';
import Hierarchy from "./Hierarchy";
import Predicates from "./Predicates";
import {useQuery} from "../../../helpers";
import RawDataViewer from "./RawDataViewer";
import {useCallback, useEffect, useMemo, useState} from "react";
import { getMatchTerms } from "../../../api/endpoints";

const OverView = ({ isCodeViewVisible, selectedDataFormat }) => {
const query = useQuery();
const searchTerm = query.get('searchTerm');
const OverView = ({ searchTerm, isCodeViewVisible, selectedDataFormat }) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);

Expand Down Expand Up @@ -67,6 +64,7 @@ const OverView = ({ isCodeViewVisible, selectedDataFormat }) => {
}

OverView.propTypes = {
searchTerm: PropTypes.string,
isCodeViewVisible: PropTypes.bool,
selectedDataFormat: PropTypes.string
}
Expand Down
60 changes: 37 additions & 23 deletions src/components/SingleTermView/index.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useState, useEffect, useRef, useContext } from "react";
import {
Box,
Button,
Expand All @@ -23,7 +24,6 @@ import CopyLinkComponent from "../common/CopyLinkComponent";
import BasicTabs from "../common/CustomTabs";
import CustomButton from "../common/CustomButton";
import CustomMenu from "./CustomMenu";
import React, { useState } from "react";
import OverView from "./OverView/OverView";
import HistoryPanel from "./History/HistoryPanel";
import VariantsPanel from "./Variants/VariantsPanel";
Expand All @@ -43,34 +43,37 @@ import CustomSingleSelect from "../common/CustomSingleSelect";
import HomeOutlinedIcon from "@mui/icons-material/HomeOutlined";
import CreateForkDialog from "./CreateForkDialog";
import TermDialog from "../TermEditor/TermDialog";
import { getSelectedTermLabel } from "../../api/endpoints/apiService";
import { GlobalDataContext } from "../../contexts/DataContext";

const { gray200, brand700, gray600 } = vars;

const dataFormats = ['JSON-LD', 'Turtle', 'N3', 'OWL', 'CSV']

const SingleTermView = () => {
const [open, setOpen] = React.useState(false);
const actionRef = React.useRef(null);
const anchorRef = React.useRef(null);
const [dataFormatAnchorEl, setDataFormatAnchorEl] = React.useState(null);
const [tabValue, setTabValue] = React.useState(0);
const [isCodeViewVisible, setIsCodeViewVisible] = React.useState(false);
const [open, setOpen] = useState(false);
const actionRef = useRef(null);
const anchorRef = useRef(null);
const [dataFormatAnchorEl, setDataFormatAnchorEl] = useState(null);
const [tabValue, setTabValue] = useState(0);
const [isCodeViewVisible, setIsCodeViewVisible] = useState(false);
const [toggleButtonValue, setToggleButtonValue] = useState('defaultView');
const [selectedDataFormat, setSelectedDataFormat] = React.useState('JSON-LD');
const [openRequestMergeDialog, setOpenRequestMergeDialog] = React.useState(false);
const [editTermDialogOpen, setEditTermDialogOpen] = React.useState(false);
const [selectedDataFormat, setSelectedDataFormat] = useState('JSON-LD');
const [openRequestMergeDialog, setOpenRequestMergeDialog] = useState(false);
const [editTermDialogOpen, setEditTermDialogOpen] = useState(false);
const query = useQuery();
const searchTerm = query.get('searchTerm');
const openDataFormatMenu = Boolean(dataFormatAnchorEl);
const [openForkDialog, setOpenForkDialog] = React.useState(false);
const [openForkDialog, setOpenForkDialog] = useState(false);
const { storedSearchTerm, updateStoredSearchTerm } = useContext(GlobalDataContext);

const handleForkDialogClose = () => {
setOpenForkDialog(false);
}
const handleForkDialogClose = () => {
setOpenForkDialog(false);
}

const handleOpenForkDialog = () => {
setOpenForkDialog(true);
}
const handleOpenForkDialog = () => {
setOpenForkDialog(true);
}
const handleClickDataFormatMenu = (event) => {
setDataFormatAnchorEl(event.currentTarget);
};
Expand Down Expand Up @@ -126,6 +129,17 @@ const SingleTermView = () => {
{ label: 'ILX:0101901' },
];

useEffect(() => {
const fetchLabel = async () => {
const result = await getSelectedTermLabel(searchTerm);
updateStoredSearchTerm(result);
};

if (searchTerm) {
fetchLabel();
}
}, [searchTerm, updateStoredSearchTerm]);

const isItFork = true;

return (
Expand Down Expand Up @@ -156,7 +170,7 @@ const SingleTermView = () => {
<Grid item xs={12} lg={2}>
<Stack direction="row" spacing=".75rem" alignItems="center">
<Typography color={gray600} fontSize="1.875rem" fontWeight={600}>
{searchTerm}
{storedSearchTerm}
</Typography>
<Chip label="Fork" variant="outlined" />
</Stack>
Expand Down Expand Up @@ -253,7 +267,7 @@ const SingleTermView = () => {
</Grid>
</Box>
{
tabValue === 0 && <OverView isCodeViewVisible={isCodeViewVisible} selectedDataFormat={selectedDataFormat} />
tabValue === 0 && <OverView searchTerm={searchTerm} isCodeViewVisible={isCodeViewVisible} selectedDataFormat={selectedDataFormat} />
}
{
tabValue === 1 && <VariantsPanel />
Expand All @@ -267,10 +281,10 @@ const SingleTermView = () => {
</Box>
<RequestMergeChanges searchTerm={searchTerm} open={openRequestMergeDialog} handleClose={handleCloseRequestMergeDialog} />
<TermDialog open={editTermDialogOpen} handleClose={handleCloseEditTermDialog} searchTerm={searchTerm} />
<CreateForkDialog
open={openForkDialog}
handleClose={handleForkDialogClose}
/>
<CreateForkDialog
open={openForkDialog}
handleClose={handleForkDialogClose}
/>
</>
)
}
Expand Down
9 changes: 8 additions & 1 deletion src/contexts/DataContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const GlobalDataProvider = ({ children }) => {
const [searchTypeFilter, setSearchTypeFilter] = useState(null);
const [predicatesSingleTermState, setPredicatesSingleTermState] = useState(false);
const [editBulkSearchFilters, setEditBulkSearchFilters] = useState([]);
const [storedSearchTerm, setStoredSearchTerm] = useState("");
const setOntologyData = (ontology) => {
setActiveOntology(ontology);
};
Expand All @@ -34,6 +35,10 @@ const GlobalDataProvider = ({ children }) => {
setUser(user);
}

const updateStoredSearchTerm = (value) => {
setStoredSearchTerm(value)
}

const dataContextValue = {
user,
setUserData,
Expand All @@ -46,7 +51,9 @@ const GlobalDataProvider = ({ children }) => {
predicatesSingleTermState,
setPredicatesSingleTermData,
editBulkSearchFilters,
setEditBulkSearchData
setEditBulkSearchData,
storedSearchTerm,
updateStoredSearchTerm
};

return (
Expand Down