Skip to content

Commit

Permalink
Support managing source component in the UI
Browse files Browse the repository at this point in the history
  • Loading branch information
csordasmarton committed Jun 5, 2018
1 parent 4dcae68 commit ccbf9b1
Show file tree
Hide file tree
Showing 7 changed files with 442 additions and 49 deletions.
312 changes: 312 additions & 0 deletions www/scripts/codecheckerviewer/SourceComponentManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
// -------------------------------------------------------------------------
// The CodeChecker Infrastructure
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// -------------------------------------------------------------------------

define([
'dojo/dom-construct',
'dojo/dom-attr',
'dojo/dom-class',
'dojo/_base/declare',
'dojo/data/ItemFileWriteStore',
'dojox/grid/DataGrid',
'dijit/ConfirmDialog',
'dijit/form/Button',
'dijit/form/SimpleTextarea',
'dijit/form/TextBox',
'dijit/layout/ContentPane'],
function (dom, domAttr, domClass, declare, ItemFileWriteStore, DataGrid,
ConfirmDialog, Button, SimpleTextarea, TextBox, ContentPane) {

var DeleteComponentDialog = declare(ConfirmDialog, {
constructor : function () {
this._confirmLabel = new ContentPane({
class : 'delete-confirm-text',
innerHTML : '<span class="warningHeader">You have selected to ' +
'delete a source component!</span>'
});
},

postCreate : function () {
this.inherited(arguments);
this.addChild(this._confirmLabel);
},

onExecute : function () {
CC_SERVICE.removeSourceComponent(this.componentName);
this.listSourceComponent.refreshGrid();
}
});

var EditSourceComponent = declare(ContentPane, {
postCreate : function () {
var that = this;

this._errorMessage = dom.create('div', {class : 'mbox mbox-error hide'});
dom.place(this._errorMessage, this.domNode);

this._componentName = new TextBox({
class : 'component-name',
placeHolder : 'Name of the source component...'
});
this._placeFormElement(this._componentName, "name", "Name*");

this._componentValue = new SimpleTextarea({
class : 'component-value',
placeHolder : 'Value of the source component...'
});
this._placeFormElement(this._componentValue, "value", "Value*");

this._componentDescription = new TextBox({
class : 'component-description',
placeHolder : 'Description of the source component...'
});
this._placeFormElement(this._componentDescription, "description",
"Description");

this._btnCreate = new Button({
class : 'btn-save',
label : "Save",
onClick : function () {
var componentName = that._componentName.get('value');
if (!componentName)
return that.showError("Component name can not be empty!");

var componentValue = that._componentValue.get('value');
if (!componentValue)
return that.showError("Component value can not be empty!");

var componentDescription = that._componentDescription.get('value');

// Remove the original component because the user would like to change
// the name.
var origComponentName = that._origComponent
? that._origComponent.name[0]
: null;

if (origComponentName && origComponentName !== componentName)
CC_SERVICE.removeSourceComponent(origComponentName);

CC_SERVICE.addSourceComponent(componentName, componentValue,
componentDescription, function (success) {
if (success) {
that.showSuccess("The component has been successfully " +
"created/edited!");
that.sourceComponentManager.updateNeeded = true;
} else {
that.showError("Failed to create/edit component!");
}
}).fail(function (jsReq, status, exc) {
if (status === "parsererror")
that.showError(exc.message);
});;
}
});
this.addChild(this._btnCreate);
},

hideError : function () {
domClass.add(this._errorMessage, 'hide');
},

showSuccess : function (msg) {
this._errorMessage.innerHTML = msg;
domClass.remove(this._errorMessage, 'hide');
domClass.remove(this._errorMessage, 'mbox-error');
domClass.add(this._errorMessage, 'mbox-success');
},

showError : function (msg) {
this._errorMessage.innerHTML = msg;
domClass.remove(this._errorMessage, 'hide');
domClass.remove(this._errorMessage, 'mbox-success');
domClass.add(this._errorMessage, 'mbox-error');
},

_placeFormElement : function (element, key, label) {
this.addChild(element);

var container = dom.create('div', {
class : 'formElement'
}, this.containerNode);

if (label) {
var labelNode = dom.create('label', {
class : 'formLabel bold',
innerHTML : label + ': '
}, container);

if (key)
domAttr.set(labelNode, 'for', key);
}

dom.place(element.domNode, container);
},

init : function (component) {
if (component) {
this._componentName.set('value', component.name[0]);
this._componentValue.set('value', component.value[0]);
this._componentDescription.set('value', component.description[0]);
this._origComponent = component;
} else {
this._componentName.set('value', null);
this._componentValue.set('value', null);
this._componentDescription.set('value', null);
this._origComponent = null;
}

this.hideError();
}
});

var ListSourceComponent = declare(DataGrid, {
constructor : function () {
this.store = new ItemFileWriteStore({
data : { identifier : 'id', items : [] }
});

this.structure = [
{ name : 'Name', field : 'name', styles : 'text-align: left;', width : '100%' },
{ name : 'Value', field : 'value', styles : 'text-align: left;', width : '100%' },
{ name : 'Description', field : 'description', styles : 'text-align: left;', width : '100%' },
{ name : '&nbsp;', field : 'editIcon', cellClasses : 'status', width : '20px', noresize : true },
{ name : '&nbsp;', field : 'deleteIcon', cellClasses : 'status', width : '20px', noresize : true }
]

this.focused = true;
this.selectable = true;
this.keepSelection = true;
this.escapeHTMLInData = false;
this.autoHeight = true;
},

postCreate : function () {
this.inherited(arguments);

this._confirmDeleteDialog = new DeleteComponentDialog({
title : 'Confirm deletion of component',
listSourceComponent : this
});
},

onRowClick : function (evt) {
var item = this.getItem(evt.rowIndex);
switch (evt.cell.field) {
case 'editIcon':
this.editComponent(item);
break;
case 'deleteIcon':
this.removeComponent(item.name[0]);
break;
}
},

removeComponent : function (name) {
this._confirmDeleteDialog.componentName = name;
this._confirmDeleteDialog.show();
},

editComponent : function (component) {
this.sourceComponentManager.showNewComponentPage(component);
},

refreshGrid : function () {
var that = this;

this.store.fetch({
onComplete : function (sourceComponents) {
sourceComponents.forEach(function (component) {
that.store.deleteItem(component);
});
that.store.save();
}
});

CC_SERVICE.getSourceComponents(null, function (sourceComponents) {
sourceComponents.forEach(function (item) {
that._addSourceComponent(item);
});
});
},

_addSourceComponent : function (component) {
this.store.newItem({
id : component.name,
name : component.name,
value : component.value,
description : component.description,
editIcon : '<span class="customIcon edit"></span>',
deleteIcon : '<span class="customIcon delete"></span>'
});
},

onShow : function () {
if (this.sourceComponentManager.updateNeeded) {
this.refreshGrid();
this.sourceComponentManager.updateNeeded = false;
}
}
});

return declare(ContentPane, {
updateNeeded : true,

postCreate : function () {
var that = this;

this._btnNew = new Button({
class : 'btn-new',
label : "New",
onClick : function () {
that.showNewComponentPage();
}
});

this._btnBack = new Button({
class : 'btn-back',
label : "Back",
onClick : function () {
that.showListOfComponentPage();
}
});

this._editSourceComponent = new EditSourceComponent({
sourceComponentManager : this
});

this._listSourceComponent = new ListSourceComponent({
editSourceComponent : this._editSourceComponent,
sourceComponentManager : this
});
},

showNewComponentPage : function (component) {
this._clearDom();

this._editSourceComponent.init(component);

this.addChild(this._btnBack);
this.addChild(this._editSourceComponent);
},

showListOfComponentPage : function () {
this._clearDom();

this.addChild(this._btnNew);
this.addChild(this._listSourceComponent);
this._listSourceComponent.onShow();
},

refreshGrid : function () {
this._listSourceComponent.refreshGrid();
},

_clearDom : function () {
this.getChildren().forEach(function (child) {
this.removeChild(child);
}, this);
}
});
});
2 changes: 2 additions & 0 deletions www/scripts/codecheckerviewer/codecheckerviewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ function (declare, cookie, topic, Lightbox, Dialog, Button, BorderContainer,
var currentProductName = util.atou(CURRENT_PRODUCT.displayedName_b64);
document.title = currentProductName + ' - CodeChecker';

IS_ADMIN_OF_ANY_PRODUCT = CC_PROD_SERVICE.isAdministratorOfAnyProduct();

//--- Back button to product list ---//

var productListButton = new Button({
Expand Down
35 changes: 4 additions & 31 deletions www/scripts/codecheckerviewer/filter/BugFilterView.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ define([
'codechecker/filter/RunBaseFilter',
'codechecker/filter/RunHistoryTagFilter',
'codechecker/filter/SelectFilter',
'codechecker/filter/SourceComponentFilter',
'codechecker/filter/UniqueFilter',
'codechecker/util'],
function (declare, lang, Deferred, domClass, dom, domStyle, topic, Button,
ContentPane, hashHelper, DateFilter, DetectionStatusFilter, DiffTypeFilter,
ReportCount, RunBaseFilter, RunHistoryTagFilter, SelectFilter, UniqueFilter,
util) {
ReportCount, RunBaseFilter, RunHistoryTagFilter, SelectFilter,
SourceComponentFilter, UniqueFilter, util) {

var FilterToggle = declare(ContentPane, {
class : 'filter-toggle',
Expand Down Expand Up @@ -434,40 +435,12 @@ function (declare, lang, Deferred, domClass, dom, domStyle, topic, Button,

//--- Soruce component filter ---//

this._sourceComponentFilter = new SelectFilter({
this._sourceComponentFilter = new SourceComponentFilter({
class : 'source-component',
title : 'Source component',
parent: this,
search : {
enable : true,
placeHolder : 'Search for source components...'
},
updateReportFilter : function (components) {
that.reportFilter.componentNames = components;
},
formatDescription : function (value) {
var list = dom.create('ul', { class : 'component-description'});
value.split('\n').forEach(function (item) {
dom.create('li', {
innerHTML : item,
class : 'component-item'
}, list);
});
return list.outerHTML;
},
getItems : function (opt) {
var that = this;

var deferred = new Deferred();
CC_SERVICE.getSourceComponents(null, function (res) {
deferred.resolve(res.map(function (component) {
return {
value : component.name,
description : that.formatDescription(component.value)
};
}));
});
return deferred;
}
});
this.register(this._sourceComponentFilter);
Expand Down
Loading

0 comments on commit ccbf9b1

Please sign in to comment.