From ab35f12556742e17f88c1fc8e7ad4270e82c1e15 Mon Sep 17 00:00:00 2001 From: Dhruv Thakur Date: Wed, 29 May 2024 17:41:04 +0200 Subject: [PATCH] fix: loss of items in filtered state Fixes a bug where the stack list would loose elements after a user fetched the status of a stack from a filtered state. This would happen because the stack reserve was configured to be replaced by the current list's items on receiving a `TemplateFetchedMsg` message. --- internal/ui/initial.go | 7 +++--- internal/ui/model.go | 2 +- internal/ui/types.go | 6 +++++ internal/ui/update.go | 52 ++++++++++++++++-------------------------- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/internal/ui/initial.go b/internal/ui/initial.go index 109637c..7742ede 100644 --- a/internal/ui/initial.go +++ b/internal/ui/initial.go @@ -8,10 +8,10 @@ import ( func InitialModel(stacks []Stack, awsCfgs map[string]AwsConfig, checkOnStart bool) model { stackItems := make([]list.Item, len(stacks)) - resultMap := make(map[int]stackResult) + stackReserve := make(map[string]Stack) for i, stack := range stacks { stackItems[i] = stack - resultMap[i] = stackResultUnchecked + stackReserve[stack.key()] = stack } var appDelegateKeys = newAppDelegateKeyMap() @@ -21,10 +21,9 @@ func InitialModel(stacks []Stack, awsCfgs map[string]AwsConfig, checkOnStart boo awsConfigs: awsCfgs, stacksList: list.New(stackItems, appDelegate, listWidth, 0), checkOnStart: checkOnStart, - resultMap: resultMap, showHelp: true, } - m.stacksListReserve = m.stacksList.Items() + m.stacksListReserve = stackReserve m.stacksList.Title = "Stacks" m.stacksList.SetStatusBarItemName("stack", "stacks") m.stacksList.DisableQuitKeybindings() diff --git a/internal/ui/model.go b/internal/ui/model.go index a0fafd4..d350ba7 100644 --- a/internal/ui/model.go +++ b/internal/ui/model.go @@ -39,7 +39,7 @@ type model struct { awsConfigs map[string]AwsConfig state stateView stacksList list.Model - stacksListReserve []list.Item + stacksListReserve map[string]Stack stacksFilter stackFilter resultMap map[int]stackResult checkOnStart bool diff --git a/internal/ui/types.go b/internal/ui/types.go index 61faa4b..2c7a368 100644 --- a/internal/ui/types.go +++ b/internal/ui/types.go @@ -37,9 +37,14 @@ type Stack struct { Err error } +func (stack Stack) key() string { + return fmt.Sprintf("%s:%s:%s", stack.AwsProfile, stack.AwsRegion, stack.Name) +} + func (stack Stack) Title() string { return fmt.Sprintf("%s", RightPadTrim(stack.Name, int(float64(listWidth)*0.8))) } + func (stack Stack) Description() string { var status string switch stack.FetchStatus { @@ -62,6 +67,7 @@ func (stack Stack) Description() string { } return fmt.Sprintf("@%s %s", RightPadTrim(desc, int(float64(listWidth)*0.6)), status) } + func (stack Stack) FilterValue() string { return stack.Name } type delegateKeyMap struct { diff --git a/internal/ui/update.go b/internal/ui/update.go index 8a7aef1..5a0f34d 100644 --- a/internal/ui/update.go +++ b/internal/ui/update.go @@ -28,7 +28,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if fs == list.Filtering || fs == list.FilterApplied { m.stacksList.ResetFilter() } else if m.stacksFilter != stacksFilterAll { - m.stacksList.SetItems(m.stacksListReserve) + var allItems []list.Item + for _, st := range m.stacksListReserve { + allItems = append(allItems, st) + } + m.stacksList.SetItems(allItems) m.stacksList.Title = "stacks" m.stacksFilter = stacksFilterAll m.stacksList.Styles.Title.Background(lipgloss.Color(stackListColor)) @@ -38,12 +42,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "o": if m.stacksFilter != stacksFilterOuttaSync { filteredItems := make([]list.Item, 0) - for _, item := range m.stacksListReserve { - stackItem, ok := item.(Stack) - if ok { - if stackItem.FetchStatus == StatusFetched && stackItem.OuttaSync { - filteredItems = append(filteredItems, item) - } + for _, st := range m.stacksListReserve { + if st.FetchStatus == StatusFetched && st.OuttaSync { + filteredItems = append(filteredItems, st) } } m.stacksList.SetItems(filteredItems) @@ -55,12 +56,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "i": if m.stacksFilter != stacksFilterInSync { filteredItems := make([]list.Item, 0) - for _, item := range m.stacksListReserve { - stackItem, ok := item.(Stack) - if ok { - if stackItem.FetchStatus == StatusFetched && !stackItem.OuttaSync { - filteredItems = append(filteredItems, item) - } + for _, st := range m.stacksListReserve { + if st.FetchStatus == StatusFetched && !st.OuttaSync { + filteredItems = append(filteredItems, st) } } m.stacksList.SetItems(filteredItems) @@ -71,12 +69,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "e": if m.stacksFilter != stacksFilterErr { filteredItems := make([]list.Item, 0) - for _, item := range m.stacksListReserve { - stackItem, ok := item.(Stack) - if ok { - if stackItem.Err != nil { - filteredItems = append(filteredItems, item) - } + for _, st := range m.stacksListReserve { + if st.Err != nil { + filteredItems = append(filteredItems, st) } } m.stacksList.SetItems(filteredItems) @@ -91,40 +86,33 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case CheckStackStatus: msg.stack.FetchStatus = StatusFetching m.stacksList.SetItem(msg.index, msg.stack) - m.stacksListReserve = m.stacksList.Items() + m.stacksListReserve[msg.stack.key()] = msg.stack return m, getCFTemplateBody(m.awsConfigs[GetAWSConfigKey(msg.stack)], msg.index, msg.stack) case TemplateFetchedMsg: if msg.err != nil { msg.stack.Err = msg.err msg.stack.FetchStatus = StatusFailure m.stacksList.SetItem(msg.index, msg.stack) - m.resultMap[msg.index] = stackResultErr } else { msg.stack.OuttaSync = true msg.stack.FetchStatus = StatusFetched msg.stack.OuttaSync = msg.outtaSync - switch msg.outtaSync { - case true: - m.resultMap[msg.index] = stackResultOuttaSync - case false: - m.resultMap[msg.index] = stackResultInSync - } msg.stack.Template = msg.template msg.stack.Err = nil m.stacksList.SetItem(msg.index, msg.stack) } + m.stacksListReserve[msg.stack.key()] = msg.stack // recompute outtasync and error numbers m.outtaSyncNum = 0 m.errorNum = 0 - for _, v := range m.resultMap { - if v == stackResultOuttaSync { - m.outtaSyncNum++ - } else if v == stackResultErr { + for _, st := range m.stacksListReserve { + if st.Err != nil { m.errorNum++ + } else if st.OuttaSync { + m.outtaSyncNum++ } } - m.stacksListReserve = m.stacksList.Items() case ShowFileFinished: if msg.err != nil { m.errorMessage = fmt.Sprintf("Error showing file: %s", Trim(msg.err.Error(), 50))