11/**
22 * Agents page functionality
33 */
4- import { createChoices , getChoicesValues , type Choices } from '../choices' ;
4+ import {
5+ createChoices ,
6+ getChoicesValues ,
7+ setChoicesValues ,
8+ type Choices ,
9+ } from '../choices' ;
510import { FuzzySearch , type SearchItem } from '../search' ;
6- import { fetchData , debounce , setupDropdownCloseHandlers , setupActionHandlers } from '../utils' ;
11+ import {
12+ fetchData ,
13+ debounce ,
14+ getQueryParam ,
15+ getQueryParamFlag ,
16+ getQueryParamValues ,
17+ setupDropdownCloseHandlers ,
18+ setupActionHandlers ,
19+ updateQueryParams ,
20+ } from '../utils' ;
721import { setupModal , openFileModal } from '../modal' ;
822import { renderAgentsHtml , sortAgents , type AgentSortOption , type RenderableAgent } from './agents-render' ;
923
@@ -111,6 +125,16 @@ function setupResourceListHandlers(list: HTMLElement | null): void {
111125 resourceListHandlersReady = true ;
112126}
113127
128+ function syncUrlState ( searchInput : HTMLInputElement | null ) : void {
129+ updateQueryParams ( {
130+ q : searchInput ?. value ?? '' ,
131+ model : currentFilters . models ,
132+ tool : currentFilters . tools ,
133+ handoffs : currentFilters . hasHandoffs ,
134+ sort : currentSort === 'title' ? '' : currentSort ,
135+ } ) ;
136+ }
137+
114138export async function initAgentsPage ( ) : Promise < void > {
115139 const list = document . getElementById ( 'resource-list' ) ;
116140 const searchInput = document . getElementById ( 'search-input' ) as HTMLInputElement ;
@@ -132,35 +156,67 @@ export async function initAgentsPage(): Promise<void> {
132156 // Initialize Choices.js for model filter
133157 modelSelect = createChoices ( '#filter-model' , { placeholderValue : 'All Models' } ) ;
134158 modelSelect . setChoices ( data . filters . models . map ( m => ( { value : m , label : m } ) ) , 'value' , 'label' , true ) ;
159+
160+ const initialQuery = getQueryParam ( 'q' ) ;
161+ const initialModels = getQueryParamValues ( 'model' ) . filter ( model => data . filters . models . includes ( model ) ) ;
162+ const initialTools = getQueryParamValues ( 'tool' ) . filter ( tool => data . filters . tools . includes ( tool ) ) ;
163+ const initialSort = getQueryParam ( 'sort' ) ;
164+
165+ if ( searchInput ) searchInput . value = initialQuery ;
166+ if ( initialModels . length > 0 ) {
167+ currentFilters . models = initialModels ;
168+ setChoicesValues ( modelSelect , initialModels ) ;
169+ }
170+
135171 document . getElementById ( 'filter-model' ) ?. addEventListener ( 'change' , ( ) => {
136172 currentFilters . models = getChoicesValues ( modelSelect ) ;
137173 applyFiltersAndRender ( ) ;
174+ syncUrlState ( searchInput ) ;
138175 } ) ;
139176
140177 // Initialize Choices.js for tool filter
141178 toolSelect = createChoices ( '#filter-tool' , { placeholderValue : 'All Tools' } ) ;
142179 toolSelect . setChoices ( data . filters . tools . map ( t => ( { value : t , label : t } ) ) , 'value' , 'label' , true ) ;
180+ if ( initialTools . length > 0 ) {
181+ currentFilters . tools = initialTools ;
182+ setChoicesValues ( toolSelect , initialTools ) ;
183+ }
143184 document . getElementById ( 'filter-tool' ) ?. addEventListener ( 'change' , ( ) => {
144185 currentFilters . tools = getChoicesValues ( toolSelect ) ;
145186 applyFiltersAndRender ( ) ;
187+ syncUrlState ( searchInput ) ;
146188 } ) ;
147189
148190 // Initialize sort select
191+ if ( initialSort === 'lastUpdated' ) {
192+ currentSort = initialSort ;
193+ if ( sortSelect ) sortSelect . value = initialSort ;
194+ }
149195 sortSelect ?. addEventListener ( 'change' , ( ) => {
150196 currentSort = sortSelect . value as AgentSortOption ;
151197 applyFiltersAndRender ( ) ;
198+ syncUrlState ( searchInput ) ;
152199 } ) ;
153200
154201 const countEl = document . getElementById ( 'results-count' ) ;
155202 if ( countEl ) {
156203 countEl . textContent = `${ allItems . length } of ${ allItems . length } agents` ;
157204 }
158205
159- searchInput ?. addEventListener ( 'input' , debounce ( ( ) => applyFiltersAndRender ( ) , 200 ) ) ;
206+ searchInput ?. addEventListener ( 'input' , debounce ( ( ) => {
207+ applyFiltersAndRender ( ) ;
208+ syncUrlState ( searchInput ) ;
209+ } , 200 ) ) ;
210+
211+ if ( getQueryParamFlag ( 'handoffs' ) ) {
212+ currentFilters . hasHandoffs = true ;
213+ if ( handoffsCheckbox ) handoffsCheckbox . checked = true ;
214+ }
160215
161216 handoffsCheckbox ?. addEventListener ( 'change' , ( ) => {
162217 currentFilters . hasHandoffs = handoffsCheckbox . checked ;
163218 applyFiltersAndRender ( ) ;
219+ syncUrlState ( searchInput ) ;
164220 } ) ;
165221
166222 clearFiltersBtn ?. addEventListener ( 'click' , ( ) => {
@@ -172,8 +228,10 @@ export async function initAgentsPage(): Promise<void> {
172228 if ( searchInput ) searchInput . value = '' ;
173229 if ( sortSelect ) sortSelect . value = 'title' ;
174230 applyFiltersAndRender ( ) ;
231+ syncUrlState ( searchInput ) ;
175232 } ) ;
176233
234+ applyFiltersAndRender ( ) ;
177235 setupModal ( ) ;
178236 setupDropdownCloseHandlers ( ) ;
179237 setupActionHandlers ( ) ;
0 commit comments