Add labels to CreatePipelineRun modal#699
Conversation
carlos-logro
left a comment
There was a problem hiding this comment.
Great PR Brandon! Most of my feedback are suggestions and minor changes you missed in the new test file.
| .toString(36) | ||
| .substring(2, 11) | ||
| valuePlaceholder: 'https://github.com', | ||
| id: 'annotation0' |
There was a problem hiding this comment.
as per Alan Green's comment on using index or array length for key value:
key should be a value derived from the data being rendered as react uses it to determine which elements need to be updated during the render cycle in response to data change, using the array index is not a good idea as it can lead to unexpected behaviour.
There was a problem hiding this comment.
Ok... it was this before
Math.random()
.toString(36)
.substr(2, 9);
so I'll update the id to this in the SecretsModal and CreatePipelineRun modal.
| annotations: [ | ||
| { | ||
| label: `tekton.dev/git-0`, | ||
| key: 'tekton.dev/git-0', |
There was a problem hiding this comment.
what's the difference between key & keyPlaceholder?
There was a problem hiding this comment.
The key, is the actual text that is in the "key" TextInput (the value prop), whereas the keyPlaceholder is the placeholder text in the "key" TextInput (the placeholder prop).
Do you think that these names are confusing/do you have an idea for an alternative name?
|
Thanks for the thorough feedback @carlos-logro & @AlanGreene 🙂 I have updated the code to addressed all of your comments.
@AlanGreene you make a good point about the remove behavior being a little unintuitive. Fortunately, since the KeyValueList is now a reusable component, it will be relatively easy to modify 😁 Since we already have this component in the Dashboard, would it be alright if we handle this redesign under a separate issue (separate from this PR)? I think that it could get messy redesigning the component under this PR, because this PR is primarily concerned with adding labels to the Create PipelineRun modal. |
|
Hey @ncskier, yes let's create an issue to make sure that's tracked and try to get to it soon. I'll take another looks at your changes this evening. |
| : 'removeIcon' | ||
| } | ||
| onClick={onRemove} | ||
| aria-label={`Remove Button. Removes ${legendText} entry.`} |
There was a problem hiding this comment.
same as above, would this be useful for all users?
There was a problem hiding this comment.
Sorry, I'm not sure what you mean by this. What would I do differently if it was useful or wasn't useful for all users?
There was a problem hiding this comment.
aria-label will only be read by screen readers or similar assistive technologies. If the text in this label is useful / intended for all users it should be a tooltip, an actual label, or some other visible element on the page.
There was a problem hiding this comment.
Ah, gotcha, thanks for clarifying. I personally don't think that the text will help users without screen readers. I think that the icons on the buttons are pretty self-explanatory.
| } | ||
|
|
||
| // Generates a unique id | ||
| export function generateId() { |
There was a problem hiding this comment.
If we need to guarantee uniqueness we should either use a UUID or add additional context to reduce likelihood of a conflict with other elements on the page that may be difficult to debug. Do we already have another value we could use instead? e.g. are the keys required to be unique already?
There was a problem hiding this comment.
Yes, it used the index in the list before, but I received this comment, so I changed it to the generateId() function.
There was a problem hiding this comment.
I'm a little confused about this, but I added a prefix for each id based on the item in the KeyValueList; for example:
id: generateId(`annotation${annotations.length}-`)Do you think this is alright?
| /> | ||
| </FormGroup> | ||
| )} | ||
| <FormGroup legendText=""> |
There was a problem hiding this comment.
should the legend text be applied to the FormGroup instead or can we remove the group here?
There was a problem hiding this comment.
The current style has the legend text inline with the Add & Remove buttons. We can't do this with a normal FormGroup legendText. So, instead, I'm using the styles that were in the SecretModal which make it look like a FormGroup's legendText.
c4a8681 to
eef6064
Compare
|
Thanks for the review @AlanGreene! I think that I've addressed all of your comments. Can you please take another look when you get the chance? |
| { legendText } | ||
| )} | ||
| /> | ||
| <Add |
There was a problem hiding this comment.
Sorry I didn't pick up on this in previous reviews, I didn't realise these were just icons and not buttons.
We should use Button components here with the icon prop set, this will ensure keyboard accessibility etc. works as expected. If you want to hide the button border and background you can set kind="ghost". See LabelFilter, LogoutButton, or Rerun for examples.
| defaultMessage: 'Labels' | ||
| })} | ||
| invalidText={intl.formatMessage( | ||
| { |
There was a problem hiding this comment.
We can't translate fragments of a sentence in isolation (e.g. 'kubernetes labels syntax'), it won't work for many languages.
Instead what we want is to add placeholders for the link markup so the sentence can be translated as a whole, with the correct context for each part.
Something like this:
'Labels must follow the {0}kubernetes labels syntax{1}.'
There was a problem hiding this comment.
@AlanGreene I don't think it lets me split up JSX tags like that:

(is this what you were suggesting?)
There was a problem hiding this comment.
ok looks like react-intl decided this was something people don't need, but there's still a way to get what we want. React's scarily named dangerouslySetInnerHTML to the rescue 😆 In this case it's safe as we fully control the content, there's no user data involved, we can consider the HTML content sanitised.
invalidText={
<span
dangerouslySetInnerHTML /* eslint-disable-line react/no-danger */={{
__html: intl.formatMessage(
{
id: 'dashboard.createPipelineRun.labels.invalidText',
defaultMessage:
'Labels must follow the {0}kubernetes labels syntax{1}.'
},
[
`<a
href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set"
target="_blank"
rel="noopener noreferrer"
>`,
'</a>'
]
)
}}
/>
}There was a problem hiding this comment.
Awesome, thanks Alan! I just made the change.
| "dashboard.errorBoundary.pageError": "Error loading page", | ||
| "dashboard.header.logOut": "Log out", | ||
| "dashboard.keyValueList.addButton.ariaLabel": "Add Button. Adds {legendText} entry.", | ||
| "dashboard.keyValueList.deleteButton.ariaLabel": "Delete Button#{index}. Deletes entire entry in current text field.", |
There was a problem hiding this comment.
I'm still struggling a bit with these strings.
'Delete Button#0', will this make sense to a user?
'current text field', how do I know which is the 'current' text field?
There was a problem hiding this comment.
You're right, those strings don't really make sense. Since there's already text on the screen for each of these elements, I'm going to remove the aria labels. Is that alright?
c0f29c4 to
1dc033c
Compare
Fixes tektoncd#323 This PR turns the Annotations component into a reusable KeyValueList component. This KeyValueList component is used to manage annotations in the SecretsModal, and it is used in the CreatePipelineRun modal to manage labels.
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: AlanGreene The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |



Changes
Fixes #323
This PR turns the Annotations component into a reusable KeyValueList
component. This KeyValueList component is used to manage annotations in
the SecretsModal, and it is used in the CreatePipelineRun modal to
manage labels.
Here's an image of the labels in the CreatePipelineRun modal (feedback is welcome 🙂):

/cc @AlanGreene
/cc @carlos-logro
Submitter Checklist
These are the criteria that every PR should meet, please check them off as you
review them:
See the contribution guide
for more details.