mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 10:51:36 -04:00
Removing consolidated hook because values were not being passed up.
This commit is contained in:
parent
2053dc46f9
commit
3f08bce9ea
11 changed files with 106 additions and 98 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import {API_URI, ARCHIVES_API, DEFAULT_LIMIT, OTP_API, VIDEOS_API} from "./components/Common";
|
||||
import {API_URI, ARCHIVES_API, DEFAULT_LIMIT, OTP_API, secondsToDateTime, VIDEOS_API} from "./components/Common";
|
||||
import {toast} from 'react-semantic-toasts';
|
||||
|
||||
function timeoutPromise(ms, promise) {
|
||||
|
|
@ -303,8 +303,8 @@ export async function deleteArchive(archive_id) {
|
|||
|
||||
export async function searchArchives(offset, limit, domain = null, searchStr = null) {
|
||||
// Build a search query to retrieve a list of videos from the API
|
||||
offset = offset || 0;
|
||||
limit = limit || DEFAULT_LIMIT;
|
||||
offset = parseInt(offset || 0);
|
||||
limit = parseInt(limit || DEFAULT_LIMIT);
|
||||
let body = {offset, limit};
|
||||
if (domain) {
|
||||
body['domain'] = domain;
|
||||
|
|
@ -372,10 +372,33 @@ export async function getDownloaders() {
|
|||
return await response.json();
|
||||
}
|
||||
|
||||
const replaceFileDatetimes = (files) => {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let file = files[i]['modified'];
|
||||
if (file['modified']) {
|
||||
files[i]['modified'] = secondsToDateTime(file['modified']);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
export async function filesSearch(offset, limit, searchStr) {
|
||||
const body = {search_str: searchStr, offset: parseInt(offset), limit: parseInt(limit)};
|
||||
const response = await apiPost(`${API_URI}/files/search`, body);
|
||||
return await response.json();
|
||||
|
||||
if (response.status === 200) {
|
||||
let data = await response.json();
|
||||
let [files, total] = [data['files'], data['totals']['files']];
|
||||
files = replaceFileDatetimes(files);
|
||||
return [files, total];
|
||||
} else {
|
||||
toast({
|
||||
type: 'error',
|
||||
title: 'Unable to search files',
|
||||
description: 'Cannot search files. See server logs.',
|
||||
time: 5000,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function refreshFiles() {
|
||||
|
|
@ -385,7 +408,9 @@ export async function refreshFiles() {
|
|||
export async function getFiles(directories) {
|
||||
let body = {directories: directories || []};
|
||||
let response = await apiPost(`${API_URI}/files`, body);
|
||||
return await response.json();
|
||||
let {files} = await response.json();
|
||||
files = replaceFileDatetimes(files);
|
||||
return files;
|
||||
}
|
||||
|
||||
export async function deleteFile(file) {
|
||||
|
|
|
|||
|
|
@ -443,9 +443,9 @@ class Downloads extends React.Component {
|
|||
export default function Admin(props) {
|
||||
|
||||
const links = [
|
||||
{text: 'Downloads', to: '/admin', exact: true},
|
||||
{text: 'Settings', to: '/admin/settings'},
|
||||
{text: 'WROL Mode', to: '/admin/wrol'},
|
||||
{text: 'Downloads', to: '/admin', exact: true, key: 'admin'},
|
||||
{text: 'Settings', to: '/admin/settings', key: 'settings'},
|
||||
{text: 'WROL Mode', to: '/admin/wrol', key: 'wrol'},
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import {
|
|||
CardGroupCentered,
|
||||
ClearButton,
|
||||
ExternalLink,
|
||||
PageContainer, Paginator,
|
||||
PageContainer,
|
||||
Paginator,
|
||||
SearchInput,
|
||||
TabLinks,
|
||||
textEllipsis,
|
||||
|
|
@ -202,9 +203,8 @@ export function ArchivesList({archives, searchStr, syncArchive, localDeleteArchi
|
|||
}
|
||||
|
||||
export function Archives() {
|
||||
const {archivesData, setPage, totalPages, searchStr, activePage, setSearchStr, domain, setDomain, search} =
|
||||
useArchives();
|
||||
const {archives} = archivesData;
|
||||
const {archives, setPage, totalPages, searchStr, activePage, setSearchStr, domain, setDomain, search} =
|
||||
useArchives(20);
|
||||
|
||||
const syncArchive = async (url) => {
|
||||
await postDownload(url, 'archive');
|
||||
|
|
@ -237,7 +237,7 @@ export function Archives() {
|
|||
setDomain={setDomain}
|
||||
/>
|
||||
<div style={{marginTop: '3em', textAlign: 'center'}}>
|
||||
<Paginator totalPages={totalPages}/>
|
||||
<Paginator activePage={activePage} totalPages={totalPages} onPageChange={setPage}/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
|
@ -319,9 +319,9 @@ function Domains() {
|
|||
|
||||
export function ArchiveRoute(props) {
|
||||
const links = [
|
||||
{text: 'Archives', to: '/archive', exact: true},
|
||||
{text: 'Domains', to: '/archive/domains'},
|
||||
{text: 'Manage', to: '/archive/manage'},
|
||||
{text: 'Archives', to: '/archive', exact: true, key: 'archive'},
|
||||
{text: 'Domains', to: '/archive/domains', key: 'domains'},
|
||||
{text: 'Manage', to: '/archive/manage', key: 'manage'},
|
||||
];
|
||||
return <PageContainer>
|
||||
<TabLinks links={links}/>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import Button from "semantic-ui-react/dist/commonjs/elements/Button";
|
|||
import Grid from "semantic-ui-react/dist/commonjs/collections/Grid";
|
||||
import Message from "semantic-ui-react/dist/commonjs/collections/Message";
|
||||
import {getConfig} from "../api";
|
||||
import {useSearchParams} from "../hooks/customHooks";
|
||||
|
||||
export const API_URI = `http://${window.location.host}/api`;
|
||||
export const VIDEOS_API = `${API_URI}/videos`;
|
||||
|
|
@ -55,26 +54,21 @@ export default class OldPaginator extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
export function Paginator(props) {
|
||||
let {activePage, setPage} = useSearchParams(props.defaultLimit || 20);
|
||||
|
||||
const handlePaginationChange = (e, {activePage}) => {
|
||||
setPage(activePage);
|
||||
export function Paginator({activePage, onPageChange, totalPages, showFirstAndLast}) {
|
||||
const handlePageChange = (e, {activePage}) => {
|
||||
onPageChange(activePage);
|
||||
}
|
||||
|
||||
return (
|
||||
<Pagination
|
||||
activePage={activePage}
|
||||
boundaryRange={1}
|
||||
onPageChange={handlePaginationChange}
|
||||
onPageChange={handlePageChange}
|
||||
size='mini'
|
||||
siblingRange={2}
|
||||
totalPages={props.totalPages}
|
||||
ellipsisItem={true}
|
||||
firstItem={null}
|
||||
lastItem={null}
|
||||
prevItem={true}
|
||||
nextItem={true}
|
||||
totalPages={totalPages}
|
||||
firstItem={showFirstAndLast ? undefined : null}
|
||||
lastItem={showFirstAndLast ? undefined : null}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -607,6 +601,7 @@ export function TabLinks({links}) {
|
|||
className={'item'}
|
||||
exact={link.exact || false}
|
||||
style={{padding: '1em'}}
|
||||
key={link.key}
|
||||
>
|
||||
{link.text}
|
||||
</NavLink>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const icons = {
|
|||
PDF: <Icon name='file pdf'/>,
|
||||
};
|
||||
|
||||
export function Files(props) {
|
||||
export function Files() {
|
||||
const {searchFiles, setPage, totalPages, activePage, searchStr, setSearchStr} = useSearchFiles(50);
|
||||
const {browseFiles, setOpenFolders, fetchFiles} = useBrowseFiles();
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ export function Files(props) {
|
|||
</>
|
||||
}
|
||||
|
||||
function ManageFiles(props) {
|
||||
function ManageFiles() {
|
||||
return (<>
|
||||
<Button secondary
|
||||
id='refresh_files'
|
||||
|
|
|
|||
|
|
@ -1090,8 +1090,8 @@ class InventoryAddList extends React.Component {
|
|||
|
||||
export function InventoryRoute(props) {
|
||||
const links = [
|
||||
{text: 'List', to: '/inventory', exact: true},
|
||||
{text: 'Summary', to: '/inventory/summary'},
|
||||
{text: 'List', to: '/inventory', exact: true, key: 'inventory'},
|
||||
{text: 'Summary', to: '/inventory/summary', key: 'summary'},
|
||||
];
|
||||
return (
|
||||
<PageContainer>
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@ import {Dropdown, Menu, Responsive} from "semantic-ui-react";
|
|||
const responsiveWidth = 500;
|
||||
|
||||
const links = [
|
||||
{text: 'Videos', to: '/videos'},
|
||||
{text: 'Inventory', to: '/inventory'},
|
||||
{text: 'Archive', to: '/archive'},
|
||||
{text: 'Files', to: '/files'},
|
||||
{text: 'Videos', to: '/videos', key: 'videos'},
|
||||
{text: 'Inventory', to: '/inventory', key: 'inventory'},
|
||||
{text: 'Archive', to: '/archive', key: 'archive'},
|
||||
{text: 'Files', to: '/files', key: 'files'},
|
||||
{
|
||||
text: 'Apps', links: [
|
||||
key: 'apps', text: 'Apps', links: [
|
||||
{to: '/apps/otp', text: 'One Time Pad', exact: true},
|
||||
]
|
||||
},
|
||||
];
|
||||
const admin = {to: '/admin', text: 'Admin', exact: true};
|
||||
const admin = {to: '/admin', text: 'Admin', exact: true, key: 'admin'};
|
||||
const rightLinks = [admin,];
|
||||
|
||||
const collapsedLinks = links.concat([admin,]);
|
||||
|
|
@ -67,22 +67,20 @@ export function NavBar() {
|
|||
{/*Show the links in a menu when on desktop*/}
|
||||
{links.map((link) => {
|
||||
return (
|
||||
<Responsive minWidth={responsiveWidth} as={MenuLink} link={link} key={link.to}/>
|
||||
<Responsive minWidth={responsiveWidth} as={MenuLink} link={link} key={link.key}/>
|
||||
)
|
||||
})}
|
||||
<Responsive minWidth={responsiveWidth} as={Menu.Menu} position="right">
|
||||
{rightLinks.map((link) => {
|
||||
return (<MenuLink link={link} key={link.to}/>)
|
||||
})}
|
||||
{rightLinks.map((link) => <MenuLink link={link} key={link.key}/>)}
|
||||
</Responsive>
|
||||
|
||||
{/*Show the menu items in a dropdown when on mobile*/}
|
||||
<Responsive as={Menu.Menu} maxWidth={responsiveWidth - 1} position='right'>
|
||||
<Dropdown item icon="bars">
|
||||
<Dropdown.Menu>
|
||||
{collapsedLinks.map((link) => {
|
||||
return (<MenuLink link={link} key={link.to}/>)
|
||||
})}
|
||||
{collapsedLinks.map((link) =>
|
||||
<MenuLink link={link} key={link.key}/>
|
||||
)}
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</Responsive>
|
||||
|
|
|
|||
|
|
@ -496,10 +496,10 @@ function ManageTab(props) {
|
|||
export function VideosRoute(props) {
|
||||
|
||||
const links = [
|
||||
{text: 'Videos', to: '/videos', exact: true},
|
||||
{text: 'Favorites', to: '/videos/favorites'},
|
||||
{text: 'Channels', to: '/videos/channel',},
|
||||
{text: 'Manage', to: '/videos/manage'},
|
||||
{text: 'Videos', to: '/videos', exact: true, key: 'videos'},
|
||||
{text: 'Favorites', to: '/videos/favorites', key: 'favorites'},
|
||||
{text: 'Channels', to: '/videos/channel', key: 'channel'},
|
||||
{text: 'Manage', to: '/videos/manage', key: 'manage'},
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import {useEffect, useState} from "react";
|
||||
import {fetchDomains, filesSearch, getFiles, getVersion, searchArchives, searchVideos} from "../api";
|
||||
import {useHistory} from "react-router-dom";
|
||||
import {secondsToDateTime} from "../components/Common";
|
||||
|
||||
export const useSearchParam = (key, defaultValue = null) => {
|
||||
// Get a window.location.search param.
|
||||
|
|
@ -22,23 +21,6 @@ export const useSearchParam = (key, defaultValue = null) => {
|
|||
return [value, setValue];
|
||||
}
|
||||
|
||||
export const useSearchParams = ({defaultLimit = 20}) => {
|
||||
let [limit, setLimit] = useSearchParam('l', defaultLimit);
|
||||
let [offset, setOffset] = useSearchParam('o');
|
||||
let [searchStr, setSearchStr] = useSearchParam('q');
|
||||
|
||||
let [activePage, setActivePage] = useState(1);
|
||||
|
||||
const setPage = (i) => {
|
||||
i = parseInt(i);
|
||||
let l = parseInt(limit);
|
||||
setOffset((l * i) - l);
|
||||
setActivePage(i);
|
||||
}
|
||||
|
||||
return {limit, setLimit, offset, setOffset, searchStr, setSearchStr, activePage, setPage};
|
||||
}
|
||||
|
||||
export const useSearch = () => {
|
||||
let [searchStr, setSearchStr] = useSearchParam('q');
|
||||
|
||||
|
|
@ -86,28 +68,36 @@ export const useDomains = () => {
|
|||
return [domains, total];
|
||||
}
|
||||
|
||||
export const useArchives = (defaultLimit = 20) => {
|
||||
const [archivesData, setArchives] = useState({archives: null, total: 0});
|
||||
const [totalPages, setTotalPages] = useState(0);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
let {limit, setLimit, offset, setOffset, searchStr, setSearchStr, setPage} = useSearchParams(defaultLimit);
|
||||
export const useArchives = ({defaultLimit = 20}) => {
|
||||
let [limit, setLimit] = useSearchParam('l', defaultLimit);
|
||||
let [offset, setOffset] = useSearchParam('o');
|
||||
let [searchStr, setSearchStr] = useSearchParam('q');
|
||||
let [domain, setDomain] = useSearchParam('domain');
|
||||
|
||||
const search = async (term) => {
|
||||
setArchives({archives: null, total: 0});
|
||||
setTotalPages(0);
|
||||
const [archives, total] = await searchArchives(offset, limit, domain, term);
|
||||
const [archives, setArchives] = useState(null);
|
||||
const [totalPages, setTotalPages] = useState(0);
|
||||
const [activePage, setActivePage] = useState((offset / limit) + 1);
|
||||
|
||||
const search = async () => {
|
||||
setArchives(null);
|
||||
const [archives, total] = await searchArchives(offset, limit, domain, searchStr);
|
||||
setTotalPages(Math.floor(total / limit) + 1);
|
||||
setArchives({archives, total});
|
||||
setArchives(archives);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
search(searchStr);
|
||||
search();
|
||||
}, [offset, limit, domain, searchStr]);
|
||||
|
||||
const setPage = (i) => {
|
||||
i = parseInt(i);
|
||||
let l = parseInt(limit);
|
||||
setOffset((l * i) - l);
|
||||
setActivePage(i);
|
||||
}
|
||||
|
||||
return {
|
||||
archivesData,
|
||||
archives,
|
||||
totalPages,
|
||||
setTotalPages,
|
||||
offset,
|
||||
|
|
@ -140,30 +130,22 @@ export const useVersion = () => {
|
|||
return version;
|
||||
}
|
||||
|
||||
const replaceFileDatetimes = (files) => {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
if (files[i]['modified']) {
|
||||
files[i]['modified'] = secondsToDateTime(files[i]['modified']);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
export const useSearchFiles = ({defaultLimit = 50}) => {
|
||||
let {limit, setLimit, offset, setOffset, searchStr, setSearchStr, activePage, setPage} =
|
||||
useSearchParams(defaultLimit);
|
||||
let [limit, setLimit] = useSearchParam('l', defaultLimit);
|
||||
let [offset, setOffset] = useSearchParam('o');
|
||||
let [searchStr, setSearchStr] = useSearchParam('q');
|
||||
|
||||
const [searchFiles, setSearchFiles] = useState([]);
|
||||
const [totalPages, setTotalPages] = useState(0);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
const localSearchFiles = async () => {
|
||||
setSearchFiles([]);
|
||||
setTotalPages(0);
|
||||
if (searchStr) {
|
||||
let {files, totals} = await filesSearch(offset, limit, searchStr);
|
||||
files = replaceFileDatetimes(files);
|
||||
let [files, total] = await filesSearch(offset, limit, searchStr);
|
||||
setSearchFiles(files);
|
||||
setTotalPages(Math.floor(totals['files'] / limit) + 1);
|
||||
setTotalPages(Math.floor(total / limit) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,6 +153,13 @@ export const useSearchFiles = ({defaultLimit = 50}) => {
|
|||
localSearchFiles();
|
||||
}, [searchStr, limit, offset, activePage]);
|
||||
|
||||
const setPage = (i) => {
|
||||
i = parseInt(i);
|
||||
let l = parseInt(limit);
|
||||
setOffset((l * i) - l);
|
||||
setActivePage(i);
|
||||
}
|
||||
|
||||
return {searchFiles, totalPages, limit, setLimit, setOffset, searchStr, setSearchStr, activePage, setPage};
|
||||
}
|
||||
|
||||
|
|
@ -179,8 +168,7 @@ export const useBrowseFiles = () => {
|
|||
const [openFolders, setOpenFolders] = useState([]);
|
||||
|
||||
const fetchFiles = async () => {
|
||||
let {files} = await getFiles(openFolders);
|
||||
files = replaceFileDatetimes(files);
|
||||
const files = await getFiles(openFolders);
|
||||
setBrowseFiles(files);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ def _refresh_files():
|
|||
with get_db_curs(commit=True) as curs:
|
||||
curs.execute('DELETE FROM file WHERE idempotency IS NULL')
|
||||
|
||||
logger.info('Done refreshing Files')
|
||||
|
||||
|
||||
@wraps(_refresh_files)
|
||||
def refresh_files():
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class File(ModelHelper, Base):
|
|||
d = dict(
|
||||
id=self.id,
|
||||
mimetype=self.mimetype,
|
||||
modification_datetime=self.modification_datetime,
|
||||
modified=self.modification_datetime, # React browser expects this.
|
||||
path=path,
|
||||
size=self.size,
|
||||
key=path,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue