-
Notifications
You must be signed in to change notification settings - Fork 167
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
Labels editing and validation #3426
base: main
Are you sure you want to change the base?
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@yih-wang Haley please take a look as well, and let me know what you think |
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.
One quick comment from looking at the video - I will give a more thorough review when I get a chance
editableProps={{ | ||
'aria-label': 'Add label', | ||
defaultValue: '', | ||
'data-testid': 'add-label-input', | ||
}} |
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 way I understand the mockup, I don't think we want the "Add label" button to be an editable label itself. It can just be a button like before, but instead of its onClick
opening a modal, it should add a new label called "New label" via setUnsavedLabels()
. Then the user can click that label to edit 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.
+1 to @mturley.
@YuliaKrimerman here's a PF demo of how should the Add label
work: https://www.patternfly.org/components/label/#editable-label-group-with-add-button Hope it helps.
Thanks for the updates @YuliaKrimerman! My only comment is when handling duplicate label errors, the newly created label should be marked in red to indicate the error. From the video, it looks like the existing label is flagged instead. |
And one question to the loading time - from the video the newly added label takes a while to load after saving. Would this delay also occur in the production environment, or is it only in development environment? It’s a bit confusing to me before the label is loaded, so if this is expected in production, adding a loading state might help improve clarity. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3426 +/- ##
==========================================
+ Coverage 85.12% 85.75% +0.62%
==========================================
Files 1338 1347 +9
Lines 30127 30681 +554
Branches 8274 8547 +273
==========================================
+ Hits 25647 26310 +663
+ Misses 4480 4371 -109
... and 133 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
Thanks for the updates @YuliaKrimerman! All look good now! One thing that wasn’t part of the original design proposal but stood out to me as potentially confusing from the video - currently, after saving an edit, the label list keeps its original expanded/collapsed state. This means if the list was collapsed before editing, and the user enters the edit mode then saves any changes, the newly added label isn’t visible because the list stays collapsed. To avoid this potential confusion, it might be clearer to have the label list automatically expand after any edit is saved, regardless of its original collapsed/expanded state. Anyway it doesn't belong to the original scope of the issue, and I don't know how much work it needs, so not sure whether we should create a new story to improve this experience separately in a future sprint @mturley |
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.
@YuliaKrimerman can you add testing instructions in the "How has this been tested?" section of PR description?
modelVersionDetails.findAddLabelButton().click(); | ||
|
||
// Check label exists and is visible | ||
cy.findByTestId('editable-label-New Label').should('exist'); |
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 findLabel('New label')
be used instead ofeditable-label-New label
? I believe findLabel
was added for this?
cy.findByTestId('editable-label-New Label').click(); | ||
|
||
// Type the new label | ||
cy.get('input[data-testid="edit-label-input-New Label"]').should('exist'); |
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.
same applies here: modelVersionDetails.findLabelInput('New Label')
instead of 'input[data-testid="edit-label-input-New Label"]'
and the following 2-3 lines...
|
||
cy.findByTestId('editable-label-Testing label').click(); | ||
|
||
cy.get('input[data-testid="edit-label-input-Testing label"]') |
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.
same here
it('should handle label validation', () => { | ||
modelVersionDetails.findEditLabelsButton().click(); | ||
|
||
cy.findByTestId('editable-label-Testing label').click(); |
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.
use findLabelInput('Testing label')
instead
isSavingEdits={isSavingEdits} | ||
contentWhenEditing={ | ||
<DashboardDescriptionListGroup | ||
data-testid="editable-labels-group" |
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 test-id necessary? I don't see this test-id used anywhere.
<LabelGroup | ||
data-testid="label-group" | ||
data-testid="editable-label-group" |
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 don't see this testid used anywhere.
@@ -62,6 +64,7 @@ const ModelDetailsView: React.FC<ModelDetailsViewProps> = ({ | |||
) | |||
.then(refresh) | |||
} | |||
data-testid="model-labels" |
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 don't see this testid anywhere
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.
Hey @YuliaKrimerman, progress is looking great here but we need a bit of refactoring.
newText: string, | ||
currentLabel?: string, | ||
) => { | ||
const error = validateLabel(newText, currentLabel); |
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 I cause an error (e.g. add a duplicate label) and don't fix it, then add another label, the error disappears and submission is allowed even though there is still a problem. This is because we store errors in state and we can only have one at a time.
Errors don't need to be state here, they can be derived from the existing unsavedLabels
state on each render. I think instead of having the labelErrors
come from React.useState
, we can just have a const labelErrors
object that we compute as part of the rendering logic of the component. That way, simply the call to setUnsavedLabels
that puts us in an error state will cause errors to appear. That does mean a bit of refactoring, since you won't be validating a specific label anymore but validating the list of labels. This also means we may have multiple errors to display - if you have two sets of duplicate labels, you'll want to call them both out.
if (error) { | ||
setLabelErrors({ [newText]: error }); | ||
setUnsavedLabels((prev) => { | ||
const filtered = prev.filter((label) => label !== currentLabel); | ||
return [...filtered, newText]; | ||
}); | ||
} else if (newText) { | ||
setUnsavedLabels((prev) => { | ||
if (currentLabel) { | ||
return [...prev, newText]; | ||
} | ||
const filtered = prev.filter((label) => label !== currentLabel); | ||
return [...filtered, newText]; | ||
}); | ||
setLabelErrors({}); | ||
} | ||
}; |
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 not sure why the setUnsavedLabels
behavior is different if there's an error vs if there isn't. This may resolve itself if you move the validation from here to render time, but I'm pretty sure handleEditComplete
should update the unsaved labels state the same way no matter whether there is an error to show. I think this first call in your if (error)
case is correct:
setUnsavedLabels((prev) => {
const filtered = prev.filter((label) => label !== currentLabel);
return [...filtered, newText];
});
Your other case is making it so any time edit focus is lost, if the user didn't enter duplicate label text, the old label is not filtered out on update and we end up with another duplicate:
RHOAIENG-6994
RHOAIENG-6995
Description
[
Screen.Recording.2024-11-06.at.1.31.09.PM.mov
](url)
When going to model/version Detail, editing the labels are behaving as inline labels and also now have a validation for a case a new label already exists ( side not the background of the error message is red in paternfly )
How Has This Been Tested?
on the UI
Test Impact
Working on adding test while getting feedback on the implementation
Request review criteria:
Self checklist (all need to be checked):
If you have UI changes:
After the PR is posted & before it merges:
main