Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ src/platform/packages/shared/content-management/content_editor @elastic/appex-sh
src/platform/packages/shared/content-management/content_insights/content_insights_public @elastic/appex-sharedux
src/platform/packages/shared/content-management/content_insights/content_insights_server @elastic/appex-sharedux
src/platform/packages/shared/content-management/content_list/kbn-content-list-mock-data @elastic/appex-sharedux
src/platform/packages/shared/content-management/content_list/kbn-content-list-provider @elastic/appex-sharedux
src/platform/packages/shared/content-management/content_list/kbn-content-list-provider-client @elastic/appex-sharedux
src/platform/packages/shared/content-management/favorites/favorites_common @elastic/appex-sharedux
src/platform/packages/shared/content-management/favorites/favorites_public @elastic/appex-sharedux
src/platform/packages/shared/content-management/favorites/favorites_server @elastic/appex-sharedux
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@
"@kbn/connector-specs": "link:src/platform/packages/shared/kbn-connector-specs",
"@kbn/console-plugin": "link:src/platform/plugins/shared/console",
"@kbn/content-connectors-plugin": "link:x-pack/platform/plugins/shared/content_connectors",
"@kbn/content-list-provider": "link:src/platform/packages/shared/content-management/content_list/kbn-content-list-provider",
"@kbn/content-list-provider-client": "link:src/platform/packages/shared/content-management/content_list/kbn-content-list-provider-client",
"@kbn/content-management-access-control-public": "link:src/platform/packages/shared/content-management/access_control/access_control_public",
"@kbn/content-management-access-control-server": "link:src/platform/packages/shared/content-management/access_control/access_control_server",
"@kbn/content-management-content-editor": "link:src/platform/packages/shared/content-management/content_editor",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# @kbn/content-list-provider-client

Client-side Content List Provider — designed for easy migration from `TableListView`.

## Overview

This package provides a client-side adapter for content listing that wraps existing `TableListView`-style `findItems` functions. It enables consumers to migrate from `TableListView` to the new `ContentListProvider` architecture with minimal code changes.

## When to Use

Use this provider when:

- **Migrating from `TableListView`** with minimal code changes.
- Working with **smaller datasets** (< 10,000 items).
- Your existing `findItems` implementation already handles data fetching.

## How It Works

This adapter is designed for easy migration from `TableListView`. It:

- **Passes only `searchQuery`** to your existing `findItems` function (matching `TableListView` behavior).
- **Applies client-side sorting and pagination** on the returned results — your `findItems` fetches all matching items, and the adapter sorts and paginates in memory.
- **Does not forward** `sort`, `page`, or `filters` parameters to your `findItems` implementation.
- **Caches by `searchQuery`** — React Query caches results based on the search query. Changing sort or page reuses cached data.

## Usage

### Basic Migration from TableListView

The key migration step is passing your existing `findItems` function:

```tsx
import { ContentListClientProvider } from '@kbn/content-list-provider-client';

// Your existing findItems function from TableListView - no changes needed!
const findItems = useCallback(
async (searchTerm) => {
return dashboardClient.search({
search: searchTerm,
}).then(({ total, dashboards }) => ({
total,
hits: dashboards.map(transformToDashboardUserContent),
}));
},
[]
);

// Before: TableListView
<TableListView
findItems={findItems}
entityName="dashboard"
entityNamePlural="dashboards"
// ...other props
/>

// After: ContentListClientProvider
<ContentListClientProvider
id="dashboard"
labels={{
entity: i18n.translate('dashboard.listing.entity', { defaultMessage: 'dashboard' }),
entityPlural: i18n.translate('dashboard.listing.entityPlural', { defaultMessage: 'dashboards' }),
}}
findItems={findItems}
>
<MyDashboardList />
</ContentListClientProvider>
```

### Using the Adapter Function Directly

If you need more control, you can use the adapter function directly:

```tsx
import { createFindItemsFn } from '@kbn/content-list-provider-client';
import { ContentListProvider } from '@kbn/content-list-provider';

// Wrap your existing findItems.
const findItems = createFindItemsFn(myExistingFindItems);

// Use with the base provider.
<ContentListProvider
id="dashboard"
labels={{ entity: 'dashboard', entityPlural: 'dashboards' }}
dataSource={{ findItems }}
>
<MyListComponent />
</ContentListProvider>
```

## Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `id` | `string` | Yes* | Unique identifier. `queryKeyScope` derived as `${id}-listing` if not provided. |
| `queryKeyScope` | `string` | Yes* | Explicit React Query cache key scope. |
| `labels` | `ContentListLabels` | Yes | User-facing entity labels (should be i18n-translated). |
| `findItems` | `TableListViewFindItemsFn` | Yes | Your existing `TableListView` findItems function. |
| `features` | `ContentListFeatures` | No | Feature configuration. |
| `item` | `ContentListItemConfig` | No | Per-item configuration for links. |
| `isReadOnly` | `boolean` | No | Disable mutation actions. |

*At least one of `id` or `queryKeyScope` is required.

## findItems Function Signature

Your existing `findItems` function should match this signature:

```typescript
interface SavedObjectReference {
type: string;
id: string;
name?: string;
}

type TableListViewFindItemsFn = (
searchQuery: string,
refs?: {
references?: SavedObjectReference[];
referencesToExclude?: SavedObjectReference[];
}
) => Promise<{ total: number; hits: UserContentCommonSchema[] }>;
```

This is the same signature expected by `TableListView.findItems`.

> **Note:** The `refs` parameter (for tag filtering) is not yet supported in the new `ContentListProvider` architecture. Only `searchQuery` is forwarded in this initial version. Tag filtering support is planned for a future release.

## Exports

```typescript
// Provider component.
export { ContentListClientProvider } from './provider';
export type { ContentListClientProviderProps } from './provider';

// Adapter for direct usage.
export { createFindItemsFn } from './strategy';

// Types.
export type {
TableListViewFindItemsFn,
TableListViewFindItemsResult,
SavedObjectReference,
} from './types';
```

## Related Packages

- [`@kbn/content-list-provider`](../kbn-content-list-provider) — Core provider and hooks.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

// Provider.
export { ContentListClientProvider } from './src/provider';
export type { ContentListClientProviderProps } from './src/provider';

// Strategy.
export { createFindItemsFn } from './src/strategy';

// Types.
export type {
TableListViewFindItemsFn,
TableListViewFindItemsResult,
SavedObjectReference,
} from './src/types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../../../../../..',
roots: [
'<rootDir>/src/platform/packages/shared/content-management/content_list/kbn-content-list-provider-client',
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "shared-browser",
"id": "@kbn/content-list-provider-client",
"owner": [
"@elastic/appex-sharedux"
],
"group": "platform",
"visibility": "shared"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This file is generated by the @kbn/moon package. Any manual edits will be erased!
# To extend this, write your extensions/overrides to 'moon.extend.yml'
# then regenerate this file with: 'node scripts/regenerate_moon_projects.js --update --filter @kbn/content-list-provider-client'

$schema: https://moonrepo.dev/schemas/project.json
id: '@kbn/content-list-provider-client'
type: unknown
owners:
defaultOwner: '@elastic/appex-sharedux'
toolchain:
default: node
language: typescript
project:
name: '@kbn/content-list-provider-client'
description: Moon project for @kbn/content-list-provider-client
channel: ''
owner: '@elastic/appex-sharedux'
metadata:
sourceRoot: src/platform/packages/shared/content-management/content_list/kbn-content-list-provider-client
dependsOn:
- '@kbn/content-list-provider'
- '@kbn/content-management-table-list-view-common'
tags:
- shared-browser
- package
- prod
- group-platform
- shared
- jest-unit-tests
fileGroups:
src:
- '**/*.ts'
- '**/*.tsx'
- '!target/**/*'
tasks:
jest:
args:
- '--config'
- $projectRoot/jest.config.js
inputs:
- '@group(src)'
jestCI:
args:
- '--config'
- $projectRoot/jest.config.js
inputs:
- '@group(src)'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@kbn/content-list-provider-client",
"private": true,
"version": "1.0.0",
"license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0",
"sideEffects": false
}
Loading
Loading