<a class="js-measures">{{t 'component_viewer.show_details'}}</a>
<br>
<a class="js-new-window">{{t 'component_viewer.new_window'}}</a>
-<br>
-<a class="js-workspace">{{t 'component_viewer.open_in_workspace'}}</a>
+{{#unless options.workspace}}
+ <br>
+ <a class="js-workspace">{{t 'component_viewer.open_in_workspace'}}</a>
+{{/unless}}
<br>
<a class="js-raw-source">{{t 'component_viewer.show_raw_source'}}</a>
showRawSource: function () {
this.options.parent.showRawSources();
+ },
+
+ serializeData: function () {
+ var options = this.options.parent.options.viewer.options;
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ options: options
+ });
}
});
'source-viewer/popups/coverage-popup',
'source-viewer/popups/duplication-popup',
'source-viewer/popups/line-actions-popup',
- 'workspace/main',
'templates/source-viewer'
],
function (Source,
SCMPopupView,
CoveragePopupView,
DuplicationPopupView,
- LineActionsPopupView,
- Workspace) {
+ LineActionsPopupView) {
var $ = jQuery,
HIGHLIGHTED_ROW_CLASS = 'source-line-highlighted';
this.bindScrollEvents();
},
- open: function (id) {
+ open: function (id, options) {
var that = this,
+ opts = typeof options === 'object' ? options : {},
finalize = function () {
that.requestIssues().done(function () {
that.render();
that.trigger('loaded');
});
};
+ _.extend(this.options, _.defaults(opts, { workspace: false }));
this.model
.clear()
.set(_.result(this.model, 'defaults'))
this.items = new Items();
this.items.load();
+ this.items.on('change', function () {
+ that.save();
+ });
this.itemsView = new ItemsView({ collection: this.items });
this.itemsView.render().$el.appendTo(document.body);
- this.itemsView.on('click', function (uuid, model) {
- model.collection.remove(model);
- that.showComponentViewer(model.toJSON());
+ this.itemsView.on('click', function (model) {
+ that.open(model);
});
},
this.items.load();
},
- addComponent: function (options) {
- if (options == null || typeof options.uuid !== 'string') {
- throw new Error('You must specify the component\'s uuid');
- }
- this.items.add(options);
+ addComponent: function (model) {
+ this.items.add(model);
this.save();
},
- openComponent: function (options) {
- if (options == null || typeof options.uuid !== 'string') {
- throw new Error('You must specify the component\'s uuid');
+ open: function (options) {
+ var model = typeof options.toJSON === 'function' ? options : new Item(options);
+ if (!model.isValid()) {
+ throw new Error(model.validationError);
+ }
+ this.addComponent(model);
+ if (model.isComponent()) {
+ this.showComponentViewer(model);
}
- this.showComponentViewer(options);
},
- showComponentViewer: function (options) {
- var that = this,
- model = new Item(options);
+ openComponent: function (options) {
+ return this.open(_.extend(options, { type: 'component' }));
+ },
+
+ showComponentViewer: function (model) {
+ var that = this;
if (this.viewerView != null) {
this.viewerView.close();
}
this.viewerView = new ViewerView({
model: model
});
- model
- .on('minimize', function () {
- that.addComponent(model.toJSON());
+ this.viewerView
+ .on('viewerMinimize', function () {
that.closeComponentViewer();
})
- .on('close', function () {
+ .on('viewerClose', function (model) {
that.closeComponentViewer();
+ model.destroy();
});
this.viewerView.render().$el.appendTo(document.body);
},
define(function () {
return Backbone.Model.extend({
- idAttribute: 'uuid',
validate: function () {
- if (!this.has('uuid')) {
+ if (!this.has('type')) {
+ return 'type is missing';
+ }
+ if (this.get('type') === 'component' && !this.has('uuid')) {
return 'uuid is missing';
}
+ if (this.get('type') === 'rule' && !this.has('key')) {
+ return 'key is missing';
+ }
+ },
+
+ isComponent: function () {
+ return this.get('type') === 'component';
+ },
+
+ isRule: function () {
+ return this.get('type') === 'rule';
},
destroy: function (options) {
className: 'workspace-nav-item',
template: Templates['workspace-item'],
+ modelEvents: {
+ 'change': 'render'
+ },
+
events: {
'click': 'onClick',
'click .js-close': 'onCloseClick'
onClick: function (e) {
e.preventDefault();
- this.options.collectionView.trigger('click', this.model.id, this.model);
+ this.options.collectionView.trigger('click', this.model);
},
onCloseClick: function (e) {
onMinimizeClick: function (e) {
e.preventDefault();
- this.model.trigger('minimize');
+ this.trigger('viewerMinimize');
},
onFullScreenClick: function (e) {
onCloseClick: function (e) {
e.preventDefault();
- this.model.trigger('close');
+ this.trigger('viewerClose');
},
-
toFullScreen: function () {
this.$el.closest('.workspace-viewer').addClass('workspace-viewer-full-screen');
},
this.$('.workspace-viewer-container').isolatedScroll();
},
+ onViewerMinimize: function () {
+ this.trigger('viewerMinimize');
+ },
+
+ onViewerClose: function () {
+ this.trigger('viewerClose', this.model);
+ },
+
showHeader: function () {
var headerView = new HeaderView({ model: this.model });
+ this.listenTo(headerView, 'viewerMinimize', this.onViewerMinimize);
+ this.listenTo(headerView, 'viewerClose', this.onViewerClose);
this.headerRegion.show(headerView);
},
var that = this,
viewer = new SourceViewer(),
options = this.model.toJSON();
- viewer.open(this.model.id);
+ viewer.open(this.model.get('uuid'), { workspace: true });
viewer.on('loaded', function () {
- that.model.set(viewer.model.toJSON());
+ that.model.set({
+ name: viewer.model.get('name'),
+ q: viewer.model.get('q')
+ });
if (options.line != null) {
viewer.highlightLine(options.line);
viewer.scrollToLine(options.line);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/* globals casper: false */
+
+var lib = require('../lib'),
+ testName = lib.testName('Workspace');
+
+
+lib.initMessages();
+lib.configureCasper();
+
+
+casper.test.begin(testName('API'), function (test) {
+ casper
+ .start(lib.buildUrl('nav'), function () {
+ lib.setDefaultViewport();
+ })
+
+ .then(function () {
+ test.assertNotEquals(casper.evaluate(function () {
+ window.workspace = require(['/js/workspace/main.js'])();
+ console.log(window.workspace);
+ return window.workspace;
+ }), null);
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
component_viewer.show_raw_source=Show Raw Source
component_viewer.more_actions=More Actions
component_viewer.new_window=Open in New Window
-component_viewer.open_in_workspace=Open in Workspace
+component_viewer.open_in_workspace=Pin This File
component_viewer.get_permalink=Get Permalink
component_viewer.covered_lines=Covered Lines
component_viewer.issues_limit_reached=For usability reasons, only the {0} first issues will be fully displayed. Remaining issues will simply be underlined.