Skip to content
This repository was archived by the owner on Feb 5, 2026. It is now read-only.

Commit 80100bf

Browse files
committed
Refactor filtering with getAbilities to account for query args
1 parent 01c4b20 commit 80100bf

8 files changed

Lines changed: 39 additions & 28 deletions

File tree

packages/client/README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function MyComponent() {
7575

7676
### Functions
7777

78-
#### `getAbilities(category?: string): Promise<Ability[]>`
78+
#### `getAbilities( args: AbilitiesQueryArgs = {} ): Promise<Ability[]>`
7979

8080
Returns all registered abilities. Optionally filter by category slug. Automatically handles pagination to fetch all abilities across multiple pages if needed.
8181

@@ -85,11 +85,11 @@ const abilities = await getAbilities();
8585
console.log( `Found ${ abilities.length } abilities` );
8686

8787
// Get abilities in a specific category
88-
const dataAbilities = await getAbilities( 'data-retrieval' );
88+
const dataAbilities = await getAbilities( { category: 'data-retrieval' } );
8989
console.log( `Found ${ dataAbilities.length } data retrieval abilities` );
9090
```
9191

92-
#### `getAbility(name: string): Promise<Ability | null>`
92+
#### `getAbility( name: string ): Promise<Ability | null>`
9393

9494
Returns a specific ability by name, or null if not found.
9595

@@ -100,7 +100,7 @@ if ( ability ) {
100100
}
101101
```
102102

103-
#### `registerAbility(ability: Ability): void`
103+
#### `registerAbility( ability: Ability ): void`
104104

105105
Registers a client-side ability. Client abilities are executed locally in the browser and must include a callback function and a valid category.
106106

@@ -115,18 +115,18 @@ registerAbility( {
115115
input_schema: {
116116
type: 'object',
117117
properties: {
118-
url: { type: 'string' }
118+
url: { type: 'string' },
119119
},
120-
required: [ 'url' ]
120+
required: [ 'url' ],
121121
},
122122
callback: async ( { url } ) => {
123123
window.location.href = url;
124124
return { success: true };
125-
}
125+
},
126126
} );
127127
```
128128

129-
#### `executeAbility(name: string, input?: Record<string, any>): Promise<any>`
129+
#### `executeAbility( name: string, input?: Record<string, any> ): Promise<any>`
130130

131131
Executes an ability with optional input parameters. The HTTP method is automatically determined based on the ability's annotations:
132132

@@ -150,8 +150,8 @@ const result = await executeAbility( 'my-plugin/create-item', {
150150

151151
When using with `@wordpress/data`:
152152

153-
- `getAbilities(category?)` - Returns all abilities from the store, optionally filtered by category
154-
- `getAbility(name)` - Returns a specific ability from the store
153+
- `getAbilities( args: AbilitiesQueryArgs = {} )` - Returns all abilities from the store, optionally filtered by query arguments
154+
- `getAbility( name: string )` - Returns a specific ability from the store
155155

156156
```javascript
157157
import { useSelect } from '@wordpress/data';
@@ -166,7 +166,8 @@ function MyComponent() {
166166

167167
// Get abilities in a specific category
168168
const dataAbilities = useSelect(
169-
( select ) => select( abilitiesStore ).getAbilities( 'data-retrieval' ),
169+
( select ) =>
170+
select( abilitiesStore ).getAbilities( { category: 'data-retrieval' } ),
170171
[]
171172
);
172173

packages/client/src/__tests__/api.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ describe( 'API functions', () => {
101101
getAbilities: mockGetAbilities,
102102
} );
103103

104-
const result = await getAbilities( 'data-retrieval' );
104+
const result = await getAbilities( { category: 'data-retrieval' } );
105105

106106
expect( resolveSelect ).toHaveBeenCalledWith( store );
107-
expect( mockGetAbilities ).toHaveBeenCalledWith( 'data-retrieval' );
107+
expect( mockGetAbilities ).toHaveBeenCalledWith( { category: 'data-retrieval' } );
108108
expect( result ).toEqual( mockAbilities );
109109
} );
110110
} );

