Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 214
Add endless-scrolling TUI table for interactive list commands#4729
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
e672906d7a71048b589d1b7ca3d8aa4cdb0dbd2241831b105229baa978e672078b56b796e614a3143a72a548b7943c526d4281953b3a6a537b4c0eeaaf150e5709b10ed23efcc7fb162ffe9d6aed878808d63e1a649f435ff16f2bf755a0ebe88c2e673d24ea9cc00ed4fe4fbc185c988e7674fbcf339dd967b28046f656da84d97baaf1a844046115767ea3c0f314ea8b262656e38294981680e269ea383662c5File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package alerts | ||
| import ( | ||
| "github.com/databricks/cli/libs/cmdio" | ||
| "github.com/databricks/cli/libs/tableview" | ||
| "github.com/databricks/databricks-sdk-go/service/sql" | ||
| "github.com/spf13/cobra" | ||
| ) | ||
| func listOverride(listCmd *cobra.Command, _ *sql.ListAlertsRequest) { | ||
| // Template is the text-mode fallback for non-interactive/piped output. | ||
| // TableConfig drives the interactive TUI when the terminal supports it. | ||
| listCmd.Annotations["template"] = cmdio.Heredoc(` | ||
| {{range .}}{{green "%s" .Id}} {{.DisplayName}} {{.State}} | ||
| {{end}}`) | ||
| columns := []tableview.ColumnDef{ | ||
| tableview.Col("ID", func(a sql.ListAlertsResponseAlert) string { return a.Id }), | ||
| tableview.Col("Name", func(a sql.ListAlertsResponseAlert) string { return a.DisplayName }), | ||
| tableview.Col("State", func(a sql.ListAlertsResponseAlert) string { return string(a.State) }), | ||
| } | ||
| tableview.SetTableConfigOnCmd(listCmd, &tableview.TableConfig{Columns: columns}) | ||
| } | ||
| func init() { | ||
| listOverrides = append(listOverrides, listOverride) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| package apps | ||
| import ( | ||
| "testing" | ||
| "github.com/databricks/cli/libs/tableview" | ||
| sdkapps "github.com/databricks/databricks-sdk-go/service/apps" | ||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
| func TestListTableConfig(t *testing.T) { | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why test here and not other commands? MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apps has nested pointer dereferences ( | ||
| cmd := newList() | ||
| cfg := tableview.GetTableConfigForCmd(cmd) | ||
| require.NotNil(t, cfg) | ||
| require.Len(t, cfg.Columns, 4) | ||
| tests := []struct { | ||
| name string | ||
| app sdkapps.App | ||
| wantName string | ||
| wantURL string | ||
| wantCompute string | ||
| wantDeploy string | ||
| }{ | ||
| { | ||
| name: "with nested fields", | ||
| app: sdkapps.App{ | ||
| Name: "test-app", | ||
| Url: "https://example.com", | ||
| ComputeStatus: &sdkapps.ComputeStatus{ | ||
| State: sdkapps.ComputeStateActive, | ||
| }, | ||
| ActiveDeployment: &sdkapps.AppDeployment{ | ||
| Status: &sdkapps.AppDeploymentStatus{ | ||
| State: sdkapps.AppDeploymentStateSucceeded, | ||
| }, | ||
| }, | ||
| }, | ||
| wantName: "test-app", | ||
| wantURL: "https://example.com", | ||
| wantCompute: "ACTIVE", | ||
| wantDeploy: "SUCCEEDED", | ||
| }, | ||
| { | ||
| name: "nil nested fields", | ||
| app: sdkapps.App{ | ||
| Name: "test-app", | ||
| Url: "https://example.com", | ||
| ActiveDeployment: &sdkapps.AppDeployment{}, | ||
| }, | ||
| wantName: "test-app", | ||
| wantURL: "https://example.com", | ||
| wantCompute: "", | ||
| wantDeploy: "", | ||
| }, | ||
| } | ||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| assert.Equal(t, tt.wantName, cfg.Columns[0].Extract(tt.app)) | ||
| assert.Equal(t, tt.wantURL, cfg.Columns[1].Extract(tt.app)) | ||
| assert.Equal(t, tt.wantCompute, cfg.Columns[2].Extract(tt.app)) | ||
| assert.Equal(t, tt.wantDeploy, cfg.Columns[3].Extract(tt.app)) | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| package jobs | ||
| import ( | ||
| "testing" | ||
| "github.com/databricks/cli/libs/tableview" | ||
| sdkjobs "github.com/databricks/databricks-sdk-go/service/jobs" | ||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
| func TestListTableConfig(t *testing.T) { | ||
| cmd := newList() | ||
| cfg := tableview.GetTableConfigForCmd(cmd) | ||
| require.NotNil(t, cfg) | ||
| require.Len(t, cfg.Columns, 2) | ||
| tests := []struct { | ||
| name string | ||
| job sdkjobs.BaseJob | ||
| wantID string | ||
| wantName string | ||
| }{ | ||
| { | ||
| name: "with settings", | ||
| job: sdkjobs.BaseJob{ | ||
| JobId: 123, | ||
| Settings: &sdkjobs.JobSettings{Name: "test-job"}, | ||
| }, | ||
| wantID: "123", | ||
| wantName: "test-job", | ||
| }, | ||
| { | ||
| name: "nil settings", | ||
| job: sdkjobs.BaseJob{ | ||
| JobId: 456, | ||
| }, | ||
| wantID: "456", | ||
| wantName: "", | ||
| }, | ||
| } | ||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| assert.Equal(t, tt.wantID, cfg.Columns[0].Extract(tt.job)) | ||
| assert.Equal(t, tt.wantName, cfg.Columns[1].Extract(tt.job)) | ||
| }) | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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.
Do we still need the template if we also use the tableview?
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, the template is the fallback for non-interactive output (piped,
--output text, non-TTY). The TUI only runs whenSupportsTUI()is true. Added a comment to all overrides clarifying this.