github.com/oam-dev/kubevela@v1.9.11/references/cli/top/view/resource_view.go (about) 1 /* 2 Copyright 2022 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package view 18 19 import ( 20 "context" 21 "time" 22 23 "github.com/gdamore/tcell/v2" 24 "github.com/rivo/tview" 25 26 "github.com/oam-dev/kubevela/references/cli/top/component" 27 "github.com/oam-dev/kubevela/references/cli/top/model" 28 ) 29 30 const ( 31 // RefreshDelay is refresh delay 32 RefreshDelay = 10 33 resourceReqTimeout = 3 34 ) 35 36 // ResourceView is the interface to abstract resource view 37 type ResourceView interface { 38 model.View 39 InitView(ctx context.Context, app *App) 40 Refresh(event *tcell.EventKey) *tcell.EventKey 41 Update(timeoutCancel func()) 42 BuildHeader() 43 BuildBody() 44 } 45 46 // ResourceViewMap is a map from resource name to resource view 47 var ResourceViewMap = map[string]ResourceView{ 48 "app": new(ApplicationView), 49 "cluster": new(ClusterView), 50 "resource": new(ManagedResourceView), 51 "ns": new(NamespaceView), 52 "cns": new(ClusterNamespaceView), 53 "pod": new(PodView), 54 "container": new(ContainerView), 55 } 56 57 // CommonResourceView is an abstract of resource view 58 type CommonResourceView struct { 59 *component.Table 60 app *App 61 cancelFunc func() 62 } 63 64 // NewCommonView return a new common view 65 func NewCommonView(app *App) *CommonResourceView { 66 resourceView := &CommonResourceView{ 67 Table: component.NewTable(app.config.Theme), 68 app: app, 69 cancelFunc: func() {}, 70 } 71 return resourceView 72 } 73 74 // Init the common resource view 75 func (v *CommonResourceView) Init() { 76 v.Table.Init() 77 v.SetBorder(true) 78 v.SetTitleColor(v.app.config.Theme.Table.Title.Color()) 79 v.SetSelectable(true, false) 80 v.bindKeys() 81 v.app.SetFocus(v) 82 } 83 84 // Name return the name of common view 85 func (v *CommonResourceView) Name() string { 86 return "Resource" 87 } 88 89 // BuildHeader render the header of table 90 func (v *CommonResourceView) BuildHeader(header []string) { 91 for i := 0; i < len(header); i++ { 92 c := tview.NewTableCell(header[i]) 93 c.SetTextColor(v.app.config.Theme.Table.Header.Color()) 94 c.SetExpansion(3) 95 v.SetCell(0, i, c) 96 } 97 } 98 99 // BuildBody render the body of table 100 func (v *CommonResourceView) BuildBody(body [][]string) { 101 rowNum := len(body) 102 for i := 0; i < rowNum; i++ { 103 columnNum := len(body[i]) 104 for j := 0; j < columnNum; j++ { 105 c := tview.NewTableCell(body[i][j]) 106 c.SetTextColor(v.app.config.Theme.Table.Body.Color()) 107 c.SetExpansion(3) 108 v.SetCell(i+1, j, c) 109 } 110 } 111 } 112 113 // Stop the refresh goroutine and clear the table content 114 func (v *CommonResourceView) Stop() { 115 v.Table.Stop() 116 v.cancelFunc() 117 } 118 119 // Refresh the base resource view 120 func (v *CommonResourceView) Refresh(clear bool, update func(timeoutCancel func())) { 121 if clear { 122 v.Clear() 123 } 124 updateWithTimeout := func() { 125 ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*resourceReqTimeout) 126 defer cancelFunc() 127 go update(cancelFunc) 128 129 select { 130 case <-time.After(time.Second * resourceReqTimeout): // timeout 131 case <-ctx.Done(): // success 132 } 133 } 134 135 v.app.QueueUpdateDraw(updateWithTimeout) 136 } 137 138 // AutoRefresh will refresh the view in every RefreshDelay delay 139 func (v *CommonResourceView) AutoRefresh(update func(timeoutCancel func())) { 140 var ctx context.Context 141 ctx, v.cancelFunc = context.WithCancel(context.Background()) 142 go func() { 143 for { 144 time.Sleep(RefreshDelay * time.Second) 145 select { 146 case <-ctx.Done(): 147 return 148 default: 149 v.Refresh(true, update) 150 } 151 } 152 }() 153 } 154 155 func (v *CommonResourceView) bindKeys() { 156 v.Actions().Delete([]tcell.Key{tcell.KeyESC}) 157 v.Actions().Add(model.KeyActions{ 158 component.KeyQ: model.KeyAction{Description: "Back", Action: v.app.Back, Visible: true, Shared: true}, 159 component.KeyHelp: model.KeyAction{Description: "Help", Action: v.app.helpView, Visible: true, Shared: true}, 160 tcell.KeyCtrlT: model.KeyAction{Description: "Switch Theme", Action: v.app.SwitchTheme, Visible: true, Shared: true}, 161 }) 162 }