Skip to content

Commit d97ba47

Browse files
authored
add an "add" button when there are no secrets, also add wsh secret ui cli command (#2598)
1 parent 27b3df8 commit d97ba47

4 files changed

Lines changed: 93 additions & 10 deletions

File tree

cmd/wsh/cmd/wshcmd-secret.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ import (
99
"strings"
1010

1111
"github.com/spf13/cobra"
12+
"github.com/wavetermdev/waveterm/pkg/waveobj"
1213
"github.com/wavetermdev/waveterm/pkg/wshrpc"
1314
"github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient"
1415
)
1516

1617
// secretNameRegex must match the validation in pkg/wconfig/secretstore.go
1718
var secretNameRegex = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_]*$`)
1819

20+
var secretUiMagnified bool
21+
1922
var secretCmd = &cobra.Command{
2023
Use: "secret",
2124
Short: "manage secrets",
@@ -54,12 +57,22 @@ var secretDeleteCmd = &cobra.Command{
5457
PreRunE: preRunSetupRpcClient,
5558
}
5659

60+
var secretUiCmd = &cobra.Command{
61+
Use: "ui",
62+
Short: "open secrets UI",
63+
Args: cobra.NoArgs,
64+
RunE: secretUiRun,
65+
PreRunE: preRunSetupRpcClient,
66+
}
67+
5768
func init() {
69+
secretUiCmd.Flags().BoolVarP(&secretUiMagnified, "magnified", "m", false, "open secrets UI in magnified mode")
5870
rootCmd.AddCommand(secretCmd)
5971
secretCmd.AddCommand(secretGetCmd)
6072
secretCmd.AddCommand(secretSetCmd)
6173
secretCmd.AddCommand(secretListCmd)
6274
secretCmd.AddCommand(secretDeleteCmd)
75+
secretCmd.AddCommand(secretUiCmd)
6376
}
6477

6578
func secretGetRun(cmd *cobra.Command, args []string) (rtnErr error) {
@@ -156,4 +169,26 @@ func secretDeleteRun(cmd *cobra.Command, args []string) (rtnErr error) {
156169

157170
WriteStdout("secret deleted: %s\n", name)
158171
return nil
172+
}
173+
174+
func secretUiRun(cmd *cobra.Command, args []string) (rtnErr error) {
175+
defer func() {
176+
sendActivity("secret", rtnErr == nil)
177+
}()
178+
179+
wshCmd := &wshrpc.CommandCreateBlockData{
180+
BlockDef: &waveobj.BlockDef{
181+
Meta: map[string]interface{}{
182+
waveobj.MetaKey_View: "secretstore",
183+
},
184+
},
185+
Magnified: secretUiMagnified,
186+
Focused: true,
187+
}
188+
189+
_, err := RpcClient.SendRpcRequest(wshrpc.Command_CreateBlock, wshCmd, &wshrpc.RpcOpts{Timeout: 2000})
190+
if err != nil {
191+
return fmt.Errorf("opening secrets UI: %w", err)
192+
}
193+
return nil
159194
}

docs/docs/wsh-reference.mdx

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -342,19 +342,36 @@ This will connect to a WSL distribution on the local machine. It will use the de
342342
343343
## web
344344
345-
You can search for a given url using:
345+
The `web` command opens URLs in a web block within Wave Terminal.
346346
347347
```sh
348-
wsh web open [url]
348+
wsh web open [url] [-m] [-r blockid]
349349
```
350350
351-
Alternatively, you can search with the configured search engine using:
351+
You can open a specific URL or perform a search using the configured search engine.
352+
353+
Flags:
354+
355+
- `-m, --magnified` - open the web block in magnified mode
356+
- `-r, --replace <blockid>` - replace an existing block instead of creating a new one
357+
358+
Examples:
352359
353360
```sh
354-
wsh web open [search-query]
361+
# Open a URL
362+
wsh web open https://waveterm.dev
363+
364+
# Search with the configured search engine
365+
wsh web open "wave terminal documentation"
366+
367+
# Open in magnified mode
368+
wsh web open -m https://github.com
369+
370+
# Replace an existing block
371+
wsh web open -r 2 https://example.com
355372
```
356373
357-
Both of these commands will open a new web block with the desired page.
374+
The command will open a new web block with the desired page, or replace an existing block if the `-r` flag is used. Note that `--replace` and `--magnified` cannot be used together.
358375
359376
---
360377
@@ -978,6 +995,30 @@ wsh secret delete old_api_key
978995
wsh secret delete temp_token
979996
```
980997
998+
### ui
999+
1000+
```sh
1001+
wsh secret ui [-m]
1002+
```
1003+
1004+
Open the secrets management interface in a new block. This provides a graphical interface for viewing and managing all your secrets.
1005+
1006+
Flags:
1007+
1008+
- `-m, --magnified` - open the secrets UI in magnified mode
1009+
1010+
Examples:
1011+
1012+
```sh
1013+
# Open the secrets UI
1014+
wsh secret ui
1015+
1016+
# Open the secrets UI in magnified mode
1017+
wsh secret ui -m
1018+
```
1019+
1020+
The secrets UI provides a convenient visual way to browse, add, edit, and delete secrets without needing to use the command-line interface.
1021+
9811022
:::tip
9821023
Use secrets in your scripts to avoid hardcoding sensitive values. Secrets work across remote machines - store an API key locally with `wsh secret set`, then access it from any SSH or WSL connection with `wsh secret get`. The secret is securely retrieved from your local machine without needing to duplicate it on remote systems.
9831024
:::

frontend/app/view/secretstore/secretstore.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,19 @@ const LoadingSpinner = memo(({ message }: { message: string }) => {
3838
});
3939
LoadingSpinner.displayName = "LoadingSpinner";
4040

41-
const EmptyState = memo(() => {
41+
const EmptyState = memo(({ onAddSecret }: { onAddSecret: () => void }) => {
4242
return (
43-
<div className="flex flex-col items-center justify-center gap-3 py-12">
43+
<div className="flex flex-col items-center justify-center gap-4 py-12">
4444
<i className="fa-sharp fa-solid fa-key text-4xl text-gray-600" />
4545
<h3 className="text-lg font-semibold text-gray-400">No Secrets</h3>
4646
<p className="text-gray-500">Add a secret to get started</p>
47+
<button
48+
className="flex items-center gap-2 px-4 py-2 bg-accent-600 hover:bg-accent-500 rounded cursor-pointer transition-colors"
49+
onClick={onAddSecret}
50+
>
51+
<i className="fa-sharp fa-solid fa-plus" />
52+
<span className="font-medium">Add New Secret</span>
53+
</button>
4754
</div>
4855
);
4956
});
@@ -352,7 +359,7 @@ export const SecretStoreView = memo(({ model }: { blockId: string; model: Secret
352359
}
353360

354361
if (secretNames.length === 0) {
355-
return <EmptyState />;
362+
return <EmptyState onAddSecret={() => model.startAddingSecret()} />;
356363
}
357364

358365
return (

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)