Compare commits

..

5 Commits

Author SHA1 Message Date
IRBorisov
b757c1a1da Update robots.txt
Some checks failed
Frontend CI / build (18.x) (push) Has been cancelled
2024-06-27 11:57:00 +03:00
IRBorisov
aac805d478 Refactor location naming 2024-06-27 11:34:52 +03:00
IRBorisov
d230295004 Downgrade framer-motion to fix opacity changing bug 2024-06-26 22:30:52 +03:00
IRBorisov
5af65ecb06 Wait for user loading before loading Library or Schema 2024-06-26 21:52:18 +03:00
IRBorisov
05811fe0f8 npm update major 2024-06-26 21:31:43 +03:00
12 changed files with 667 additions and 468 deletions

File diff suppressed because it is too large Load Diff

View File

@ -18,19 +18,19 @@
"@uiw/react-codemirror": "^4.22.2",
"axios": "^1.7.2",
"clsx": "^2.1.1",
"framer-motion": "^10.18.0",
"framer-motion": "^11.0.10",
"js-file-download": "^0.4.12",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
"react-icons": "^4.12.0",
"react-icons": "^5.2.1",
"react-intl": "^6.6.8",
"react-loader-spinner": "^5.4.5",
"react-loader-spinner": "^6.1.6",
"react-pdf": "^9.0.0",
"react-router-dom": "^6.24.0",
"react-select": "^5.8.0",
"react-tabs": "^6.0.2",
"react-toastify": "^9.1.3",
"react-toastify": "^10.0.5",
"react-tooltip": "^5.27.0",
"reagraph": "^4.19.2",
"use-debounce": "^10.0.1"
@ -41,21 +41,21 @@
"@types/node": "^20.14.9",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-tsdoc": "^0.2.17",
"eslint-plugin-simple-import-sort": "^12.1.0",
"eslint-plugin-tsdoc": "^0.3.0",
"jest": "^29.7.0",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.4",
"ts-jest": "^29.1.5",
"typescript": "^5.5.2",
"vite": "^4.5.3"
"vite": "^5.3.1"
},
"jest": {
"preset": "ts-jest",

View File

@ -1,2 +1,5 @@
User-agent: *
Disallow: /library
Disallow: /library
Disallow: /restore-password
Disallow: /signup
Disallow: /profile

View File

@ -3,8 +3,8 @@ import { useIntl } from 'react-intl';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar';
import { useLibrary } from '@/context/LibraryContext';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext';
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
import { ILibraryFilter } from '@/models/miscellaneous';

View File

@ -65,7 +65,7 @@ interface LibraryStateProps {
}
export const LibraryState = ({ children }: LibraryStateProps) => {
const { user } = useAuth();
const { user, loading: userLoading } = useAuth();
const { adminMode } = useConceptOptions();
const [items, setItems] = useState<ILibraryItem[]>([]);
@ -92,8 +92,8 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
if (!filter.folderMode && filter.head) {
result = result.filter(item => item.location.startsWith(filter.head!));
}
if (filter.folderMode && filter.folder) {
result = result.filter(item => item.location == filter.folder);
if (filter.folderMode && filter.location) {
result = result.filter(item => item.location == filter.location);
}
if (filter.type) {
result = result.filter(item => item.item_type === filter.type);
@ -175,16 +175,18 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
const reloadTemplates = useCallback(() => {
setTemplates([]);
getTemplates({
setLoading: setLoading,
onError: setLoadingError,
setLoading: setProcessing,
onError: setProcessingError,
showError: true,
onSuccess: newData => setTemplates(newData)
});
}, []);
useEffect(() => {
reloadItems();
}, [reloadItems]);
if (!userLoading) {
reloadItems();
}
}, [reloadItems, userLoading]);
useEffect(() => {
reloadTemplates();

View File

@ -4,10 +4,12 @@ import { useCallback, useEffect, useState } from 'react';
import { getOssDetails } from '@/app/backendAPI';
import { type ErrorData } from '@/components/info/InfoError';
import { useAuth } from '@/context/AuthContext';
import { IOperationSchema, IOperationSchemaData } from '@/models/oss';
import { OssLoader } from '@/models/OssLoader';
function useOssDetails({ target }: { target?: string }) {
const { loading: userLoading } = useAuth();
const [schema, setInner] = useState<IOperationSchema | undefined>(undefined);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<ErrorData>(undefined);
@ -44,8 +46,10 @@ function useOssDetails({ target }: { target?: string }) {
);
useEffect(() => {
reload();
}, [reload]);
if (!userLoading) {
reload();
}
}, [reload, userLoading]);
return { schema, setSchema, reload, error, setError, loading };
}

View File

@ -4,10 +4,12 @@ import { useCallback, useEffect, useState } from 'react';
import { getRSFormDetails } from '@/app/backendAPI';
import { type ErrorData } from '@/components/info/InfoError';
import { useAuth } from '@/context/AuthContext';
import { IRSForm, IRSFormData } from '@/models/rsform';
import { RSFormLoader } from '@/models/RSFormLoader';
function useRSFormDetails({ target, version }: { target?: string; version?: string }) {
const { loading: userLoading } = useAuth();
const [schema, setInnerSchema] = useState<IRSForm | undefined>(undefined);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<ErrorData>(undefined);
@ -44,8 +46,10 @@ function useRSFormDetails({ target, version }: { target?: string; version?: stri
);
useEffect(() => {
reload();
}, [reload]);
if (!userLoading) {
reload();
}
}, [reload, userLoading]);
return { schema, setSchema, reload, error, setError, loading };
}

View File

@ -144,11 +144,10 @@ export interface ILibraryFilter {
type?: LibraryItemType;
query?: string;
folderMode?: boolean;
path?: string;
head?: LocationHead;
folderMode?: boolean;
folder?: string;
location?: string;
isVisible?: boolean;
isOwned?: boolean;

View File

@ -14,7 +14,7 @@ import { toggleTristateFlag } from '@/utils/utils';
import TableLibraryItems from './TableLibraryItems';
import ToolbarSearch from './ToolbarSearch';
import ViewSideFolders from './ViewSideFolders';
import ViewSideLocation from './ViewSideLocation';
function LibraryPage() {
const library = useLibrary();
@ -26,7 +26,7 @@ function LibraryPage() {
const [head, setHead] = useLocalStorage<LocationHead | undefined>(storage.librarySearchHead, undefined);
const [folderMode, setFolderMode] = useLocalStorage<boolean>(storage.librarySearchFolderMode, true);
const [folder, setFolder] = useLocalStorage<string>(storage.librarySearchFolder, '');
const [location, setLocation] = useLocalStorage<string>(storage.librarySearchLocation, '');
const [isVisible, setIsVisible] = useLocalStorage<boolean | undefined>(storage.librarySearchVisible, true);
const [isSubscribed, setIsSubscribed] = useLocalStorage<boolean | undefined>(
storage.librarySearchSubscribed,
@ -45,9 +45,9 @@ function LibraryPage() {
isSubscribed: user ? isSubscribed : undefined,
isVisible: user ? isVisible : true,
folderMode: folderMode,
folder: folder
location: location
}),
[head, path, query, isEditor, isOwned, isSubscribed, isVisible, user, folderMode, folder]
[head, path, query, isEditor, isOwned, isSubscribed, isVisible, user, folderMode, location]
);
const hasCustomFilter = useMemo(
@ -59,13 +59,13 @@ function LibraryPage() {
filter.isOwned !== undefined ||
filter.isSubscribed !== undefined ||
filter.isVisible !== true ||
!!filter.folder,
!!filter.location,
[filter]
);
useLayoutEffect(() => {
setItems(library.applyFilter(filter));
}, [library, filter, filter.query]);
}, [library, library.items.length, filter]);
const toggleVisible = useCallback(() => setIsVisible(prev => toggleTristateFlag(prev)), [setIsVisible]);
const toggleOwned = useCallback(() => setIsOwned(prev => toggleTristateFlag(prev)), [setIsOwned]);
@ -81,13 +81,13 @@ function LibraryPage() {
setIsSubscribed(undefined);
setIsOwned(undefined);
setIsEditor(undefined);
setFolder('');
}, [setHead, setIsVisible, setIsSubscribed, setIsOwned, setIsEditor, setFolder]);
setLocation('');
}, [setHead, setIsVisible, setIsSubscribed, setIsOwned, setIsEditor, setLocation]);
const view = useMemo(
const viewLibrary = useMemo(
() => (
<TableLibraryItems
resetQuery={resetFilter} // prettier: split lines
resetQuery={resetFilter}
items={items}
folderMode={folderMode}
toggleFolderMode={toggleFolderMode}
@ -96,6 +96,18 @@ function LibraryPage() {
[resetFilter, items, folderMode, toggleFolderMode]
);
const viewLocations = useMemo(
() => (
<ViewSideLocation
active={location}
setActive={setLocation}
folderTree={library.folders}
toggleFolderMode={toggleFolderMode}
/>
),
[location, library.folders, setLocation, toggleFolderMode]
);
return (
<DataLoader
id='library-page' // prettier: split lines
@ -127,17 +139,8 @@ function LibraryPage() {
/>
<div className='flex'>
<AnimatePresence initial={false}>
{folderMode ? (
<ViewSideFolders
currentFolder={folder} // prettier: split-lines
setFolder={setFolder}
folders={library.folders}
toggleFolderMode={toggleFolderMode}
/>
) : null}
</AnimatePresence>
{view}
<AnimatePresence initial={false}>{folderMode ? viewLocations : null}</AnimatePresence>
{viewLibrary}
</div>
</DataLoader>
);

View File

@ -161,7 +161,7 @@ function TableLibraryItems({ items, resetQuery, folderMode, toggleFolderMode }:
columns={columns}
data={items}
headPosition='0'
className={clsx('text-xs sm:text-sm cc-scroll-y', { 'border-l border-b': folderMode })}
className={clsx('text-xs sm:text-sm cc-scroll-y h-fit', { 'border-l border-b': folderMode })}
style={{ maxHeight: tableHeight }}
noDataComponent={
<FlexColumn className='dense p-3 items-center min-h-[6rem]'>

View File

@ -14,14 +14,14 @@ import { animateSideView } from '@/styling/animations';
import { PARAMETER, prefixes } from '@/utils/constants';
import { information } from '@/utils/labels';
interface ViewSideFoldersProps {
folders: FolderTree;
currentFolder: string;
setFolder: React.Dispatch<React.SetStateAction<string>>;
interface ViewSideLocationProps {
folderTree: FolderTree;
active: string;
setActive: React.Dispatch<React.SetStateAction<string>>;
toggleFolderMode: () => void;
}
function ViewSideFolders({ folders, currentFolder, setFolder, toggleFolderMode }: ViewSideFoldersProps) {
function ViewSideLocation({ folderTree, active, setActive: setActive, toggleFolderMode }: ViewSideLocationProps) {
const handleClickFolder = useCallback(
(event: CProps.EventMouse, target: FolderNode) => {
event.preventDefault();
@ -32,10 +32,10 @@ function ViewSideFolders({ folders, currentFolder, setFolder, toggleFolderMode }
.then(() => toast.success(information.pathReady))
.catch(console.error);
} else {
setFolder(target.getPath());
setActive(target.getPath());
}
},
[setFolder]
[setActive]
);
return (
@ -59,8 +59,8 @@ function ViewSideFolders({ folders, currentFolder, setFolder, toggleFolderMode }
/>
</div>
<SelectLocation
value={currentFolder}
folderTree={folders}
value={active}
folderTree={folderTree}
prefix={prefixes.folders_list}
onClick={handleClickFolder}
/>
@ -68,4 +68,4 @@ function ViewSideFolders({ folders, currentFolder, setFolder, toggleFolderMode }
);
}
export default ViewSideFolders;
export default ViewSideLocation;

View File

@ -95,7 +95,7 @@ export const storage = {
librarySearchHead: 'library.search.head',
librarySearchFolderMode: 'library.search.folder_mode',
librarySearchFolder: 'library.search.folder',
librarySearchLocation: 'library.search.location',
librarySearchVisible: 'library.search.visible',
librarySearchOwned: 'library.search.owned',
librarySearchSubscribed: 'library.search.subscribed',