-
Notifications
You must be signed in to change notification settings - Fork 25
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
Fr/range select #113
Fr/range select #113
Conversation
@@ -59,7 +59,7 @@ Detailed API and example usage can be found in the sample application in tests/d | |||
| `Sub Attribute` | `activeSorting` | `array` | | Array that specifies the sort order. eg. [{"direction: "asc/desc", "value": <attr-name>}], This is an attribute on frost-list-expansion component.| | |||
| `Sub Attribute` | `properties` | `array` | | Array of sortable attributes. eg. [{"label: "foo", "value": "bar"}], This is an attribute on frost-sort component.| | |||
| `Sub Attribute` | `onSort` | `action closure` | | callback functions user provided to handle sorting. This is an attribute on frost-sort component.| | |||
| `Attribute` | `itemComparator` | `action closure` | | callback functions user provided to handle custom item comparisons.| |
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.
Technically this removal would be considered a breaking change - I'm going to let it slide this time because I'm confident this hasn't propagated far and you're likely the only one using it, but you should announce this removal on #frost-announcements
Please be careful in the future about choosing appropriate interfaces up front, even if the design phase takes longer
addon/components/frost-list.js
Outdated
@@ -134,6 +136,20 @@ export default Component.extend({ | |||
} | |||
}, | |||
|
|||
didReceiveAttrs () { |
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 would put this in the init
, not the receive, since there should be no expectation of your itemKey
changing
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 will update to reflect this.
addon/components/frost-list.js
Outdated
} | ||
} | ||
}, | ||
|
||
// == Computed Properties =================================================== | ||
|
||
@readOnly | ||
@computed('expandedItems.[]', 'items.[]', 'selectedItems.[]', 'itemComparator') | ||
@computed('expandedItems.[]', 'items.[]', 'selectedItems.[]', '_itemComparator') | ||
_items (expandedItems, items, selectedItems, itemComparator) { |
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.
Probably makes sense for your variable to match the source - i.e. _itemComparator
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 saw it was being done earlier so I decided I better copy the flow.
addon/components/frost-list.js
Outdated
@@ -167,19 +183,24 @@ export default Component.extend({ | |||
this.onExpansionChange(this.get('items')) | |||
}, | |||
|
|||
_onPaginationChange () { |
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.
What's the purpose of this?
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.
Originally I was going to write a action that fired on pagination change that would reset the anchors. I then realized the more I stared at the flow of the code, this cause extra complexity and I forgot to remove it before I moved onto a different route. Good catch though.
addon/utils/selection.js
Outdated
// Range select is always a positive selection (no deselect) | ||
rangeState['anchor'] = item | ||
|
||
// New anchor, clear any previous endpoint | ||
rangeState['endpoint'] = Ember.Object.create() | ||
|
||
// Add the anchor to the selected items | ||
selectedItems.pushObject(item) | ||
// Add the anchor to the selected items if not already in it from a previous page |
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.
The "previous page" comment has me wary - what scenario are you attempting to cover?
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.
In pagination, the way this code is set up, your anchors should be reset.
If you are on page 2, do some shift clicking.
Switch to page 1, do a shift click on a already selected item. You will add this item into selectedItems due to there was no check.
addon/utils/selection.js
Outdated
// If an anchor isn't set, then set the anchor and exit | ||
const rangeAnchor = rangeState['anchor'] | ||
if (isNone(rangeAnchor)) { |
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've checked the behaviour of the list selection prior to your last set of comparator changes and the behaviour is correct - what case are you addressing here that requires a change to the logic / flow?
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.
isNone works when you set items as null.
my itemComparator was getting lhs.get('key') === rhs.get('key') problems due to you can't .get on null items.
I removed setting items as null and set them to empty ember objects. If a .get fails on that, at least you get undefined.
addon/utils/selection.js
Outdated
if (isNone(rangeAnchor)) { | ||
|
||
const anchor = items.findIndex(currentItem => itemComparator(currentItem, rangeState['anchor'])) | ||
// If anchor is -1 then it was a anchor from a previous page that we can not find, so reset |
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'm very curious about this comment, can you elaborate on your scenario?
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.
Anchors are being set and assume the 'items' never changes.
When switching pages in pagination, the 20 items that were in 'items' are no longer present.
So looking for anchor in 20 'items' that no longer exist give you -1 in the new 20
'items'. In this case pagination requires you to reset anchors entirely.
addon/utils/selection.js
Outdated
|
||
const anchor = items.findIndex(currentItem => itemComparator(currentItem, rangeState['anchor'])) | ||
// If anchor is -1 then it was a anchor from a previous page that we can not find, so reset | ||
if (Ember.isEmpty(rangeAnchor) || anchor === -1) { |
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.
Destructure isEmpty
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.
Also, the anchor isn't an array, so isNone
should be more appropriate
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.
isNone is not good with the new item key.
itemComparators .get method does not work on null items.
isEmpty tests for empty ember objects based what I googled.
It's also passing all the tests in expected behavior so I believe its working as intended.
addon/utils/selection.js
Outdated
// Add the anchor to the selected items | ||
selectedItems.pushObject(item) | ||
// Add the anchor to the selected items if not already in it from a previous page | ||
if (!selectedItems.some(selectedItem => itemComparator(selectedItem, item))) { |
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.
Why are we assuming that a comparison needs to be done to check for uniqueness? Do you have duplicate objects/keys in your list?
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.
If you are on page 2 of pagination, switch back to page 1, your previous anchors are no longer valid.
Now that you are on page 1, if you shift select on item already selected, you will just throw it into 'selectedItems'. Since anchors are no longer valid you have no check to see if this item was already selected.
addon/utils/selection.js
Outdated
@@ -114,6 +116,14 @@ export default { | |||
} | |||
} | |||
|
|||
// Wipe out duplicates if range selection covered already selected items | |||
// e.g item2-3 already selected but shift click item0 through item5 happens |
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.
Again, this behaviour was working previously, what changed?
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.
Visually it works until you count 'selectedItems' growth and you notice duplicates are being sent in by default.
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 need clarification on what this PR is intended to accomplish and what broke the previously correct behaviour in prior PRs
Some bugs I noticed. First bug: Solution: Second bug: Solution: Third bug: Why was it growing?: Fourth bug(I introduced after resetting anchors based on pagination): Scenario 1, two pages, 10 items each page: Solution: Scenario 2, two pages, 10 items each page: Solution: My general opinion is selectedItems should be a map but I was looking to just keep things as they were with out doing major rewrites. |
Ok, so if I boil down the issues:
Is that a reasonable summary? |
Yes, that is what I noticed. |
Changes Unknown when pulling 030d36c on frosetti:fr/range_select into ** on ciena-frost:master**. |
Changes Unknown when pulling 2333966 on frosetti:fr/range_select into ** on ciena-frost:master**. |
1 similar comment
Changes Unknown when pulling 2333966 on frosetti:fr/range_select into ** on ciena-frost:master**. |
Changes Unknown when pulling d71a500 on frosetti:fr/range_select into ** on ciena-frost:master**. |
Updated
Page testing
This project uses semver, please check the scope of this pr:
CHANGELOG