-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add Secrets view and deploy with Secrets to extension #2288
Conversation
6feea3a
to
0db4846
Compare
1a31ac8
to
40f4200
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 early feedback, happy to discuss or explain my observations. Thanks!
import { ActionButton } from "src/components/ActionToolbar.vue"; | ||
|
||
interface Props { | ||
name: string; |
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 have expected that this component would be a UI component that would accept its name and value through a prop and emit a change when the value changed. I would then have expected the view using this component to have to deal with the storage of the secret value.
While this approach will work, it makes this component extremely dedicated to this particular input vs. having a component that allows its value to be edited. I think we would benefit from having it be a bit more general purpose, especially when you think of using it for environment variables as well.
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 actually started writing it this way at the start, but found it more difficult to keep the home.secrets
Map in line with the value that was being v-model
ed in Secret.vue
instead I made it just reflect the state of home.secrets.get('name')
for the name
key provided
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 main difficulty when using v-model
was grabbing the most recent value when swapping over to the input mode. It worked great when setting the value, but not when the value changed out from under the component.
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.
Did you get a chance to play with the approach we discussed via zoom? That would be where outside component would pass in the map value from the store and then update the store when receiving the change emitted event from the component?
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 mess around with this, and it ended up re-creating the Map in the Secrets
component a bit as an array so each v-model
accessed an index in that array. It felt duplicative to me.
@@ -57,6 +60,32 @@ export const useHomeStore = defineStore("home", () => { | |||
}, | |||
); | |||
|
|||
watch( | |||
[selectedContentRecord, selectedConfiguration], |
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 was wondering about simplifying this into two different watches.
- on change of content record, remove all secrets.
- on change of config, set the secret from the values present and clear the ones that have gone away.
I've spent a few minutes making sure I understand what your implementation was doing and I think splitting it may avoid that for others in the future.
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 initially planned to do this as two separate watches due to the reason you stated, but I was worried about any timing issues that could have spawned from that. For example, some code somewhere could potentially change the content record first then the configuration, and code elsewhere does the opposite potentially leaving secrets in a different state.
Keeping it as I have it avoids that by ensuring secrets is in the correct state no matter if one or both change.
Let me know if I'm making a bad assumption though. I would like to simplify if possible.
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.
Let me know if I'm making a bad assumption though. I would like to simplify if possible.
Would the opposite order really end up not equaling the same outcome?
- Content-Record changes and then Configuration changes
- Content-Record change removes all secrets
- Configuration change has no secrets set, so it does nothing
- Configuration changes and then Content-Record changes
- Configuration change sets the secret from the values present and clears the ones that have gone away
- Content-Record change removes all secrets
In both cases, no secrets are set after both of these events.
Am I seeing this wrong?
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.
No I think you got it, let me play around with this split into two watches and see if I can break anything. Your logic is sound.
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 played around with this a bit, and it ended up being really close to a duplication for both watchers. If you have a code block suggestion we can take a look.
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 probably just missing something in my quick analysis, so I'll defer to yours. Let's go with what you've got working. Thanks for indulging me!
If the element is an input it should not have lower opacity Flex is necessary for the description to take up the remaining space, and behave similarly to the previous iteration of TreeItem
Do not show actions when editing the value
f2078cf
to
723dd4f
Compare
@@ -151,6 +155,7 @@ const toggleExpanded = () => { | |||
|
|||
.tree-item-label-container { | |||
flex: 1; | |||
display: flex; |
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.
Had to bring in flex for the label container so that the input in the description span
could be displayed the way we want. This required bringing down the
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
CSS for dealing with overflowing with ellipsis.
} | ||
|
||
.tree-item-description { | ||
line-height: 22px; |
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.
line-height
has returned. Now that we are using display: flex
here the span
is no longer being rendered the same way. Without this the height changes, and the description wasn't on the baseline.
font-size: 0.9em; | ||
margin-left: 0.5em; | ||
opacity: 0.7; |
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.
Since description
can contain an input
now we don't want the description to always be opacity: 0.7
. Now we apply this only if the description doesn't contain an input
(see below)
font-size: 0.9em; | ||
margin-left: 0.5em; | ||
opacity: 0.7; | ||
flex-shrink: 100000; |
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.
This retains the behavior we had before where the description would shrink before the title.
extensions/vscode/webviews/homeView/src/components/views/secrets/Secret.vue
Outdated
Show resolved
Hide resolved
{ | ||
label: "Clear Values for all Secrets", | ||
codicon: "codicon-clear-all", | ||
fn: () => { | ||
home.secrets.forEach((_, key) => { | ||
home.secrets.set(key, undefined); | ||
}); | ||
}, | ||
}, |
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 could optionally show this only if 1 or more secrets have values?
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 more I use this the more I want to do this, since the button moves if the count badge is showing or not.
::selection { | ||
background-color: rgba(195, 183, 184, 0.15); | ||
} |
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.
This preserves the input
selection color, and matches the highlight color across VS Code. This doesn't appear to be a variable, instead it is hardcoded which is interesting. I did check, it is consistent across themes.
@@ -57,6 +60,32 @@ export const useHomeStore = defineStore("home", () => { | |||
}, | |||
); | |||
|
|||
watch( | |||
[selectedContentRecord, selectedConfiguration], |
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 played around with this a bit, and it ended up being really close to a duplication for both watchers. If you have a code block suggestion we can take a look.
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.
Added a few responses, which I'll leave to your discretion. I'm approving it so you can determine where you do any followup.
This PR adds a new Secrets section to the Home view.
Some new features:
Preview
CleanShot.2024-09-19.at.16.43.00.mp4
Intent
Resolves #2252, #2257, #2258
Type of Change
Approach
The approach here was to expand previously made components, and create new ones (when necessary) to allow for the new model of "editing" a Tree Item description.
In this case editing the value of the Secret items.
Actions are used to edit and clear Secrets. Instead of clicking directly the action button is more clear, and avoids issues with duplicated click events when the input field is already up.
When editing a Secret value the action buttons are removed from the UI until editing is complete. This was done to avoid confusing the user and dealing with tricky cases like what clicking "edit" or "clear" should do while the input is open. It also provides more space for the input field which is horizontally constrained.
Directions for Reviewers
Ensure that Tree Item descriptions function and are styled as they previously were.
Ensure the new Tree Item with description input (the Secrets) function as expected.
Ensure that Secrets with values are sent up and are correct on the Connect Server. Secrets without values should remain the same across multiple re-deployments.