Skip to content

Commit

Permalink
workspace list card
Browse files Browse the repository at this point in the history
Signed-off-by: Hailong Cui <[email protected]>
  • Loading branch information
Hailong-am committed Jul 17, 2024
1 parent 84537b5 commit 1b798a3
Show file tree
Hide file tree
Showing 13 changed files with 522 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/core/types/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface WorkspaceAttribute {
icon?: string;
reserved?: boolean;
uiSettings?: Record<string, any>;
lastUpdatedTime?: string;
}

export interface WorkspaceAttributeWithPermission extends WorkspaceAttribute {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import React from 'react';
import { useObservable } from 'react-use';

import { SavedObjectsClientContract } from 'opensearch-dashboards/public';
import { Page } from '../services';
import { SectionRender } from './section_render';
import { EmbeddableStart } from '../../../embeddable/public';
import { SavedObjectsClientContract } from 'opensearch-dashboards/public';

export interface Props {
page: Page;
Expand All @@ -24,6 +24,7 @@ export const PageRender = ({ page, embeddable, savedObjectsClient }: Props) => {
<div className="contentManagement-page" style={{ margin: '10px 20px' }}>
{sections.map((section) => (
<SectionRender
key={section.id}
embeddable={embeddable}
section={section}
savedObjectsClient={savedObjectsClient}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import React, { useState, useEffect, useMemo } from 'react';
import { useObservable } from 'react-use';
import { BehaviorSubject } from 'rxjs';

import { EuiTitle } from '@elastic/eui';
import { SavedObjectsClientContract } from 'opensearch-dashboards/public';
import { Content, Section } from '../services';
import { EmbeddableInput, EmbeddableRenderer, EmbeddableStart } from '../../../embeddable/public';
import { DashboardContainerInput } from '../../../dashboard/public';
import { createCardSection, createDashboardSection } from './utils';
import { CARD_CONTAINER } from './card_container/card_container';
import { EuiTitle } from '@elastic/eui';
import { SavedObjectsClientContract } from 'opensearch-dashboards/public';

interface Props {
section: Section;
Expand All @@ -36,7 +36,7 @@ const DashboardSection = ({ section, embeddable, contents$, savedObjectsClient }
setInput(ds)
);
}
}, [section, contents]);
}, [section, contents, savedObjectsClient]);

const factory = embeddable.getEmbeddableFactory('dashboard');

Expand Down
2 changes: 2 additions & 0 deletions src/plugins/workspace/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,5 @@ export const WORKSPACE_USE_CASES = Object.freeze({
});

export const CURRENT_USER_PLACEHOLDER = '%me%';
export const MAX_WORKSPACE_NAME_LENGTH = 25;
export const RECENT_WORKSPACES_KEY = 'recentWorkspaces';
2 changes: 1 addition & 1 deletion src/plugins/workspace/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"savedObjects",
"opensearchDashboardsReact"
],
"optionalPlugins": ["savedObjectsManagement","management","dataSourceManagement"],
"optionalPlugins": ["savedObjectsManagement","management","dataSourceManagement","contentManagement"],
"requiredBundles": ["opensearchDashboardsReact"]
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/plugins/workspace/public/components/service_card/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { WorkspaceListCard } from './workspace_list_card';
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { coreMock } from '../../../../../core/public/mocks';
import { fireEvent, render } from '@testing-library/react';
import { WorkspaceListCard } from './workspace_list_card';
import { addRecentWorkspace } from '../../utils';

interface LooseObject {
[key: string]: any;
}

// Mock localStorage
const localStorageMock = (() => {
let store = {} as LooseObject;
return {
getItem(key: string) {
return store[key] || null;
},
setItem(key: string, value: string) {
store[key] = value.toString();
},
removeItem(key: string) {
delete store[key];
},
clear() {
store = {};
},
};
})();

Object.defineProperty(window, 'localStorage', { value: localStorageMock });

describe('workspace list card render normally', () => {
const coreStart = coreMock.createStart();

beforeAll(() => {
const workspaceList = [
{
id: 'ws-1',
name: 'foo',
lastUpdatedTime: new Date().toISOString(),
},
{
id: 'ws-2',
name: 'bar',
lastUpdatedTime: new Date().toISOString(),
},
];
coreStart.workspaces.workspaceList$.next(workspaceList);
addRecentWorkspace('foo');
});

it('should show workspace list card correctly', () => {
const { container } = render(<WorkspaceListCard core={coreStart} />);
expect(container).toMatchSnapshot();
});

it('should show default filter as recently viewed', () => {
const { getByTestId, getByText } = render(<WorkspaceListCard core={coreStart} />);
expect(getByTestId('workspace_filter')).toHaveDisplayValue('Recently viewed');

expect(getByText('foo')).toBeInTheDocument();
});

it('should show empty state if no recently viewed workspace', () => {
localStorageMock.clear();

const { getByTestId, getByText } = render(<WorkspaceListCard core={coreStart} />);
expect(getByTestId('workspace_filter')).toHaveDisplayValue('Recently viewed');

// empty statue for recently viewed
expect(getByText('Workspaces you have recently viewed will appear here.')).toBeInTheDocument();
});

it('should show updated filter correctly', () => {
const { getByTestId, getByText } = render(<WorkspaceListCard core={coreStart} />);
expect(getByTestId('workspace_filter')).toHaveDisplayValue('Recently viewed');

const filterSelector = getByTestId('workspace_filter');
fireEvent.change(filterSelector, { target: { value: 'updated' } });
expect(getByTestId('workspace_filter')).toHaveDisplayValue('Recently updated');

// workspace list
expect(getByText('foo')).toBeInTheDocument();
expect(getByText('bar')).toBeInTheDocument();
});
});
Loading

0 comments on commit 1b798a3

Please sign in to comment.