mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[CM] Improve CRUD & RPC interfaces (#154150)
This commit is contained in:
parent
5b250268e7
commit
56c28af1f5
43 changed files with 672 additions and 372 deletions
|
@ -6,13 +6,17 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import {
|
||||
CreateIn,
|
||||
CreateResult,
|
||||
DeleteIn,
|
||||
DeleteResult,
|
||||
GetIn,
|
||||
GetResult,
|
||||
SearchIn,
|
||||
SearchResult,
|
||||
UpdateIn,
|
||||
UpdateResult,
|
||||
} from '@kbn/content-management-plugin/common';
|
||||
|
||||
export const TODO_CONTENT_ID = 'todos';
|
||||
|
@ -21,43 +25,18 @@ export interface Todo {
|
|||
title: string;
|
||||
completed: boolean;
|
||||
}
|
||||
const todoSchema = schema.object({
|
||||
id: schema.string(),
|
||||
title: schema.string(),
|
||||
completed: schema.boolean(),
|
||||
});
|
||||
|
||||
export type TodoCreateIn = CreateIn<'todos', { title: string }>;
|
||||
export type TodoCreateOut = Todo; // TODO: Is this correct?
|
||||
export const createInSchema = schema.object({ title: schema.string() });
|
||||
export const createOutSchema = todoSchema;
|
||||
export type TodoCreateOut = CreateResult<Todo>;
|
||||
|
||||
export type TodoUpdateIn = UpdateIn<'todos', Partial<Omit<Todo, 'id'>>>;
|
||||
export type TodoUpdateOut = Todo;
|
||||
export const updateInSchema = schema.object({
|
||||
title: schema.maybe(schema.string()),
|
||||
completed: schema.maybe(schema.boolean()),
|
||||
});
|
||||
export const updateOutSchema = todoSchema;
|
||||
export type TodoUpdateOut = UpdateResult<Todo>;
|
||||
|
||||
export type TodoDeleteIn = DeleteIn<'todos', { id: string }>;
|
||||
export type TodoDeleteOut = void;
|
||||
export type TodoDeleteOut = DeleteResult;
|
||||
|
||||
export type TodoGetIn = GetIn<'todos'>;
|
||||
export type TodoGetOut = Todo;
|
||||
export const getOutSchema = todoSchema;
|
||||
export type TodoGetOut = GetResult<Todo>;
|
||||
|
||||
export type TodoSearchIn = SearchIn<'todos', { filter?: 'todo' | 'completed' }>;
|
||||
export interface TodoSearchOut {
|
||||
hits: Todo[];
|
||||
}
|
||||
export const searchInSchema = schema.object({
|
||||
filter: schema.maybe(
|
||||
schema.oneOf([schema.literal('todo'), schema.literal('completed')], {
|
||||
defaultValue: undefined,
|
||||
})
|
||||
),
|
||||
});
|
||||
export const searchOutSchema = schema.object({
|
||||
hits: schema.arrayOf(todoSchema),
|
||||
});
|
||||
export type TodoSearchOut = SearchResult<Todo>;
|
||||
|
|
|
@ -39,22 +39,40 @@ export class TodosClient implements CrudClient {
|
|||
completed: false,
|
||||
};
|
||||
this.todos.push(todo);
|
||||
return todo;
|
||||
return {
|
||||
item: todo,
|
||||
};
|
||||
}
|
||||
|
||||
async delete(input: TodoDeleteIn): Promise<TodoDeleteOut> {
|
||||
this.todos = this.todos.filter((todo) => todo.id !== input.id);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async get(input: TodoGetIn): Promise<TodoGetOut> {
|
||||
return this.todos.find((todo) => todo.id === input.id)!;
|
||||
return {
|
||||
item: this.todos.find((todo) => todo.id === input.id)!,
|
||||
};
|
||||
}
|
||||
|
||||
async search(input: TodoSearchIn): Promise<TodoSearchOut> {
|
||||
const filter = input.query.filter;
|
||||
if (filter === 'todo') return { hits: this.todos.filter((t) => !t.completed) };
|
||||
if (filter === 'completed') return { hits: this.todos.filter((t) => t.completed) };
|
||||
return { hits: [...this.todos] };
|
||||
const filter = input.options?.filter;
|
||||
let hits = [...this.todos];
|
||||
|
||||
if (filter === 'todo') {
|
||||
hits = this.todos.filter((t) => !t.completed);
|
||||
}
|
||||
|
||||
if (filter === 'completed') {
|
||||
hits = this.todos.filter((t) => t.completed);
|
||||
}
|
||||
|
||||
return {
|
||||
hits,
|
||||
pagination: {
|
||||
total: hits.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async update(input: TodoUpdateIn): Promise<TodoUpdateOut> {
|
||||
|
@ -63,6 +81,10 @@ export class TodosClient implements CrudClient {
|
|||
if (todoToUpdate) {
|
||||
Object.assign(todoToUpdate, input.data);
|
||||
}
|
||||
return { ...todoToUpdate };
|
||||
return {
|
||||
item: {
|
||||
...todoToUpdate,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,11 @@ import {
|
|||
const useCreateTodoMutation = () => useCreateContentMutation<TodoCreateIn, TodoCreateOut>();
|
||||
const useDeleteTodoMutation = () => useDeleteContentMutation<TodoDeleteIn, TodoDeleteOut>();
|
||||
const useUpdateTodoMutation = () => useUpdateContentMutation<TodoUpdateIn, TodoUpdateOut>();
|
||||
const useSearchTodosQuery = ({ filter }: { filter: TodoSearchIn['query']['filter'] }) =>
|
||||
const useSearchTodosQuery = ({ options: { filter } = {} }: { options: TodoSearchIn['options'] }) =>
|
||||
useSearchContentQuery<TodoSearchIn, TodoSearchOut>({
|
||||
contentTypeId: TODO_CONTENT_ID,
|
||||
query: { filter },
|
||||
query: {},
|
||||
options: { filter },
|
||||
});
|
||||
|
||||
type TodoFilter = 'all' | 'completed' | 'todo';
|
||||
|
@ -63,7 +64,7 @@ export const Todos = () => {
|
|||
const [filterIdSelected, setFilterIdSelected] = React.useState<TodoFilter>('all');
|
||||
|
||||
const { data, isError, error, isFetching, isLoading } = useSearchTodosQuery({
|
||||
filter: filterIdSelected === 'all' ? undefined : filterIdSelected,
|
||||
options: { filter: filterIdSelected === 'all' ? undefined : filterIdSelected },
|
||||
});
|
||||
|
||||
const createTodoMutation = useCreateTodoMutation();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { BulkGetResult } from '@kbn/content-management-plugin/common';
|
||||
import {
|
||||
ContentStorage,
|
||||
StorageContext,
|
||||
|
@ -39,7 +40,7 @@ export const registerTodoContentType = ({
|
|||
});
|
||||
};
|
||||
|
||||
class TodosStorage implements ContentStorage {
|
||||
class TodosStorage implements ContentStorage<Todo> {
|
||||
private db: Map<string, Todo> = new Map();
|
||||
|
||||
constructor() {
|
||||
|
@ -58,11 +59,15 @@ class TodosStorage implements ContentStorage {
|
|||
}
|
||||
|
||||
async get(ctx: StorageContext, id: string): Promise<TodoGetOut> {
|
||||
return this.db.get(id)!;
|
||||
return {
|
||||
item: this.db.get(id)!,
|
||||
};
|
||||
}
|
||||
|
||||
async bulkGet(ctx: StorageContext, ids: string[]): Promise<TodoGetOut[]> {
|
||||
return ids.map((id) => this.db.get(id)!);
|
||||
async bulkGet(ctx: StorageContext, ids: string[]): Promise<BulkGetResult<Todo>> {
|
||||
return {
|
||||
hits: ids.map((id) => ({ item: this.db.get(id)! })),
|
||||
};
|
||||
}
|
||||
|
||||
async create(ctx: StorageContext, data: TodoCreateIn['data']): Promise<TodoCreateOut> {
|
||||
|
@ -74,7 +79,9 @@ class TodosStorage implements ContentStorage {
|
|||
|
||||
this.db.set(todo.id, todo);
|
||||
|
||||
return todo;
|
||||
return {
|
||||
item: todo,
|
||||
};
|
||||
}
|
||||
|
||||
async update(
|
||||
|
@ -94,17 +101,36 @@ class TodosStorage implements ContentStorage {
|
|||
|
||||
this.db.set(id, updatedContent);
|
||||
|
||||
return updatedContent;
|
||||
return {
|
||||
item: updatedContent,
|
||||
};
|
||||
}
|
||||
|
||||
async delete(ctx: StorageContext, id: string): Promise<TodoDeleteOut> {
|
||||
this.db.delete(id);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async search(ctx: StorageContext, query: TodoSearchIn['query']): Promise<TodoSearchOut> {
|
||||
const hits = Array.from(this.db.values());
|
||||
if (query.filter === 'todo') return { hits: hits.filter((t) => !t.completed) };
|
||||
if (query.filter === 'completed') return { hits: hits.filter((t) => t.completed) };
|
||||
return { hits };
|
||||
async search(
|
||||
ctx: StorageContext,
|
||||
_: TodoSearchIn['query'],
|
||||
options: TodoSearchIn['options']
|
||||
): Promise<TodoSearchOut> {
|
||||
let hits = Array.from(this.db.values());
|
||||
|
||||
if (options?.filter === 'todo') {
|
||||
hits = hits.filter((t) => !t.completed);
|
||||
}
|
||||
|
||||
if (options?.filter === 'completed') {
|
||||
hits = hits.filter((t) => t.completed);
|
||||
}
|
||||
|
||||
return {
|
||||
hits,
|
||||
pagination: {
|
||||
total: hits.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"kbn_references": [
|
||||
"@kbn/core",
|
||||
"@kbn/developer-examples-plugin",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/content-management-plugin",
|
||||
"@kbn/core-application-browser",
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue