Dashboards & Visualizations

3.x-style list of saved searches on dashboard - followup

Jason
Motivator

I have been working on the list of saved searches for a client. Based on some suggestions on here, the best I can get is a one-column paginated list of searches, but there are still two problems:

  • BIG issue: ALL searches open in flashtimeline, not the view they are supposed to open in!
  • Whenever you click on one of the pagination buttons, it works, but a red error bar appears:

PARSER: Applying intentions failed Error in 'savedsearch' command: Unable to find saved search named 'null'.

How do I fix these? Code is below. It's meant to be pasted just before the final </view> in the default search app dashboard.

<module name="StaticContentSample" layoutPanel="panel_row3_col1" group="Saved Searches">
    <param name="text">This lists all of the saved searches you have created and/or have access to see. <![CDATA[<a href="https://answers.splunk.commanager/search/saved/searches">Edit saved searches</a>]]> via Manager.</param>
</module>

<!-- The first list of sources -->
<module name="HiddenSearch" layoutPanel="panel_row3_col1_grp1" autoRun="true">
    <param name="search">| head 1</param>
    <param name="maxCount">100000</param>
    <module name="SimpleResultsHeader">
        <param name="entityName">results</param>
        <param name="headerFormat">Saved Searches</param>
    </module>
</module>
<module name="Sorter" layoutPanel="panel_row3_col1_grp1">
    <param name="sortKey">name</param>
    <param name="sortDir">asc</param>
    <param name="fields">
        <list>
            <param name="label">Name</param>
            <param name="value">name</param>
        </list>
    </param>
    <module name="Paginator">
        <param name="count">15</param>
        <param name="entityName">settings</param>
        <param name="maxPages">10</param>
        <module name="EntityLinkLister">
            <param name="count">15</param>
            <param name="entityPath">saved/searches</param>
            <param name="settingToCreate">list4</param>
            <param name="entityFieldsToDisplay">
                <list>
                    <param name="label">name</param>
                    <param name="value">name</param>
                </list>
            </param>


            <module name="HiddenSearch" >
                <param name="search">| savedsearch "$savedSearch$"</param>
                <module name="ConvertToIntention">
                    <param name="intention">
                        <param name="name">stringreplace</param>
                        <param name="arg">
                            <param name="savedSearch">
                                <param name="fillOnEmpty">True</param>
                                <param name="value">$list4$</param>
                            </param>
                        </param>
                    </param>
                    <module name="ViewRedirector">
                        <param name="viewTarget">flashtimeline</param>
                    </module>
                </module>
            </module>
        </module>
    </module>
</module>
Tags (2)
1 Solution

Jason
Motivator

Here's the answer I got when following up with Nick:

"The simplest way to end up with nice @go url's was to use a trick I've been using in custom app development, where I just put a NullModule in a view, and in that view I then redefine NullModule to have some specific behavior that I want."


Here are the snippets of code to make it work. Move etc/apps/search/default/data/ui/views/dashboard.xml to etc/apps/search/local/ui/views/ and add the following before the final . If you use this in another app, you must change search to reflect the name of your app.

<!-- begin addition -->
<!--
    saved search panel
-->

<module name="StaticContentSample" layoutPanel="panel_row3_col1" group="Saved Searches">
    <param name="text">
        This lists all of the saved searches you have created and/or have access to see. <a href="https://answers.splunk.commanager/search/saved/searches">Edit saved searches</a> via Manager.
    </param>
</module>

<!-- The first list of searches - Search View -->

<module name="GenericHeader" layoutPanel="panel_row3_col1">
    <param name="label">Open in Search View</param>
</module>

