Filter drill down fields per widget

Comments

14 comments

  • Avatar
    shilpa

    Tried this . Got the Plug-in but did not work. 

    //Script to disable "Drill-into" functionality on a specific widget
    //This will work only if there is no script related to Drill-into at the Dashboard level
    prism.disableDrillDown(widget);

    */
    var fieldsToKeep = [];
    var fieldsToRemove = ['[Revenue_Detail.ProjectNumber]'];
    prism.FilterDrillDownFieldsPerWidget(widget, fieldsToKeep, fieldsToRemove);

    I have 8 tables in the elasticube. How do I not show 7 tables and display certain columns in one table?

     

     

    0
    Comment actions Permalink
  • Avatar
    Tony Fonager

    Seems like this is not in 6.7.1.15016

    Any updated versions of the script ?

    0
    Comment actions Permalink
  • Avatar
    support cessoftware

    This plugin does not work with version 7.0.2.11001, when trying to use the field selector during editing of widgets, the field selector box does not populate.

    0
    Comment actions Permalink
  • Avatar
    Graeme Davidson

    Hi, I can't get it to work, but I may be doing something wrong.  Also, I don't want to permanently remove the filters.  just remove them now, so that the next time they use them it will be the correct filters.

     

    0
    Comment actions Permalink
  • Avatar
    Samuel Mendu (Edited )

    Plug In is not working for date-time fields

    0
    Comment actions Permalink
  • Avatar
    Chris Kerrison (Edited )

    As suggested in the post, I want to apply this from the dashboard level so it is automatically applied to all widgets. The link in the post does not work though. this is what I've got in my dashboard script but it's not working 

    _.each(prism.activeDashboard.widgets.$$widgets, function(widget){
    var fieldsToRemove = ['[timesheet details.Revenue]', '[timesheet details.Net Savings]'];
    var fieldsToKeep = [];

    prism.FilterDrillDownFieldsPerWidget(widget, fieldsToKeep, fieldsToRemove);
    });

    It works fine on an individual widget though but some dashboards have  8 widgets on them

    0
    Comment actions Permalink
  • Avatar
    Chris Kerrison

    It doesn't look like this plugin works with version 8.1.

    When you click on the drill into option, the field list popup box doesn't show anything at all. And, in the developer console window there is an error -

    common.js?g=4874335bfec11091b9ca5e1b9ec6de10:13 TypeError: promise.success is not a function
    at Object.getFields (main.9928a6b34e00da468ce0.js:1)
    at R (app-account.js?g=4874335bfec11091b9ca5e1b9ec6de10:357)
    at t.e.loadMore (app-account.js?g=4874335bfec11091b9ca5e1b9ec6de10:357)
    at Object.<anonymous> (app-account.js?g=4874335bfec11091b9ca5e1b9ec6de10:357)
    at Object.invoke (common.js?g=4874335bfec11091b9ca5e1b9ec6de10:13)
    at _.instance (common.js?g=4874335bfec11091b9ca5e1b9ec6de10:13)
    at se (common.js?g=4874335bfec11091b9ca5e1b9ec6de10:13)
    at common.js?g=4874335bfec11091b9ca5e1b9ec6de10:13
    at common.js?g=4874335bfec11091b9ca5e1b9ec6de10:13
    at app-account.js?g=4874335bfec11091b9ca5e1b9ec6de10:357 "Possibly unhandled rejection: {}"

    I believe the "Possibly unhandled rejection: {}" is an Angular error. 

     

     

    0
    Comment actions Permalink
  • Avatar
    Chris Kerrison (Edited )

    I have a fix for the script that works in version 8.1. so if anyone else has the same issue then the fix is to convert he depreciated process.success into a promise.then.  Note the variable called data that is referenced inside of this method also has to change as it now is data.data

    Code

     

    if (!String.prototype.format) {
    String.prototype.format = function() {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function(match, number) {
    return typeof args[number] != 'undefined'
    ? args[number]
    : match
    ;
    });
    };
    }

    prism.on("beforemenu", function(e,args){

    window.currentWidget = args.settings.widget;
    });

    prism.FilterDrillDownFieldsPerWidget = function (widget, elementsToKeep, elementsToRemove) {
    $$set(prism,"filteredWidgets."+widget.oid+".fieldsToRemove", elementsToRemove);
    $$set(prism,"filteredWidgets."+widget.oid+".fieldsToKeep", elementsToKeep);

    for(var i=0;i< widget.dashboard.$$events.refreshend.handlers.length;i++){
    if(JSON.stringify(widget.dashboard.$$events.refreshend.handlers[i]) == JSON.stringify(onDashboardRefreshEnd)) return
    }
    var onDashboardRefreshEnd = function(d, args) {

    /*********** USER CONFIGURATION ***********/
    //set fields to remove OR fields to keep, fields must contain table name and column name.
    var fieldsToRemove = elementsToRemove || [];
    var fieldsToKeep = elementsToKeep || [];
    var enableFiltering = true;
    // max count is needed in order to return all fields and filter them, if few fields remain after filter, scrolling will not be available and getting other fields will not be possible
    // set maxCount to be number of fields in the datasource
    var maxCount = 500;

    /*********** NOT USER CONFIGURATION ***********/
    if (enableFiltering) {
    function fromBrackets(str) {

    // validate.
    if (!angular.isString(str) || str.length < 2 || str[0] != '[' || str[str.length - 1] != ']') {
    return str;
    }

    return str.substring(1, str.length - 1);
    }

    function stuffRepo(data, datasource) {
    var service = prism.$injector.get('eucalyptus.services.metaService');
    datasource = datasource.toLowerCase();

    _.each(data, function (item) {

    /*var table = item.table;*/
    var id = fromBrackets(item.id).toLowerCase();

    if (!service.repository.hasOwnProperty(datasource))
    service.repository[datasource] = {};

    /* if(!repository[datasource].hasOwnProperty(table))
    repository[datasource][table] = {};*/
    if (service.repository[datasource][id] == undefined) {
    service.repository[datasource]/*[table]*/
    [id] = {
    type : item.dimtype,
    isMerged : item.merged,
    isIndexed : item.indexed
    };
    }

    });
    }

    setTimeout(function () {
    function removeCurrentWidget(){
    window.currentWidget = null;

    }
    $('.ew-i-add, .right-box').on('click', removeCurrentWidget);

    function getFields(ds, q, offset, count, ignoretypes) {

    if (window.currentWidget && prism.filteredWidgets[window.currentWidget.oid]) {
    var firstTime = false;
    if (count == 100) {
    firstTime = true;
    }
    //$('.md-modal') - prevent from filtering fields when creating new widget
    if (count == 50 && $('.md-modal').length == 0) {

    count = maxCount;
    }
    }
    if (typeof ds != 'string' && typeof ds != 'object')
    throw 'Datasource parameter must be a string or object!';

    if (defined(q) && typeof q != 'string')
    throw 'Query must be a string!';

    if (defined(offset) && defined(count) && (isNaN(offset) || isNaN(count)))
    throw 'Offset/Count must be integers!';

    var dsTitle = typeof ds == 'string' ? ds : '{0}@{1}'.format(ds.title, ds.address);
    var url = '../api/datasources/{0}/fields?'.format(encodeURIComponent(dsTitle));

    if (defined(offset) && defined(count)) {

    url += '&offset={0}&count={1}'.format(offset, count);
    }

    if (defined(q)) {

    if (defined(offset) || defined(count)) {

    url += '&';
    }

    url += 'q={0}'.format(encodeURIComponent(q));
    }

    if (defined(ignoretypes)) {

    if (defined(offset) || defined(count) || defined(q)) {

    url += '&';
    }

    var types = angular.isArray(ignoretypes) ? ignoretypes.join('|') : ignoretypes;
    url += 'ignoretypes={0}'.format(encodeURIComponent(types));

    }

    var promise = prism.$injector.get('$http')({
    method : 'GET',
    url : url
    });

    promise.then(function (e) {
    if (window.currentWidget && prism.filteredWidgets[window.currentWidget.oid]) {
    if (offset == 50) {
    e.data.splice(0, e.data.length);
    }
    if (!firstTime && $('.md-modal').length == 0) {

    if (prism.filteredWidgets[window.currentWidget.oid].fieldsToRemove.length > 0) {
    var i = e.data.length - 1;
    while (i >= 0) {
    if (prism.filteredWidgets[window.currentWidget.oid].fieldsToRemove.indexOf(e.data[i].id) > -1) {
    e.data.splice(i, 1);
    }
    i--;
    }
    } else { //fieldsToKeep.length > 0
    var i = e.data.length - 1;
    while (i >= 0) {
    if (prism.filteredWidgets[window.currentWidget.oid].fieldsToKeep.indexOf(e.data[i].id) < 0) {
    e.data.splice(i, 1);
    }
    i--;
    }
    }
    }
    }

    var datasource = ds.title || ds;
    stuffRepo(e.data, datasource);
    });
    return promise;
    }


    prism.$injector.get('eucalyptus.services.metaService').getFields = getFields;
    prism.$injector.get('eucalyptus.services.$suggest').getSuggestions = function (datasource) {

    var allWidgets;
    var $root = prism.$ngscope.$root;
    // dashboard state
    if (defined($root.dashboard)) {

    allWidgets = $root.dashboard.widgets.toArray();
    }

    // widget state
    else if (defined($root.widget)) {

    allWidgets = $root.widget.dashboard.widgets.toArray();
    } else {

    return [];
    }

    var relevantWidgets = _.filter(allWidgets, function (widget) {
    return _.isEqual(widget.datasource, datasource); // widget.datasource == datasource;
    });
    var dims = {};
    _.each(relevantWidgets, function (widget) {

    var panels = _.map(widget.metadata.panels, function (panel) {
    return panel.items;
    });

    var meta = [].concat.apply([], panels);

    _.each(meta, function (item) {

    if (item.jaql && item.jaql.dim) {

    var jaql = item.jaql;
    var dim,
    dimObj,
    agg,
    level;

    if (jaql.agg)
    agg = jaql.agg;
    if (jaql.level)
    level = jaql.level;

    if (typeof jaql.dim == 'string') {
    dim = jaql.dim;
    dimObj = {}; //restoreDim(jaql);
    } else {
    dim = jaql.dim.id;
    dimObj = jaql.dim;
    }

    if (dims.hasOwnProperty(dim)) {
    dims[dim].count = dims[dim].count + 1;
    } else {
    dims[dim] = {
    id : dim,
    count : 1,
    obj : dimObj,
    agg : agg,
    level : level
    };
    }
    }
    });
    });

    // TODO: also sort actions by popularity;

    var suggestions = _.chain(dims)
    .sortBy(dims, function (value, key, list) {
    return value.count;
    })
    .last(15)
    .map(function (item) {
    return item; //.id; //.obj;
    })
    .value();

    if (window.currentWidget && prism.filteredWidgets[window.currentWidget.oid]) {
    //filter the suggestions

    if (suggestions.length > 0 && $('.md-modal').length == 0) {
    if (prism.filteredWidgets[window.currentWidget.oid].fieldsToRemove.length > 0) {
    var i = suggestions.length - 1;
    while (i >= 0) {
    if (prism.filteredWidgets[window.currentWidget.oid].fieldsToRemove.indexOf(suggestions[i].id) > -1) {
    suggestions.splice(i, 1);
    }
    i--;
    }
    } else { //fieldsToKeep.length > 0
    var i = suggestions.length - 1;
    while (i >= 0) {
    if (prism.filteredWidgets[window.currentWidget.oid].fieldsToKeep.indexOf(suggestions[i].id) < 0) {
    suggestions.splice(i, 1);
    }
    i--;
    }
    }
    }
    }
    return suggestions;

    };
    //angular.element($('body')).scope().$apply();
    }, 1000)
    }
    }
    widget.dashboard.on('refreshend', onDashboardRefreshEnd);
    }

     

     

    0
    Comment actions Permalink
  • Avatar
    Hamza Jap-Tjong

    Hi Chris,

    Could you possibly share your reworked script? I cannot seem to get it to work.

    Thanks alot

    0
    Comment actions Permalink
  • Avatar
    Chris Kerrison

    I have updated my original comment to include the code block

    0
    Comment actions Permalink
  • Avatar
    Hamza Jap-Tjong (Edited )

    Works like a charm. Thanks Chris

     

    Did you also got your script on dashboard level working? I tried it but the script you provided earlier, didnt work for me

    0
    Comment actions Permalink
  • Avatar
    Chris Kerrison

    After a lot of trial and error I basically have to add 2 bits of script. One at the dashboard in the on ready method (example fields to remove)

     

    dashboard.on('widgetbuildquery', function(d, args) {

    var fieldsToRemove = ['[Candidates.Age]','[Candidates.Citizenship status]','[Candidates.City]','[Candidates.date_of_birth (Calendar)]'];

    var fieldsToKeep = [];
    prism.FilterDrillDownFieldsPerWidget(args.widget, fieldsToKeep, fieldsToRemove);

    });

     

     

    and then one on the first widget, but not inside any method (again example fields to hide)

     

    var fieldsToRemove = ['[Candidates.Age]','[Candidates.Citizenship status]','[Candidates.City]','[Candidates.date_of_birth (Calendar)]'];

    var fieldsToKeep = [];
    prism.FilterDrillDownFieldsPerWidget(widget, fieldsToKeep, fieldsToRemove);

     

     

    I have also added some script to hide the "you might be interested in" suggestions box as well as that could show fields I didn't want to allow the user to see.  

    0
    Comment actions Permalink
  • Avatar
    Tamir Basin

    What is this script adding to the built-in functionality of the "drill into" feature that is part of the widget's menu?

    0
    Comment actions Permalink
  • Avatar
    Hamza Jap-Tjong

    Hi Tamir,

    This plugin/script makes it possible to easily include/exclude drill into-fields on a widget or dashboard level. If you want to let your users drill into everything besides  Field X, then this plugin will make it possible. 

    We use it to hide certain confidential fields for certain users, while making it visible for others

    0
    Comment actions Permalink

Please sign in to leave a comment.