Added search/filter in patterns tab

Added pattern as dep to filter memo

Format
This commit is contained in:
John Björk 2025-12-20 17:26:23 +01:00
parent 0a2f2eaa3d
commit 6908ea38e4
No known key found for this signature in database
GPG key ID: 303B6ADF2F569B0A
2 changed files with 106 additions and 86 deletions

View file

@ -1,4 +1,4 @@
const ALLOW_MANY = ['by', 'url', 'genre', 'license']; const ALLOW_MANY = ['by', 'url', 'genre', 'license', 'tag'];
export function getMetadata(raw_code) { export function getMetadata(raw_code) {
if (raw_code == null) { if (raw_code == null) {

View file

@ -18,6 +18,7 @@ import { Pagination } from '../pagination/Pagination.jsx';
import { useState } from 'react'; import { useState } from 'react';
import { useDebounce } from '../usedebounce.jsx'; import { useDebounce } from '../usedebounce.jsx';
import cx from '@src/cx.mjs'; import cx from '@src/cx.mjs';
import { Textbox } from '../textbox/Textbox.jsx';
export function PatternLabel({ pattern } /* : { pattern: Tables<'code'> } */) { export function PatternLabel({ pattern } /* : { pattern: Tables<'code'> } */) {
const meta = useMemo(() => getMetadata(pattern.code), [pattern]); const meta = useMemo(() => getMetadata(pattern.code), [pattern]);
@ -33,7 +34,7 @@ export function PatternLabel({ pattern } /* : { pattern: Tables<'code'> } */) {
} }
const author = Array.isArray(meta.by) ? meta.by.join(',') : 'Anonymous'; const author = Array.isArray(meta.by) ? meta.by.join(',') : 'Anonymous';
return <>{`${pattern.id}: ${title} by ${author.slice(0, 100)}`.slice(0, 60)}</>; return <>{`${title} by ${author.slice(0, 100)}`.slice(0, 60)}</>;
} }
function PatternButton({ showOutline, onClick, pattern, showHiglight }) { function PatternButton({ showOutline, onClick, pattern, showHiglight }) {
@ -79,13 +80,56 @@ const updateCodeWindow = (context, patternData, reset = false) => {
context.handleUpdate(patternData, reset); context.handleUpdate(patternData, reset);
}; };
function UserPatterns({ context }) { export function PatternsTab({ context }) {
const [search, setSearch] = useState('');
const activePattern = useActivePattern(); const activePattern = useActivePattern();
const viewingPatternStore = useViewingPatternData(); const viewingPatternStore = useViewingPatternData();
const viewingPatternData = parseJSON(viewingPatternStore); const viewingPatternData = parseJSON(viewingPatternStore);
const { userPatterns, patternFilter, patternAutoStart } = useSettings(); const { userPatterns, patternAutoStart } = useSettings();
const viewingPatternID = viewingPatternData?.id; const viewingPatternID = viewingPatternData?.id;
const visiblePatterns = useMemo(() => {
return Object.fromEntries(
Object.entries(userPatterns).filter(([_key, pattern]) => {
if (!search) {
return true;
}
const meta = getMetadata(pattern.code);
// Search for specific meta keys
const searchTrimmed = search.trim();
if (searchTrimmed.includes(':')) {
const [metaKey, metaSearch] = searchTrimmed.split(':');
if (metaKey !== undefined && metaSearch !== undefined && metaKey in meta) {
const metaValues = meta[metaKey];
if (Array.isArray(metaValues)) {
return metaValues.some((metaValue) => metaValue.toLowerCase().includes(metaSearch.trim().toLowerCase()));
} else if (typeof metaValues === 'string') {
return metaValues.toLowerCase().includes(metaSearch.trim().toLowerCase());
} else {
return false;
}
}
}
const title = meta.title ? meta.title : 'unnamed';
const authors = meta.by ? meta.by : ['anonymous'];
const tags = meta.tag ? meta.tag : [];
const lowerCaseSearch = search.toLowerCase();
return ( return (
title.toLowerCase().includes(lowerCaseSearch) ||
authors.some((author) => author.toLowerCase().includes(lowerCaseSearch)) ||
tags.some((tag) => tag.toLowerCase().includes(lowerCaseSearch))
);
}),
);
}, [search, viewingPatternStore]);
return (
<div className="px-4 w-full text-foreground space-y-2 flex flex-col overflow-hidden max-h-full h-full">
<div class="w-full flex">
<Textbox className="w-full" placeholder="Search" value={search} onChange={setSearch} />
</div>
<div className="flex flex-col gap-2 flex-grow overflow-hidden h-full pb-2 "> <div className="flex flex-col gap-2 flex-grow overflow-hidden h-full pb-2 ">
<div className="pr-4 space-x-4 flex max-w-full overflow-x-auto"> <div className="pr-4 space-x-4 flex max-w-full overflow-x-auto">
<ActionButton <ActionButton
@ -140,7 +184,7 @@ function UserPatterns({ context }) {
context.handleEvaluate(); context.handleEvaluate();
} }
}} }}
patterns={userPatterns} patterns={visiblePatterns}
started={context.started} started={context.started}
activePattern={activePattern} activePattern={activePattern}
viewingPatternID={viewingPatternID} viewingPatternID={viewingPatternID}
@ -148,6 +192,7 @@ function UserPatterns({ context }) {
{/* )} */} {/* )} */}
</div> </div>
</div> </div>
</div>
); );
} }
@ -232,28 +277,3 @@ function PublicPatterns({ context }) {
} }
return <LatestPatterns context={context} />; return <LatestPatterns context={context} />;
} }
export function PatternsTab({ context }) {
const { patternFilter } = useSettings();
return (
<div className="px-4 w-full text-foreground space-y-2 flex flex-col overflow-hidden max-h-full h-full">
<UserPatterns context={context} />
</div>
);
/* return (
<div className="px-4 w-full text-foreground space-y-2 flex flex-col overflow-hidden max-h-full h-full">
<ButtonGroup
value={patternFilter}
onChange={(value) => settingsMap.setKey('patternFilter', value)}
items={patternFilterName}
></ButtonGroup>
{patternFilter === patternFilterName.user ? (
<UserPatterns context={context} />
) : (
<PublicPatterns context={context} />
)}
</div>
); */
}