-
Notifications
You must be signed in to change notification settings - Fork 6
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
Advanced Timeline Filtering #1535
Open
AaronPlave
wants to merge
92
commits into
develop
Choose a base branch
from
feature/advanced-timeline-item-filtering
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 88 commits
Commits
Show all changes
92 commits
Select commit
Hold shift + click to select a range
050c46b
WIP
AaronPlave 55e7706
Fixes for spans
AaronPlave edd0037
Componentize editor section headers. Remove unused styles.
AaronPlave 61b72eb
Refactoring, fixing, improving timeline editor
AaronPlave e5d558b
Add icon
AaronPlave 6a9fbef
Add svelte dragging library
AaronPlave 2595f71
Style refactor
AaronPlave fa0b8bf
Make menu items tab focusable
AaronPlave 3e740e5
Style tweak
AaronPlave 1b1f16e
WIP activity layer filtering
AaronPlave e24e16b
style refactor
AaronPlave d4cfdb2
Get default activity arguments during plan load
AaronPlave 69c0f4e
Potentially remove unused input workaround
AaronPlave 251e6b5
WIP filtering
AaronPlave ef8a7b4
Basic manual type selection list filtering
AaronPlave 52cd277
add cssgrid to activity filter builder
AaronPlave 3f0cae1
Bring back resource editing in old form for now
AaronPlave cab3815
Remove all layer fixes
AaronPlave 23ac089
Style fix
AaronPlave 650525f
Refactor
AaronPlave a15739c
Show an indication dot when an activity layer has active filters
AaronPlave 3ed8826
Show resulting type and instance counts
AaronPlave 3c0a6a8
Greater/less than support
AaronPlave b657b24
Remove log
AaronPlave 1f2d615
use > and <
AaronPlave 5896f10
Reactivity fix
AaronPlave 91d5d54
Support boolean comparison
AaronPlave 6ac5399
Input filtering
AaronPlave 6c548ca
Bug fix
AaronPlave d7a961e
Support for min col and row css grid sizing
AaronPlave 111d808
Add derived subsystem tags store. Fix subsystem tags filtering.
AaronPlave cd183c0
Tooltip tweaks
AaronPlave 949689a
Fixes
AaronPlave c5805a3
Scheduling goal id filtering WIP support
AaronPlave 18a4c90
Manual type selection menu positioning fix
AaronPlave 4d24008
Filter parameter possibilities by resulting types if any. List all re…
AaronPlave 839d2cb
Tweak SearchableDropdown to be more like a dropdown
AaronPlave 8738671
Popper positioning workaround when inside css transformed parent. Use…
AaronPlave 933a3a6
Fixes and refactoring
AaronPlave 0a8c461
Fixes
AaronPlave 1e1e5f2
Support within and not within
AaronPlave bfe0d7b
Apply subfilters to resulting types
AaronPlave dd3fa2e
Type fixes
AaronPlave 2b5999c
Type fixes
AaronPlave ce3229c
Fixes and refactoring
AaronPlave 31d4342
Bug fix for confirm modal when adding activities to timeline
AaronPlave 4085ab6
Type fix
AaronPlave ac87fcd
Swap x-range icon
AaronPlave eba5450
Add left slot to MenuHeader
AaronPlave 640ef76
Refactor SearchableDropdown to allow for multiple options if requested
AaronPlave 13092c6
Style and functionality updates for all layers
AaronPlave 96581d9
Bug fixes
AaronPlave 7b954e1
Bug fixes
AaronPlave 4d97f7b
Use resource layer name as override on SearchableDropdown selected op…
AaronPlave 1e05be9
Show units for duration, int, and real parameters. Filter window drag…
AaronPlave ce208e7
Show all activities when no filters exist on layer. Bug fix.
AaronPlave 5bd1530
Virtualization of SearchableDropdown. Fixes.
AaronPlave eeba7b1
View migration to v2
AaronPlave 4f2ac4f
Prevent highlight on drag
AaronPlave b939ec3
Improve auto width sizing of SearchableDropdown
AaronPlave 9ed8e65
Fixes
AaronPlave c46718c
Type fix
AaronPlave 33c39bc
Type fixes
AaronPlave 3ea7ca8
Type fix
AaronPlave 85815f8
Tests
AaronPlave e3a1e39
Remove unused code
AaronPlave e196337
Type fixes
AaronPlave ab5576e
Tests. Rename field Tag -> Tags. Remove unused is_one_of and is_not_o…
AaronPlave 781b78f
Fix
AaronPlave 027b8b3
Test fix
AaronPlave f9787ed
Unit test fixes
AaronPlave 702b9b6
Tweak
AaronPlave c7fd1f5
Aria labels
AaronPlave b0f93ff
Dispatch show event
AaronPlave 10db2c1
Aria fixes
AaronPlave 5fd5f49
Basic test for DynamicFilter
AaronPlave c609e0e
Remove log
AaronPlave 8a44eb6
Remove .only
AaronPlave 753248c
Fixes
AaronPlave fac7ae8
e2e tests and fixes
AaronPlave cb90b1e
Remove pause in e2e test
AaronPlave 48813fd
Test fix
AaronPlave 71af95f
Test fixes
AaronPlave e46e8bd
Fixes
AaronPlave 5eb918e
Remove logs
AaronPlave b7fbd44
Add tooltip
AaronPlave a0fb1d8
Use Activity Layer instead of All Activities as default activity laye…
AaronPlave 11e2d90
Change global filters to other filters
AaronPlave 4658bcf
Turn off native autosuggest in various inputs. Add string input for t…
AaronPlave f8bea69
Fix within input values
AaronPlave dd79f3c
Filtering bug fixes and refactoring
AaronPlave c09c288
Resource layer tests
AaronPlave File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,6 +50,7 @@ test.describe.serial('Timeline View Editing', () => { | |
test('Add an activity to the parent plan', async () => { | ||
await plan.showPanel(PanelNames.TIMELINE_ITEMS); | ||
await plan.addActivity('PickBanana'); | ||
await plan.addActivity('PeelBanana'); | ||
}); | ||
|
||
test('Change the start time of the activity', async () => { | ||
|
@@ -105,26 +106,121 @@ test.describe.serial('Timeline View Editing', () => { | |
// Look for back button indicating that the row editor is active | ||
expect(page.locator('.section-back-button ').first()).toBeDefined(); | ||
|
||
const existingLayerCount = await page.locator('.timeline-layer').count(); | ||
|
||
// Give the row a name | ||
await page.locator('input[name="name"]').first().fill(rowName); | ||
await page.locator('input[name="name"]').first().blur(); | ||
}); | ||
|
||
test('Add an activity layer', async () => { | ||
const activityLayerEditor = page.getByLabel('Activity Layer-editor'); | ||
const existingLayerCount = await activityLayerEditor.locator('.timeline-layer-editor').count(); | ||
|
||
// Add a layer | ||
await page.getByRole('button', { name: 'New Layer' }).click(); | ||
const newLayerCount = await page.locator('.timeline-layer').count(); | ||
// Add an activity layer | ||
await activityLayerEditor.getByRole('button', { name: 'New Activity Layer' }).click(); | ||
const newLayerCount = await activityLayerEditor.locator('.timeline-layer-editor').count(); | ||
expect(newLayerCount - existingLayerCount).toEqual(1); | ||
|
||
// Expect an activity layer to be created by default | ||
expect(await page.locator('select[name="chartType"]').last().inputValue()).toBe('activity'); | ||
// Expect the activity layer to include all activities | ||
expect(await activityLayerEditor.locator('.timeline-layer-editor').first()).toHaveText('Activity Layer'); | ||
}); | ||
|
||
// Expect the filter list to open | ||
await page.getByPlaceholder('Search').last().click(); | ||
await expect(page.locator('.menu-slot > .header')).toBeDefined(); | ||
test('Edit an activity layer', async () => { | ||
const activityLayerEditor = page.getByLabel('Activity Layer-editor'); | ||
|
||
// Open the activity filter builder | ||
await activityLayerEditor | ||
.locator('.timeline-layer-editor') | ||
.first() | ||
.getByLabel('activity-filter-builder-trigger') | ||
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'm a little hesitant about using the label as a way to select the button in the test. Anyway this could be getting the button by text or role? |
||
.click(); | ||
|
||
// Expect that the modal is present | ||
const modal = activityLayerEditor.getByLabel('activity-filter-builder'); | ||
expect(modal).toBeDefined(); | ||
|
||
// Expect that layer name is showing in the name input | ||
expect(modal.locator('input[name="layer-name"]')).toHaveValue('Activity Layer'); | ||
|
||
// Expect that the resulting types list is not empty | ||
const resultingTypesList = modal.locator('.resulting-types-list'); | ||
const allActivityTypesCount = await resultingTypesList.locator('.activity-type-result').count(); | ||
expect(allActivityTypesCount).toBeGreaterThan(0); | ||
|
||
// Expect that manually selecting types cause the types to appear in the resulting types list | ||
await modal.locator("input[name='manual-types-filter-input']").click(); | ||
expect(await modal.locator('.manual-types-menu').first()).toBeDefined(); | ||
await modal.getByRole('menuitem', { name: 'ChangeProducer' }).click(); | ||
await modal.getByRole('menuitem', { name: 'ControllableDurationActivity' }).click(); | ||
await page.keyboard.press('Escape'); | ||
|
||
expect(await resultingTypesList.getByText('ChangeProducer')).toBeDefined(); | ||
expect(await resultingTypesList.getByText('ControllableDurationActivity')).toBeDefined(); | ||
|
||
// Expect that dynamic types can be added | ||
await modal.getByLabel('dynamic-types').getByRole('button', { name: 'Add Filter' }).click(); | ||
expect(await modal.getByLabel('dynamic-types').getByRole('listitem').count()).toBe(1); | ||
await modal.getByLabel('dynamic-types').getByRole('listitem').locator("input[name='filter-value']").fill('banana'); | ||
expect(await resultingTypesList.locator('.activity-type-result').count()).toEqual(11); | ||
|
||
// Expect that other filters can be added | ||
await modal.getByLabel('other-filters').getByRole('button', { name: 'Add Filter' }).click(); | ||
expect(await modal.getByLabel('other-filters').getByRole('listitem').count()).toBe(1); | ||
// Select parameter field | ||
await modal.getByLabel('other-filters').locator("select[aria-label='field']").selectOption('Parameter'); | ||
// Select specific parameter | ||
await modal.getByLabel('other-filters').getByText('Select Parameter').click(); | ||
await modal.getByLabel('other-filters').getByText('quantity (int)').click(); | ||
// Select operator | ||
await modal.getByLabel('other-filters').locator("select[aria-label='operator']").selectOption('equals'); | ||
// Fill filter value input | ||
await modal.getByLabel('other-filters').getByRole('listitem').locator("input[name='filter-value']").fill('10'); | ||
// Ensure that only one instance (PickBanana) is listed | ||
expect(await modal.getByText('1 instance')).toBeDefined(); | ||
|
||
// Expect that type subfilters can be added | ||
const activityResult = resultingTypesList.getByRole('listitem', { name: 'activity-type-result-PickBanana' }); | ||
await activityResult.getByRole('button', { name: 'Add Filter' }).click(); | ||
expect(await activityResult.getByRole('listitem').count()).toBe(1); | ||
// Select name field | ||
await activityResult.locator("select[aria-label='field']").selectOption('Name'); | ||
// Select operator | ||
await activityResult.locator("select[aria-label='operator']").selectOption('includes'); | ||
// Fill filter value input | ||
await activityResult.getByRole('listitem').locator("input[name='filter-value']").fill('foo'); | ||
// Ensure that only one instance (PickBanana) is listed | ||
expect(await modal.getByText('0 instances')).toBeDefined(); | ||
|
||
// Expect that type subfilters can be removed | ||
await activityResult.getByRole('button', { name: 'Remove filter' }).click(); | ||
expect(await modal.getByText('1 instance')).toBeDefined(); | ||
|
||
// Expect that other filters can be removed | ||
await modal.getByLabel('other-filters').getByRole('button', { name: 'Remove filter' }).click(); | ||
expect(await modal.getByText('2 instances')).toBeDefined(); | ||
|
||
// Expect that dynamic types can be removed | ||
await modal.getByLabel('dynamic-types').getByRole('button', { name: 'Remove filter' }).click(); | ||
expect(await resultingTypesList.locator('.activity-type-result').count()).toEqual(2); | ||
|
||
// Expect that manual types can be cleared | ||
await modal.locator("input[name='manual-types-filter-input']").click(); | ||
await modal.getByRole('menuitem', { name: 'ChangeProducer' }).click(); | ||
await page.keyboard.press('Escape'); | ||
await modal.getByRole('button', { name: 'Remove Types' }).click(); | ||
expect(await resultingTypesList.locator('.activity-type-result').count()).toEqual(allActivityTypesCount); | ||
|
||
// Give the layer a new name | ||
await modal.locator('input[name="layer-name"]').fill('Foo'); | ||
|
||
// Close the modal | ||
await modal.getByRole('button', { name: 'close' }).click(); | ||
|
||
// Expect name to match given name | ||
expect(await activityLayerEditor.locator('.timeline-layer-editor').first()).toHaveText('Foo'); | ||
}); | ||
|
||
// Add all activities | ||
await page.locator('button', { hasText: /Select [0-9]* activit/ }).click(); | ||
test('Change activity layer settings', async () => { | ||
const activityLayerEditor = await page.getByLabel('Activity Layer-editor'); | ||
|
||
// Expect to not see an activity tree group in this row | ||
expect(await page.locator('.timeline-row-wrapper', { hasText: rowName }).locator('.activity-tree').count()).toBe(0); | ||
|
@@ -141,9 +237,7 @@ test.describe.serial('Timeline View Editing', () => { | |
).toBe(1); | ||
|
||
// Delete an activity layer | ||
await page.getByRole('button', { name: 'Layer Settings' }).last().click(); | ||
await page.getByText('Delete Layer').click(); | ||
const finalLayerCount = await page.locator('.timeline-layer').count(); | ||
expect(finalLayerCount - newLayerCount).toEqual(-1); | ||
await activityLayerEditor.locator('.timeline-layer-editor').first().getByRole('button', { name: 'Delete' }).click(); | ||
expect(await activityLayerEditor.locator('.timeline-layer-editor').count()).toBe(0); | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
It's no longer possible to get this by role?