From e0ddff6e086842788c37e6f56f0054d4917d96a6 Mon Sep 17 00:00:00 2001 From: Bill Riehl Date: Mon, 11 Dec 2017 17:10:51 -0800 Subject: [PATCH 1/3] Fix problem with genome icons, some cleanup of various pieces of JS code --- kbase-extension/static/kbase/js/util/icon.js | 31 +- .../widgets/narrative_core/kbaseDataCard.js | 377 +++++++++--------- .../narrative_core/kbaseNarrativeDataList.js | 39 +- 3 files changed, 224 insertions(+), 223 deletions(-) diff --git a/kbase-extension/static/kbase/js/util/icon.js b/kbase-extension/static/kbase/js/util/icon.js index a8bc98971f..36efe1ccad 100644 --- a/kbase-extension/static/kbase/js/util/icon.js +++ b/kbase-extension/static/kbase/js/util/icon.js @@ -14,10 +14,29 @@ define([ iconColors = icons.colors, iconColorMapping = icons.color_mapping; + /** + * Legacy code that overwrites any existing DOM elements in params.elt. Used for passing in + * a set of parameters to buildDataIcon as an object instead of a list. + * @param {object} params - The set of parameters to use. + * @param {object} params.elt - The JQuery element containing the logo to overwrite. + * @param {string} params.type - The type of object to build a logo from. + * @param {boolean} params.stacked - If true, creates a stacked effect of multiple icons on each other + * @param {int} params.indent - How many spaces to indent (can be null or undefined) + */ function overwriteDataIcon(params) { return buildDataIcon(params.elt, params.type, params.stacked, params.indent); } + /** + * @method + * @public + * Builds a data icon in the given $logo div. + * @param {object} $logo The div in which to insert an icon. + * @param {string} type The shortened type of object to fetch the icon for. E.g. "Genome" not + * "KBaseGenomes.Genome-2.1" + * @param {boolean} stacked If true, creates a stacked effect of multiple 'icons'. + * @param {int} indent How many spaces to indent the icon (typically 0 or just null) + */ function buildDataIcon($logo, type, stacked, indent) { if (indent === undefined || indent === null) { indent = 0; @@ -27,7 +46,7 @@ define([ var icons = dataIcons; var icon = _.has(icons, type) ? icons[type] : icons.DEFAULT; // background circle - $logo.addClass("fa-stack fa-2x").css({ + $logo.addClass('fa-stack fa-2x').css({ 'cursor': 'pointer' }); @@ -78,8 +97,8 @@ define([ } $logo.append($('') - .addClass(circle_classes) - .css({'color': circle_color})); + .addClass(circle_classes) + .css({'color': circle_color})); // to avoid repetition, define the func. here that will // add one set of icons var addLogoFunc = function(fa_icon, $logo, cls) { @@ -100,7 +119,7 @@ define([ * Whether the stack of icons is using font-awesome * or our own custom set. * - * @param iconList {list of str} Icon classes, from icons.json + * @param {list of str} iconList Icon classes, from icons.json * @returns {boolean} */ function isCustomIcon(iconList) { @@ -110,7 +129,7 @@ define([ /** * Get color for data or method icon. - * @param type + * @param {string} type String that gets "hashed" into a color. * @returns {string} Color code */ function logoColorLookup (type) { @@ -127,5 +146,5 @@ define([ return { overwriteDataIcon: overwriteDataIcon, buildDataIcon: buildDataIcon - } + }; }); diff --git a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js index 4df7438313..90f881ee18 100644 --- a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js +++ b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js @@ -1,215 +1,198 @@ /** * kbaseDataCard.js -- used making object cards in narrative * - * Authors: zzheng@lbl.gov + * Authors: zzheng@lbl.gov, wjriehl@lbl.gov * - * Example and expected out put:s + * Example and expected outputs * - * var $card = new kbaseDataCard( - { - //expected values - object_info: object_info (array) - - //values with default, enter falsey value to hide; passing in value will override default - version: str or integer, - narrative: str, - date: str, - editBy: str, - type: str, - - //optional values - moreContent: jquery object, - is_set: boolean, - max_name_length: int, - - }); - - // object_info: - // [0] : obj_id objid // [1] : obj_name name // [2] : type_string type - // [3] : timestamp save_date // [4] : int version // [5] : username saved_by - // [6] : ws_id wsid // [7] : ws_name workspace // [8] : string chsum - // [9] : int size // [10] : usermeta meta + * var $card = new kbaseDataCard({ + * // required values + * object_info: object_info (array) * -*/ - -define ( - [ - 'bootstrap', - 'util/icon', - 'bluebird', - 'util/bootstrapDialog', - 'util/timeFormat', - 'kbase/js/widgets/narrative_core/kbaseCardLayout', - 'narrativeConfig', - 'jquery' - ], function( - bootstrap, - Icon, - Promise, - BootstrapDialog, - TimeFormat, - kbaseCardLayout, - Config, - $ - ) { - function KbaseDataCard(entry) { - var self = this; - var object_info = entry.object_info; - - //params - var shortName = entry.name ? entry.name : object_info[1]; - var version = entry.version ? entry.version : ('v' + object_info[4]); - var date = entry.date ? entry.date : TimeFormat.getTimeStampStr(object_info[3]); - var type = entry.type; - var editBy = entry.editedBy ? entry.editedBy : (' by ' + object_info[5]); - if(!entry.type){ - var type_tokens = object_info[2].split('.'); - type = entry.type ? entry.type : type_tokens[1].split('-')[0]; - } + * //values with default, enter falsey value to hide; passing in value will override default + * version: str or integer, the version of the object + * narrative: str, the name of the narrative that object is in + * date: str, the date when it was last saved + * editBy: str, the username of the person who saved the object + * type: str, the shortened type of object. E.g., if it's KBaseGenomes.Genome-2.1, then "Genome" + * viewType: str, the viewed object type. Mainly for Genomes that should have the scientific name appended. + * + * //optional values + * moreContent: jquery object, + * is_set: boolean, true if this is a Set object + * + * }); + */ + +define ([ + 'bootstrap', + 'util/icon', + 'bluebird', + 'util/bootstrapDialog', + 'util/timeFormat', + 'kbase/js/widgets/narrative_core/kbaseCardLayout', + 'narrativeConfig', + 'jquery' +], function( + bootstrap, + Icon, + Promise, + BootstrapDialog, + TimeFormat, + kbaseCardLayout, + Config, + $ +) { + 'use strict'; + function KbaseDataCard(entry) { + var self = this, + object_info = entry.object_info, + maxNameLength = Config.get('data_panel').max_name_length; + + //params + var shortName = entry.name ? entry.name : object_info[1], + version = entry.version ? entry.version : ('v' + object_info[4]), + date = entry.date ? entry.date : TimeFormat.getTimeStampStr(object_info[3]), + editBy = entry.editedBy ? entry.editedBy : (' by ' + object_info[5]); + + // in order - entry.viewType > entry.type > parsing it out of the object_info type string. + var objectType = entry.type ? entry.type : object_info[2].split('.')[1].split('-')[0], + viewType = entry.viewType ? entry.viewType : entry.type; + viewType = viewType ? viewType : objectType; + + //shorten name if applicable + var isShortened = false; + if ((maxNameLength && shortName) && shortName.length > maxNameLength) { + shortName = shortName.substring(0, maxNameLength - 3) + '...'; + isShortened = true; + } - //shorten name if applicable - var isShortened = false; - if ((entry.max_name_length && shortName) && shortName.length > entry.max_name_length) { - shortName = shortName.substring(0, entry.max_name_length - 3) + '...'; - isShortened = true; - } + var $logo = $('
'); + Icon.buildDataIcon($logo, objectType, entry.is_set, 0); - var $logo = $('
'); - Icon.buildDataIcon($logo, type, entry.is_set, 0); - - var $name = $('').addClass('kb-data-list-name').append(shortName); - var $version = $('').addClass('kb-data-list-version').append(version); - var $type = $('
').addClass('kb-data-list-type').append(type); - var $date = $('').addClass('kb-data-list-date').append(date); + var $name = $('').addClass('kb-data-list-name').append(shortName), + $version = $('').addClass('kb-data-list-version').append(version), + $type = $('
').addClass('kb-data-list-type').append(viewType), + $date = $('').addClass('kb-data-list-date').append(date); - //no default - var $byUser = $('').addClass('kb-data-list-edit-by').append(editBy); - var $narrative = $('
').addClass('kb-data-list-narrative').append(entry.narrative); - - var $title = $('
').append($name); - var $subcontent = $('
') + //no default + var $byUser = $('').addClass('kb-data-list-edit-by').append(editBy), + $narrative = $('
').addClass('kb-data-list-narrative').append(entry.narrative), + $title = $('
').append($name), + $subcontent = $('
') .addClass('narrative-data-list-subcontent'); - - if(entry.version === undefined || entry.version) { - $title.append($version); - } - - if(entry.type === undefined || entry.type) { - $subcontent.append($type); - } - if(entry.narrative === undefined || entry.narrative) { - $subcontent.append($narrative); - } - if(entry.date === undefined || entry.date) { - $subcontent.append($date); - } - if(entry.editedBy === undefined || entry.editedBy) { - $byUser - .click(function (object_info, e) { - e.stopPropagation(); - window.open('/#people/' + object_info[5]); - }.bind( null, object_info)); - $subcontent.append($byUser); - } + $title.append($version); + $subcontent.append($type) + .append($narrative) + .append($date) + .append($byUser); + $byUser + .click(function (object_info, e) { + e.stopPropagation(); + window.open('/#people/' + object_info[5]); + }.bind(null, object_info)); + + //tooltip for long title + if (isShortened) { + $name.tooltip({ + title: entry.name, + placement: 'bottom', + delay: { + show: Config.get('tooltip').showDelay, + hide: Config.get('tooltip').hideDelay + } + }); + } - //tooltip for long title - if (isShortened) { - $name.tooltip({ - title: entry.name, - placement: 'bottom', - delay: { - show: Config.get('tooltip').showDelay, - hide: Config.get('tooltip').hideDelay - } - }); + //create card + var actionButtonClick = function (e) { + if(!entry.ws_name){ + return; } - - //create card - var actionButtonClick = function (e) { - if(!entry.ws_name){ - return; - } - e.stopPropagation(); - var updateButton = function () { - var className = '.' + object_info[1].split('.').join('\\.'); - var btns = $(className); - var thisHolder = this; - var $thisBtn = $($(this).children()[0]); - $(this).html(''); - Promise.resolve(self.serviceClient.sync_call( - 'NarrativeService.copy_object', - [{ - ref: object_info[6] + '/' + object_info[0], - target_ws_name: entry.ws_name, - }] - )) - .then(function () { - var $button; - for(var i = 0 ; i< btns.length; i++){ - $button = btns[i]; - $($button).find('div').text(' Copy'); - } - $(thisHolder).html(''); - $(thisHolder).append($thisBtn); - self.trigger('updateDataList.Narrative'); - }) - .catch(function (error) { - $(this).html('Error'); - if (error.error && error.error.message) { - if (error.error.message.indexOf('may not write to workspace') >= 0) { - self.options.$importStatus.html($('
').css({ 'color': '#F44336', 'width': '500px' }).append('Error: you do not have permission to add data to this Narrative.')); - } else { - self.options.$importStatus.html($('
').css({ 'color': '#F44336', 'width': '500px' }).append('Error: ' + error.error.message)); - } + e.stopPropagation(); + var updateButton = function () { + var className = '.' + object_info[1].split('.').join('\\.'); + var btns = $(className); + var thisHolder = this; + var $thisBtn = $($(this).children()[0]); + $(this).html(''); + Promise.resolve(self.serviceClient.sync_call( + 'NarrativeService.copy_object', + [{ + ref: object_info[6] + '/' + object_info[0], + target_ws_name: entry.ws_name, + }] + )) + .then(function () { + var $button; + for(var i = 0 ; i< btns.length; i++){ + $button = btns[i]; + $($button).find('div').text(' Copy'); + } + $(thisHolder).html(''); + $(thisHolder).append($thisBtn); + self.trigger('updateDataList.Narrative'); + }) + .catch(function (error) { + $(this).html('Error'); + var $importError = $('
').css({ 'color': '#F44336', 'width': '500px' }); + if (error.error && error.error.message) { + if (error.error.message.indexOf('may not write to workspace') >= 0) { + $importError.append('Error: you do not have permission to add data to this Narrative.'); } else { - self.options.$importStatus.html($('
').css({ 'color': '#F44336', 'width': '500px' }).append('Unknown error!')); + $importError.append('Error: ' + error.error.message); } - console.error(error); - }); - }; - if ($(this).text().split(' ')[1] === 'Copy') { - var dialog = new BootstrapDialog({ - title: 'An item with this name already exists in this Narrative.', - body: 'Do you want to override the existing copy?', - buttons: [$('') - .append('Yes') - .click(function () { - dialog.hide(); - updateButton.call(this); - - }.bind(this)) - , $('') - .append('No') - .click(function () { - dialog.hide(); - }) - ], - closeButton: true + } else { + $importError.append('Unknown error!'); + } + self.options.$importStatus.html($importError); + console.error(error); }); - dialog.show(); - } else { - updateButton.call(this); - } - }; - var layout = { - actionButtonText: entry.actionButtonText, - actionButtonClick: actionButtonClick, - logo: $logo, - title: $title, - subcontent: $subcontent, - moreContent : entry.moreContent - }; - - var $card = new kbaseCardLayout(layout); - - var $renderedActionButton = $card.find('.narrative-card-action-button'); - - $renderedActionButton.addClass(function () { return object_info[1].split('.').join('\.'); }) - .hide(); + if ($(this).text().split(' ')[1] === 'Copy') { + var dialog = new BootstrapDialog({ + title: 'An item with this name already exists in this Narrative.', + body: 'Do you want to override the existing copy?', + buttons: [$('') + .append('Yes') + .click(function () { + dialog.hide(); + updateButton.call(this); + + }.bind(this)) + , $('') + .append('No') + .click(function () { + dialog.hide(); + }) + ], + closeButton: true + }); + dialog.show(); + } else { + updateButton.call(this); + } - return $card; - } - return KbaseDataCard; //end init - }); + }; + var layout = { + actionButtonText: entry.actionButtonText, + actionButtonClick: actionButtonClick, + logo: $logo, + title: $title, + subcontent: $subcontent, + moreContent : entry.moreContent + }; + + var $card = new kbaseCardLayout(layout); + + var $renderedActionButton = $card.find('.narrative-card-action-button'); + $renderedActionButton.addClass(function () { + return object_info[1].split('.').join('\.'); + }) + .hide(); + + return $card; + } + return KbaseDataCard; //end init +}); diff --git a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeDataList.js b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeDataList.js index d7521735f4..ec704fcef4 100644 --- a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeDataList.js +++ b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeDataList.js @@ -474,7 +474,7 @@ define([ this.populateAvailableTypes(); var typeSelected = this.$filterTypeSelect.val(); - if(this.selectedType === 'filterTypeSelect'){ + if(this.selectedType === 'filterTypeSelect'){ this.currentMatch = this.viewOrder; this.filterByType(typeSelected); }else if(this.selectedType === 'sortData'){ @@ -918,10 +918,10 @@ define([ if(self.refreshwritingLock !== null) { clearTimeout(self.refreshwritingLock); } - + self.refreshwritingLock = setTimeout(function () { self.writingLock = false; - }, 900000); + }, 900000); }; var $newNameInput = $('') .addClass('form-control') @@ -937,7 +937,7 @@ define([ Jupyter.narrative.enableKeyboardManager(); } }); - + $newNameInput.unbind('focus',releaseLock); $newNameInput.bind('focus',releaseLock); @@ -1102,13 +1102,13 @@ define([ } var metadata = object_info[10] || {}; + var viewType = type; if (type === 'Genome' || type === 'GenomeAnnotation') { if (metadata.hasOwnProperty('Name')) { - type = type + ': ' + metadata['Name']; + viewType = type + ': ' + metadata['Name']; } } - var metadataText = ''; for (var key in metadata) { if (metadata.hasOwnProperty(key)) { @@ -1132,17 +1132,16 @@ define([ .append('Full Type' + typeLink + '') .append($('').append('Saved by').append($savedByUserSpan)) .append(metadataText)); - - var $card = kbaseDataCard.apply(this,[ - { - type: type, - editedBy: author, - moreContent: $moreContent, - is_set: is_set, - max_name_length: this.options.max_name_length, - object_info: object_info, - }]); - + + var $card = kbaseDataCard.apply(this,[{ + viewType: viewType, + type: type, + editedBy: author, + moreContent: $moreContent, + is_set: is_set, + object_info: object_info, + }]); + if (objData.fromPalette) { var $paletteIcon = $('
') .addClass('pull-right narrative-card-palette-icon') @@ -1159,10 +1158,10 @@ define([ } }); $card.find('.kb-data-list-info').append($paletteIcon); - + } - //add custom click events - + //add custom click events + $card.find('.narrative-card-logo , .kb-data-list-name').click(function (e) { e.stopPropagation(); self.insertViewer(object_key); From 36670c923ee29d1bc550e64b12867ab6f5d0cefa Mon Sep 17 00:00:00 2001 From: Bill Riehl Date: Mon, 11 Dec 2017 17:45:24 -0800 Subject: [PATCH 2/3] fix tests --- .../kbase/js/widgets/narrative_core/kbaseDataCard.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js index 90f881ee18..75426a89c7 100644 --- a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js +++ b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js @@ -19,8 +19,9 @@ * * //optional values * moreContent: jquery object, - * is_set: boolean, true if this is a Set object - * + * is_set: boolean, true if this is a Set object, + * max_name_length: int, overrides the Config'd max_name_length if present (chops down the + * objects name to some maximum number of characters) * }); */ @@ -48,6 +49,9 @@ define ([ var self = this, object_info = entry.object_info, maxNameLength = Config.get('data_panel').max_name_length; + if (entry.max_name_length) { + maxNameLength = entry.max_name_length; + } //params var shortName = entry.name ? entry.name : object_info[1], @@ -116,7 +120,7 @@ define ([ var btns = $(className); var thisHolder = this; var $thisBtn = $($(this).children()[0]); - $(this).html(''); + $(this).html(''); Promise.resolve(self.serviceClient.sync_call( 'NarrativeService.copy_object', [{ From 22441e84992ce26d5f3c5e62c5398218cdfd3df5 Mon Sep 17 00:00:00 2001 From: Bill Riehl Date: Tue, 12 Dec 2017 15:13:12 -0800 Subject: [PATCH 3/3] fix some code legibility --- .../kbase/js/widgets/narrative_core/kbaseDataCard.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js index 75426a89c7..d17b9d7ef2 100644 --- a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js +++ b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseDataCard.js @@ -61,8 +61,15 @@ define ([ // in order - entry.viewType > entry.type > parsing it out of the object_info type string. var objectType = entry.type ? entry.type : object_info[2].split('.')[1].split('-')[0], - viewType = entry.viewType ? entry.viewType : entry.type; - viewType = viewType ? viewType : objectType; + viewType = entry.viewType; + if (!viewType) { + if (entry.type) { + viewType = entry.type; + } + else { + viewType = objectType; + } + } //shorten name if applicable var isShortened = false;