-
Notifications
You must be signed in to change notification settings - Fork 231
feat: Table Column Groups Collection Prefs #4487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1bef684
685b2ba
3516ac1
7b58334
3388a83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| import React, { useState } from 'react'; | ||
|
|
||
| import Box from '~components/box'; | ||
| import CollectionPreferences, { CollectionPreferencesProps } from '~components/collection-preferences'; | ||
| import SpaceBetween from '~components/space-between'; | ||
|
|
||
| import { contentDisplayPreferenceI18nStrings } from '../common/i18n-strings'; | ||
| import { | ||
| baseProperties, | ||
| contentDisplayGroups, | ||
| groupedContentDisplay, | ||
| groupedContentDisplayOptions, | ||
| } from './shared-configs'; | ||
|
|
||
| export default function ContentDisplayGroupsPage() { | ||
| const [preferences, setPreferences] = useState<CollectionPreferencesProps.Preferences>({ | ||
| contentDisplay: groupedContentDisplay, | ||
| }); | ||
|
|
||
| return ( | ||
| <SpaceBetween size="l"> | ||
| <h1>Content Display with Groups</h1> | ||
|
|
||
| <CollectionPreferences | ||
| {...baseProperties} | ||
| preferences={preferences} | ||
| onConfirm={({ detail }) => setPreferences(detail)} | ||
| contentDisplayPreference={{ | ||
| title: 'Column preferences', | ||
| description: 'Customize column visibility and order.', | ||
| options: groupedContentDisplayOptions, | ||
| groups: contentDisplayGroups, | ||
| enableColumnFiltering: true, | ||
| ...contentDisplayPreferenceI18nStrings, | ||
| }} | ||
| /> | ||
|
|
||
| <Box variant="h2">Current preferences.contentDisplay</Box> | ||
| <pre | ||
| tabIndex={0} | ||
| style={{ background: '#f4f4f4', padding: '12px', borderRadius: '4px', overflow: 'auto', maxHeight: '400px' }} | ||
| > | ||
| {JSON.stringify(preferences.contentDisplay, null, 2)} | ||
| </pre> | ||
| </SpaceBetween> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| import useBrowser from '@cloudscape-design/browser-test-tools/use-browser'; | ||
|
|
||
| import createWrapper from '../../../../lib/components/test-utils/selectors'; | ||
| import ContentDisplayPageObject from './pages/content-display-page'; | ||
|
|
||
| const windowDimensions = { | ||
| width: 1200, | ||
| height: 1200, | ||
| }; | ||
|
|
||
| const setupTest = (testFn: (page: ContentDisplayPageObject) => Promise<void>) => { | ||
| return useBrowser(async browser => { | ||
| const page = new ContentDisplayPageObject(browser); | ||
| await browser.url('#/light/collection-preferences/content-display-groups'); | ||
| await page.setWindowSize(windowDimensions); | ||
| page.wrapper = createWrapper().findCollectionPreferences(); | ||
| await page.openCollectionPreferencesModal(); | ||
| await testFn(page); | ||
| }); | ||
| }; | ||
|
|
||
| describe('Collection preferences - Grouped Content Display', () => { | ||
| test( | ||
| 'renders group headers and leaf options', | ||
| setupTest(async page => { | ||
| const modal = page.wrapper.findModal().findContentDisplayPreference(); | ||
| const options = modal.findOptions(); | ||
|
|
||
| // Should have options rendered | ||
| const texts = await page.getElementsText(options.toSelector()); | ||
| expect(texts.length).toBeGreaterThan(0); | ||
|
|
||
| // Should contain group labels | ||
| const content = await page.getText(modal.toSelector()); | ||
| expect(content).toContain('Configuration'); | ||
| expect(content).toContain('Performance'); | ||
| expect(content).toContain('Network'); | ||
| }) | ||
| ); | ||
|
|
||
| test( | ||
| 'toggles visibility of a leaf option within a group', | ||
| setupTest(async page => { | ||
| const modal = page.wrapper.findModal().findContentDisplayPreference(); | ||
| const options = modal.findOptions(); | ||
| const firstOption = options.get(1); | ||
| const toggle = firstOption.findVisibilityToggle().findNativeInput(); | ||
|
|
||
| // Toggle visibility | ||
| await page.click(toggle.toSelector()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We typically write an assertion statement after an event |
||
| }) | ||
| ); | ||
|
|
||
| test( | ||
| 'reorders a group item with drag and drop', | ||
| setupTest(async page => { | ||
| const modal = page.wrapper.findModal().findContentDisplayPreference(); | ||
| const options = modal.findOptions(); | ||
|
|
||
| // Get initial order | ||
| const initialTexts = await page.getElementsText(options.toSelector()); | ||
| expect(initialTexts.length).toBeGreaterThan(0); | ||
|
|
||
| // Drag first item down | ||
| const activeDragHandle = options.get(1).findDragHandle(); | ||
| const targetDragHandle = options.get(3).findDragHandle(); | ||
| await page.dragAndDropTo(activeDragHandle.toSelector(), targetDragHandle.toSelector()); | ||
|
|
||
| // Order should have changed | ||
| const newTexts = await page.getElementsText(options.toSelector()); | ||
| expect(newTexts).not.toEqual(initialTexts); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest explicitly checking options order after drag and drop and introduce more complex scenarios such as:
|
||
| }) | ||
| ); | ||
|
|
||
| test( | ||
| 'filters options within groups', | ||
| setupTest(async page => { | ||
| const modal = page.wrapper.findModal().findContentDisplayPreference(); | ||
| const filterInput = modal.findTextFilter().findInput().findNativeInput(); | ||
|
|
||
| // Type a filter | ||
| await page.click(filterInput.toSelector()); | ||
| await page.keys('Network'); | ||
|
|
||
| // Should show filtered results | ||
| const content = await page.getText(modal.toSelector()); | ||
| expect(content).toContain('Network'); | ||
| }) | ||
| ); | ||
|
|
||
| test( | ||
| 'nested list has aria-label matching group name', | ||
| setupTest(async page => { | ||
| const modal = page.wrapper.findModal().findContentDisplayPreference(); | ||
| // Verify nested lists exist by checking content | ||
| const content = await page.getText(modal.toSelector()); | ||
| expect(content).toContain('Configuration'); | ||
| }) | ||
| ); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd cover this in unit tests since they're cheaper to run. Is there anything browser-specific that jsdom can't reproduce? Looks like only drag and drop really needs integ tests in this file, the rest could be unit tests