mirror of
https://github.com/Ravinou/borgwarehouse
synced 2024-06-07 16:32:28 +02:00
perf: displayDetails pref is now in LocalStorage
This commit is contained in:
parent
b96bfbff13
commit
045f1d1576
|
@ -1,15 +1,61 @@
|
||||||
//Lib
|
//Lib
|
||||||
import React from 'react';
|
import { useState } from 'react';
|
||||||
import classes from './Repo.module.css';
|
import classes from './Repo.module.css';
|
||||||
import { IconSettings, IconInfoCircle } from '@tabler/icons-react';
|
import {
|
||||||
|
IconSettings,
|
||||||
|
IconInfoCircle,
|
||||||
|
IconChevronDown,
|
||||||
|
IconChevronUp,
|
||||||
|
} from '@tabler/icons-react';
|
||||||
import timestampConverter from '../../helpers/functions/timestampConverter';
|
import timestampConverter from '../../helpers/functions/timestampConverter';
|
||||||
import StorageBar from '../UI/StorageBar/StorageBar';
|
import StorageBar from '../UI/StorageBar/StorageBar';
|
||||||
import QuickCommands from './QuickCommands/QuickCommands';
|
import QuickCommands from './QuickCommands/QuickCommands';
|
||||||
|
|
||||||
export default function Repo(props) {
|
export default function Repo(props) {
|
||||||
|
//Load displayDetails from LocalStorage
|
||||||
|
const displayDetailsFromLS = () => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
localStorage.getItem('displayDetailsRepo' + props.id) === null
|
||||||
|
) {
|
||||||
|
localStorage.setItem(
|
||||||
|
'displayDetailsRepo' + props.id,
|
||||||
|
JSON.stringify(true)
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return JSON.parse(
|
||||||
|
localStorage.getItem('displayDetailsRepo' + props.id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(
|
||||||
|
'LocalStorage error, key',
|
||||||
|
'displayDetailsRepo' + props.id,
|
||||||
|
'will be removed. Try again.',
|
||||||
|
'Error message on this key : ',
|
||||||
|
error
|
||||||
|
);
|
||||||
|
localStorage.removeItem('displayDetailsRepo' + props.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//States
|
||||||
|
const [displayDetails, setDisplayDetails] = useState(displayDetailsFromLS);
|
||||||
|
|
||||||
|
//BUTTON : Display or not repo details for ONE repo
|
||||||
|
const displayDetailsForOneHandler = (boolean) => {
|
||||||
|
//Update localStorage
|
||||||
|
localStorage.setItem(
|
||||||
|
'displayDetailsRepo' + props.id,
|
||||||
|
JSON.stringify(boolean)
|
||||||
|
);
|
||||||
|
setDisplayDetails(boolean);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{props.displayDetails ? (
|
{displayDetails ? (
|
||||||
<>
|
<>
|
||||||
<div className={classes.RepoOpen}>
|
<div className={classes.RepoOpen}>
|
||||||
<div className={classes.openFlex}>
|
<div className={classes.openFlex}>
|
||||||
|
@ -127,6 +173,27 @@ export default function Repo(props) {
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{displayDetails ? (
|
||||||
|
<div className={classes.chevron}>
|
||||||
|
<IconChevronUp
|
||||||
|
color='#494b7a'
|
||||||
|
size={28}
|
||||||
|
onClick={() => {
|
||||||
|
displayDetailsForOneHandler(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className={classes.chevron}>
|
||||||
|
<IconChevronDown
|
||||||
|
color='#494b7a'
|
||||||
|
size={28}
|
||||||
|
onClick={() => {
|
||||||
|
displayDetailsForOneHandler(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
margin: 20px 0px 0px 0px;
|
margin: 20px 0px 0px 0px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
transition: max-height 0.2s linear;
|
transition: max-height 0.1s linear;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
/* Need to display comment on hover (which is position : absolute) */
|
/* Need to display comment on hover (which is position : absolute) */
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -193,6 +193,17 @@
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chevron {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chevron :focus,
|
||||||
|
.chevron :hover {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: invert(27%) sepia(82%) saturate(2209%) hue-rotate(240deg)
|
||||||
|
brightness(99%) contrast(105%);
|
||||||
|
}
|
||||||
|
|
||||||
/* MOBILE */
|
/* MOBILE */
|
||||||
@media all and (max-width: 1000px) {
|
@media all and (max-width: 1000px) {
|
||||||
.tabInfo {
|
.tabInfo {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//Lib
|
//Lib
|
||||||
import classes from './RepoList.module.css';
|
import classes from './RepoList.module.css';
|
||||||
import { useState, useEffect, useRef } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { IconPlus, IconChevronDown, IconChevronUp } from '@tabler/icons-react';
|
import { IconPlus } from '@tabler/icons-react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import useSWR, { useSWRConfig } from 'swr';
|
import useSWR, { useSWRConfig } from 'swr';
|
||||||
|
@ -48,7 +48,6 @@ export default function RepoList() {
|
||||||
////States
|
////States
|
||||||
const [displayRepoAdd, setDisplayRepoAdd] = useState(false);
|
const [displayRepoAdd, setDisplayRepoAdd] = useState(false);
|
||||||
const [displayRepoEdit, setDisplayRepoEdit] = useState(false);
|
const [displayRepoEdit, setDisplayRepoEdit] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
|
|
||||||
////Functions
|
////Functions
|
||||||
|
|
||||||
|
@ -67,32 +66,6 @@ export default function RepoList() {
|
||||||
return <ToastContainer />;
|
return <ToastContainer />;
|
||||||
}
|
}
|
||||||
|
|
||||||
//BUTTON : Display or not repo details for ONE repo
|
|
||||||
const displayDetailsForOneHandler = async (id, boolean) => {
|
|
||||||
setIsLoading(true);
|
|
||||||
await fetch('/api/repo/id/' + id + '/displayDetails', {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
'Content-type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ displayDetails: boolean }),
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.ok) {
|
|
||||||
mutate('/api/repo');
|
|
||||||
setIsLoading(false);
|
|
||||||
} else {
|
|
||||||
setIsLoading(false);
|
|
||||||
toast.error('API error', toastOptions);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
setIsLoading(false);
|
|
||||||
toast.error('API error', toastOptions);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//BUTTON : Display RepoManage component box for ADD
|
//BUTTON : Display RepoManage component box for ADD
|
||||||
const manageRepoAddHandler = () => {
|
const manageRepoAddHandler = () => {
|
||||||
router.replace('/manage-repo/add');
|
router.replace('/manage-repo/add');
|
||||||
|
@ -131,45 +104,11 @@ export default function RepoList() {
|
||||||
storageSize={repo.storageSize}
|
storageSize={repo.storageSize}
|
||||||
storageUsed={repo.storageUsed}
|
storageUsed={repo.storageUsed}
|
||||||
sshPublicKey={repo.sshPublicKey}
|
sshPublicKey={repo.sshPublicKey}
|
||||||
displayDetails={repo.displayDetails}
|
|
||||||
unixUser={repo.unixUser}
|
unixUser={repo.unixUser}
|
||||||
comment={repo.comment}
|
comment={repo.comment}
|
||||||
lanCommand={repo.lanCommand}
|
lanCommand={repo.lanCommand}
|
||||||
repoManageEditHandler={() => repoManageEditHandler(repo.id)}
|
repoManageEditHandler={() => repoManageEditHandler(repo.id)}
|
||||||
></Repo>
|
></Repo>
|
||||||
{repo.displayDetails ? (
|
|
||||||
<div className={classes.chevron}>
|
|
||||||
{isLoading ? (
|
|
||||||
<IconChevronUp color='#494b7a' size={28} />
|
|
||||||
) : (
|
|
||||||
<IconChevronUp
|
|
||||||
color='#494b7a'
|
|
||||||
size={28}
|
|
||||||
onClick={() => {
|
|
||||||
displayDetailsForOneHandler(repo.id, false);
|
|
||||||
// tell all SWRs with this key to revalidate
|
|
||||||
mutate('/api/repo');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className={classes.chevron}>
|
|
||||||
{isLoading ? (
|
|
||||||
<IconChevronDown color='#494b7a' size={28} />
|
|
||||||
) : (
|
|
||||||
<IconChevronDown
|
|
||||||
color='#494b7a'
|
|
||||||
size={28}
|
|
||||||
onClick={() => {
|
|
||||||
displayDetailsForOneHandler(repo.id, true);
|
|
||||||
// tell all SWRs with this key to revalidate
|
|
||||||
mutate('/api/repo');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -112,17 +112,6 @@
|
||||||
transform: scale(0.96);
|
transform: scale(0.96);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chevron {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chevron :focus,
|
|
||||||
.chevron :hover {
|
|
||||||
cursor: pointer;
|
|
||||||
filter: invert(27%) sepia(82%) saturate(2209%) hue-rotate(240deg)
|
|
||||||
brightness(99%) contrast(105%);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all and (max-width: 1000px) {
|
@media all and (max-width: 1000px) {
|
||||||
.newRepoButton {
|
.newRepoButton {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
import { promises as fs } from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import { authOptions } from '../../../auth/[...nextauth]';
|
|
||||||
import { getServerSession } from 'next-auth/next';
|
|
||||||
|
|
||||||
export default async function handler(req, res) {
|
|
||||||
if (req.method == 'PUT') {
|
|
||||||
//Verify that the user is logged in.
|
|
||||||
const session = await getServerSession(req, res, authOptions);
|
|
||||||
if (!session) {
|
|
||||||
res.status(401).json({ message: 'You must be logged in.' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//The data we expect to receive
|
|
||||||
const { displayDetails } = req.body;
|
|
||||||
//We check that we receive displayDetails and it must be a bool.
|
|
||||||
if (typeof displayDetails != 'boolean') {
|
|
||||||
//If a variable is empty.
|
|
||||||
res.status(422).json({
|
|
||||||
message: 'Unexpected data',
|
|
||||||
});
|
|
||||||
//A return to make sure we don't go any further if data are incorrect.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
//console.log('API call (PUT)');
|
|
||||||
//Find the absolute path of the json directory
|
|
||||||
const jsonDirectory = path.join(process.cwd(), '/config');
|
|
||||||
let repoList = await fs.readFile(
|
|
||||||
jsonDirectory + '/repo.json',
|
|
||||||
'utf8'
|
|
||||||
);
|
|
||||||
//Parse the repoList
|
|
||||||
repoList = JSON.parse(repoList);
|
|
||||||
|
|
||||||
//Find the ID in the data and change the values transmitted by the form
|
|
||||||
let newRepoList = repoList.map((repo) =>
|
|
||||||
repo.id == req.query.slug
|
|
||||||
? {
|
|
||||||
...repo,
|
|
||||||
displayDetails: displayDetails,
|
|
||||||
}
|
|
||||||
: repo
|
|
||||||
);
|
|
||||||
//Stringify the newRepoList to write it into the json file.
|
|
||||||
newRepoList = JSON.stringify(newRepoList);
|
|
||||||
//Write the new json
|
|
||||||
await fs.writeFile(
|
|
||||||
jsonDirectory + '/repo.json',
|
|
||||||
newRepoList,
|
|
||||||
(err) => {
|
|
||||||
if (err) console.log(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
res.status(200).json({ message: 'Envoi API réussi' });
|
|
||||||
} catch (error) {
|
|
||||||
//Log for backend
|
|
||||||
console.log(error);
|
|
||||||
//Log for frontend
|
|
||||||
if (error.code == 'ENOENT') {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
message: 'No such file or directory',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
message: 'API error, contact the administrator',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.status(405).json({
|
|
||||||
status: 405,
|
|
||||||
message: 'Method Not Allowed ',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue