diff --git a/cmd/query.go b/cmd/query.go index 245768c..a3fe4c4 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -41,11 +41,11 @@ var ( defaultEnd = "now" // save filter flags - saveFilterFlag = "save-as" - saveFilterShort = "s" + saveQueryFlag = "save-as" + saveQueryShort = "s" // save filter with time flags - saveFilterTimeFlag = "with-time" - saveFilterTimeShort = "w" + saveQueryTimeFlag = "with-time" + saveQueryTimeShort = "w" // interactiveFlag = "interactive" // interactiveFlagShort = "i" @@ -98,16 +98,16 @@ var query = &cobra.Command{ // return err // } - keepTime, err := command.Flags().GetBool(saveFilterTimeFlag) + keepTime, err := command.Flags().GetBool(saveQueryTimeFlag) if err != nil { return err } - filterName, err := command.Flags().GetString(saveFilterFlag) + savedQueryName, err := command.Flags().GetString(saveQueryFlag) if err != nil { return err } - filterNameTrimmed := strings.Trim(filterName, " ") + savedQueryNameTrimmed := strings.Trim(savedQueryName, " ") // TODO: Interactive Flag disabled // if interactive { @@ -120,20 +120,20 @@ var query = &cobra.Command{ // } // Checks if there is filter name which is not empty. Empty filter name wont be allowed - if command.Flags().Changed(saveFilterFlag) { - if filterName == "" || len(filterNameTrimmed) == 0 || filterName == "=" { + if command.Flags().Changed(saveQueryFlag) { + if savedQueryName == "" || len(savedQueryNameTrimmed) == 0 || savedQueryName == "=" { fmt.Println("please provide a filter name") command.Help() return nil - } else if filterName != "" { + } else if savedQueryName != "" { if keepTime { - createFilterWithTime(query, filterNameTrimmed, start, end) + createFilterWithTime(query, savedQueryNameTrimmed, start, end) } else { // if there is no keep time filter pass empty values for startTime and endTime - createFilter(query, filterNameTrimmed) + createFilter(query, savedQueryNameTrimmed) } } - } else if filterName == "" && keepTime { + } else if savedQueryName == "" && keepTime { fmt.Println("please provide a filter name") command.Help() return nil @@ -145,11 +145,11 @@ var query = &cobra.Command{ } var QueryCmd = func() *cobra.Command { - query.Flags().BoolP(saveFilterTimeFlag, saveFilterTimeShort, false, "Save the time range associated in the query to the filter") // save time for a filter flag; default value = false (boolean type) + query.Flags().BoolP(saveQueryTimeFlag, saveQueryTimeShort, false, "Save the time range associated in the query to the filter") // save time for a filter flag; default value = false (boolean type) // query.Flags().BoolP(interactiveFlag, interactiveFlagShort, false, "open the query result in interactive mode") query.Flags().StringP(startFlag, startFlagShort, defaultStart, "Start time for query. Takes date as '2024-10-12T07:20:50.52Z' or string like '10m', '1hr'") query.Flags().StringP(endFlag, endFlagShort, defaultEnd, "End time for query. Takes date as '2024-10-12T07:20:50.52Z' or 'now'") - query.Flags().StringP(saveFilterFlag, saveFilterShort, "", "Save a query filter") // save filter flag. Default value = FILTER_NAME (type string) + query.Flags().StringP(saveQueryFlag, saveQueryShort, "", "Save a query filter") // save filter flag. Default value = FILTER_NAME (type string) return query }() diff --git a/cmd/filterlist.go b/cmd/queryList.go similarity index 79% rename from cmd/filterlist.go rename to cmd/queryList.go index 2f686c2..7bff80c 100644 --- a/cmd/filterlist.go +++ b/cmd/queryList.go @@ -25,38 +25,38 @@ import ( "github.com/spf13/cobra" ) -var FilterList = &cobra.Command{ +var SavedQueryList = &cobra.Command{ Use: "list", Example: "pb query list ", - Short: "List of saved filters", - Long: "\nShow the list of saved filters for current user", + Short: "List of saved queries", + Long: "\nShow the list of saved quries for active user", PreRunE: PreRunDefaultProfile, Run: func(_ *cobra.Command, _ []string) { client := DefaultClient() - p := model.UIApp() + p := model.SavedQueriesMenu() if _, err := p.Run(); err != nil { os.Exit(1) } - a := model.FilterToApply() - d := model.FilterToDelete() + a := model.QueryToApply() + d := model.QueryToDelete() if a.Stream() != "" { - filterToPbQuery(a.Stream(), a.StartTime(), a.EndTime()) + savedQueryToPbQuery(a.Stream(), a.StartTime(), a.EndTime()) } - if d.FilterID() != "" { - deleteFilter(&client, d.FilterID(), d.Title()) + if d.SavedQueryID() != "" { + deleteSavedQuery(&client, d.SavedQueryID(), d.Title()) } }, } -// Delete a saved filter from the list of filter -func deleteFilter(client *HTTPClient, filterID, title string) { +// Delete a saved query from the list. +func deleteSavedQuery(client *HTTPClient, savedQueryID, title string) { fmt.Printf("\nAttempting to delete '%s'", title) - deleteURL := `filters/filter/` + filterID + deleteURL := `filters/filter/` + savedQueryID req, err := client.NewRequest("DELETE", deleteURL, nil) if err != nil { - fmt.Println("Failed to delete the filter with error: ", err) + fmt.Println("Failed to delete the saved query with error: ", err) } resp, err := client.client.Do(req) @@ -66,12 +66,12 @@ func deleteFilter(client *HTTPClient, filterID, title string) { defer resp.Body.Close() if resp.StatusCode == 200 { - fmt.Printf("\nFilter deleted\n\n") + fmt.Printf("\nSaved Query deleted\n\n") } } -// Convert a filter to executable pb query -func filterToPbQuery(query string, start string, end string) { +// Convert a saved query to executable pb query +func savedQueryToPbQuery(query string, start string, end string) { var timeStamps string if start == "" || end == "" { timeStamps = `` diff --git a/main.go b/main.go index e356167..7237226 100644 --- a/main.go +++ b/main.go @@ -113,7 +113,7 @@ func main() { stream.AddCommand(cmd.StatStreamCmd) query.AddCommand(cmd.QueryCmd) - query.AddCommand(cmd.FilterList) + query.AddCommand(cmd.SavedQueryList) cli.AddCommand(profile) cli.AddCommand(query) diff --git a/pkg/model/savedfilters.go b/pkg/model/savedQueries.go similarity index 66% rename from pkg/model/savedfilters.go rename to pkg/model/savedQueries.go index d498381..c5e757c 100644 --- a/pkg/model/savedfilters.go +++ b/pkg/model/savedQueries.go @@ -20,10 +20,11 @@ import ( "fmt" "io" "net/http" - "pb/pkg/config" "strings" "time" + "pb/pkg/config" + "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" @@ -31,27 +32,27 @@ import ( ) const ( - applyFilterButton = "a" - deleteFilterButton = "d" - confirmDelete = "y" - cancelDelete = "n" + applyQueryButton = "a" + deleteQueryButton = "d" + confirmDelete = "y" + cancelDelete = "n" ) var ( - docStyle = lipgloss.NewStyle().Margin(1, 2) - deleteFilterState = false + docStyle = lipgloss.NewStyle().Margin(1, 2) + deleteSavedQueryState = false ) -// FilterDetails represents the structure of filter data +// FilterDetails represents the struct of filter data fetched from the server type FilterDetails struct { - FilterID string `json:"filter_id"` - FilterName string `json:"filter_name"` - StreamName string `json:"stream_name"` - QueryField map[string]interface{} `json:"query"` - TimeFilter map[string]interface{} `json:"time_filter"` + SavedQueryID string `json:"filter_id"` + SavedQueryName string `json:"filter_name"` + StreamName string `json:"stream_name"` + QueryField map[string]interface{} `json:"query"` + TimeFilter map[string]interface{} `json:"time_filter"` } -// Item represents the structure of the filter item +// Item represents the struct of the saved query item type Item struct { id, title, stream, desc, from, to string } @@ -95,7 +96,7 @@ func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list } func (d itemDelegate) ShortHelp() []key.Binding { - if deleteFilterState { + if deleteSavedQueryState { return []key.Binding{ key.NewBinding( key.WithKeys(confirmDelete), @@ -109,12 +110,12 @@ func (d itemDelegate) ShortHelp() []key.Binding { } return []key.Binding{ key.NewBinding( - key.WithKeys(applyFilterButton), - key.WithHelp(applyFilterButton, "apply"), + key.WithKeys(applyQueryButton), + key.WithHelp(applyQueryButton, "apply"), ), key.NewBinding( - key.WithKeys(deleteFilterButton), - key.WithHelp(deleteFilterButton, "delete"), + key.WithKeys(deleteQueryButton), + key.WithHelp(deleteQueryButton, "delete"), ), } } @@ -124,23 +125,23 @@ func (d itemDelegate) FullHelp() [][]key.Binding { return [][]key.Binding{ { key.NewBinding( - key.WithKeys(applyFilterButton), - key.WithHelp(applyFilterButton, "apply"), + key.WithKeys(applyQueryButton), + key.WithHelp(applyQueryButton, "apply"), ), key.NewBinding( - key.WithKeys(deleteFilterButton), - key.WithHelp(deleteFilterButton, "delete"), + key.WithKeys(deleteQueryButton), + key.WithHelp(deleteQueryButton, "delete"), ), }, } } var ( - selectedFilterApply Item - selectedFilterDelete Item + selectedQueryApply Item + selectedQueryDelete Item ) -func (i Item) Title() string { return fmt.Sprintf("Filter:%s, Query:%s", i.title, i.desc) } +func (i Item) Title() string { return fmt.Sprintf("Title:%s, Query:%s", i.title, i.desc) } func (i Item) Description() string { if i.to == "" || i.from == "" { @@ -149,43 +150,43 @@ func (i Item) Description() string { return fmt.Sprintf("From:%s To:%s", i.from, i.to) } -func (i Item) FilterValue() string { return i.title } -func (i Item) FilterID() string { return i.id } -func (i Item) Stream() string { return i.desc } -func (i Item) StartTime() string { return i.from } -func (i Item) EndTime() string { return i.to } +func (i Item) FilterValue() string { return i.title } +func (i Item) SavedQueryID() string { return i.id } +func (i Item) Stream() string { return i.desc } +func (i Item) StartTime() string { return i.from } +func (i Item) EndTime() string { return i.to } -type modelFilter struct { +type modelSavedQueries struct { list list.Model } -func (m modelFilter) Init() tea.Cmd { +func (m modelSavedQueries) Init() tea.Cmd { return nil } -func (m modelFilter) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: if msg.String() == "ctrl+c" { return m, tea.Quit } if msg.String() == "a" || msg.Type == tea.KeyEnter { - selectedFilterApply = m.list.SelectedItem().(Item) + selectedQueryApply = m.list.SelectedItem().(Item) return m, tea.Quit } if msg.String() == "d" { - deleteFilterState = true + deleteSavedQueryState = true return m, nil } if msg.String() != "d" { - deleteFilterState = false + deleteSavedQueryState = false } if msg.String() == "y" { - selectedFilterDelete = m.list.SelectedItem().(Item) + selectedQueryDelete = m.list.SelectedItem().(Item) return m, tea.Quit } if msg.String() == "n" { - deleteFilterState = false + deleteSavedQueryState = false return m, nil } case tea.WindowSizeMsg: @@ -198,12 +199,12 @@ func (m modelFilter) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, cmd } -func (m modelFilter) View() string { +func (m modelSavedQueries) View() string { return docStyle.Render(m.list.View()) } -// UIApp lists interactive list for the user to display all the available filters (only saved SQL filters ) -func UIApp() *tea.Program { +// SavedQueriesMenu is a TUI which lists all available saved queries for the active user (only SQL queries ) +func SavedQueriesMenu() *tea.Program { userConfig, err := config.ReadConfigFromFile() if err != nil { fmt.Println("Error reading Default Profile") @@ -216,15 +217,15 @@ func UIApp() *tea.Program { client := &http.Client{ Timeout: time.Second * 60, } - userFilters := fetchFilters(client, &userProfile) + userSavedQueries := fetchFilters(client, &userProfile) - m := modelFilter{list: list.New(userFilters, itemDelegate{}, 0, 0)} - m.list.Title = fmt.Sprintf("Saved Filters for User: %s", userProfile.Username) + m := modelSavedQueries{list: list.New(userSavedQueries, itemDelegate{}, 0, 0)} + m.list.Title = fmt.Sprintf("Saved Queries for User: %s", userProfile.Username) return tea.NewProgram(m, tea.WithAltScreen()) } -// fetchFilters fetches filters from the server and sends them to the channel +// fetchFilters fetches saved SQL queries for the active user from the server func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { endpoint := fmt.Sprintf("%s/%s/%s", profile.URL, "api/v1/filters", profile.Username) req, err := http.NewRequest("GET", endpoint, nil) @@ -256,9 +257,9 @@ func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { } // This returns only the SQL type filters - var userFilters []list.Item + var userSavedQueries []list.Item for _, filter := range filters { - var userFilter Item + var userSavedQuery Item queryBytes, _ := json.Marshal(filter.QueryField["filter_query"]) // Extract "from" and "to" from time_filter @@ -269,28 +270,28 @@ func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { if toValue, exists := filter.TimeFilter["to"]; exists { to = fmt.Sprintf("%v", toValue) } - // filtering only SQL type filters Filter_name is tile and Stream Name is desc + // filtering only SQL type filters.. **Filter_name is title and Stream Name is desc if string(queryBytes) != "null" { - userFilter = Item{ - id: filter.FilterID, - title: filter.FilterName, + userSavedQuery = Item{ + id: filter.SavedQueryID, + title: filter.SavedQueryName, stream: filter.StreamName, desc: string(queryBytes), from: from, to: to, } - userFilters = append(userFilters, userFilter) + userSavedQueries = append(userSavedQueries, userSavedQuery) } } - return userFilters + return userSavedQueries } -// FilterToApply returns the selected filter by user in the interactive list to apply -func FilterToApply() Item { - return selectedFilterApply +// QueryToApply returns the selected saved query by user in the interactive list to apply +func QueryToApply() Item { + return selectedQueryApply } -// FilterToDelete returns the selected filter by user in the interactive list to delete -func FilterToDelete() Item { - return selectedFilterDelete +// QueryToDelete returns the selected saved query by user in the interactive list to delete +func QueryToDelete() Item { + return selectedQueryDelete }