<module name="Sorter" layoutPanel="panel_row3_col1_grp1">
    <param name="sortKey">name</param>
    <param name="sortDir">asc</param>

    <param name="fields">
        <list>
            <param name="label">Name</param>
            <param name="value">name</param>
        </list>
    </param>
    <module name="Paginator">
        <param name="count">15</param>
        <param name="entityName">settings</param>
        <param name="maxPages">10</param>
        <module name="EntityLinkLister">
            <param name="count">15</param>
            <param name="entityPath">/saved/searches</param>
            <param name="namespace">search</param>
            <param name="settingToCreate">savedSearchName</param>
            <param name="entityFieldsToDisplay">
                <list>
                    <param name="label">name</param>
                    <param name="value">name</param>
                </list>
            </param>

            <!--
                Instead of the normal stack of HiddenSearch + 
                ConvertToIntention + ViewRedirector, which cant do what we want, 
                we instead place a NullModule and then we customize it to do 
                exactly what we want. See application.js
            -->
            <module name="NullModule"/>
        </module>
    </module>
</module>

The other snippet must be added to etc/apps/search/appserver/static/application.js. This snippet will be the entire file if it does not yet exist. Replace case "dashboard" : with the name of your view, if you are not adding to dashboard.xml.

switch (Splunk.util.getCurrentView()) {
    case "dashboard" :
        // PATCH 1 
        //   -- the entityLinkLister does not stop framework pushes. 

        if (Splunk.Module.EntityLinkLister) {
            Splunk.Module.EntityLinkLister= $.klass(Splunk.Module.EntityLinkLister, {
                onUserAction: function($super, event) {
                    $super(event);
                    this.pushContextToChildren(null, true);
                },
                pushContextToChildren: function($super, explicitContext, simonSays) {
                    if (!this.isPageLoadComplete || simonSays) {
                        $super(explicitContext);
                    }
                }

            });
        }
        // PATCH 2 - Neither ViewRedirector nor anyone else 
        // allows you to redirect a saved search link such that 
        // the displayView and the timerange are set correctly. 
        if (Splunk.Module.NullModule) {
            Splunk.Module.NullModule= $.klass(Splunk.Module.NullModule, {
                onContextChange: function() {
                    var context = this.getContext();
                    var savedSearchName = context.get("savedSearchName");
                    Splunk.util.redirect_to("/app/" + Splunk.util.getCurrentApp() + "/@go?s=" + encodeURIComponent(savedSearchName));
                }
            });
        }
        break;
}

View solution in original post

wwhitener
Communicator

Just out of curiosity--we are trying to get the flash timelines to reappear in 4.2.2.....what appears to be the reverse of what you are doing. Any idea what you might have done to turn it on and off?

0 Karma

Jason
Motivator

Here's the answer I got when following up with Nick:

"The simplest way to end up with nice @go url's was to use a trick I've been using in custom app development, where I just put a NullModule in a view, and in that view I then redefine NullModule to have some specific behavior that I want."


Here are the snippets of code to make it work. Move etc/apps/search/default/data/ui/views/dashboard.xml to etc/apps/search/local/ui/views/ and add the following before the final . If you use this in another app, you must change search to reflect the name of your app.

<!-- begin addition -->
<!--
    saved search panel
-->

<module name="StaticContentSample" layoutPanel="panel_row3_col1" group="Saved Searches">
    <param name="text">
        This lists all of the saved searches you have created and/or have access to see. <a href="https://answers.splunk.commanager/search/saved/searches">Edit saved searches</a> via Manager.
    </param>
</module>

<!-- The first list of searches - Search View -->

<module name="GenericHeader" layoutPanel="panel_row3_col1">
    <param name="label">Open in Search View</param>
</module>

<module name="Sorter" layoutPanel="panel_row3_col1_grp1">
    <param name="sortKey">name</param>
    <param name="sortDir">asc</param>

    <param name="fields">
        <list>
            <param name="label">Name</param>
            <param name="value">name</param>
        </list>
    </param>
    <module name="Paginator">
        <param name="count">15</param>
        <param name="entityName">settings</param>
        <param name="maxPages">10</param>
        <module name="EntityLinkLister">
            <param name="count">15</param>
            <param name="entityPath">/saved/searches</param>
            <param name="namespace">search</param>
            <param name="settingToCreate">savedSearchName</param>
            <param name="entityFieldsToDisplay">
                <list>
                    <param name="label">name</param>
                    <param name="value">name</param>
                </list>
            </param>

            <!--
                Instead of the normal stack of HiddenSearch + 
                ConvertToIntention + ViewRedirector, which cant do what we want, 
                we instead place a NullModule and then we customize it to do 
                exactly what we want. See application.js
            -->
            <module name="NullModule"/>
        </module>
    </module>
</module>

The other snippet must be added to etc/apps/search/appserver/static/application.js. This snippet will be the entire file if it does not yet exist. Replace case "dashboard" : with the name of your view, if you are not adding to dashboard.xml.

switch (Splunk.util.getCurrentView()) {
    case "dashboard" :
        // PATCH 1 
        //   -- the entityLinkLister does not stop framework pushes. 

        if (Splunk.Module.EntityLinkLister) {
            Splunk.Module.EntityLinkLister= $.klass(Splunk.Module.EntityLinkLister, {
                onUserAction: function($super, event) {
                    $super(event);
                    this.pushContextToChildren(null, true);
                },
                pushContextToChildren: function($super, explicitContext, simonSays) {
                    if (!this.isPageLoadComplete || simonSays) {
                        $super(explicitContext);
                    }
                }

            });
        }
        // PATCH 2 - Neither ViewRedirector nor anyone else 
        // allows you to redirect a saved search link such that 
        // the displayView and the timerange are set correctly. 
        if (Splunk.Module.NullModule) {
            Splunk.Module.NullModule= $.klass(Splunk.Module.NullModule, {
                onContextChange: function() {
                    var context = this.getContext();
                    var savedSearchName = context.get("savedSearchName");
                    Splunk.util.redirect_to("/app/" + Splunk.util.getCurrentApp() + "/@go?s=" + encodeURIComponent(savedSearchName));
                }
            });
        }
        break;
}

sideview
SplunkTrust
SplunkTrust

1) Regarding the view that it goes to -- you want the links to go to whatever the saved search has listed as its 'displayView' param.
Im afraid there's no way to do that at the moment without writing your own javascript to change the ViewRedirector to do what you want instead.
Of course you can make all of the saved searches go to a different view using the 'targetView' param.

2) I'm not at all sure what's up with that error when you use the Paginator. i tried to reproduce it but i cant im afraid. Sounds like a bug.

3) I dont think you want to pass the name out of the entity lister, but instead pass the 'search' key, ie the full search language string.
Then you end up with just $savedSearch$ as your search instead of | savedsearch "$savedSearch$". If you do go ahead and use the savedsearch command, the savedsearch command will always override the selected timerange in the TimeRangePicker, and use the time range from the saved search instead. Which is really confusing to the user. (although i wonder whether you went down this road because you thought the savedsearch command might take care of the displayView problem for you)

Jason
Motivator

It's a list of saved searches, with no time picker nearby, I do want the time range from the saved search to show up.

0 Karma

Jason
Motivator

(2)(3) This was tested in 4.1.3. I changed the output value to search and then the HiddenSearch to just $savedSearch$ - but anytime I clicked on Next> or a number on the paginator, it would jump into a search for null in the flashtimeline! So, that red bar is appearing because it is attempting to run | savedsearch "null" - do I have things improperly nested? Why is this happening?

0 Karma

Jason
Motivator

Nick, as for (1) that's really unfortunate. I'm going to have to make two lists, one to open in flashtimeline and one to open with users' charting setting in the charting view. How can you make it just generate a list of @go= links which handle this properly?

0 Karma
Get Updates on the Splunk Community!

Take Your Breath Away with Splunk Risk-Based Alerting (RBA)

WATCH NOW!The Splunk Guide to Risk-Based Alerting is here to empower your SOC like never before. Join Haylee ...

SignalFlow: What? Why? How?

What is SignalFlow? Splunk Observability Cloud’s analytics engine, SignalFlow, opens up a world of in-depth ...

Federated Search for Amazon S3 | Key Use Cases to Streamline Compliance Workflows

Modern business operations are supported by data compliance. As regulations evolve, organizations must ...