feat: unify plugin workspace navigation
This commit is contained in:
54
src/pages/Plugins/plugin-workspace-query.ts
Normal file
54
src/pages/Plugins/plugin-workspace-query.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import type {
|
||||
PluginWorkspaceFilters,
|
||||
PluginWorkspaceKey,
|
||||
PluginWorkspaceScope,
|
||||
PluginWorkspaceSource,
|
||||
PluginWorkspaceState,
|
||||
} from './plugin-workspace-model';
|
||||
|
||||
const SCOPES: readonly PluginWorkspaceScope[] = ['all', 'project'];
|
||||
const SOURCES: readonly PluginWorkspaceSource[] = ['all', 'official', 'local'];
|
||||
const STATES: readonly PluginWorkspaceState[] = [
|
||||
'all', 'available', 'mine', 'enabled', 'update', 'unavailable',
|
||||
];
|
||||
|
||||
function member<T extends string>(value: string | null, values: readonly T[]): value is T {
|
||||
return value !== null && values.includes(value as T);
|
||||
}
|
||||
|
||||
function pluginKey(value: string | null): PluginWorkspaceKey | null {
|
||||
if (!value) return null;
|
||||
if (value.startsWith('official:') && value.length > 'official:'.length) return value as `official:${string}`;
|
||||
if (value.startsWith('local:') && value.length > 'local:'.length) return value as `local:${string}`;
|
||||
if (value.startsWith('retained:') && value.length > 'retained:'.length) return value as `retained:${string}`;
|
||||
return null;
|
||||
}
|
||||
|
||||
export function parsePluginWorkspaceSearch(
|
||||
search: URLSearchParams,
|
||||
hasActiveProject: boolean,
|
||||
): PluginWorkspaceFilters {
|
||||
const defaultScope: PluginWorkspaceScope = hasActiveProject ? 'project' : 'all';
|
||||
const requestedScope = search.get('scope');
|
||||
const requestedSource = search.get('source');
|
||||
const requestedState = search.get('state');
|
||||
const parsedScope = member(requestedScope, SCOPES) ? requestedScope : defaultScope;
|
||||
return {
|
||||
scope: parsedScope === 'project' && !hasActiveProject ? 'all' : parsedScope,
|
||||
source: member(requestedSource, SOURCES) ? requestedSource : 'all',
|
||||
state: member(requestedState, STATES) ? requestedState : 'all',
|
||||
search: search.get('q')?.trim() ?? '',
|
||||
selectedKey: pluginKey(search.get('plugin')),
|
||||
};
|
||||
}
|
||||
|
||||
export function serializePluginWorkspaceSearch(filters: PluginWorkspaceFilters): URLSearchParams {
|
||||
const search = new URLSearchParams();
|
||||
search.set('scope', filters.scope);
|
||||
search.set('source', filters.source);
|
||||
search.set('state', filters.state);
|
||||
const query = filters.search.trim();
|
||||
if (query) search.set('q', query);
|
||||
if (filters.selectedKey) search.set('plugin', filters.selectedKey);
|
||||
return search;
|
||||
}
|
||||
Reference in New Issue
Block a user