-
Notifications
You must be signed in to change notification settings - Fork 23
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
feat(stark-ui): add support for click callbacks and row(s) selection to Table component #870
feat(stark-ui): add support for click callbacks and row(s) selection to Table component #870
Conversation
7bb032a
to
5742013
Compare
packages/stark-ui/src/modules/action-bar/components/action-bar.component.ts
Outdated
Show resolved
Hide resolved
} | ||
|
||
// If multi-select is enabled, select the row | ||
if (this.isMultiSelectEnabled) { |
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.
Previously, if the developer set an action on the row, we didn't select the row. It was the job of the dev if he wanted to select it... I think maybe it should stay as this, otherwise it will become really complex to understand what's happening when we click 😕
What do you think about this ?
@christophercr @dsebastien ? 😊
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 did do this, but I terminated the function if an event observer is found.
I could also do this with else if
if it is preferred.
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.
Indeed, I agree with @SuperITMan, we should keep the old behaviour, but as far as I can see it is already the case in this implementation right?
By the way, the rowsSelectable
input is missing in this component... it is there in the old Stark... so the row will be selected only if rowsSelectable
is enabled.
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.
Actually, to be honest, I didn't see the return
s :-p
Anyways, I prefer to have if
, else if
than return
. I find it more readable 😊
5742013
to
7e6b017
Compare
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.
Some remarks. Also it would be convenient to check whether we can rely a bit more on the SelectionModel
from the MaterialTable which we use in this variable:
public selection: SelectionModel<any> = new SelectionModel<any>(true, []);
so we can keep it in sync with our multiselect
input.
@@ -83,6 +83,10 @@ | |||
} | |||
} | |||
|
|||
tr:hover td { | |||
background: rgba(0, 0, 0, 0.05); |
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 think this rule should be in the _table-theme.scss
file. Normally as a convention we put all the styles about "themable" properties (i.e. colors that the developer can override) in those theme
files.
You can check other components where we have these "theme" files to see how you can get a color from the current theme ;)
@@ -38,7 +38,7 @@ | |||
|
|||
<div [ngClass]="{'fixed-header': isFixedHeaderEnabled}"> | |||
<table #matTable mat-table [dataSource]="dataSource" [ngClass]="{'multi-sorting': isMultiSorting}"> | |||
<ng-container *ngIf="isMultiSelectEnabled" matColumnDef="select"> | |||
<ng-container matColumnDef="select"> |
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.
Shouldn't the "select all" checkbox be visible only when the multiselect
option is enabled?
In fact, in the old Stark the "select" checkbox was shown in every row when the rows-selectable
input was enabled...
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 agree with you. If you multiSelect is not enabled, we shouldn't have the checkbox to select all...
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 added a check below to only render the header checkbox if the multiSelect is added, the showing of the other checkboxes is depends on the state of rowsSelectable
, but is controlled with the dispalyedColumns
field.
* If there are no observers it will not emit, but instead select the row. | ||
*/ | ||
@Output() | ||
public rowClick: EventEmitter<any> = new EventEmitter<any>(); |
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.
As a convention, the name of the outputs should be in past tense like "rowClicked"
* If there are no observers it will not emit, but instead select the row. | ||
*/ | ||
@Output() | ||
public rowClick: EventEmitter<any> = new EventEmitter<any>(); |
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 think this EventEmitter should emit the row object according to the API from the old Stark
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 does, doesn't it? 🤔
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.
Yes, I just meant the type of this property: "public rowClick: EventEmitter<object> = new EventEmitter<object>();"
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.
Ah ok, I understand. Should I also change the other types referring to the row?
if (this.isMultiSelectEnabled && this.displayedColumns) { | ||
if (changes["multiSelect"] && this.isMultiSelectEnabled) { | ||
if (!this.displayedColumns) { | ||
this.displayedColumns = []; |
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 think this block of code should not be here, it should be somewhere else but not here since this is only for checking changes on the "multiselect" input, otherwise out code will get very confusing and difficult to troubleshoot in case of errors. Moreover, the displayedColumns
property is already initialized in the property declaration.
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 changed the code in this block a bit, but there is still some logic about multiselect there. I could move it to a setter. But there would be some weird logic because it is a string treated as a boolean.
I'm watching for this issue but I doubt it will be picked up up anytime soon.
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.
Ah this is fine, I was referring to the fact that the displayedColumns
were initialized here as well, but you have changed this already 👍
} | ||
|
||
// If multi-select is enabled, select the row | ||
if (this.isMultiSelectEnabled) { |
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.
Indeed, I agree with @SuperITMan, we should keep the old behaviour, but as far as I can see it is already the case in this implementation right?
By the way, the rowsSelectable
input is missing in this component... it is there in the old Stark... so the row will be selected only if rowsSelectable
is enabled.
@@ -171,6 +171,13 @@ export class StarkTableComponent extends AbstractStarkUiComponent implements OnI | |||
@Output() | |||
public selectChanged: EventEmitter<number[]> = new EventEmitter<number[]>(); |
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 think this input is not used at all for now... but it should right? This should emit whenever a row is selected as in the old Stark (on-select
)
@@ -100,6 +100,9 @@ export class StarkActionBarComponent extends AbstractStarkUiComponent implements | |||
* Action onClick handler | |||
*/ | |||
public onClick(action: StarkAction, $event: Event): void { | |||
if ($event) { | |||
$event.stopPropagation(); |
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.
Can you add a comment here to explain why this is needed?
@@ -83,6 +83,10 @@ | |||
} | |||
} | |||
|
|||
tr:hover td { |
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.
We need to set a background in the selected rows as well. This is not only in the old Stark but also in the Material Design specs: https://material.io/design/components/data-tables.html#anatomy -> Row Checkbox
1d98688
to
45df506
Compare
ea4e0a4
to
c84cafd
Compare
this.displayedColumns = []; | ||
|
||
// Emit event when selection changes | ||
if (this.selection.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.
Is this check really needed? Normally this.selection
is initialized in its declaration and the "changes" observable should always be there right?
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.
Indeed, I don't remember why I did that. 🤔
} | ||
} | ||
|
||
if (changes["multiSelect"]) { | ||
this.selection = new SelectionModel<object>(this.isMultiSelectEnabled, []); |
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 think we might have a problem here: we re-assign the SelectionModel
here meaning that the subscription we did on the ngOnInit
will still be on the old SelectionModel
right?
You could extract the code to initialize the SelectionModel
and its subscription to a separate function which you can call on the ngOnInit
and here...
if (this.isMultiSelectEnabled && this.displayedColumns) { | ||
if (changes["multiSelect"] && this.isMultiSelectEnabled) { | ||
if (!this.displayedColumns) { | ||
this.displayedColumns = []; |
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.
Ah this is fine, I was referring to the fact that the displayedColumns
were initialized here as well, but you have changed this already 👍
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.
Small remarks
} | ||
|
||
public handleRowSelected(data: object[]): void { | ||
this.logger.debug(data); |
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.
Can you add an string before the data so we know in the console what this logging is about?
tr { | ||
&:hover td { | ||
background-color: mat-color($grey-palette, 400); | ||
color: mat-contrast($grey-palette, 400); |
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.
Can we set a lighter gray on hover? And also.. can we leave the color of the text unchanged?
Basically as it was in the old Stark and I think this is also what the Material Design guideline suggests...
if (this.selection.changed) { | ||
this._selectionSub = this.selection.changed.subscribe((change: SelectionChange<object>) => { | ||
const selected: object[] = change.source.selected; | ||
this.selectChanged.emit(selected); |
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.
Now that we use the SelectionModel
to handle the selection, the array we emit is an array of objects (rows) while in the old Stark it was an array of ids. So could you add this API change in the Confluence page please about Stark 9 vs Stark 10?
552961a
to
f298e3a
Compare
@christophercr I updated the PR. |
f298e3a
to
99b66f3
Compare
- added event emitter to handle a row click - set default row click to selecting the row - fixed selecting rows - fixed action buttons propagation - added hover styling to rows - added test for row click - added example to demo page - fixed issue with double scrollbar - fixed issue with extra padding - added demo for table with selection - added test for selection in table - changed type of rows from any to object ISSUES CLOSED: NationalBankBelgium#795
99b66f3
to
0182344
Compare
ISSUES CLOSED: #795 #880
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
Enable
(rowClick)
onTable
componentWhat is the current behavior?
Clicking on a row does nothing
Issue Number: #795 #880
What is the new behavior?
(rowClick)
emitter to handle a row click so that an observer can be passed to the emitter for custom behaviour.Does this PR introduce a breaking change?
Other information