Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions kbncontent.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (v VisualizationDescriptor) findDocumentPathsAsString(paths []string) strin
m := objx.Map(v.Doc)

for _, path := range paths {
if m.Get(path).IsStr() {
if m.Get(path).IsStr() && m.Get(path).Str() != "" {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this change this seems to return the first path it founds, even if it is empty. There are cases where the first path is empty, but there are others with values.

return m.Get(path).Str()
}
}
Expand Down Expand Up @@ -137,6 +137,7 @@ func (v VisualizationDescriptor) HasFilters() (bool, error) {
queryPaths := []string{
"attributes.kibanaSavedObjectMeta.searchSourceJSON.query.query",
"attributes.state.query.query",
"embeddableConfig.attributes.mapStateJSON.query.query",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you also add the path embeddableConfig.attributes.mapStateJSON.filters?

Maps uses Kibana's unified search, which applies filtering from 2 locations. query captures the contents search bar while filters captures the contents of the filter bar. Both should be checked to know if a map panel applies a panel level filtering.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it in https://github.com/elastic/kbncontent/pull/5/files#diff-922b6d6bcd00ced7f244a57230a1075d65e42bae8fe3e8c8ac18ce9b82d03d9cR154.

The structure for queries and filters are different, so there are two different checks, each one with its own list of paths.

"embeddableConfig.attributes.state.query.query",
"embeddableConfig.savedVis.data.searchSource.query.query",
}
Expand All @@ -150,6 +151,7 @@ func (v VisualizationDescriptor) HasFilters() (bool, error) {
filterPaths := []string{
"attributes.state.filters",
"embeddableConfig.attributes.state.filters",
"embeddableConfig.attributes.mapStateJSON.filters",
"embeddableConfig.savedVis.data.searchSource.filter",
"attributes.kibanaSavedObjectMeta.searchSourceJSON.filter",
}
Expand Down Expand Up @@ -178,10 +180,6 @@ func (v VisualizationDescriptor) TSVBType() string {

// Title returns the visualization title
func (v VisualizationDescriptor) Title() string {
if v.SavedObjectType != "visualization" {
return ""
}

Comment on lines -181 to -184
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to return a title only for visualizations?

return v.findDocumentPathsAsString([]string{
"attributes.title",
"title",
Expand All @@ -191,9 +189,14 @@ func (v VisualizationDescriptor) Title() string {

func deserializeSubPaths(doc objx.Map) error {
jsonPaths := []string{
"attributes.kibanaSavedObjectMeta.searchSourceJSON",
"attributes.mapStateJSON",
"attributes.uiStateJSON",
"attributes.visState",
"attributes.kibanaSavedObjectMeta.searchSourceJSON",
"embeddableConfig.attributes.kibanaSavedObjectMeta.searchSourceJSON",
"embeddableConfig.attributes.mapStateJSON",
"embeddableConfig.attributes.uiStateJSON",
"embeddableConfig.attributes.visState",
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the paths with the embeddableConfig prefix. Actually in all the test cases these paths are prefixed with embeddableConfig, so not sure if we need the others 🤔

}
for _, fieldName := range jsonPaths {
field := doc.Get(fieldName)
Expand All @@ -207,6 +210,22 @@ func deserializeSubPaths(doc objx.Map) error {
doc.Set(fieldName, parsed)
}

jsonSlicePaths := []string{
"attributes.layerListJSON",
"embeddableConfig.attributes.layerListJSON",
Comment on lines +214 to +215
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

layerListJSON is an slice, and fails to be decoded with FromJSON, we need to use FromJSONSlice for them.

}
for _, fieldName := range jsonSlicePaths {
field := doc.Get(fieldName)
if !field.IsStr() {
continue
}
parsed, err := objx.FromJSONSlice(field.Str())
if err != nil {
return fmt.Errorf("failed to decode embedded json in %q: %w", fieldName, err)
}
doc.Set(fieldName, parsed)
}

/* these transformations from the original script facilitate the vis_tsvb_aggs and other TSVB-related runtime fields
TODO - implement these or convert the
vis_tsvb_aggs and any other necessary runtime fields to Go
Expand Down
7 changes: 4 additions & 3 deletions kbncontent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestDescribeByValueDashboardPanels(t *testing.T) {
}{
{title: "Legacy input control vis", editor: "Aggs-based", legacy: false, soType: "visualization", visType: "input_control_vis", tsvbType: "", makesQueries: true},
{title: "", editor: "Aggs-based", legacy: false, soType: "visualization", visType: "markdown", tsvbType: ""},
{title: "", editor: "Lens", legacy: false, soType: "lens", visType: "", tsvbType: "", makesQueries: true},
{title: "Lens bar", editor: "Lens", legacy: false, soType: "lens", visType: "", tsvbType: "", makesQueries: true},
{title: "Vega time series", editor: "Vega", legacy: false, soType: "visualization", visType: "vega", tsvbType: "", makesQueries: true},
{title: "", editor: "Maps", legacy: false, soType: "map", visType: "", tsvbType: "", makesQueries: true},
{title: "TSVB Markdown", editor: "TSVB", legacy: false, soType: "visualization", visType: "metrics", tsvbType: "markdown", makesQueries: true},
Expand All @@ -34,6 +34,8 @@ func TestDescribeByValueDashboardPanels(t *testing.T) {
{title: "Aggs-based tag cloud", editor: "Aggs-based", legacy: true, soType: "visualization", visType: "tagcloud", tsvbType: "", makesQueries: true},
{title: "", editor: "Aggs-based", legacy: true, soType: "visualization", visType: "heatmap", tsvbType: "", makesQueries: true},
{title: "Timelion time series", editor: "Timelion", legacy: true, soType: "visualization", visType: "timelion", tsvbType: "", makesQueries: true},
{title: "Unique IPs map", editor: "Maps", legacy: false, soType: "map", visType: "", tsvbType: "", makesQueries: true, hasFilters: true},
{title: "Unique IPs map encoded", editor: "Maps", legacy: false, soType: "map", visType: "", tsvbType: "", makesQueries: true, hasFilters: true},
}

content, err := ioutil.ReadFile("./testdata/dashboard.json")
Expand All @@ -48,12 +50,11 @@ func TestDescribeByValueDashboardPanels(t *testing.T) {
}

descriptions, err := DescribeByValueDashboardPanels(dashboard)

if err != nil {
t.Fatalf("Encountered error during subject execution: %v", err)
}

assert.Equal(t, len(descriptions), 15, "The number of panels should be correct")
assert.Equal(t, len(descriptions), 17, "The number of panels should be correct")
for i, desc := range descriptions {
title := desc.Title()
var editor string
Expand Down
Loading