Skip to content

Commit

Permalink
[Dashboard De-Angular] Render dashboard listing page (opensearch-proj…
Browse files Browse the repository at this point in the history
…ect#4015)

Render the dashboard listing component with basic functionalities:
* When there is no dashboard, render the empty dashboard page
* When there are dashboards, show the dashboard listing table
* When click on the dashboard, show the editor page
* Delete the dashboards when selected
* Can use search bar to filter dashboard

TODO:

* use URL param to filter dashboards based on dashboard titles
* implement actions column
* global persistence on the listing page

Issue Resolved:
opensearch-project#4000

Signed-off-by: abbyhu2000 <abigailhu2000@gmail.com>
  • Loading branch information
abbyhu2000 committed Jun 27, 2023
1 parent 819b13d commit b091b74
Show file tree
Hide file tree
Showing 8 changed files with 319 additions and 252 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,156 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import React, { useCallback, useMemo } from 'react';
import { i18n } from '@osd/i18n';
import { useMount } from 'react-use';
import {
useOpenSearchDashboards,
TableListView,
} from '../../../../opensearch_dashboards_react/public';
import { CreateButton } from '../listing/create_button';
import { DashboardConstants } from '../../dashboard_constants';
import { DashboardServices } from '../../types';
import { getTableColumns } from '../utils/get_table_columns';
import { getNoItemsMessage } from '../utils/get_no_items_message';

export const EMPTY_FILTER = '';

export const DashboardListing = () => {
return <div>Dashboard Listing</div>;
const {
services: {
application,
chrome,
savedObjectsPublic,
savedObjectsClient,
dashboardConfig,
history,
uiSettings,
notifications,
savedDashboards,
dashboardProviders,
addBasePath,
},
} = useOpenSearchDashboards<DashboardServices>();

const hideWriteControls = dashboardConfig.getHideWriteControls();

const tableColumns = useMemo(() => getTableColumns(application, history, uiSettings), [
application,
history,
uiSettings,
]);

const createItem = useCallback(() => {
history.push(DashboardConstants.CREATE_NEW_DASHBOARD_URL);
}, [history]);

const noItemsFragment = useMemo(
() => getNoItemsMessage(hideWriteControls, createItem, application),
[hideWriteControls, createItem, application]
);

const dashboardProvidersForListing = dashboardProviders() || {};

const dashboardListTypes = Object.keys(dashboardProvidersForListing);
const initialPageSize = savedObjectsPublic.settings.getPerPage();
const listingLimit = savedObjectsPublic.settings.getListingLimit();

const mapListAttributesToDashboardProvider = (obj: any) => {
const provider = dashboardProvidersForListing[obj.type];
return {
id: obj.id,
appId: provider.appId,
type: provider.savedObjectsName,
...obj.attributes,
updated_at: obj.updated_at,
viewUrl: provider.viewUrlPathFn(obj),
editUrl: provider.editUrlPathFn(obj),
};
};

const find = async (search: any) => {
const res = await savedObjectsClient.find({
type: dashboardListTypes,
search: search ? `${search}*` : undefined,
fields: ['title', 'type', 'description', 'updated_at'],
perPage: listingLimit,
page: 1,
searchFields: ['title^3', 'type', 'description'],
defaultSearchOperator: 'AND',
});
const list = res.savedObjects?.map(mapListAttributesToDashboardProvider) || [];

return {
total: list.length,
hits: list,
};
};

const editItem = useCallback(
({ editUrl }: any) => {
if (addBasePath) {
history.push(addBasePath(editUrl));
}
},
[history, addBasePath]
);

const viewItem = useCallback(
({ viewUrl }: any) => {
if (addBasePath) {
history.push(addBasePath(viewUrl));
}
},
[history, addBasePath]
);

const deleteItems = useCallback(
(dashboards: object[]) => {
return savedDashboards.delete(dashboards.map((d: any) => d.id));
},
[savedDashboards]
);

useMount(() => {
chrome.setBreadcrumbs([
{
text: i18n.translate('dashboard.dashboardBreadcrumbsTitle', {
defaultMessage: 'Dashboards',
}),
},
]);

chrome.docTitle.change(
i18n.translate('dashboard.dashboardPageTitle', { defaultMessage: 'Dashboards' })
);
});

return (
<TableListView
headingId="dashboardListingHeading"
createItem={hideWriteControls ? undefined : createItem}
createButton={
hideWriteControls ? undefined : <CreateButton dashboardProviders={dashboardProviders()} />
}
findItems={find}
deleteItems={hideWriteControls ? undefined : deleteItems}
editItem={hideWriteControls ? undefined : editItem}
tableColumns={tableColumns}
listingLimit={listingLimit}
initialFilter={''}
initialPageSize={initialPageSize}
noItemsFragment={noItemsFragment}
entityName={i18n.translate('dashboard.listing.table.entityName', {
defaultMessage: 'dashboard',
})}
entityNamePlural={i18n.translate('dashboard.listing.table.entityNamePlural', {
defaultMessage: 'dashboards',
})}
tableListTitle={i18n.translate('dashboard.listing.dashboardsTitle', {
defaultMessage: 'Dashboards',
})}
toastNotifications={notifications.toasts}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import type { DashboardProvider } from '../../types';

interface CreateButtonProps {
dashboardProviders?: DashboardProvider[];
dashboardProviders?: { [key: string]: DashboardProvider };
}

const CreateButton = (props: CreateButtonProps) => {
Expand Down
Loading

0 comments on commit b091b74

Please sign in to comment.