diff --git a/plugins/todo/src/api/TodoClient.ts b/plugins/todo/src/api/TodoClient.ts index 44d80ba22e..ca5284537b 100644 --- a/plugins/todo/src/api/TodoClient.ts +++ b/plugins/todo/src/api/TodoClient.ts @@ -36,6 +36,7 @@ export class TodoClient implements TodoApi { entity, offset, limit, + orderBy, }: TodoListOptions): Promise { const baseUrl = await this.discoveryApi.getBaseUrl('todo'); const token = await this.identityApi.getIdToken(); @@ -50,6 +51,9 @@ export class TodoClient implements TodoApi { if (typeof limit === 'number') { query.set('limit', String(limit)); } + if (orderBy) { + query.set('orderBy', `${orderBy.field}=${orderBy.direction}`); + } const res = await fetch(`${baseUrl}/v1/todos?${query}`, { headers: token diff --git a/plugins/todo/src/api/types.ts b/plugins/todo/src/api/types.ts index 759df24b60..22eff72b3a 100644 --- a/plugins/todo/src/api/types.ts +++ b/plugins/todo/src/api/types.ts @@ -38,6 +38,10 @@ export type TodoListOptions = { entity?: Entity; offset?: number; limit?: number; + orderBy?: { + field: 'text' | 'author' | 'viewUrl' | 'repoFilePath'; + direction: 'asc' | 'desc'; + }; }; export type TodoListResult = { diff --git a/plugins/todo/src/components/TodoList/TodoList.tsx b/plugins/todo/src/components/TodoList/TodoList.tsx index 1201dca4fd..a18e8f8626 100644 --- a/plugins/todo/src/components/TodoList/TodoList.tsx +++ b/plugins/todo/src/components/TodoList/TodoList.tsx @@ -15,7 +15,6 @@ */ import { - Progress, Table, TableColumn, useApi, @@ -25,19 +24,22 @@ import { import { useEntity } from '@backstage/plugin-catalog-react'; import Alert from '@material-ui/lab/Alert'; import React, { useState } from 'react'; -import { useAsync } from 'react-use'; import { todoApiRef } from '../../api'; -import { TodoItem } from '../../api/types'; +import { TodoItem, TodoListOptions } from '../../api/types'; + +const PAGE_SIZE = 10; const columns: TableColumn[] = [ { title: 'Text', + field: 'text', width: '100%', highlight: true, render: ({ text }) => , }, { title: 'File', + field: 'repoFilePath', width: '80%', render: ({ viewUrl, repoFilePath }) => viewUrl ? ( @@ -59,39 +61,50 @@ const columns: TableColumn[] = [ export const TodoList = () => { const { entity } = useEntity(); const todoApi = useApi(todoApiRef); - const [page, setPage] = useState(0); - const [pageSize, setPageSize] = useState(10); + const [error, setError] = useState(); - const { value, loading, error } = useAsync( - async () => - todoApi.listTodos({ - entity, - offset: page * pageSize, - limit: pageSize, - }), - [todoApi, entity, page, pageSize], - ); - - if (loading) { - return ; - } else if (error) { + if (error) { return {error.message}; } return ( - title="TODOs" options={{ search: false, - pageSize, + pageSize: PAGE_SIZE, padding: 'dense', + sorting: true, + draggable: false, + paging: true, + paginationType: 'stepped', }} - page={page} columns={columns} - totalCount={value!.totalCount} - onChangePage={setPage} - onChangeRowsPerPage={setPageSize} - data={value!.items} + data={async query => { + try { + const page = query?.page ?? 0; + const pageSize = query?.pageSize ?? PAGE_SIZE; + const result = await todoApi.listTodos({ + entity, + offset: page * pageSize, + limit: pageSize, + orderBy: + query?.orderBy && + ({ + field: query.orderBy.field, + direction: query.orderDirection, + } as TodoListOptions['orderBy']), + }); + return { + data: result.items, + totalCount: result.totalCount, + page: Math.floor(result.offset / result.limit), + }; + } catch (loadingError) { + setError(loadingError); + return { data: [], totalCount: 0, page: 0 }; + } + }} /> ); };