packages/client/src/api.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ import { sprintf } from '@wordpress/i18n';
1010
* Internal dependencies
1111
*/
1212
import { store } from './store';
13-
import type { Ability, AbilityInput, AbilityOutput } from './types';
13+
import type { Ability, AbilitiesQueryArgs, AbilityInput, AbilityOutput } from './types';
1414
import { validateValueFromSchema } from './validation';
1515

1616
/**
17-
* Get all available abilities.
17+
* Get all available abilities with optional filtering.
1818
*
19-
* @param category Optional category slug to filter abilities.
19+
* @param args Optional query arguments to filter. Defaults to empty object.
2020
* @return Promise resolving to array of abilities.
2121
*/
22-
export async function getAbilities( category?: string ): Promise< Ability[] > {
23-
return await resolveSelect( store ).getAbilities( category );
22+
export async function getAbilities( args: AbilitiesQueryArgs = {} ): Promise< Ability[] > {
23+
return await resolveSelect( store ).getAbilities( args );
2424
}
2525

2626
/**

packages/client/src/store/__tests__/resolvers.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ describe( 'Store Resolvers', () => {
9999

100100
mockRegistry.resolveSelect.mockReturnValue( mockResolveSelect );
101101

102-
const resolver = getAbilities( 'data-retrieval' );
102+
const resolver = getAbilities( { category: 'data-retrieval' } );
103103
await resolver( {
104104
dispatch: mockDispatch,
105105
registry: mockRegistry,

packages/client/src/store/__tests__/selectors.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ describe( 'Store Selectors', () => {
142142
},
143143
};
144144

145-
const result = getAbilities( state, 'data-retrieval' );
145+
const result = getAbilities( state, { category: 'data-retrieval' } );
146146

147147
expect( result ).toHaveLength( 2 );
148148
expect( result ).toContainEqual(
@@ -170,7 +170,7 @@ describe( 'Store Selectors', () => {
170170
},
171171
};
172172

173-
const result = getAbilities( state, 'non-existent-category' );
173+
const result = getAbilities( state, { category: 'non-existent-category' } );
174174

175175
expect( result ).toEqual( [] );
176176
} );

packages/client/src/store/resolvers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import { receiveAbilities } from './actions';
1414
* Resolver for getAbilities selector.
1515
* Fetches all abilities from the server.
1616
*
17-
* The resolver only fetches once (without category filter) and stores all abilities.
18-
* Category filtering handled client-side by the selector for better performance
17+
* The resolver only fetches once (without query args filter) and stores all abilities.
18+
* Query args filtering handled client-side by the selector for better performance
1919
* and to avoid multiple API requests when filtering by different categories.
2020
*/
2121
export function getAbilities() {

packages/client/src/store/selectors.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ import { createSelector } from '@wordpress/data';
66
/**
77
* Internal dependencies
88
*/
9-
import type { Ability, AbilitiesState } from '../types';
9+
import type { Ability, AbilitiesQueryArgs, AbilitiesState } from '../types';
1010

1111
/**
1212
* Returns all registered abilities.
13-
* Optionally filters by category.
13+
* Optionally filters by query arguments.
1414
*
15-
* @param state Store state.
16-
* @param category Optional category slug to filter by.
15+
* @param state Store state.
16+
* @param args Optional query arguments to filter. Defaults to empty object.
1717
* @return Array of abilities.
1818
*/
1919
export const getAbilities = createSelector(
20-
( state: AbilitiesState, category?: string ): Ability[] => {
20+
( state: AbilitiesState, { category }: AbilitiesQueryArgs = {} ): Ability[] => {
2121
const abilities = Object.values( state.abilitiesByName );
2222
if ( category ) {
2323
return abilities.filter(

packages/client/src/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ export interface Ability {
9191
};
9292
}
9393

94+
/**
95+
* The shape of the arguments for querying abilities.
96+
*/
97+
export interface AbilitiesQueryArgs {
98+
/**
99+
* Optional category slug to filter abilities.
100+
*/
101+
category?: string;
102+
}
103+
94104
/**
95105
* The state shape for the abilities store.
96106
*/

0 commit comments

Comments
 (0)