diff --git a/.features/pending/14807-workflow-templates-label-filter-sync.md b/.features/pending/14807-workflow-templates-label-filter-sync.md new file mode 100644 index 000000000000..64bcbfabc90c --- /dev/null +++ b/.features/pending/14807-workflow-templates-label-filter-sync.md @@ -0,0 +1,9 @@ +Component: UI +Issues: 14807 +Description: Add label query parameter sync with URL in WorkflowTemplates UI to match Workflows list behavior for consistent filtering. +Author: [puretension](https://github.com/puretension) + +- WorkflowTemplates UI now properly handles label query parameters (e.g., ?label=key%3Dvalue) +- Combined URL updates and localStorage persistence in single useEffect +- Enables custom UI links for filtered template views +- Verified that URL updates when changing filters and filters persist on page refresh diff --git a/ui/src/workflow-templates/workflow-template-list.tsx b/ui/src/workflow-templates/workflow-template-list.tsx index 26dc9df01637..21cec48f5504 100644 --- a/ui/src/workflow-templates/workflow-template-list.tsx +++ b/ui/src/workflow-templates/workflow-template-list.tsx @@ -44,7 +44,13 @@ export function WorkflowTemplateList({match, location, history}: RouteComponentP const [namespace, setNamespace] = useState(nsUtils.getNamespace(match.params.namespace) || ''); const [sidePanel, setSidePanel] = useState(queryParams.get('sidePanel') === 'true'); const [namePattern, setNamePattern] = useState(''); - const [labels, setLabels] = useState([]); + const [labels, setLabels] = useState(() => { + const savedOptions = storage.getItem('options', {}); + const savedLabels = savedOptions.labels || []; + const labelQueryParam = queryParams.getAll('label'); + return labelQueryParam.length > 0 ? labelQueryParam : savedLabels; + }); + const [pagination, setPagination] = useState({ offset: queryParams.get('offset'), limit: parseLimit(queryParams.get('limit')) || savedOptions.paginationLimit || 500 @@ -62,14 +68,19 @@ export function WorkflowTemplateList({match, location, history}: RouteComponentP isFirstRender.current = false; return; } + storage.setItem('options', {labels}, {}); + const params = new URLSearchParams(); + labels?.forEach(label => params.append('label', label)); + if (sidePanel) { + params.append('sidePanel', 'true'); + } history.push( historyUrl('workflow-templates' + (nsUtils.getManagedNamespace() ? '' : '/{namespace}'), { namespace, - sidePanel + extraSearchParams: params }) ); - }, [namespace, sidePanel]); - + }, [namespace, sidePanel, labels.toString()]); // internal state const [error, setError] = useState(); const [templates, setTemplates] = useState();