Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moveregistriesandtheme #664

Merged
merged 6 commits into from
May 31, 2024
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
82 changes: 35 additions & 47 deletions frontend/components/Admin/Registries.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,34 @@ const headers = ['URI Prefix', 'SynBioHub URL', ''];
export default function Registries() {
const token = useSelector(state => state.user.token);
const dispatch = useDispatch();
const { registries, loading } = useRegistries(token, dispatch);
const [registries, setRegistries] = useState([]);
const [loading, setLoading] = useState(false);

useEffect(() => {
setLoading(true);
try {
const registriesData = JSON.parse(localStorage.getItem('registries')) || [];
setRegistries(registriesData);
} catch (error) {
console.error('Error fetching registries from localStorage', error);
dispatch(addError(error));
} finally {
setLoading(false);
}
}, [dispatch]);

return (
<div className={styles.plugintable}>
<RegistryActions />
<Table
data={registries ? registries.registries : undefined}
data={registries}
loading={loading}
title="Local Registries"
searchable={searchable}
headers={headers}
sortOptions={options}
defaultSortOption={options[0]}
sortMethods={sortMethods}
searchable={true} // Assuming you want to enable search
headers={['Header1', 'Header2']} // Replace with your actual headers
sortOptions={['Option1', 'Option2']} // Replace with your actual sort options
defaultSortOption={'Option1'} // Replace with your actual default sort option
sortMethods={{}} // Replace with your actual sort methods
hideFooter={true}
finalRow={<NewRegistryRow token={token} />}
dataRowDisplay={registry => (
Expand Down Expand Up @@ -349,50 +363,24 @@ const fetcher = (url, dispatch) =>
dispatch(addError(error));
});

export async function processUrl(inputUrl, token, dispatch) {

const data = await fetcher(`${publicRuntimeConfig.backend}/admin/registries`, dispatch);



if (data && data.registries) {
let registries;
// Check if data.registries is an array
if (data.registries && Array.isArray(data.registries)) {
registries = data.registries;
} else if (data && typeof data === 'object') {
registries = [data]; // This is an example, adjust based on your needs
} else {
registries = [];
}

for (const registry of registries) {
if (inputUrl.startsWith(registry.uri)) {
const urlRemovedForLink = inputUrl.replace(registry.uri, ""); // TODO: Should only strip for only "you"
const urlReplacedForBackend = inputUrl.replace(registry.uri, registry.url);
return { urlRemovedForLink, urlReplacedForBackend };
}
export async function processUrl(inputUrl, registries) {
for (const registry of registries) {
if (inputUrl.startsWith(registry.uri)) {
const urlRemovedForLink = inputUrl.replace(registry.uri, "");
const urlReplacedForBackend = inputUrl.replace(registry.uri, registry.url);
return { urlRemovedForLink, urlReplacedForBackend };
}
return { original: inputUrl }; // if you don't match any uri
}
return { original: inputUrl }; // if you don't match any uri
return { original: inputUrl };
}

export async function processUrlReverse(inputUrl, token, dispatch) {

const data = await fetcher(`${publicRuntimeConfig.backend}/admin/registries`, dispatch);

if (data && data.registries) {
const registries = data.registries;

for (const registry of registries) {
if (inputUrl.startsWith(registry.url)) {
const uriRemovedForLink = inputUrl.replace(registry.url, "");
const uriReplacedForBackend = inputUrl.replace(registry.url, registry.uri);
return { uriRemovedForLink, uriReplacedForBackend };
}
export async function processUrlReverse(inputUrl, registries) {
for (const registry of registries) {
if (inputUrl.startsWith(registry.url)) {
const uriRemovedForLink = inputUrl.replace(registry.url, "");
const uriReplacedForBackend = inputUrl.replace(registry.url, registry.uri);
return { uriRemovedForLink, uriReplacedForBackend };
}
return { original: inputUrl }; // if you don't match any uri
}
return { original: inputUrl }; // if you don't match any uri
return { original: inputUrl };
}
22 changes: 13 additions & 9 deletions frontend/components/Admin/Theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,19 @@ export default function Theme() {
);
}

export const useTheme = dispatch => {
const { data, error } = useSWR(
[`${publicRuntimeConfig.backend}/admin/theme`, dispatch],
fetcher
);
return {
theme: data,
loading: !error && !data
};
export const useTheme = () => {
const [theme, setTheme] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const storedTheme = localStorage.getItem('theme');
if (storedTheme) {
setTheme(JSON.parse(storedTheme));
}
setLoading(false);
}, []);

return { theme, loading };
};

const fetcher = (url, dispatch) =>
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/Basket/BasketItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function BasketItem(properties) {

// Process the URI using processUrl function
const handleClick = async () => {
const processedUrlData = await processUrl(properties.item.uri, token, dispatch);
const processedUrlData = await processUrl(properties.item.uri, localStorage.getItem('registries'));
if (processedUrlData.urlReplacedForBackend) {
router.push(processedUrlData.urlReplacedForBackend);
} else if (processedUrlData.original) {
Expand Down
24 changes: 14 additions & 10 deletions frontend/components/Navbar/Navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import {
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Image from 'next/image';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import Loader from 'react-loader-spinner';
import { useSelector } from 'react-redux';
import { useTheme } from '../Admin/Theme';

import styles from '../../styles/navbar.module.css';
import Profile from './Profile';
import Selector from './Selector';
Expand All @@ -30,32 +29,37 @@ export default function Navbar() {
);

useEffect(() => {
if (loggedIn) setProfileControl(<Profile />);
else
if (loggedIn) {
setProfileControl(<Profile />);
} else {
setProfileControl(
<Selector icon={faSignInAlt} name="Sign In" href="/login" />
);
}
}, [loggedIn]);

if (loading) {
return <div>Loading...</div>; // Adjust this to your loading indicator
}

let linkHref = "/";
if (theme && theme.altHome && theme.altHome.length > 0) {
linkHref = theme.altHome;
}

return (
<header className={styles.container}
style={{ backgroundColor: theme?.themeParameters?.[0]?.value || '#465775' }}
<header
className={styles.container}
style={{ backgroundColor: theme?.themeParameters?.[0]?.value || '#465775' }}
>

<div className={styles.logoAndInstanceContainer}> {/* This is your new div container */}
<div className={styles.logoAndInstanceContainer}>
<Link href={linkHref}>
<a className={styles.logo}>
<Image alt="logo" width={80} height={80} src="/images/logo.svg" />
{/* <Image alt="logo" width={80} height={80} src="/images/widevibe.gif" /> */}
</a>
</Link>

{!loading && theme && (
{theme && (
<Selector name={theme.instanceName} href="/" isInstanceName={true} />
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ export default function ResultRow(properties) {

useEffect(() => {
async function processAndSetUri() {
const result = await processUrl(properties.uri, token, dispatch);
const result = await processUrl(properties.uri, localStorage.getItem('registries'));
setProcessedUri(result.urlRemovedForLink || result.original);
}

processAndSetUri();
}, [properties.uri]);
}, [dispatch, properties.uri]);

// Identify what type of object the search result is from type url
if (potentialType.includes('component')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ const getTypeAndUrl = async (result, token, dispatch) => {

result.type = type;

const processed = await processUrl(result.uri, token, dispatch);
const processed = await processUrl(result.uri, localStorage.getItem('registries'));
result.url = processed.urlRemovedForLink || processed.original;

// let newUrl = result.uri.replace('https://synbiohub.org', '');
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/Submission/SubmissionDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function SubmissionDisplay(properties) {

useEffect(() => {
async function processAndSetUri() {
const result = await processUrl(properties.submission.uri, token, dispatch);
const result = await processUrl(properties.submission.uri, localStorage.getItem('registries'));
setProcessedUri(result.urlRemovedForLink || result.original);
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/components/Submit/SubmissionStatusPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function SubmissionStatusPanel() {

useEffect(() => {
async function processAndSetUri() {
const result = await processUrl(submissionUri, token, dispatch);
const result = await processUrl(submissionUri, localStorage.getItem('registries'));
setProcessedUri(result.urlRemovedForLink || result.original);
}

Expand Down
46 changes: 46 additions & 0 deletions frontend/components/TopLevel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import Head from 'next/head';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useState } from 'react';

import { addError, markPageVisited, restoreLogin } from '../redux/actions';
import styles from '../styles/layout.module.css';
import Footer from './Footer';
import Navbar from './Navbar/Navbar';
import DownloadStatus from './Reusable/Download/DownloadStatus';
import Errors from './Error/Errors';
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();
import axios from 'axios';

/* eslint sonarjs/cognitive-complexity: "off" */

Expand All @@ -23,6 +27,48 @@ export default function TopLevel(properties) {
const router = useRouter();
const loggedIn = useSelector(state => state.user.loggedIn);
const pageVisited = useSelector(state => state.tracking.pageVisited);
const [registries, setRegistries] = useState([]);
const [theme, setTheme] = useState([]);
const [loading, setLoading] = useState(false);

// Fetch registries once on component mount
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const [registriesResponse, themeResponse] = await Promise.all([
axios.get(`${publicRuntimeConfig.backend}/admin/registries`, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
}),
axios.get(`${publicRuntimeConfig.backend}/admin/theme`, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
})
]);

const registriesData = registriesResponse.data.registries || [];
const themeData = themeResponse.data || [];

setRegistries(registriesData);
setTheme(themeData);

localStorage.setItem('registries', JSON.stringify(registriesData));
localStorage.setItem('theme', JSON.stringify(themeData));
} catch (error) {
console.error('Error fetching data', error);
dispatch(addError(error));
} finally {
setLoading(false);
}
};

fetchData();
}, [dispatch]);

useEffect(() => {
if (!pageVisited && !properties.doNotTrack) dispatch(markPageVisited(true));
Expand Down
8 changes: 4 additions & 4 deletions frontend/components/Viewing/Collection/Members.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default function Members(properties) {
useEffect(() => {
let isMounted = true;
async function processUri() {
const result = await processUrlReverse(publicRuntimeConfig.backend, token, dispatch);
const result = await processUrlReverse(publicRuntimeConfig.backend, localStorage.getItem('registries'));
if (isMounted) {
setProcessedUri(result.uriReplacedForBackend);
}
Expand Down Expand Up @@ -272,7 +272,7 @@ function MemberTable(properties) {
async function processMembers() {
if (properties.members) {
const updatedMembers = await Promise.all(properties.members.map(async member => {
const processed = await processUrl(member.uri, token, dispatch);
const processed = await processUrl(member.uri, localStorage.getItem('registries'));
return {
...member,
uri: processed.urlRemovedForLink
Expand Down Expand Up @@ -434,13 +434,13 @@ function compareUri(memberUri, baseUri) {
const userUriPrefix = '/user/';
const publicUriPrefix = '/public/';

if (memberUri.startsWith(userUriPrefix)) {
if (memberUri && memberUri.startsWith(userUriPrefix)) {
// Check if member.uri matches properties.uri for the first 3 slashes
const matchUri = baseUri.split('/').slice(0, 4).join('/');
if (memberUri.startsWith(matchUri)) {
return faTrash;
}
} else if (memberUri.startsWith(publicUriPrefix)) {
} else if (memberUri && memberUri.startsWith(publicUriPrefix)) {
// Check if member.uri matches properties.uri for the first 2 slashes
const matchUri = baseUri.split('/').slice(0, 3).join('/');
if (memberUri.startsWith(matchUri)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export default function executeQueryFromTableJSON(
uri = "URI is undefined";
}

console.log(uri);

return getQueryResponse(
dispatch,
prefixes + '\n' + buildQuery(uri, table),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default function SectionRenderer({ section, metadata }) {

// After you set the data, process the link
if (isMounted && section.link) {
const processed = await processUrl(section.link, token, dispatch); // Assuming you have token available
const processed = await processUrl(section.link, localStorage.getItem('registries')); // Assuming you have token available
setProcessedLink(processed);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@ function TableRenderer({ uri, prefixes, table, metadata, owner }) {
const token = useSelector(state => state.user.token);
const [content, setContent] = useState(null);
const dispatch = useDispatch();
console.log(uri);
console.log(prefixes);
console.log(table);
useEffect(() => {
executeQueryFromTableJSON(dispatch, uri, prefixes, table).then(response => {
console.log(response);
setContent(parseQueryResult(table, response, prefixes));
});
}, [uri, prefixes, table]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function AttachmentRows(properties) {
// async function processAttachments() {
// const processedAttachments = await Promise.all(attachments.map(async attachment => {
// if (!attachment.processedTopLevel) {
// const result = await processUrl(attachment.topLevel, token, dispatch);
// const result = await processUrl(attachment.topLevel, localStorage.getItem('registries'));
// return { ...attachment, processedTopLevel: result.urlRemovedForLink };
// }
// return attachment;
Expand Down
Loading
Loading