Add archive filter

This commit is contained in:
Arnaud 2024-10-21 16:28:35 +02:00
parent 6729e64be7
commit a0c8bd7d1d
No known key found for this signature in database
GPG Key ID: 69D6CE281FCAE663
4 changed files with 44 additions and 25 deletions

View File

@ -6,27 +6,19 @@ import { Check } from "lucide-react";
type Props = { type Props = {
files: CodexDataContent[]; files: CodexDataContent[];
onFilterToggle: (filter: string) => void; onFilterToggle: (filter: string) => void;
selected: string[];
}; };
const archiveMimetypes = [ export function FilterFilters({ selected, files, onFilterToggle }: Props) {
"application/zip",
"application/x-rar-compressed",
"application/x-tar",
"application/gzip",
"application/x-7z-compressed",
"application/gzip", // for .tar.gz
"application/x-bzip2",
"application/x-xz",
];
export function FilterFilters({ files, onFilterToggle }: Props) {
const filters = Array.from( const filters = Array.from(
new Set( new Set(
files.map((file) => files
archiveMimetypes.includes(file.manifest.mimetype) .filter((f) => f.manifest.mimetype !== "")
? "archive" .map((file) =>
: Files.type(file.manifest.mimetype) Files.isArchive(file.manifest.mimetype)
) ? "archive"
: Files.type(file.manifest.mimetype)
)
) )
); );
@ -35,7 +27,7 @@ export function FilterFilters({ files, onFilterToggle }: Props) {
key={type} key={type}
className={classnames( className={classnames(
["files-filter"], ["files-filter"],
["files-filter--active", filters.includes(type)] ["files-filter--active", !!filters.find((f) => selected.includes(f))]
)} )}
onClick={() => onFilterToggle(type)}> onClick={() => onFilterToggle(type)}>
<span>{type}</span> <Check size={"1rem"}></Check> <span>{type}</span> <Check size={"1rem"}></Check>

View File

@ -13,6 +13,12 @@
} }
.files-fileMeta { .files-fileMeta {
display: flex;
align-items: center;
gap: 0.5rem;
}
.files-fileMeta-cid {
word-break: break-all; word-break: break-all;
} }

View File

@ -33,7 +33,7 @@ export function Files() {
const [error, setError] = useState(""); const [error, setError] = useState("");
const [details, setDetails] = useState<CodexDataContent | null>(null); const [details, setDetails] = useState<CodexDataContent | null>(null);
const [sortFn, setSortFn] = useState<SortFn | null>(null); const [sortFn, setSortFn] = useState<SortFn | null>(null);
const [filters, setFilters] = useState<string[]>([]); const [selectedFilters, setSelectedFilters] = useState<string[]>([]);
useEffect(() => { useEffect(() => {
WebStorage.folders.list().then((items) => setFolders(items)); WebStorage.folders.list().then((items) => setFolders(items));
@ -191,9 +191,9 @@ export function Files() {
}; };
const onToggleFilter = (filter: string) => const onToggleFilter = (filter: string) =>
filters.includes(filter) selectedFilters.includes(filter)
? setFilters(filters.filter((f) => f !== filter)) ? setSelectedFilters(selectedFilters.filter((f) => f !== filter))
: setFilters([...filters, filter]); : setSelectedFilters([...selectedFilters, filter]);
tabs.unshift({ tabs.unshift({
label: "All files", label: "All files",
@ -214,7 +214,10 @@ export function Files() {
const filtered = items.filter( const filtered = items.filter(
(item) => (item) =>
filters.length === 0 || filters.includes(F.type(item.manifest.mimetype)) selectedFilters.length === 0 ||
selectedFilters.includes(F.type(item.manifest.mimetype)) ||
(selectedFilters.includes("archive") &&
F.isArchive(item.manifest.mimetype))
); );
const sorted = sortFn ? [...filtered].sort(sortFn) : filtered; const sorted = sortFn ? [...filtered].sort(sortFn) : filtered;
@ -264,11 +267,15 @@ export function Files() {
<Tabs onTabChange={onTabChange} tabIndex={index} tabs={tabs}></Tabs> <Tabs onTabChange={onTabChange} tabIndex={index} tabs={tabs}></Tabs>
<div className="files-filters"> <div className="files-filters">
<FilterFilters files={files} onFilterToggle={onToggleFilter} /> <FilterFilters
files={files}
onFilterToggle={onToggleFilter}
selected={selectedFilters}
/>
</div> </div>
<div className="files-fileBody"> <div className="files-fileBody">
<Table headers={headers} rows={rows} defaultSortIndex={3} /> <Table headers={headers} rows={rows} defaultSortIndex={2} />
</div> </div>
<FileDetails onClose={onClose} details={details} /> <FileDetails onClose={onClose} details={details} />

View File

@ -1,3 +1,14 @@
const archiveMimetypes = [
"application/zip",
"application/x-rar-compressed",
"application/x-tar",
"application/gzip",
"application/x-7z-compressed",
"application/gzip", // for .tar.gz
"application/x-bzip2",
"application/x-xz",
];
export const Files = { export const Files = {
isImage(type: string) { isImage(type: string) {
return type.startsWith("image"); return type.startsWith("image");
@ -5,6 +16,9 @@ export const Files = {
type(mimetype: string) { type(mimetype: string) {
const [type] = mimetype.split("/") const [type] = mimetype.split("/")
return type return type
},
isArchive(mimetype: string) {
return archiveMimetypes.includes(mimetype)
} }
}; };