From 8cb4be0643a661a3a5c54ac570388598c7ab1bad Mon Sep 17 00:00:00 2001 From: oxixes Date: Thu, 16 May 2024 16:21:32 +0200 Subject: [PATCH 01/28] Add multiple screen size functionality --- .../commons/static/js/wirecloud/Utils.js | 15 ++ .../locale/es/LC_MESSAGES/django.po | 2 +- src/wirecloud/platform/iwidget/utils.py | 142 ++++++++-- .../platform/static/js/wirecloud/Widget.js | 152 +++++++++-- .../static/js/wirecloud/ui/ColumnLayout.js | 30 ++- .../static/js/wirecloud/ui/DragboardLayout.js | 10 +- .../static/js/wirecloud/ui/FreeLayout.js | 52 ++-- .../js/wirecloud/ui/FullDragboardLayout.js | 8 +- .../static/js/wirecloud/ui/GridLayout.js | 30 ++- .../static/js/wirecloud/ui/SidebarLayout.js | 10 +- .../js/wirecloud/ui/SmartColumnLayout.js | 2 +- .../static/js/wirecloud/ui/WidgetView.js | 248 +++++++++++++++--- .../js/wirecloud/ui/WorkspaceTabView.js | 152 +++++++---- .../wirecloud/ui/WorkspaceTabViewDragboard.js | 35 ++- src/wirecloud/platform/workspace/utils.py | 55 ++-- 15 files changed, 720 insertions(+), 223 deletions(-) diff --git a/src/wirecloud/commons/static/js/wirecloud/Utils.js b/src/wirecloud/commons/static/js/wirecloud/Utils.js index 5b68e68ae5..c31f901084 100644 --- a/src/wirecloud/commons/static/js/wirecloud/Utils.js +++ b/src/wirecloud/commons/static/js/wirecloud/Utils.js @@ -26,3 +26,18 @@ Wirecloud.Utils = StyledElements.Utils; Wirecloud.Utils.gettext = gettext; Wirecloud.Utils.ngettext = ngettext; +Wirecloud.Utils.getLayoutMatrix = function getLayoutMatrix(layout, widgets, screenSize) { + const matrix = []; + for (let x = 0; x < layout.columns; x++) { + matrix[x] = []; + } + + widgets.forEach((widget) => { + if (!(widget.layout instanceof Wirecloud.ui.FullDragboardLayout) && !(widget.layout instanceof Wirecloud.ui.FreeLayout)) { + const layoutConfig = widget.model.getLayoutConfigBySize(screenSize); + layout._reserveSpace2(matrix, "NOTAWIDGET", layoutConfig.left, layoutConfig.top, layoutConfig.width, layoutConfig.height); + } + }); + + return matrix; +}; \ No newline at end of file diff --git a/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po b/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po index 601805e01b..b7d51d77c8 100644 --- a/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po +++ b/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po @@ -117,7 +117,7 @@ msgstr "Contraseña" #: templates/registration/login.html:48 templates/wirecloud/signin.html:3 msgid "Sign in" -msgstr "Iniciar sessión" +msgstr "Iniciar sesión" #: templates/wirecloud/catalogue/main_resource_details.html:3 msgid "Description" diff --git a/src/wirecloud/platform/iwidget/utils.py b/src/wirecloud/platform/iwidget/utils.py index 7e5f23545d..f52b495e3f 100644 --- a/src/wirecloud/platform/iwidget/utils.py +++ b/src/wirecloud/platform/iwidget/utils.py @@ -72,6 +72,17 @@ def update_boolean_value(model, data, field): model[field] = value +def update_screen_size_value(model, data, field): + if field in data: + value = data[field] + + if type(value) not in (int,): + raise TypeError(_('Field %(field)s must contain a number value') % {"field": field}) + + if value < -1: + raise ValueError(_('Invalid value for %(field)s') % {"field": field}) + + model[field] = value def update_position_value(model, data, field, data_field=None): data_field = data_field if data_field is not None else field @@ -112,23 +123,89 @@ def update_anchor_value(model, data): model["anchor"] = anchor +def check_intervals(data): + # The screen size intervals should cover the interval [0, +inf) and should not overlap nor have gaps, + # each interval is defined by the properties 'moreOrEqual' and 'lessOrEqual' + + if not isinstance(data, list) or not all(isinstance(i, dict) and ('moreOrEqual' in i and 'lessOrEqual' in i) for i in data): + raise ValueError('data must be a list of dictionaries with "moreOrEqual" and "lessOrEqual" keys') + + data.sort(key=lambda x: x.get('moreOrEqual', float('-inf'))) + + if data[0].get('moreOrEqual') != 0: + raise ValueError('The first interval must start from 0') + + for i in range(len(data) - 1): + if data[i]['lessOrEqual'] + 1 != data[i + 1].get('moreOrEqual'): + raise ValueError('Intervals should not overlap nor have gaps') + + if data[-1]['lessOrEqual'] != -1: + raise ValueError('The last interval must extend to infinity') def update_position(iwidget, key, data): - position = iwidget.positions.setdefault(key, {}) - - update_boolean_value(position, data, 'relwidth') - update_boolean_value(position, data, 'relheight') - update_size_value(position, data, 'width') - update_size_value(position, data, 'height') - update_position_value(position, data, 'top') - update_position_value(position, data, 'left') - update_anchor_value(position, data) - update_boolean_value(position, data, 'relx') - update_boolean_value(position, data, 'rely') - update_position_value(position, data, 'zIndex') - update_boolean_value(position, data, 'minimized') - update_boolean_value(position, data, 'titlevisible') - update_boolean_value(position, data, 'fulldragboard') + if not 'layoutConfigurations' in data: + raise ValueError('Missing layoutConfigurations field') + + # Check if we have duplicate ids in the layoutConfigurations + ids = set() + for layoutConfig in data["layoutConfigurations"]: + if 'id' not in layoutConfig: + raise ValueError('Missing id field') + if layoutConfig['id'] in ids: + raise ValueError('Duplicate id field') + ids.add(layoutConfig['id']) + + intervals = {} + for conf in iwidget.positions["configurations"]: + intervals[conf['id']] = conf + + for layoutConfig in data["layoutConfigurations"]: + if not 'action' in layoutConfig: + raise ValueError('Missing action field') + if layoutConfig['action'] not in ('update', 'delete'): + raise ValueError('Invalid value for action field: ' + layoutConfig['action']) + + if layoutConfig['action'] == 'delete': + del intervals[layoutConfig['id']] + else: + if not layoutConfig['id'] in intervals: + intervals[layoutConfig['id']] = { + 'id': layoutConfig['id'], + 'moreOrEqual': 0, + 'lessOrEqual': -1, + } + + intervals[layoutConfig['id']][key] = { + 'top': 0, + 'left': 0, + 'zIndex': 0, + 'height': 0, + 'width': 0, + 'minimized': False, + 'titlevisible': True, + 'fulldragboard': False + } + + update_screen_size_value(intervals[layoutConfig['id']], layoutConfig, 'moreOrEqual') + update_screen_size_value(intervals[layoutConfig['id']], layoutConfig, 'lessOrEqual') + update_position_value(intervals[layoutConfig['id']][key], layoutConfig, 'top') + update_position_value(intervals[layoutConfig['id']][key], layoutConfig, 'left') + update_position_value(intervals[layoutConfig['id']][key], layoutConfig, 'zIndex') + update_size_value(intervals[layoutConfig['id']][key], layoutConfig, 'height') + update_size_value(intervals[layoutConfig['id']][key], layoutConfig, 'width') + update_boolean_value(intervals[layoutConfig['id']][key], layoutConfig, 'minimized') + update_boolean_value(intervals[layoutConfig['id']][key], layoutConfig, 'titlevisible') + update_boolean_value(intervals[layoutConfig['id']][key], layoutConfig, 'fulldragboard') + update_boolean_value(intervals[layoutConfig['id']][key], layoutConfig, 'relwidth') + update_boolean_value(intervals[layoutConfig['id']][key], layoutConfig, 'relheight') + update_boolean_value(intervals[layoutConfig['id']][key], layoutConfig, 'relx') + update_boolean_value(intervals[layoutConfig['id']][key], layoutConfig, 'rely') + update_anchor_value(intervals[layoutConfig['id']][key], layoutConfig) + + newPositions = list(intervals.values()) + check_intervals(newPositions) + + iwidget.positions["configurations"] = newPositions def update_permissions(iwidget, data): @@ -174,23 +251,31 @@ def SaveIWidget(iwidget, user, tab, initial_variable_values=None, commit=True): # set default positions new_iwidget.positions = { - 'widget': { - 'top': 0, - 'left': 0, - 'zIndex': 0, - 'height': 0, - 'width': 0, - 'minimized': False, - 'titlevisible': True, - 'fulldragboard': False, - }, + 'configurations': [ + { + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'id': 0, + 'widget': { + 'top': 0, + 'left': 0, + 'zIndex': 0, + 'height': 1, + 'width': 1, + 'minimized': False, + 'titlevisible': True, + 'fulldragboard': False, + }, + } + ] } if initial_variable_values is not None: set_initial_values(new_iwidget, initial_variable_values, iwidget_info, user) update_title_value(new_iwidget, iwidget) - update_position(new_iwidget, 'widget', iwidget) + if "layoutConfigurations" in iwidget: + update_position(new_iwidget, 'widget', iwidget) if commit: new_iwidget.save() @@ -211,13 +296,16 @@ def UpdateIWidget(data, user, tab, updatecache=True): iwidget.tab = newtab if 'layout' in data: + if data['layout'] < 0: + raise ValueError('Invalid value for layout field') layout = data['layout'] iwidget.layout = layout update_permissions(iwidget, data.get('permissions', {}).get('viewer', {})) # update positions - update_position(iwidget, 'widget', data) + if "layoutConfigurations" in data: + update_position(iwidget, 'widget', data) # save the changes iwidget.save(updatecache=updatecache) diff --git a/src/wirecloud/platform/static/js/wirecloud/Widget.js b/src/wirecloud/platform/static/js/wirecloud/Widget.js index c6df319929..c56a310368 100644 --- a/src/wirecloud/platform/static/js/wirecloud/Widget.js +++ b/src/wirecloud/platform/static/js/wirecloud/Widget.js @@ -185,6 +185,7 @@ const _setTitleVisibility = function _setTitleVisibility(widget, visibility) { privates.get(widget).titlevisible = visibility; + privates.get(widget).currentLayoutConfiguration.titlevisible = visibility; widget.dispatchEvent('change', ['titlevisible']); return Promise.resolve(widget); }; @@ -245,6 +246,23 @@ this.loaded_scripts = []; }; + // It is assumed that the layoutConfigurations cover every screen size from 0 to infinity without gaps or overlaps + // (this is guaranteed by checks in the server side code) + const _getCurrentLayoutConfiguration = function _getCurrentLayoutConfiguration(layoutConfigurations, windowSize) { + let currentLayoutConfiguration; + for (const i in layoutConfigurations) { + const isValid = (layoutConfigurations[i]["moreOrEqual"] != -1 && layoutConfigurations[i]["lessOrEqual"] == -1 && layoutConfigurations[i].moreOrEqual <= windowSize) || + (layoutConfigurations[i]["moreOrEqual"] == -1 && layoutConfigurations[i]["lessOrEqual"] != -1 && layoutConfigurations[i].lessOrEqual >= windowSize) || + (layoutConfigurations[i]["moreOrEqual"] != -1 && layoutConfigurations[i]["lessOrEqual"] != -1 && layoutConfigurations[i].moreOrEqual <= windowSize && layoutConfigurations[i].lessOrEqual >= windowSize); + + if (isValid) { + currentLayoutConfiguration = layoutConfigurations[i]; + break; + } + } + return currentLayoutConfiguration; + }; + const clean_title = function clean_title(title) { if (typeof title !== 'string' || !title.trim().length) { throw new TypeError("invalid title parameter"); @@ -464,26 +482,29 @@ permissions.viewer.upgrade = false; } + const currentLayoutConfiguration = _getCurrentLayoutConfiguration(data.layoutConfigurations, window.innerWidth); privates.set(this, { permissions: permissions, position: { - anchor: data.anchor, - relx: data.relx, - rely: data.rely, - x: data.left, - y: data.top, - z: data.zIndex + anchor: currentLayoutConfiguration.anchor, + relx: currentLayoutConfiguration.relx, + rely: currentLayoutConfiguration.rely, + x: currentLayoutConfiguration.left, + y: currentLayoutConfiguration.top, + z: currentLayoutConfiguration.zIndex }, meta: meta, shape: { - relheight: data.relheight, - relwidth: data.relwidth, - width: data.width, - height: data.height + relheight: currentLayoutConfiguration.relheight, + relwidth: currentLayoutConfiguration.relwidth, + width: currentLayoutConfiguration.width, + height: currentLayoutConfiguration.height }, + layoutConfigurations: data.layoutConfigurations, + currentLayoutConfiguration: currentLayoutConfiguration, status: STATUS.CREATED, tab: tab, - titlevisible: !!data.titlevisible, + titlevisible: !!currentLayoutConfiguration.titlevisible, on_preremovetab: on_preremovetab.bind(this) }); @@ -569,9 +590,27 @@ */ volatile: { value: !!data.volatile + }, + /** + * @memberOf Wirecloud.Widget# + * @type {Object} + */ + currentLayoutConfig: { + get: function () { + return privates.get(this).currentLayoutConfiguration; + } + }, + /** + * @memberOf Wirecloud.Widget# + * @type {Object} + */ + layoutConfigurations: { + get: function () { + return privates.get(this).layoutConfigurations; + } } }); - this.fulldragboard = data.fulldragboard; + this.fulldragboard = currentLayoutConfiguration.fulldragboard; _createWrapper.call(this); @@ -593,8 +632,12 @@ * @type {Boolean} */ minimized: { - writable: true, - value: data.minimized + get: function() { + return privates.get(this).currentLayoutConfiguration.minimized; + }, + set: function(value) { + privates.get(this).currentLayoutConfiguration.minimized = value; + } }, /** * @memberOf Wirecloud.Widget# @@ -964,6 +1007,58 @@ return this; } + setLayoutPosition(layoutPosition) { + Wirecloud.Utils.merge(privates.get(this).currentLayoutConfiguration, { + anchor: layoutPosition.anchor, + relx: layoutPosition.relx, + rely: layoutPosition.rely, + left: layoutPosition.x, + top: layoutPosition.y, + zIndex: layoutPosition.z + }); + return this; + } + + setLayoutIndex(index) { + this.layout = index; + return this; + } + + updateWindowSize(windowSize) { + const currentLayoutConfiguration = _getCurrentLayoutConfiguration(privates.get(this).layoutConfigurations, windowSize); + if (currentLayoutConfiguration === privates.get(this).currentLayoutConfiguration) { + return false; + } + + privates.get(this).currentLayoutConfiguration = currentLayoutConfiguration; + + // Update shape, position, titlevisible and fulldragboard + privates.get(this).shape = { + relheight: currentLayoutConfiguration.relheight, + relwidth: currentLayoutConfiguration.relwidth, + height: currentLayoutConfiguration.height, + width: currentLayoutConfiguration.width + }; + + privates.get(this).position = { + anchor: currentLayoutConfiguration.anchor, + relx: currentLayoutConfiguration.relx, + rely: currentLayoutConfiguration.rely, + x: currentLayoutConfiguration.left, + y: currentLayoutConfiguration.top, + z: currentLayoutConfiguration.zIndex + }; + + privates.get(this).titlevisible = !!currentLayoutConfiguration.titlevisible; + this.fulldragboard = currentLayoutConfiguration.fulldragboard; + + return true; + } + + getLayoutConfigBySize(size) { + return _getCurrentLayoutConfiguration(privates.get(this).layoutConfigurations, size); + } + setPreferences(newValues) { // We are going to modify the object, let's create a copy newValues = Object.assign({}, newValues); @@ -1026,6 +1121,21 @@ return this; } + setLayoutShape(layoutShape) { + Wirecloud.Utils.merge(privates.get(this).currentLayoutConfiguration, layoutShape); + return this; + } + + setLayoutFulldragboard(fulldragboard) { + privates.get(this).currentLayoutConfiguration.fulldragboard = fulldragboard; + return this; + } + + setLayoutMinimizedStatus(minimized) { + privates.get(this).currentLayoutConfiguration.minimized = minimized; + return this; + } + /** * Set title visibility on persistence * @@ -1034,9 +1144,7 @@ setTitleVisibility(visibility, persistence) { visibility = !!visibility; - if (this.volatile) { - return _setTitleVisibility(this, visibility); - } else if (persistence) { + if (persistence && !this.volatile) { const url = Wirecloud.URLs.IWIDGET_ENTRY.evaluate({ workspace_id: this.tab.workspace.id, tab_id: this.tab.id, @@ -1044,7 +1152,11 @@ }); const payload = { - titlevisible: visibility + layoutConfigurations: [{ + id: privates.get(this).currentLayoutConfiguration.id, + titlevisible: visibility, + action: 'update' + }] }; return Wirecloud.io.makeRequest(url, { @@ -1060,9 +1172,7 @@ } }); } else { - privates.get(this).titlevisible = visibility; - this.dispatchEvent('change', ['titlevisible']); - return Promise.resolve(this); + return _setTitleVisibility(this, visibility); } } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js index 562b4023ac..7fece5f863 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js @@ -100,32 +100,32 @@ return (cells * this.cellHeight); } - getWidthInPixels(cells) { - return this.fromHCellsToPixels(cells) - this.leftMargin - this.rightMargin; + getWidthInPixels(cells, width) { + return this.fromHCellsToPixels(cells, width) - this.leftMargin - this.rightMargin; } getHeightInPixels(cells) { return this.fromVCellsToPixels(cells) - this.topMargin - this.bottomMargin; } - fromPixelsToHCells(pixels) { + fromPixelsToHCells(pixels, width) { if (pixels <= 0) { return 0; } - const cells = pixels / this.fromHCellsToPixels(1); + const cells = pixels / this.fromHCellsToPixels(1, width); return Math.round(cells); } - fromHCellsToPixels(cells) { - return (this.getWidth() * this.fromHCellsToPercentage(cells)) / 100; + fromHCellsToPixels(cells, width) { + return ((width || this.getWidth()) * this.fromHCellsToPercentage(cells)) / 100; } fromHCellsToPercentage(cells) { return cells * (100 / this.columns); } - adaptColumnOffset(size) { + adaptColumnOffset(size, width) { let offsetInLU, pixels; const parsedSize = this.parseSize(size); @@ -133,13 +133,13 @@ offsetInLU = Math.round(parsedSize[0]); } else { if (parsedSize[1] === '%') { - pixels = Math.round((parsedSize[0] * this.getWidth()) / 100); + pixels = Math.round((parsedSize[0] * (width || this.getWidth())) / 100); } else { pixels = parsedSize[0] < this.dragboard.leftMargin ? 0 : parsedSize[0] - this.dragboard.leftMargin; } - offsetInLU = this.fromPixelsToHCells(pixels); + offsetInLU = this.fromPixelsToHCells(pixels, width); } - return new Wirecloud.ui.MultiValuedSize(this.getColumnOffset({x: offsetInLU}), offsetInLU); + return new Wirecloud.ui.MultiValuedSize(this.getColumnOffset({x: offsetInLU}, width), offsetInLU); } adaptRowOffset(size) { @@ -167,8 +167,8 @@ return height + this.topMargin + this.bottomMargin; } - getColumnOffset(position, css) { - let tmp = Math.floor((this.getWidth() * this.fromHCellsToPercentage(position.x)) / 100); + getColumnOffset(position, width, css) { + let tmp = Math.floor(((width || this.getWidth()) * this.fromHCellsToPercentage(position.x)) / 100); tmp += this.leftMargin + this.dragboard.leftMargin; return css ? tmp + 'px' : tmp; } @@ -498,12 +498,16 @@ } _searchFreeSpace(width, height) { + return this._searchFreeSpace2(width, height, this.matrix); + } + + _searchFreeSpace2(width, height, matrix) { let positionX = 0, positionY = 0; const maxX = this.columns - width; for (positionY = 0; true ; positionY++) { for (positionX = 0; positionX <= maxX; positionX++) { - if (this._hasSpaceFor(this.matrix, positionX, positionY, width, height)) { + if (this._hasSpaceFor(matrix, positionX, positionY, width, height)) { return {relx: true, x: positionX, rely: true, y: positionY}; } } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js index 2080fb9193..715126cf28 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js @@ -126,7 +126,7 @@ } } - adaptColumnOffset(pixels) { + adaptColumnOffset(pixels, width) { const msg = utils.interpolate( "method \"%(method)s\" must be implemented.", {method: "adaptColumnOffset"}, @@ -162,7 +162,7 @@ return new Wirecloud.ui.MultiValuedSize(this.getHeightInPixels(sizeInLU), sizeInLU); } - adaptWidth(size) { + adaptWidth(size, width) { let pixels, sizeInLU; const parsedSize = this.parseSize(size); @@ -170,14 +170,14 @@ sizeInLU = Math.round(parsedSize[0]); } else { if (parsedSize[1] === '%') { - pixels = Math.round((parsedSize[0] * this.getWidth()) / 100); + pixels = Math.round((parsedSize[0] * (width || this.getWidth())) / 100); } else { pixels = this.padWidth(parsedSize[0]); } - sizeInLU = Math.round(this.fromPixelsToHCells(pixels)); + sizeInLU = Math.round(this.fromPixelsToHCells(pixels, width)); } sizeInLU = Math.max(1, sizeInLU); - return new Wirecloud.ui.MultiValuedSize(this.getWidthInPixels(sizeInLU), sizeInLU); + return new Wirecloud.ui.MultiValuedSize(this.getWidthInPixels(sizeInLU, width), sizeInLU); } updatePosition(widget, element) { diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js index 62e7f88e21..6c0d796c6d 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js @@ -27,7 +27,7 @@ "use strict"; - const setPosition = function setPosition(position, options, offset) { + const setPosition = function setPosition(position, options, offset, screenWidth) { delete options.left; delete options.top; delete options.right; @@ -39,7 +39,7 @@ options.top = offset.y + options.refposition.top - this.dragboard.topMargin - options.height; break; case "top-left": - options.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(options.width); + options.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(options.width, screenWidth); options.top = offset.y + options.refposition.top - this.dragboard.topMargin - options.height; break; case "bottom-right": @@ -47,14 +47,14 @@ options.top = offset.y + options.refposition.bottom - this.dragboard.topMargin; break; case "bottom-left": - options.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(options.width); + options.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(options.width, screenWidth); options.top = offset.y + options.refposition.bottom - this.dragboard.topMargin; break; } }; - const standsOut = function standsOut(options) { - const width_in_pixels = this.getWidthInPixels(options.width); + const standsOut = function standsOut(options, screenWidth) { + const width_in_pixels = this.getWidthInPixels(options.width, screenWidth); const height_in_pixels = options.height; const visible_width = width_in_pixels - Math.max(options.left + width_in_pixels - this.getWidth(), 0) - Math.max(-options.left, 0); @@ -87,23 +87,23 @@ return Math.round((this.getHeight() * cells) / this.MAX_HLU); } - getWidthInPixels(cells) { - return this.fromHCellsToPixels(cells); + getWidthInPixels(cells, width) { + return this.fromHCellsToPixels(cells, width); } getHeightInPixels(cells) { return this.fromVCellsToPixels(cells); } - fromPixelsToHCells(pixels) { - return (pixels * this.MAX_HLU / this.getWidth()); + fromPixelsToHCells(pixels, width) { + return (pixels * this.MAX_HLU / (width || this.getWidth())); } - fromHCellsToPixels(cells) { - return Math.round((this.getWidth() * cells) / this.MAX_HLU); + fromHCellsToPixels(cells, width) { + return Math.round(((width || this.getWidth()) * cells) / this.MAX_HLU); } - getColumnOffset(position, css) { + getColumnOffset(position, width, css) { const margin = position.anchor.endsWith("left") ? this.dragboard.leftMargin : this.dragboard.rightMargin; if (css) { if (position.relx) { @@ -113,7 +113,7 @@ return (margin + position.x) + "px"; } } else { - return margin + (position.relx ? this.fromHCellsToPixels(position.x) : position.x); + return margin + (position.relx ? this.fromHCellsToPixels(position.x, width) : position.x); } } @@ -131,7 +131,7 @@ } } - adaptColumnOffset(size) { + adaptColumnOffset(size, width) { let offsetInLU, pixels; const parsedSize = this.parseSize(size); @@ -139,13 +139,13 @@ offsetInLU = Math.round(parsedSize[0]); } else { if (parsedSize[1] === '%') { - pixels = Math.round((parsedSize[0] * this.getWidth()) / 100); + pixels = Math.round((parsedSize[0] * width || this.getWidth()) / 100); } else { pixels = parsedSize[0] < this.dragboard.leftMargin ? 0 : parsedSize[0] - this.dragboard.leftMargin; } - offsetInLU = Math.round(this.fromPixelsToHCells(pixels)); + offsetInLU = Math.round(this.fromPixelsToHCells(pixels, width)); } - const offsetInPixels = this.fromHCellsToPixels(offsetInLU); + const offsetInPixels = this.fromHCellsToPixels(offsetInLU, width); return new Wirecloud.ui.MultiValuedSize(offsetInPixels, offsetInLU); } @@ -351,18 +351,18 @@ case "top-right": case "bottom-right": element.style.left = ""; - element.style.right = this.getColumnOffset(widget.position, true); + element.style.right = this.getColumnOffset(widget.position, null, true); element.style.marginLeft = ""; break; case "top-left": case "bottom-left": - element.style.left = this.getColumnOffset(widget.position, true); + element.style.left = this.getColumnOffset(widget.position, null, true); element.style.right = ""; element.style.marginLeft = ""; break; case "top-center": case "bottom-center": - element.style.left = this.getColumnOffset(widget.position, true); + element.style.left = this.getColumnOffset(widget.position, null, true); element.style.right = ""; if (widget.shape.relwidth) { const percentage = widget.shape.width / 2 / this.MAX_HLU_PERCENTAGE; @@ -410,7 +410,7 @@ this.newPosition = null; } - searchBestPosition(options) { + searchBestPosition(options, screenWidth) { let offset = {x: 0, y: 0}; if (options.refiframe != null) { offset = Wirecloud.Utils.getRelativePosition(options.refiframe, this.dragboard.tab.wrapperElement); @@ -421,8 +421,8 @@ const placements = ["bottom-right", "bottom-left", "top-right", "top-left"]; let i = 0; do { - setPosition.call(this, placements[i], options, offset); - weights.push(standsOut.call(this, options)); + setPosition.call(this, placements[i], options, offset, screenWidth); + weights.push(standsOut.call(this, options, screenWidth)); i += 1; } while (weights[i - 1] > 0 && i < placements.length); @@ -430,17 +430,17 @@ const best_weight = Math.min.apply(Math, weights); const index = weights.indexOf(best_weight); const placement = placements[index]; - setPosition.call(this, placement, options, offset); + setPosition.call(this, placement, options, offset, screenWidth); options.top = this.adaptRowOffset(options.top + "px").inPixels; - options.left = this.adaptColumnOffset(options.left + "px").inLU; + options.left = this.adaptColumnOffset(options.left + "px", screenWidth).inLU; if (options.left + options.width >= this.MAX_HLU) { options.width -= options.left + options.width - this.MAX_HLU; } } else { options.top = this.adaptRowOffset(options.top + "px").inPixels; - options.left = this.adaptColumnOffset(options.left + "px").inLU; + options.left = this.adaptColumnOffset(options.left + "px", screenWidth).inLU; } } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/FullDragboardLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/FullDragboardLayout.js index 29212c964a..f015e16659 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/FullDragboardLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/FullDragboardLayout.js @@ -63,7 +63,7 @@ return this.getWidth(); } - getColumnOffset(position) { + getColumnOffset(position, width) { return 0; } @@ -83,8 +83,8 @@ return new Wirecloud.ui.MultiValuedSize(this.getHeight(), 1); } - adaptWidth(size) { - return new Wirecloud.ui.MultiValuedSize(this.getWidth(), 1); + adaptWidth(size, width) { + return new Wirecloud.ui.MultiValuedSize(width || this.getWidth(), 1); } initialize() { @@ -115,7 +115,7 @@ return new Set(); } - iWidget.setPosition(new Wirecloud.DragboardPosition(0, 0)); + iWidget.setPosition(new Wirecloud.DragboardPosition(0, 0), false); return new Set(); } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/GridLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/GridLayout.js index 4de065a4fe..c96949637b 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/GridLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/GridLayout.js @@ -95,32 +95,32 @@ return rows * (100 / this.rows); } - getWidthInPixels(cells) { - return this.fromHCellsToPixels(cells) - this.leftMargin - this.rightMargin; + getWidthInPixels(cells, width) { + return this.fromHCellsToPixels(cells, width) - this.leftMargin - this.rightMargin; } getHeightInPixels(cells) { return this.fromVCellsToPixels(cells) - this.topMargin - this.bottomMargin; } - fromPixelsToHCells(pixels) { + fromPixelsToHCells(pixels, width) { if (pixels <= 0) { return 0; } - const cells = pixels / this.fromHCellsToPixels(1); + const cells = pixels / this.fromHCellsToPixels(1, width); return Math.round(cells); } - fromHCellsToPixels(columns) { - return (this.getWidth() * this.fromHCellsToPercentage(columns)) / 100; + fromHCellsToPixels(columns, width) { + return ((width || this.getWidth()) * this.fromHCellsToPercentage(columns)) / 100; } fromHCellsToPercentage(columns) { return columns * (100 / this.columns); } - adaptColumnOffset(size) { + adaptColumnOffset(size, width) { let offsetInLU; const parsedSize = this.parseSize(size); @@ -129,13 +129,13 @@ } else { let pixels; if (parsedSize[1] === '%') { - pixels = Math.round((parsedSize[0] * this.getWidth()) / 100); + pixels = Math.round((parsedSize[0] * (width || this.getWidth())) / 100); } else { pixels = parsedSize[0]; } - offsetInLU = Math.round(this.fromPixelsToHCells(pixels - this.leftMargin)); + offsetInLU = Math.round(this.fromPixelsToHCells(pixels - this.leftMargin, width)); } - return new Wirecloud.ui.MultiValuedSize(this.getColumnOffset(offsetInLU), offsetInLU); + return new Wirecloud.ui.MultiValuedSize(this.getColumnOffset(offsetInLU, width), offsetInLU); } adaptRowOffset(size) { @@ -164,8 +164,8 @@ return height + this.topMargin + this.bottomMargin; } - getColumnOffset(position) { - let tmp = Math.floor((this.getWidth() * this.fromHCellsToPercentage(position.x)) / 100); + getColumnOffset(position, width) { + let tmp = Math.floor(((width || this.getWidth()) * this.fromHCellsToPercentage(position.x)) / 100); tmp += this.leftMargin + this.dragboard.leftMargin; return tmp; } @@ -334,12 +334,16 @@ } _searchFreeSpace(width, height) { + return this._searchFreeSpace2(width, height, this.matrix); + } + + _searchFreeSpace2(width, height, matrix) { let positionX = 0, positionY = 0; const maxX = this.columns - width; for (positionY = 0; true ; positionY++) { for (positionX = 0; positionX <= maxX; positionX++) { - if (this._hasSpaceFor(this.matrix, positionX, positionY, width, height)) { + if (this._hasSpaceFor(matrix, positionX, positionY, width, height)) { return {relx: true, x: positionX, rely: true, y: positionY}; } } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js index b4a4d4c902..f852c7ef79 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js @@ -148,11 +148,11 @@ return result; } - adaptColumnOffset(size) { + adaptColumnOffset(size, width) { if (this.vertical) { return new Wirecloud.ui.MultiValuedSize(0, 0); } else { - return super.adaptColumnOffset(size); + return super.adaptColumnOffset(size, width); } } @@ -172,11 +172,11 @@ } } - adaptWidth(size) { + adaptWidth(size, width) { if (this.vertical) { - return new Wirecloud.ui.MultiValuedSize(this.getWidth(), 1); + return new Wirecloud.ui.MultiValuedSize(width || this.getWidth(), 1); } else { - return super.adaptWidth(size); + return super.adaptWidth(size, width); } } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/SmartColumnLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/SmartColumnLayout.js index e433475b56..e37cba0605 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/SmartColumnLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/SmartColumnLayout.js @@ -48,7 +48,7 @@ for (const key in this.widgets) { keys.push(key); const widget = this.widgets[key]; - modified = modified || this.moveSpaceUp(this._buffers.base, widget); + modified = modified || (this.moveSpaceUp(this._buffers.base, widget).size > 0); } if (modified) { // save these changes in the server side diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js index 729cd62f30..6389acce9a 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js @@ -104,6 +104,105 @@ }); }; + const getUpdatedLayoutConfigurations = function getUpdatedLayoutConfigurations(newLayout) { + const layoutConfigurations = this.model.layoutConfigurations; + // const updatedLayoutConfigurations = []; + + const priv = privates.get(this); + const tabChange = priv.tab !== newLayout.dragboard.tab; + const dragboardChange = this.layout.dragboard !== newLayout.dragboard || tabChange; + + layoutConfigurations.forEach((layoutConfiguration) => { + if (this.layout instanceof Wirecloud.ui.FullDragboardLayout || newLayout instanceof Wirecloud.ui.FullDragboardLayout) { + // Skip if coming from or going to a FullDragboardLayout + return; + } + + // const newLayoutConfiguration = StyledElements.Utils.clone(layoutConfiguration, true); + const newLayoutConfiguration = layoutConfiguration; + + let avgScreenSize = layoutConfiguration.lessOrEqual + (layoutConfiguration.moreOrEqual - layoutConfiguration.lessOrEqual) / 2; + if (layoutConfiguration.lessOrEqual === -1) { + avgScreenSize = layoutConfiguration.moreOrEqual; + } + + const layout = (this.layout instanceof Wirecloud.ui.FullDragboardLayout) ? this.previousLayout : this.layout; + const previousWidth = (layoutConfiguration.relwidth) ? layout.fromHCellsToPixels(layoutConfiguration.width, avgScreenSize) : layoutConfiguration.width; + const previousHeight = (layoutConfiguration.relheight) ? layout.fromVCellsToPixels(layoutConfiguration.height) : layoutConfiguration.height; + + if (newLayout instanceof Wirecloud.ui.FreeLayout) { + Wirecloud.Utils.merge(newLayoutConfiguration, { + relwidth: true, + width: newLayout.adaptWidth(previousWidth + 'px', avgScreenSize).inLU, + relheight: false, + height: newLayout.adaptHeight(previousHeight + 'px').inPixels + }); + } else { + Wirecloud.Utils.merge(newLayoutConfiguration, { + relwidth: true, + width: newLayout.adaptWidth(previousWidth + 'px', avgScreenSize).inLU, + relheight: true, + height: newLayout.adaptHeight(previousHeight + 'px').inLU + }); + + console.log("newShape", { + relwidth: true, + width: newLayout.adaptWidth(previousWidth + 'px', avgScreenSize).inLU, + relheight: true, + height: newLayout.adaptHeight(previousHeight + 'px').inLU + }); + } + + if (dragboardChange && !(newLayout instanceof Wirecloud.ui.FreeLayout)) { + const matrix = Wirecloud.Utils.getLayoutMatrix(newLayout, newLayout.dragboard.widgets, avgScreenSize); + console.log(newLayout); + const newposition = newLayout._searchFreeSpace2(newLayoutConfiguration.width, newLayoutConfiguration.height, matrix); + console.log("newposition", newposition); + console.log("matrix", matrix); + newposition.relx = true; + newposition.rely = true; + newposition.anchor = "top-left"; + Wirecloud.Utils.merge(newLayoutConfiguration, newposition); + } else { + const position = { + x: layoutConfiguration.left, + y: layoutConfiguration.top, + z: layoutConfiguration.zIndex, + relx: layoutConfiguration.relx, + rely: layoutConfiguration.rely, + anchor: layoutConfiguration.anchor + }; + + const oldPositionPixels = { + x: layout.getColumnOffset(position, avgScreenSize), + y: layout.getRowOffset(position) + }; + + if (newLayout instanceof Wirecloud.ui.FreeLayout) { + Wirecloud.Utils.merge(newLayoutConfiguration, { + left: newLayout.adaptColumnOffset(oldPositionPixels.x + 'px', avgScreenSize).inLU, + top: newLayout.adaptRowOffset(oldPositionPixels.y + 'px').inPixels, + relx: true, + rely: false, + anchor: "top-left" + }); + } else { + Wirecloud.Utils.merge(newLayoutConfiguration, { + left: newLayout.adaptColumnOffset(oldPositionPixels.x + 'px', avgScreenSize).inLU, + top: newLayout.adaptRowOffset(oldPositionPixels.y + 'px').inLU, + relx: true, + rely: true, + anchor: "top-left" + }); + } + } + + // updatedLayoutConfigurations.push(newLayoutConfiguration); + }); + + // return updatedLayoutConfigurations; + }; + // ========================================================================= // EVENT HANDLERS // ========================================================================= @@ -166,6 +265,11 @@ }, set: function (new_layout) { privates.get(this).layout = new_layout; + const fulldragboard = new_layout instanceof Wirecloud.ui.FullDragboardLayout; + this.model.setLayoutFulldragboard(fulldragboard); + if (!fulldragboard && new_layout != null) { + this.model.setLayoutIndex(new_layout.dragboard.layouts.indexOf(new_layout)); + } update.call(this); } }, @@ -362,10 +466,14 @@ } else { layout = tab.dragboard.layouts[model.layout]; } - layout.addWidget(this, true); // Init minimized and title visibility options - this.setMinimizeStatus(model.minimized, false, true); + let wrapperHeight = this.wrapperElement.offsetHeight; + wrapperHeight = (wrapperHeight === 0) ? 42 : wrapperHeight; // On first load, the height is 0. This is a workaround to avoid this issue + // and set the correct height to the widget + this._setMinimizeStatusStyle(model.minimized, layout, wrapperHeight); + + layout.addWidget(this, true); this.model.logManager.addEventListener('newentry', on_add_log.bind(this)); @@ -413,6 +521,23 @@ * @param newStatus new minimize status of the iwidget */ setMinimizeStatus(newStatus, persistence, reserveSpace) { + const oldHeight = this.shape.height; + + this._setMinimizeStatusStyle(newStatus, this.layout); + this.model.setLayoutMinimizedStatus(this.minimized); + + // Notify resize event + reserveSpace = reserveSpace != null ? reserveSpace : true; + if (reserveSpace) { + const persist = persistence != null ? persistence : true; + this.layout._notifyResizeEvent(this, this.shape.width, oldHeight, this.shape.width, this.shape.height, false, false, persist, reserveSpace); + } + + update.call(this); + return this; + } + + _setMinimizeStatusStyle(newStatus, layout, height = undefined) { const priv = privates.get(this); // Sanitize newStatus value @@ -422,7 +547,6 @@ return this; } - const oldHeight = this.shape.height; priv.minimized = newStatus; if (this.minimized) { @@ -430,9 +554,12 @@ this.minimizebutton.replaceIconClassName("fa-minus", "fa-plus"); this.wrapperElement.classList.add('wc-minimized-widget'); this.wrapperElement.style.height = ""; + + const wrapperHeight = (height) ? height : this.wrapperElement.offsetHeight; + priv.minimized_shape = { relheight: true, - height: this.layout.adaptHeight(this.wrapperElement.offsetHeight + 'px').inLU, + height: layout.adaptHeight(wrapperHeight + 'px').inLU, relwidth: priv.shape.relwidth, width: priv.shape.width }; @@ -441,7 +568,7 @@ this.minimizebutton.setTitle(utils.gettext("Minimize")); this.minimizebutton.replaceIconClassName("fa-plus", "fa-minus"); this.wrapperElement.classList.remove('wc-minimized-widget'); - this.wrapperElement.style.height = this.layout.getHeightInPixels(priv.shape.height) + 'px'; + this.wrapperElement.style.height = layout.getHeightInPixels(priv.shape.height) + 'px'; priv.minimized_shape = null; } @@ -450,16 +577,6 @@ heightInPixels: this.model.wrapperElement.offsetHeight, visible: !priv.minimized && !this.tab.hidden && !this.tab.workspace.hidden }); - - // Notify resize event - reserveSpace = reserveSpace != null ? reserveSpace : true; - if (reserveSpace) { - const persist = persistence != null ? persistence : true; - this.layout._notifyResizeEvent(this, this.shape.width, oldHeight, this.shape.width, this.shape.height, false, false, persist, reserveSpace); - } - - update.call(this); - return this; } /** @@ -489,8 +606,14 @@ return this.model.setPermissions(changes, persistence); } - setPosition(position) { + setPosition(position, updateModel = true) { utils.update(privates.get(this).position, position); + + if (updateModel) { + this.model.setPosition(this.position); + this.model.setLayoutPosition(this.position); + } + if (this.layout != null) { update_position.call(this); notify_position.call(this); @@ -498,12 +621,17 @@ return this; } - setShape(shape, resizeLeftSide, resizeTopSide, persist) { + setShape(shape, resizeLeftSide, resizeTopSide, persist, updateModel = true) { const oldWidth = this.shape.width; const oldHeight = this.shape.height; utils.update(privates.get(this).shape, shape); + if (updateModel) { + this.model.setShape(privates.get(this).shape); + this.model.setLayoutShape(privates.get(this).shape); + } + if (this.layout == null) { return; } @@ -582,6 +710,7 @@ return this; } + // MARK Adrian Quizá esto sea importante moveToLayout(newLayout) { if (this.layout === newLayout) { return Promise.resolve(); @@ -600,9 +729,12 @@ const tabChange = priv.tab !== newLayout.dragboard.tab; const dragboardChange = this.layout.dragboard !== newLayout.dragboard || tabChange; const oldLayout = this.layout; + getUpdatedLayoutConfigurations.call(this, newLayout); const affectedWidgetsRemoving = oldLayout.removeWidget(this, dragboardChange); + const updateModel = !(newLayout instanceof Wirecloud.ui.FullDragboardLayout); + if (oldLayout instanceof Wirecloud.ui.FullDragboardLayout) { this.setShape(this.previousShape); } else if (newLayout instanceof Wirecloud.ui.FreeLayout) { @@ -618,7 +750,7 @@ width: newLayout.adaptWidth(previousWidth + 'px').inLU, relheight: true, height: newLayout.adaptHeight(previousHeight + 'px').inLU - }); + }, false, false, false, updateModel); } if (dragboardChange && !(newLayout instanceof Wirecloud.ui.FreeLayout)) { @@ -649,7 +781,7 @@ relx: true, rely: true, anchor: "top-left" - }); + }, updateModel); } } @@ -664,10 +796,10 @@ this.model.changeTab(newLayout.dragboard.tab.model).then(() => { affectedWidgetsAdding.add(this.id); if (dragboardChange) { - oldLayout.dragboard.update([...affectedWidgetsRemoving]); - newLayout.dragboard.update([...affectedWidgetsAdding]); + oldLayout.dragboard.update([...affectedWidgetsRemoving], true); + newLayout.dragboard.update([...affectedWidgetsAdding], true); } else { - newLayout.dragboard.update([...utils.setupdate(affectedWidgetsAdding, affectedWidgetsRemoving)]); + newLayout.dragboard.update([...utils.setupdate(affectedWidgetsAdding, affectedWidgetsRemoving)], true); } }); } @@ -699,29 +831,65 @@ return this; } - toJSON() { + updateWindowSize(windowSize) { + this.model.updateWindowSize(windowSize); + + const newPos = { + x: this.model.position.x, + y: this.model.position.y, + z: this.model.position.z, + relx: this.model.position.relx, + rely: this.model.position.rely, + anchor: this.model.position.anchor + }; + + const newShape = { + relwidth: this.model.shape.relwidth, + width: this.model.shape.width, + relheight: this.model.shape.relheight, + height: this.model.shape.height + }; + + this.layout.removeWidget(this, false); + + this.setPosition(newPos, false); + this.setShape(newShape, false, false, false, false); + + if (this.model.fulldragboard) { + this.previousPosition = this.position; + this.previousShape = this.shape; + this.previousLayout = this.tab.dragboard.layouts[this.model.layout]; + + this._setMinimizeStatusStyle(this.model.minimized, this.tab.dragboard.fulldragboardLayout); + this.tab.dragboard.fulldragboardLayout.addWidget(this, false); + } else { + // Remove wc-widget-fulldragboard class + this.wrapperElement.classList.remove('wc-widget-fulldragboard'); + this._setMinimizeStatusStyle(this.model.minimized, this.tab.dragboard.layouts[this.model.layout]); + this.tab.dragboard.layouts[this.model.layout].addWidget(this, false); + } + } + + toJSON(action, allLayoutConfigurations) { const fulldragboard = this.layout === this.tab.dragboard.fulldragboardLayout; - const shape = fulldragboard ? this.previousShape : this.shape; - const position = fulldragboard ? this.previousPosition : this.position; + + // We keep all or only the current layout configuration and then we clone it to add the action + const configs = this.model.layoutConfigurations.reduce((result, layoutConfig) => { + if ((allLayoutConfigurations && layoutConfig.id !== this.model.currentLayoutConfig.id) || + layoutConfig.id === this.model.currentLayoutConfig.id) { + const config = StyledElements.Utils.clone(layoutConfig, true); + config.action = action; + result.push(config); + } + + return result; + }, []); + return { id: this.id, tab: this.tab.id, layout: this.tab.dragboard.layouts.indexOf(fulldragboard ? this.previousLayout : this.layout), - // position - anchor: position.anchor, - relx: position.relx, - rely: position.rely, - top: position.y, - left: position.x, - zIndex: position.z, - // shape - minimized: this.minimized, - relwidth: shape.relwidth, - width: shape.width, - relheight: shape.relheight, - height: privates.get(this).shape.height, - fulldragboard: fulldragboard, - titlevisible: this.titlevisible + layoutConfigurations: configs }; } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index 2e7f4233e2..a39584da62 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -56,6 +56,20 @@ return widgets; }; + const get_layout_configs = function get_layout_configs(widget) { + const layoutConfigs = []; + + widget.layoutConfigurations.forEach(function (layoutConfig) { + layoutConfigs.push({ + id: layoutConfig.id, + moreOrEqual: layoutConfig.moreOrEqual, + lessOrEqual: layoutConfig.lessOrEqual + }); + }); + + return layoutConfigs; + } + // ========================================================================= // EVENT HANDLERS // ========================================================================= @@ -110,6 +124,16 @@ this.prefbutton.enabled = this.workspace.editing; }; + const on_windowresize = function on_windowresize() { + this.dragboard.resetLayouts(); + this.widgets.forEach((widget) => { + widget.updateWindowSize(window.innerWidth); + }); + + this.dragboard.refreshPositionBasedOnZIndex(); + this.dragboard.paint(); + }; + ns.WorkspaceTabView = class WorkspaceTabView extends se.Tab { constructor(id, notebook, options) { @@ -126,7 +150,8 @@ on_changetab: on_changetab.bind(this), on_addwidget: on_addwidget.bind(this), on_removetab: on_removetab.bind(this), - on_removewidget: on_removewidget.bind(this) + on_removewidget: on_removewidget.bind(this), + on_windowresize: on_windowresize.bind(this) }; privates.set(this, priv); @@ -236,6 +261,7 @@ this.model.addEventListener('addwidget', priv.on_addwidget); this.model.addEventListener('remove', priv.on_removetab); this.model.addEventListener('removewidget', priv.on_removewidget); + window.addEventListener('resize', priv.on_windowresize.bind(this)); } /** @@ -246,63 +272,93 @@ * resolved, or an Error if rejected. */ createWidget(resource, options) { + let layoutConfigs = [] + if (this.widgets.length > 0) { + // All widgets SHOULD have the same layout configuration sizes. If + // this is not the case something has gonw wrong or manual modifications + // have been made to the layout configurations, but we will use the first + // widget as reference. + layoutConfigs = get_layout_configs(this.widgets[0].model); + } else { + // TODO Adrian this should come from the UI defined sizes, which are not yet available + layoutConfigs.push({ + id: 0, + moreOrEqual: 0, + lessOrEqual: -1 + }); + } + options = utils.merge({ commit: true, - height: resource.default_height, - layout: this.model.preferences.get('initiallayout') === "Free" ? 1 : 0, - width: resource.default_width, - anchor: 'top-left', - relx: true, - rely: false, - relwidth: true, - relheight: false + layout: this.model.preferences.get('initiallayout') === "Free" ? 1 : 0 }, options); - const layouts = [ - this.dragboard.baseLayout, - this.dragboard.freeLayout, - this.dragboard.leftLayout, - this.dragboard.rightLayout - ]; - const layout = layouts[options.layout]; - - if (options.left != null) { - if (layout !== this.dragboard.freeLayout || options.relx) { - options.left = layout.adaptColumnOffset(options.left).inLU; + layoutConfigs.forEach((layoutConfig) => { + Wirecloud.Utils.merge(layoutConfig, { + action: 'update', + width: resource.default_width, + anchor: 'top-left', + relx: true, + rely: false, + relwidth: true, + relheight: false, + height: resource.default_height + }); + + let avgScreenSize = layoutConfig.lessOrEqual + (layoutConfig.moreOrEqual - layoutConfig.lessOrEqual) / 2; + if (layoutConfig.lessOrEqual === -1) { + avgScreenSize = layoutConfig.moreOrEqual; + } + + const layouts = [ + this.dragboard.baseLayout, + this.dragboard.freeLayout, + this.dragboard.leftLayout, + this.dragboard.rightLayout + ]; + const layout = layouts[options.layout]; + + if (layoutConfig.left != null) { + if (layout !== this.dragboard.freeLayout || layoutConfig.relx) { + layoutConfig.left = layout.adaptColumnOffset(layoutConfig.left, avgScreenSize).inLU; + } else { + layoutConfig.left = layout.adaptColumnOffset(layoutConfig.left, avgScreenSize).inPixels; + } + } + if (layoutConfig.top != null) { + if (layout !== this.dragboard.freeLayout || layoutConfig.rely) { + layoutConfig.top = layout.adaptRowOffset(layoutConfig.top).inLU; + } else { + layoutConfig.top = layout.adaptRowOffset(layoutConfig.top).inPixels; + } + } + if (layout !== this.dragboard.freeLayout || layoutConfig.relheight) { + layoutConfig.height = clean_number(layout.adaptHeight(layoutConfig.height).inLU, 1); } else { - options.left = layout.adaptColumnOffset(options.left).inPixels; + layoutConfig.height = clean_number(layout.adaptHeight(layoutConfig.height).inPixels, 1); } - } - if (options.top != null) { - if (layout !== this.dragboard.freeLayout || options.rely) { - options.top = layout.adaptRowOffset(options.top).inLU; + if (layout !== this.dragboard.freeLayout || layoutConfig.relwidth) { + layoutConfig.width = clean_number(layout.adaptWidth(layoutConfig.width, avgScreenSize).inLU, 1, layout.columns); } else { - options.top = layout.adaptRowOffset(options.top).inPixels; + layoutConfig.width = clean_number(layout.adaptWidth(layoutConfig.width, avgScreenSize).inPixels, 1); } - } - if (layout !== this.dragboard.freeLayout || options.relheight) { - options.height = clean_number(layout.adaptHeight(options.height).inLU, 1); - } else { - options.height = clean_number(layout.adaptHeight(options.height).inPixels, 1); - } - if (layout !== this.dragboard.freeLayout || options.relwidth) { - options.width = clean_number(layout.adaptWidth(options.width).inLU, 1, layout.columns); - } else { - options.width = clean_number(layout.adaptWidth(options.width).inPixels, 1); - } - if (options.left == null || options.top == null) { - if (options.refposition && "searchBestPosition" in layout) { - layout.searchBestPosition(options); - } else if ("_searchFreeSpace" in layout) { - const position = layout._searchFreeSpace(options.width, options.height); - options.left = position.x; - options.top = position.y; - } else { - options.left = 0; - options.top = 0; + if (layoutConfig.left == null || layoutConfig.top == null) { + if (layoutConfig.refposition && "searchBestPosition" in layout) { + layout.searchBestPosition(layoutConfig, avgScreenSize); + } else if ("_searchFreeSpace2" in layout) { + const matrix = Wirecloud.Utils.getLayoutMatrix(layout, layout.dragboard.widgets, avgScreenSize); + const position = layout._searchFreeSpace2(layoutConfig.width, layoutConfig.height, matrix); + layoutConfig.left = position.x; + layoutConfig.top = position.y; + } else { + layoutConfig.left = 0; + layoutConfig.top = 0; + } } - } + }); + + options.layoutConfigurations = layoutConfigs; if (!options.commit) { return this.findWidget(this.model.createWidget(resource, options).id); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index f4aef2ce95..01b14b517e 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -37,7 +37,7 @@ this.widgets.forEach((widget, index) => { widget.setPosition({ z: index - }); + }, false); }); }; @@ -189,6 +189,14 @@ return this; } + refreshPositionBasedOnZIndex() { + // Reorder widgets based on their z-index. This is used when the screen size changes + // and the widgets are not in the correct order. + this.widgets.sort((a, b) => { + return a.position.z - b.position.z; + }); + } + paint() { if (this.painted) { @@ -210,10 +218,21 @@ this.painted = true; } + resetLayouts() { + this.painted = false; + this.fulldragboardLayout = new Wirecloud.ui.FullDragboardLayout(this); + this.baseLayout = this._buildLayoutFromPreferences(); + this.freeLayout = new Wirecloud.ui.FreeLayout(this); + this.leftLayout = new Wirecloud.ui.SidebarLayout(this); + this.rightLayout = new Wirecloud.ui.SidebarLayout(this, {position: "right"}); + this.bottomLayout = new Wirecloud.ui.SidebarLayout(this, {position: "bottom"}); + this.topLayout = new Wirecloud.ui.SidebarLayout(this, {position: "top"}); + } + /** * */ - update(ids) { + update(ids, allLayoutConfigurations) { if (this.tab.workspace.editing === false) { return Promise.resolve(this); } @@ -233,11 +252,18 @@ return Promise.resolve(this); } + // We convert the content to JSON + const JSONcontent = content.map((widget) => { + return widget.toJSON('update', allLayoutConfigurations); + }); + + console.log('Updating widgets:', content); + return Wirecloud.io.makeRequest(url, { method: 'PUT', requestHeaders: {'Accept': 'application/json'}, contentType: 'application/json', - postBody: JSON.stringify(content) + postBody: JSON.stringify(JSONcontent) }).then((response) => { if ([204, 401, 403, 404, 500].indexOf(response.status) === -1) { return Promise.reject(utils.gettext("Unexpected response from server")); @@ -277,8 +303,9 @@ newBaseLayout.initialize(); // Change our base layout - this.baseLayout.moveTo(newBaseLayout); + const oldBaseLayout = this.baseLayout; this.baseLayout = newBaseLayout; + oldBaseLayout.moveTo(newBaseLayout); } _addWidget(widget) { diff --git a/src/wirecloud/platform/workspace/utils.py b/src/wirecloud/platform/workspace/utils.py index dd695e60df..24a72283f3 100644 --- a/src/wirecloud/platform/workspace/utils.py +++ b/src/wirecloud/platform/workspace/utils.py @@ -515,7 +515,6 @@ def get_tab_data(tab, workspace=None, cache_manager=None, user=None): def get_iwidget_data(iwidget, workspace, cache_manager=None, user=None): - widget_position = iwidget.positions.get('widget', {}) permissions = iwidget.permissions if workspace.creator != user and 'owner' in permissions: del permissions['owner'] @@ -526,25 +525,51 @@ def get_iwidget_data(iwidget, workspace, cache_manager=None, user=None): 'tab': iwidget.tab.id, 'layout': iwidget.layout, 'widget': iwidget.widget_uri, - 'top': widget_position.get('top', 0), - 'left': widget_position.get('left', 0), - 'anchor': widget_position.get('anchor', 'top-left'), - 'relx': True if iwidget.layout != 1 else widget_position.get('relx', True), - 'rely': True if iwidget.layout != 1 else widget_position.get('rely', False), - 'relheight': True if iwidget.layout != 1 else widget_position.get('relheight', False), - 'relwidth': True if iwidget.layout != 1 else widget_position.get('relwidth', True), - 'zIndex': widget_position.get('zIndex', 0), - 'width': widget_position.get('width', 0), - 'height': widget_position.get('height', 0), - 'fulldragboard': widget_position.get('fulldragboard', False), - 'minimized': widget_position.get('minimized', False), + 'layoutConfigurations': [], 'readonly': iwidget.readOnly, 'permissions': permissions, 'preferences': {}, - 'properties': {}, - 'titlevisible': widget_position.get('titlevisible', True), + 'properties': {} } + # Fix old iwidget format + if not 'configurations' in iwidget.positions: + iwidget.positions['configurations'] = [ + { + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'id': 0, + 'widget': iwidget.positions.get('widget') + } + ] + + del iwidget.positions['widget'] + + iwidget.save() + + for layoutConfiguration in iwidget.positions.get('configurations'): + widget_position = layoutConfiguration.get('widget', {}) + dataLayout = { + 'top': widget_position.get('top', 0), + 'left': widget_position.get('left', 0), + 'anchor': widget_position.get('anchor', 'top-left'), + 'relx': True if iwidget.layout != 1 else widget_position.get('relx', True), + 'rely': True if iwidget.layout != 1 else widget_position.get('rely', False), + 'relheight': True if iwidget.layout != 1 else widget_position.get('relheight', False), + 'relwidth': True if iwidget.layout != 1 else widget_position.get('relwidth', True), + 'zIndex': widget_position.get('zIndex', 0), + 'width': widget_position.get('width', 0), + 'height': widget_position.get('height', 0), + 'fulldragboard': widget_position.get('fulldragboard', False), + 'minimized': widget_position.get('minimized', False), + 'titlevisible': widget_position.get('titlevisible', True), + 'id': layoutConfiguration.get('id', 0), + 'moreOrEqual': layoutConfiguration.get('moreOrEqual', 0), + 'lessOrEqual': layoutConfiguration.get('lessOrEqual', -1) + } + + data_ret['layoutConfigurations'].append(dataLayout) + if iwidget.widget is None or not iwidget.widget.resource.is_available_for(workspace.creator): # The widget used by this iwidget is missing return data_ret From dbca9f86c72f135f887d5787600640717ee87034 Mon Sep 17 00:00:00 2001 From: oxixes Date: Mon, 27 May 2024 12:03:15 +0200 Subject: [PATCH 02/28] Added editing UI for screen sizes --- .../catalogue/locale/es/LC_MESSAGES/django.po | 10 +- .../catalogue/locale/ja/LC_MESSAGES/django.po | 39 +- .../commons/static/js/StyledElements/Alert.js | 26 + .../static/js/StyledElements/CodeArea.js | 1 - .../js/StyledElements/InputInterface.js | 26 + .../js/StyledElements/InputInterfaces.js | 6 +- .../static/js/StyledElements/NumericField.js | 26 +- .../js/wirecloud/ui/InputInterfaceFactory.js | 1 + .../locale/es/LC_MESSAGES/django.po | 8 +- .../static/css/screen_size_field.css | 29 + .../styledelements/styled_numeric_field.scss | 1 - .../static/css/workspace/dragboard.scss | 21 + src/wirecloud/platform/core/plugins.py | 15 + src/wirecloud/platform/iwidget/utils.py | 37 +- .../platform/locale/es/LC_MESSAGES/django.po | 381 +++-- .../locale/es/LC_MESSAGES/djangojs.po | 1444 +++++++++------- .../platform/locale/ja/LC_MESSAGES/django.po | 390 +++-- .../locale/ja/LC_MESSAGES/djangojs.po | 1457 ++++++++++------- .../static/js/wirecloud/ui/ColumnLayout.js | 2 +- .../static/js/wirecloud/ui/DragboardLayout.js | 9 + .../js/wirecloud/ui/LayoutInputInterface.js | 2 +- .../js/wirecloud/ui/PreferencesWindowMenu.js | 22 +- .../wirecloud/ui/ScreenSizesInputInterface.js | 271 +++ .../static/js/wirecloud/ui/WidgetView.js | 12 +- .../js/wirecloud/ui/WorkspaceTabView.js | 82 +- .../wirecloud/ui/WorkspaceTabViewDragboard.js | 153 +- .../static/js/wirecloud/ui/WorkspaceView.js | 3 + 27 files changed, 2801 insertions(+), 1673 deletions(-) create mode 100644 src/wirecloud/defaulttheme/static/css/screen_size_field.css create mode 100644 src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js diff --git a/src/wirecloud/catalogue/locale/es/LC_MESSAGES/django.po b/src/wirecloud/catalogue/locale/es/LC_MESSAGES/django.po index 7cb4191730..1892384b6f 100644 --- a/src/wirecloud/catalogue/locale/es/LC_MESSAGES/django.po +++ b/src/wirecloud/catalogue/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-06-04 10:19+0200\n" +"POT-Creation-Date: 2024-05-27 12:00+0200\n" "PO-Revision-Date: 2019-06-04 10:21+0200\n" "Last-Translator: Álvaro Arranz García \n" "Language-Team: Español/España\n" @@ -167,11 +167,11 @@ msgstr "Error abriendo el fichero de registro de cambios" #: views.py:286 #, python-format msgid "" -"You can find the userguide of this component in this external link" +"You can find the userguide of this component in this external link" msgstr "" -"Puedes encontrar la documentación de este recurso in este enlace externo" +"Puedes encontrar la documentación de este recurso in este enlace externo" #: views.py:302 msgid "Error opening the userguide file" diff --git a/src/wirecloud/catalogue/locale/ja/LC_MESSAGES/django.po b/src/wirecloud/catalogue/locale/ja/LC_MESSAGES/django.po index 673c19b284..630561fd9c 100644 --- a/src/wirecloud/catalogue/locale/ja/LC_MESSAGES/django.po +++ b/src/wirecloud/catalogue/locale/ja/LC_MESSAGES/django.po @@ -10,21 +10,25 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-15 00:00+0900\n" +"POT-Creation-Date: 2024-05-27 12:00+0200\n" "PO-Revision-Date: 2019-03-15 00:00+0900\n" +"Last-Translator: Kazuhito Suda \n" +"Language-Team: Kazuhito Suda \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"Last-Translator: Kazuhito Suda \n" -"Language-Team: Kazuhito Suda \n" "X-Generator: Poedit 2.2.1\n" #: management/commands/addtocatalogue.py:82 +#, fuzzy +#| msgid "" +#| "You must use at least one of the following flags: --redeploy, --users, --" +#| "groups or --public " msgid "" "You must use at least one of the following flags: --redeploy, --users, --" -"groups or --public " +"groups or --public" msgstr "" "次のフラグの少なくとも1つを使用する必要があります: --redeploy, --users, --" "groups または --public " @@ -43,8 +47,8 @@ msgstr "\"%(file_name)s\" から \"%(name)s\" を正常にインポートしま #, python-format msgid "Failed to import the mashable application component from %(file_name)s" msgstr "" -"マッシュアップ・アプリケーションのコンポーネントを %(file_name)s からイン" -"ポートできませんでした" +"マッシュアップ・アプリケーションのコンポーネントを %(file_name)s からインポー" +"トできませんでした" #: models.py:44 msgid "Vendor" @@ -126,29 +130,24 @@ msgid "" "Error writing the resource into the filesystem. Please, contact the server " "administrator." msgstr "" -"ファイル・システムへのリソースの書き込み中にエラーが発生しました。" -"サーバ管理者に連絡してください。" +"ファイル・システムへのリソースの書き込み中にエラーが発生しました。サーバ管理" +"者に連絡してください。" -#: views.py:112 +#: views.py:130 #, python-format msgid "Invalid pagenum value: %s" msgstr "無効な pagenum 値: %s" -#: views.py:130 +#: views.py:136 #, python-format msgid "Invalid maxresults value: %s" msgstr "無効な maxresults 値: %s" -#: views.py:136 +#: views.py:140 #, python-format msgid "Orderby value not supported: %s" msgstr "Orderby 値はサポートされていません: %s" -#: views.py:140 -#, python-format -msgid "Scope value not supported: %s" -msgstr "スコープ値はサポートされていません: %s" - #: views.py:149 #, python-format msgid "Scope value not supported: %s" @@ -174,11 +173,11 @@ msgstr "変更履歴ファイルを開く際にエラーが発生しました" #: views.py:286 #, python-format msgid "" -"You can find the userguide of this component in this external link" +"You can find the userguide of this component in this external link" msgstr "" -"このコンポーネントのユーザ・ガイドは、この" -"リンクで見つけることができます" +"このコンポーネントのユーザ・ガイドは、このリ" +"ンクで見つけることができます" #: views.py:302 msgid "Error opening the userguide file" diff --git a/src/wirecloud/commons/static/js/StyledElements/Alert.js b/src/wirecloud/commons/static/js/StyledElements/Alert.js index 0cf6a82e37..928ea4c8c0 100644 --- a/src/wirecloud/commons/static/js/StyledElements/Alert.js +++ b/src/wirecloud/commons/static/js/StyledElements/Alert.js @@ -73,6 +73,7 @@ class: "se-alert-body" }); body.appendChild(options.message).insertInto(this.wrapperElement); + this.body = body; Object.defineProperties(this, { heading: {value: heading}, @@ -101,6 +102,31 @@ return blockquote; } + /** + * setMessage + * + * @param {String} message + * The message to be displayed. + */ + setMessage(message) { + this.body.clear(); + this.body.appendChild(message); + } + + /** + * show + */ + show() { + this.wrapperElement.style.display = ''; + } + + /** + * hide + */ + hide() { + this.wrapperElement.style.display = 'none'; + } + } })(StyledElements, StyledElements.Utils); diff --git a/src/wirecloud/commons/static/js/StyledElements/CodeArea.js b/src/wirecloud/commons/static/js/StyledElements/CodeArea.js index dcc4bae4c0..164a133b11 100644 --- a/src/wirecloud/commons/static/js/StyledElements/CodeArea.js +++ b/src/wirecloud/commons/static/js/StyledElements/CodeArea.js @@ -148,7 +148,6 @@ if (!window.monaco) { // If monaco is not available, use the TextArea class se.CodeArea = se.TextArea; - se.__Testing__CodeArea = CodeAreaClass; // For testing purposes } else { se.CodeArea = CodeAreaClass; } diff --git a/src/wirecloud/commons/static/js/StyledElements/InputInterface.js b/src/wirecloud/commons/static/js/StyledElements/InputInterface.js index 144cc8550a..6abd1e034b 100644 --- a/src/wirecloud/commons/static/js/StyledElements/InputInterface.js +++ b/src/wirecloud/commons/static/js/StyledElements/InputInterface.js @@ -63,6 +63,8 @@ } else { this._description = options.label; } + + this._eventListeners = {}; } repaint() { @@ -144,6 +146,30 @@ return se.InputValidationError.NO_ERROR; } + /** + * @private + * + * Calls the event listeners for the given event type. + */ + _callEvent(type, event) { + if (type in this._eventListeners) { + this._eventListeners[type].forEach(function (listener) { + listener(event); + }); + } + } + + /** + * Adds an event listener to this InputInterface. + */ + addEventListener(eventType, listener) { + if (!(eventType in this._eventListeners)) { + this._eventListeners[eventType] = []; + } + + this._eventListeners[eventType].push(listener); + } + /** * Checks if the given value is valid for this InputInterface. * diff --git a/src/wirecloud/commons/static/js/StyledElements/InputInterfaces.js b/src/wirecloud/commons/static/js/StyledElements/InputInterfaces.js index 54aaaada1d..09ce5d317f 100644 --- a/src/wirecloud/commons/static/js/StyledElements/InputInterfaces.js +++ b/src/wirecloud/commons/static/js/StyledElements/InputInterfaces.js @@ -36,7 +36,8 @@ COLOR_ERROR: 5, BOOLEAN_ERROR: 6, VERSION_ERROR: 7, - OUT_OF_RANGE_ERROR: 8 + OUT_OF_RANGE_ERROR: 8, + SCREEN_SIZES_ERROR: 9 }; se.ValidationErrorManager = class ValidationErrorManager { @@ -89,6 +90,9 @@ case StyledElements.InputValidationError.OUT_OF_RANGE_ERROR: msg = StyledElements.Utils.gettext("The following fields does contain an out of range value: %(fields)s."); break; + case StyledElements.InputValidationError.SCREEN_SIZES_ERROR: + msg = StyledElements.Utils.gettext("The sceen sizes are not correct. They must cover the whole range of possible screen sizes without gaps or overlaps."); + break; } let fields = ""; diff --git a/src/wirecloud/commons/static/js/StyledElements/NumericField.js b/src/wirecloud/commons/static/js/StyledElements/NumericField.js index da1a69da00..1d34e0a441 100644 --- a/src/wirecloud/commons/static/js/StyledElements/NumericField.js +++ b/src/wirecloud/commons/static/js/StyledElements/NumericField.js @@ -82,6 +82,9 @@ 'max': Number.POSITIVE_INFINITY, 'inc': 1 }; + + options = utils.merge({}, defaultOptions, options); + options.min = Number(options.min); options.max = Number(options.max); options.inc = Number(options.inc); @@ -89,12 +92,20 @@ super(options.initialValue, ['change', 'focus', 'blur']); - this.options = options = utils.merge({}, defaultOptions, options); + this.options = options; this.wrapperElement = document.createElement("div"); this.wrapperElement.className = "se-numeric-field"; this.inputElement = document.createElement("input"); - this.inputElement.setAttribute("type", "text"); + this.inputElement.setAttribute("type", "number"); + this.inputElement.setAttribute("step", options.inc); + if (options.min !== Number.NEGATIVE_INFINITY) { + this.inputElement.setAttribute("min", options.min); + } + + if (options.max !== Number.POSITIVE_INFINITY) { + this.inputElement.setAttribute("max", options.max); + } if (options.name != null) { this.inputElement.setAttribute("name", options.name); @@ -106,19 +117,16 @@ this.inputElement.setAttribute("value", options.initialValue); - const topButton = new StyledElements.Button({'class': 'se-numeric-field-top-button', iconClass: 'fas fa-caret-up'}); - const bottomButton = new StyledElements.Button({'class': 'se-numeric-field-bottom-button', iconClass: 'fas fa-caret-down'}); - /* Internal events */ - topButton.addEventListener("click", update.bind(this, options.inc)); - bottomButton.addEventListener("click", update.bind(this, -options.inc)); this.inputElement.addEventListener("focus", onfocus.bind(this), true); this.inputElement.addEventListener("blur", onblur.bind(this), true); this.inputElement.addEventListener("keydown", utils.stopInputKeydownPropagationListener, false); + this.inputElement.addEventListener("change", (e) => { + this.dispatchEvent('change', e); + }); + this.wrapperElement.appendChild(this.inputElement); - topButton.insertInto(this.wrapperElement); - bottomButton.insertInto(this.wrapperElement); } getValue() { diff --git a/src/wirecloud/commons/static/js/wirecloud/ui/InputInterfaceFactory.js b/src/wirecloud/commons/static/js/wirecloud/ui/InputInterfaceFactory.js index 80182b1f53..f496d0c66f 100644 --- a/src/wirecloud/commons/static/js/wirecloud/ui/InputInterfaceFactory.js +++ b/src/wirecloud/commons/static/js/wirecloud/ui/InputInterfaceFactory.js @@ -29,6 +29,7 @@ const InputInterfaceFactory = new StyledElements.InputInterfaceFactory(); InputInterfaceFactory.addFieldType('layout', Wirecloud.ui.LayoutInputInterface); + InputInterfaceFactory.addFieldType('screenSizes', Wirecloud.ui.ScreenSizesInputInterface); InputInterfaceFactory.addFieldType('parametrizableValue', Wirecloud.ui.ParametrizableValueInputInterface); InputInterfaceFactory.addFieldType('parametrizedText', Wirecloud.ui.ParametrizedTextInputInterface); InputInterfaceFactory.addFieldType('mac', Wirecloud.ui.MACInputInterface); diff --git a/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po b/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po index b7d51d77c8..ef14733632 100644 --- a/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po +++ b/src/wirecloud/defaulttheme/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-06-04 10:32+0200\n" +"POT-Creation-Date: 2024-05-27 11:17+0200\n" "PO-Revision-Date: 2019-06-04 10:34+0200\n" "Last-Translator: Álvaro Arranz García \n" "Language-Team: Español/España\n" @@ -301,10 +301,14 @@ msgstr "Detalles de la excepción" msgid "Stacktrace" msgstr "Stacktrace" -#: templates/wirecloud/modals/embed_code.html:2 +#: templates/wirecloud/modals/embed_code.html:3 msgid "Theme" msgstr "Estilo" +#: templates/wirecloud/modals/embed_code.html:4 +msgid "Language" +msgstr "Idioma" + #: templates/wirecloud/modals/upgrade_downgrade_component.html:2 msgid "Current version" msgstr "Versión actual" diff --git a/src/wirecloud/defaulttheme/static/css/screen_size_field.css b/src/wirecloud/defaulttheme/static/css/screen_size_field.css new file mode 100644 index 0000000000..c5e3b79497 --- /dev/null +++ b/src/wirecloud/defaulttheme/static/css/screen_size_field.css @@ -0,0 +1,29 @@ +.se-screen-size-field > .se-container { + display: flex; + margin: 0; +} + +.se-screen-size-from, .se-screen-size-to { + flex-grow: 1; +} + +.se-screen-size-from { + margin-left: 0; +} + +.se-screen-size-buttons { + margin-right: 0; +} + +.se-screen-size-field > .se-btn { + margin-left: 0; + margin-top: 6px; +} + +.se-screen-size-field > .se-container > .se-container > .se-numeric-field > input { + height: 100%; +} + +.se-screen-size-field > .se-container > .se-container > .se-add-on { + white-space: nowrap; +} \ No newline at end of file diff --git a/src/wirecloud/defaulttheme/static/css/styledelements/styled_numeric_field.scss b/src/wirecloud/defaulttheme/static/css/styledelements/styled_numeric_field.scss index 7500f47edd..cd0cb1f0b5 100644 --- a/src/wirecloud/defaulttheme/static/css/styledelements/styled_numeric_field.scss +++ b/src/wirecloud/defaulttheme/static/css/styledelements/styled_numeric_field.scss @@ -27,7 +27,6 @@ .se-numeric-field { @include input-root-style(); margin: 1px 4px 9px 4px; - padding: 0 24px 0 0; position: relative; width: 10em; diff --git a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss index a1d82b8f6c..71a3d3c4d3 100644 --- a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss +++ b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss @@ -113,3 +113,24 @@ padding-top: 2px; padding-bottom: 3px; } + +.wc-editing-interval { + background-color: #000; + opacity: 0.8; + position: fixed; + z-index: 101110; + color: #fff; + padding: 10px; + border-radius: 7px; + right: 50px; +} + +.wc-editing-interval-close { + color: #fff; + margin-left: 10px; +} + +.wc-editing-interval-close:hover { + cursor: pointer; + color: #fff; +} \ No newline at end of file diff --git a/src/wirecloud/platform/core/plugins.py b/src/wirecloud/platform/core/plugins.py index 0c72e3edc4..0b57961e9f 100644 --- a/src/wirecloud/platform/core/plugins.py +++ b/src/wirecloud/platform/core/plugins.py @@ -141,6 +141,7 @@ 'js/wirecloud/ui/ParametrizableValueInputInterface.js', 'js/wirecloud/ui/ParametrizedTextInputInterface.js', 'js/wirecloud/ui/LayoutInputInterface.js', + 'js/wirecloud/ui/ScreenSizesInputInterface.js', 'js/StyledElements/VersionInputInterface.js', 'js/StyledElements/InputInterfaceFactory.js', 'js/StyledElements/DefaultInputInterfaceFactory.js', @@ -170,6 +171,7 @@ CLASSIC_CORE_CSS = ( 'css/mac_search.scss', 'css/layout_field.css', + 'css/screen_size_field.css', 'css/mac_field.scss', 'css/mac_selection_dialog.css', ) @@ -435,6 +437,19 @@ def get_workspace_preferences(self): ], "description": _("Default layout for the new widgets.") }, + { + "name": "screenSizes", + "defaultValue": [ + { + "moreOrEqual": 0, + "lessOrEqual": -1, + "id": 0 + } + ], + "label": _("Screen sizes"), + "type": "screenSizes", + "description": _("List of screen sizes supported by the workspace. Each screen size is defined by a range of screen widths and different widget configurations are associated with it.") + }, { "name": "baselayout", "defaultValue": { diff --git a/src/wirecloud/platform/iwidget/utils.py b/src/wirecloud/platform/iwidget/utils.py index f52b495e3f..f33ab5694d 100644 --- a/src/wirecloud/platform/iwidget/utils.py +++ b/src/wirecloud/platform/iwidget/utils.py @@ -249,33 +249,34 @@ def SaveIWidget(iwidget, user, tab, initial_variable_values=None, commit=True): new_iwidget.name = iwidget_info['title'] new_iwidget.layout = iwidget.get('layout', 0) - # set default positions new_iwidget.positions = { - 'configurations': [ - { - 'moreOrEqual': 0, - 'lessOrEqual': -1, - 'id': 0, - 'widget': { - 'top': 0, - 'left': 0, - 'zIndex': 0, - 'height': 1, - 'width': 1, - 'minimized': False, - 'titlevisible': True, - 'fulldragboard': False, - }, - } - ] + 'configurations': [] } + if initial_variable_values is not None: set_initial_values(new_iwidget, initial_variable_values, iwidget_info, user) update_title_value(new_iwidget, iwidget) if "layoutConfigurations" in iwidget: update_position(new_iwidget, 'widget', iwidget) + else: + # set default positions + new_iwidget.positions['configurations'] = [{ + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'id': 0, + 'widget': { + 'top': 0, + 'left': 0, + 'zIndex': 0, + 'height': 1, + 'width': 1, + 'minimized': False, + 'titlevisible': True, + 'fulldragboard': False, + }, + }] if commit: new_iwidget.save() diff --git a/src/wirecloud/platform/locale/es/LC_MESSAGES/django.po b/src/wirecloud/platform/locale/es/LC_MESSAGES/django.po index 6b2a906104..60eef2a548 100644 --- a/src/wirecloud/platform/locale/es/LC_MESSAGES/django.po +++ b/src/wirecloud/platform/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-06-04 10:48+0200\n" +"POT-Creation-Date: 2024-05-27 11:21+0200\n" "PO-Revision-Date: 2019-06-04 10:48+0200\n" "Last-Translator: Álvaro Arranz García \n" "Language-Team: Español/España\n" @@ -19,7 +19,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.2\n" -#: admin.py:64 +#: admin.py:71 msgid "Edit" msgstr "Editar" @@ -32,77 +32,87 @@ msgstr "Concepto" msgid "Value" msgstr "Valor" -#: core/catalogue_manager.py:58 +#: core/catalogue_manager.py:49 #, python-format msgid "Resource already exists %(resource_id)s" msgstr "El recurso ya existe (%(resource_id)s)" -#: core/plugins.py:266 +#: core/plugins.py:283 msgid "Language" msgstr "Idioma" -#: core/plugins.py:267 +#: core/plugins.py:284 msgid "Current language used in the platform" msgstr "Idioma actualmente utilizado en la plataforma" -#: core/plugins.py:270 +#: core/plugins.py:287 msgid "Username" msgstr "Nombre de usuario" -#: core/plugins.py:271 +#: core/plugins.py:288 msgid "User name of the current logged user" msgstr "Nombre de usuario del usuario actual" -#: core/plugins.py:274 +#: core/plugins.py:291 msgid "Full name" msgstr "Nombre completo" -#: core/plugins.py:275 +#: core/plugins.py:292 msgid "Full name of the logged user" msgstr "Nombre completo del usuario actual" -#: core/plugins.py:278 +#: core/plugins.py:295 msgid "Avatar" msgstr "Avatar" -#: core/plugins.py:279 +#: core/plugins.py:296 msgid "URL of the avatar" msgstr "URL del avatar" -#: core/plugins.py:282 +#: core/plugins.py:299 msgid "Is Anonymous" msgstr "Es anónimo" -#: core/plugins.py:283 +#: core/plugins.py:300 msgid "Boolean. Designates whether current user is logged in the system." msgstr "" "Boleano. Indica cuando hay un usuario registrado actualmente en el sistema." -#: core/plugins.py:286 +#: core/plugins.py:303 msgid "Is Staff" msgstr "Es personal" -#: core/plugins.py:287 +#: core/plugins.py:304 msgid "Boolean. Designates whether current user can access the admin site." msgstr "" "Boleano. Indica cuando el usuario actual puede acceder al panel de " "administración." -#: core/plugins.py:290 +#: core/plugins.py:307 msgid "Is Superuser" msgstr "Es superusuario" -#: core/plugins.py:291 +#: core/plugins.py:308 msgid "Boolean. Designates whether current user is a super user." msgstr "" "Booleano. Indica cuando el usuario actualmente registrado es un super " "usuario." -#: core/plugins.py:294 +#: core/plugins.py:311 +#, fuzzy +#| msgid "Groups" +msgid "User Groups" +msgstr "Grupos" + +#: core/plugins.py:312 +msgid "List of the groups the user belongs to." +msgstr "" + +#: core/plugins.py:315 msgid "Mode" msgstr "Modo" -#: core/plugins.py:295 +#: core/plugins.py:316 msgid "" "Rendering mode used by the platform (available modes: classic, smartphone " "and embedded)" @@ -110,35 +120,55 @@ msgstr "" "Modo de funcionamiento usado por la plataforma (modos disponibles: classic, " "smartphone y embedded)" -#: core/plugins.py:298 +#: core/plugins.py:319 +msgid "User Organizations" +msgstr "" + +#: core/plugins.py:320 +msgid "List of the organizations the user belongs to." +msgstr "" + +#: core/plugins.py:323 msgid "Orientation" msgstr "Orientación" -#: core/plugins.py:299 +#: core/plugins.py:324 msgid "Current screen orientation" msgstr "Orientación actual de la plataforma" -#: core/plugins.py:302 +#: core/plugins.py:327 +#, fuzzy +#| msgid "Username" +msgid "Real User Username" +msgstr "Nombre de usuario" + +#: core/plugins.py:328 +#, fuzzy +#| msgid "User name of the current logged user" +msgid "User name of the real logged user" +msgstr "Nombre de usuario del usuario actual" + +#: core/plugins.py:331 msgid "Theme" msgstr "Estilo" -#: core/plugins.py:303 +#: core/plugins.py:332 msgid "Name of the theme used by the platform" msgstr "Nombre del estilo usado por la plataforma" -#: core/plugins.py:306 +#: core/plugins.py:335 msgid "Version" msgstr "Versión" -#: core/plugins.py:307 +#: core/plugins.py:336 msgid "Version of the platform" msgstr "Versión de la plataforma" -#: core/plugins.py:310 +#: core/plugins.py:339 msgid "Version Hash" msgstr "Hash de la versión" -#: core/plugins.py:311 +#: core/plugins.py:340 msgid "" "Hash for the current version of the platform. This hash changes when the " "platform is updated or when an addon is added or removed" @@ -146,59 +176,71 @@ msgstr "" "Hash asignado a la versión actual de la plataforma. Este bash cambia cuando " "la plataforma se actualiza o cuando un adán es activado o desactivado" -#: core/plugins.py:322 +#: core/plugins.py:351 msgid "Anonymous" msgstr "Anónimo" -#: core/plugins.py:343 workspace/models.py:38 workspace/models.py:104 +#: core/plugins.py:378 workspace/models.py:49 +msgid "Description" +msgstr "Descripción" + +#: core/plugins.py:379 +msgid "Short description of the workspace without formating" +msgstr "Descripción corta del dashboard sin formato" + +#: core/plugins.py:382 +msgid "Editing mode" +msgstr "" + +#: core/plugins.py:383 +#, fuzzy +#| msgid "Boolean. Designates whether current user is a super user." +msgid "Boolean. Designates whether the workspace is in editing mode." +msgstr "" +"Booleano. Indica cuando el usuario actualmente registrado es un super " +"usuario." + +#: core/plugins.py:386 workspace/models.py:39 workspace/models.py:125 msgid "Title" msgstr "Título" -#: core/plugins.py:344 +#: core/plugins.py:387 msgid "Current title of the workspace" msgstr "Título actual del entorno de trabajo" -#: core/plugins.py:347 iwidget/models.py:31 markets/models.py:29 +#: core/plugins.py:390 iwidget/models.py:31 markets/models.py:29 #: markets/models.py:46 preferences/models.py:29 preferences/models.py:43 -#: preferences/models.py:58 workspace/models.py:36 workspace/models.py:103 +#: preferences/models.py:58 workspace/models.py:37 workspace/models.py:124 msgid "Name" msgstr "Nombre" -#: core/plugins.py:348 +#: core/plugins.py:391 msgid "Current name of the workspace" msgstr "Nombre actual del entorno de trabajo" -#: core/plugins.py:351 +#: core/plugins.py:394 msgid "Owner" msgstr "Dueño" -#: core/plugins.py:352 +#: core/plugins.py:395 msgid "Workspace's owner username" msgstr "Nombre de usuario del dueño del entorno de trabajo" -#: core/plugins.py:355 workspace/models.py:47 -msgid "Description" -msgstr "Descripción" - -#: core/plugins.py:356 -msgid "Short description of the workspace without formating" -msgstr "Descripción corta del dashboard sin formato" - -#: core/plugins.py:359 workspace/models.py:48 +#: core/plugins.py:398 workspace/models.py:50 msgid "Long description" msgstr "Descripción larga" -#: core/plugins.py:360 +#: core/plugins.py:399 msgid "" "Detailed workspace's description. This description can contain formatting." msgstr "" "Descripción detallada del workspace. Esta descripción puede contener formato." -#: core/plugins.py:375 markets/models.py:30 +#: core/plugins.py:408 markets/models.py:30 msgid "Public" msgstr "Público" -#: core/plugins.py:378 +#: core/plugins.py:411 msgid "" "Allow any user to open this workspace (in read-only mode). (default: " "disabled)" @@ -206,33 +248,57 @@ msgstr "" "Permite a cualquier usuario acceder a este entorno de trabajo (en modo de " "solo lectura). (valor por defecto: deshabilitado)" -#: core/plugins.py:383 +#: core/plugins.py:416 +msgid "Required registered user" +msgstr "" + +#: core/plugins.py:419 +msgid "" +"Require users to be logged in to access the workspace (This option has only " +"effect if the workspace is public). (default: disabled)" +msgstr "" + +#: core/plugins.py:424 msgid "Share list" msgstr "Lista de compartidos" -#: core/plugins.py:386 +#: core/plugins.py:427 msgid "List of users with access to this workspace. (default: [])" msgstr "" "Lista de usuarios con acceso a este entorno de trabajo. (valor por defecto: " "[])" -#: core/plugins.py:391 +#: core/plugins.py:432 msgid "Default layout" msgstr "Esquema por defecto" -#: core/plugins.py:394 +#: core/plugins.py:435 msgid "Base" msgstr "Base" -#: core/plugins.py:395 +#: core/plugins.py:436 msgid "Free" msgstr "Libre" -#: core/plugins.py:397 +#: core/plugins.py:438 msgid "Default layout for the new widgets." msgstr "Distribución por defecto para los nuevos widgets." -#: core/plugins.py:409 +#: core/plugins.py:449 +msgid "Screen sizes" +msgstr "Tamaños de pantalla" + +#: core/plugins.py:451 +msgid "" +"List of screen sizes supported by the workspace. Each screen size is defined " +"by a range of screen widths and different widget configurations are " +"associated with it." +msgstr "" +"Lista de tamaños de pantalla soportados por el entorno de trabajo. Cada " +"tamaño de pantalla está definido por un rango de anchuras de pantalla y " +"diferentes configuraciones de widgets están asociadas a él." + +#: core/plugins.py:463 msgid "Base layout" msgstr "Distribución base" @@ -244,7 +310,7 @@ msgstr "Widget" msgid "Widget URI" msgstr "Widget URI" -#: iwidget/models.py:32 workspace/utils.py:472 workspace/views.py:61 +#: iwidget/models.py:32 workspace/utils.py:422 workspace/views.py:62 msgid "Tab" msgstr "Pestaña" @@ -252,32 +318,44 @@ msgstr "Pestaña" msgid "Layout" msgstr "Distribución" -#: iwidget/models.py:35 +#: iwidget/models.py:36 msgid "Read Only" msgstr "Sólo lectura" -#: iwidget/utils.py:70 +#: iwidget/utils.py:71 #, python-format msgid "Field %(field)s must contain a boolean value" msgstr "El campo %(field)s tiene que contener un valor booleado" -#: iwidget/utils.py:81 iwidget/utils.py:94 +#: iwidget/utils.py:80 iwidget/utils.py:93 iwidget/utils.py:106 #, python-format msgid "Field %(field)s must contain a number value" msgstr "El campo %(field)s tiene que contener un valor númerico" -#: iwidget/utils.py:84 iwidget/utils.py:97 +#: iwidget/utils.py:83 iwidget/utils.py:96 iwidget/utils.py:109 #, python-format msgid "Invalid value for %(field)s" msgstr "Valor inválido para el campo %(field)s" -#: iwidget/utils.py:137 +#: iwidget/utils.py:119 +#, fuzzy +#| msgid "Field %(field)s must contain a number value" +msgid "anchor field must contain a string value" +msgstr "El campo %(field)s tiene que contener un valor númerico" + +#: iwidget/utils.py:122 +#, fuzzy +#| msgid "Invalid value for %(field)s" +msgid "Invalid value for anchor field" +msgstr "Valor inválido para el campo %(field)s" + +#: iwidget/utils.py:225 #, python-format msgid "%(uri)s is not a widget" msgstr "%(uri)s no es un widget" -#: iwidget/views.py:42 iwidget/views.py:214 iwidget/views.py:282 -#: wiring/views.py:404 workspace/views.py:187 workspace/views.py:304 +#: iwidget/views.py:42 iwidget/views.py:217 iwidget/views.py:283 +#: wiring/views.py:407 workspace/views.py:160 workspace/views.py:277 msgid "You don't have permission to access this workspace" msgstr "No tienes permisos para acceder a este entorno de trabajo" @@ -322,7 +400,7 @@ msgstr "" msgid "IWidget cannot be deleted" msgstr "El Widget no puede ser borrado" -#: iwidget/views.py:182 iwidget/views.py:227 +#: iwidget/views.py:182 iwidget/views.py:230 msgid "Missing widget variables cannot be updated" msgstr "Las variables de los widgets ausentes no pueden ser actualizados" @@ -336,18 +414,18 @@ msgstr "Preferencia inválida: \"%s\"" msgid "\"%s\" preference is read only." msgstr "La preferencia \"%s\" es de sólo lectura." -#: iwidget/views.py:201 +#: iwidget/views.py:200 iwidget/views.py:204 msgid "" "You have not enough permission for updating the preferences of the iwidget" msgstr "" "No tienes suficientes permisos para actualizar las preferencias del widget" -#: iwidget/views.py:257 +#: iwidget/views.py:260 #, python-format msgid "Invalid persistent variable: \"%s\"" msgstr "Variable persistente inválida: \"%s\"" -#: iwidget/views.py:264 iwidget/views.py:269 +#: iwidget/views.py:266 iwidget/views.py:270 msgid "" "You have not enough permission for updating the persistent variables of this " "widget" @@ -435,22 +513,22 @@ msgstr "Opciones" msgid "Market" msgstr "Marketplace" -#: markets/views.py:76 +#: markets/views.py:77 msgid "invalid user option" msgstr "opción user inválida" -#: markets/views.py:79 +#: markets/views.py:80 msgid "" "You don't have permissions for adding marketplaces in name of other user" msgstr "" "No tienes permisos suficientes para añadir marketplaces en nombre de otros " "usuarios" -#: markets/views.py:101 markets/views.py:104 markets/views.py:131 +#: markets/views.py:102 markets/views.py:105 markets/views.py:132 msgid "You are not allowed to delete this market" msgstr "No tienes permisos para eliminar este marketplace" -#: markets/views.py:148 markets/views.py:150 +#: markets/views.py:149 markets/views.py:151 msgid "Something went wrong (see details for more info)" msgstr "Algo ha ido mal (mira los detalles para más información)" @@ -458,14 +536,32 @@ msgstr "Algo ha ido mal (mira los detalles para más información)" msgid "Inherit" msgstr "Heredar" -#: preferences/views.py:220 preferences/views.py:273 +#: preferences/views.py:221 preferences/views.py:265 preferences/views.py:357 +msgid "Invalid payload: root type must be object" +msgstr "" + +#: preferences/views.py:225 preferences/views.py:269 preferences/views.py:361 +msgid "Invalid type for pref value: {}" +msgstr "" + +#: preferences/views.py:227 preferences/views.py:271 preferences/views.py:363 +msgid "Invalid structure for pref: {}" +msgstr "" + +#: preferences/views.py:230 preferences/views.py:274 preferences/views.py:366 +#, fuzzy +#| msgid "Invalid value for %(field)s" +msgid "Invalid value for pref: {}" +msgstr "Valor inválido para el campo %(field)s" + +#: preferences/views.py:247 preferences/views.py:339 msgid "You are not allowed to read this workspace" msgstr "No tienes permisos para leer este entorno de trabajo" -#: preferences/views.py:234 preferences/views.py:287 wiring/views.py:72 -#: wiring/views.py:102 wiring/views.py:129 wiring/views.py:293 -#: wiring/views.py:348 workspace/views.py:203 workspace/views.py:316 -#: workspace/views.py:320 workspace/views.py:398 +#: preferences/views.py:261 preferences/views.py:353 wiring/views.py:76 +#: wiring/views.py:106 wiring/views.py:133 wiring/views.py:297 +#: wiring/views.py:351 workspace/views.py:176 workspace/views.py:289 +#: workspace/views.py:367 msgid "You are not allowed to update this workspace" msgstr "No tienes permisos para actualizar este entorno de trabajo" @@ -518,53 +614,53 @@ msgstr "" msgid "Error processing widget code" msgstr "Error procesando el código del widget" -#: wiring/views.py:125 wiring/views.py:267 +#: wiring/views.py:129 wiring/views.py:271 msgid "Read only properties cannot be updated" msgstr "Las variables de solo lectura no se pueden actualizar" -#: wiring/views.py:156 wiring/views.py:160 +#: wiring/views.py:160 wiring/views.py:164 msgid "You are not allowed to remove or update read only connections" msgstr "" "No tienes permisos para eliminar o actualizar conexiones de solo lectura" -#: wiring/views.py:197 +#: wiring/views.py:201 msgid "Read only and hidden preferences cannot be created using this API" msgstr "" "No se pueden crear preferencias de solo lectura u ocultas usando esta API" -#: wiring/views.py:211 +#: wiring/views.py:215 msgid "Read only and hidden preferences cannot be removed" msgstr "Las preferencias de solo lectura y ocultas no se pueden eliminar" -#: wiring/views.py:224 wiring/views.py:264 +#: wiring/views.py:228 wiring/views.py:268 msgid "Read only and hidden status cannot be changed using this API" msgstr "" "Los estados de solo lectura y oculto no se pueden cambiar usando esta API" -#: wiring/views.py:227 +#: wiring/views.py:231 msgid "Read only preferences cannot be updated" msgstr "Las preferencias de solo lectura no se pueden actualizar" -#: wiring/views.py:239 +#: wiring/views.py:243 msgid "Read only and hidden properties cannot be created using this API" msgstr "" "No se pueden crear variables persistentes de solo lectura u ocultas usando " "esta API" -#: wiring/views.py:248 +#: wiring/views.py:252 msgid "Read only and hidden properties cannot be removed" msgstr "" "Las variables persistentes de solo lectura y ocultas no se pueden eliminar" -#: wiring/views.py:320 wiring/views.py:341 +#: wiring/views.py:320 wiring/views.py:344 msgid "Invalid JSON patch" msgstr "Parche JSON inválido" -#: wiring/views.py:334 +#: wiring/views.py:337 msgid "Missing operators variables cannot be updated" msgstr "Las variables de los operadores ausentes no se pueden actualizar" -#: wiring/views.py:339 +#: wiring/views.py:342 msgid "Failed to apply patch" msgstr "Fallo al aplicar el parche" @@ -572,170 +668,177 @@ msgstr "Fallo al aplicar el parche" msgid "Missing dependencies" msgstr "Dependencias incumplidas" -#: workspace/mashupTemplateParser.py:361 +#: workspace/mashupTemplateParser.py:363 msgid "Original wiring" msgstr "Wiring original" -#: workspace/mashupTemplateParser.py:361 +#: workspace/mashupTemplateParser.py:363 msgid "This is the wiring description of the original workspace" msgstr "Esta es la descripción del wiring del espacio de trabajo original" -#: workspace/mashupTemplateParser.py:364 +#: workspace/mashupTemplateParser.py:366 msgid "Merged wiring" msgstr "Wiring mezclado" -#: workspace/mashupTemplateParser.py:364 +#: workspace/mashupTemplateParser.py:366 msgid "This is the wiring description of the merged mashup." msgstr "" "Esta es la descripción del comportamiento creado para el mashup mezclado." -#: workspace/models.py:35 +#: workspace/models.py:36 msgid "Creator" msgstr "Creador" -#: workspace/models.py:40 +#: workspace/models.py:41 msgid "Creation Date" msgstr "Fecha de creación" -#: workspace/models.py:41 +#: workspace/models.py:42 msgid "Last Modification Date" msgstr "Fecha de última modificación" -#: workspace/models.py:43 +#: workspace/models.py:44 msgid "Searchable" msgstr "Buscable" -#: workspace/models.py:44 +#: workspace/models.py:45 msgid "Available to all users" msgstr "Disponible para todos los usuarios" -#: workspace/models.py:45 +#: workspace/models.py:46 +msgid "" +"Require users to be logged in to access the workspace (This option has only " +"effect if the workspace is public)" +msgstr "" + +#: workspace/models.py:47 msgid "Users" msgstr "Usuarios" -#: workspace/models.py:46 +#: workspace/models.py:48 msgid "Groups" msgstr "Grupos" -#: workspace/models.py:90 -msgid "Manager" -msgstr "Gestor" - -#: workspace/models.py:91 -msgid "Reason Ref" -msgstr "Referencia de razón" - -#: workspace/models.py:91 -msgid "" -"Reference to the reason why it was added. Used by Workspace Managers to sync " -"workspaces" +#: workspace/models.py:111 +msgid "Access Level" msgstr "" -"Referencia a la razón por la que fue añadido. Este campo es usado por los " -"gestores de entornos de trabajo para sincronizar los entornos de trabajo" -#: workspace/models.py:106 +#: workspace/models.py:127 msgid "Visible" msgstr "Visible" -#: workspace/models.py:108 +#: workspace/models.py:129 msgid "Workspace" msgstr "Entorno de trabajo" -#: workspace/utils.py:630 workspace/views.py:119 workspace/views.py:413 +#: workspace/utils.py:594 workspace/views.py:382 msgid "invalid mashup id" msgstr "identificador de mashup inválido" -#: workspace/utils.py:638 +#: workspace/utils.py:602 #, python-format msgid "Mashup not found: %(mashup)s" msgstr "Mashup no encontrado: %(mashup)s" -#: workspace/views.py:94 +#: workspace/views.py:95 msgid "Missing name or title parameter" msgstr "Falta el parámetro name o title" -#: workspace/views.py:96 workspace/views.py:408 +#: workspace/views.py:97 workspace/views.py:377 msgid "Workspace and mashup parameters cannot be used at the same time" msgstr "No se pueden usar los parámetros workspace y mashup al mismo tiempo" -#: workspace/views.py:104 +#: workspace/views.py:105 msgid "invalid workspace name" msgstr "nombre de entorno de trabajo inválido" -#: workspace/views.py:112 workspace/views.py:164 workspace/views.py:224 +#: workspace/views.py:113 workspace/views.py:134 workspace/views.py:197 msgid "A workspace with the given name already exists" msgstr "Ya existe un entorno de trabajo con el nombre indicado" -#: workspace/views.py:127 workspace/views.py:421 -#, python-format -msgid "Mashup not found: %(mashup_id)s" -msgstr "Mashup no encontrado: %(mashup_id)s" - -#: workspace/views.py:137 workspace/views.py:431 +#: workspace/views.py:122 workspace/views.py:400 #, python-format msgid "You are not allowed to read from workspace %s" msgstr "No tienes permisos para leer desde el entorno de trabajo %s" -#: workspace/views.py:235 +#: workspace/views.py:208 msgid "You are not allowed to delete this workspace" msgstr "No tienes permisos para borrar este entorno de trabajo" -#: workspace/views.py:257 +#: workspace/views.py:230 msgid "Malformed tab JSON: expecting tab name or title." msgstr "JSON mal formado: se esperaba el nombre o el título de la pestaña." -#: workspace/views.py:260 workspace/views.py:283 +#: workspace/views.py:233 workspace/views.py:256 msgid "You are not allowed to create new tabs for this workspace" msgstr "" "No tienes permisos para crear nuevas pestañas para este entorno de trabajo" -#: workspace/views.py:268 workspace/views.py:349 +#: workspace/views.py:241 workspace/views.py:318 msgid "A tab with the given name already exists for the workspace" msgstr "" "Una pestaña con el nombre indicado ya existe para el entorno de trabajo" -#: workspace/views.py:329 workspace/views.py:332 +#: workspace/views.py:298 workspace/views.py:301 msgid "Invalid visible value" msgstr "Valor de visibilidad inválido" -#: workspace/views.py:361 +#: workspace/views.py:330 msgid "You are not allowed to remove this tab" msgstr "No tienes permiso para eliminar esta pestaña" -#: workspace/views.py:365 +#: workspace/views.py:334 msgid "Tab cannot be deleted as workspaces need at least one tab" msgstr "" "La pestaña no se puede borra dado que el entorno de trabajo necesita como " "mínimo una pestaña" -#: workspace/views.py:369 +#: workspace/views.py:338 msgid "Tab cannot be deleted as it contains widgets that cannot be deleted" msgstr "" "La pestaña no se puede borrar ya que contiene widgets que no pueden ser " "borrados" -#: workspace/views.py:406 +#: workspace/views.py:375 msgid "Missing workspace or mashup parameter" msgstr "Falta o el parámetro workspace o el parámetro mashup" -#: workspace/views.py:490 +#: workspace/views.py:390 +#, python-format +msgid "Mashup not found: %(mashup_id)s" +msgstr "Mashup no encontrado: %(mashup_id)s" + +#: workspace/views.py:459 #, python-format msgid "malformed json data: %s" msgstr "datos json malformados: %s" -#: workspace/views.py:495 +#: workspace/views.py:464 #, python-format msgid "Malformed JSON. The following field(s) are missing: %(fields)s." msgstr "JSON mal formado. Faltan los siguientes campos: %(fields)s." -#: workspace/views.py:498 +#: workspace/views.py:467 msgid "Invalid vendor" msgstr "Distribuidor inválido" -#: workspace/views.py:501 +#: workspace/views.py:470 msgid "Invalid name" msgstr "Nombre inválido" -#: workspace/views.py:504 +#: workspace/views.py:473 msgid "Invalid version number" msgstr "Número de versión inválido" + +#~ msgid "Manager" +#~ msgstr "Gestor" + +#~ msgid "Reason Ref" +#~ msgstr "Referencia de razón" + +#~ msgid "" +#~ "Reference to the reason why it was added. Used by Workspace Managers to " +#~ "sync workspaces" +#~ msgstr "" +#~ "Referencia a la razón por la que fue añadido. Este campo es usado por los " +#~ "gestores de entornos de trabajo para sincronizar los entornos de trabajo" diff --git a/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po b/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po index bc520678e7..25de779e9e 100644 --- a/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po +++ b/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-06-04 10:48+0200\n" +"POT-Creation-Date: 2024-05-27 11:22+0200\n" "PO-Revision-Date: 2019-06-04 10:40+0200\n" "Last-Translator: Álvaro Arranz García \n" "Language-Team: Español/España\n" @@ -19,166 +19,78 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.2\n" -#: static/js/WirecloudAPI/DashboardManagementAPI.js:154 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:103 +#: static/js/WirecloudAPI/DashboardManagementAPI.js:148 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:104 msgid "Do you really want to remove the \"%(name)s\" workspace?" msgstr "¿Realmente quieres eliminar el entorno de trabajo \"%(name)s\"?" -#: static/js/WirecloudAPI/WirecloudAPICommon.js:226 +#: static/js/WirecloudAPI/WirecloudAPICommon.js:234 msgid "" "
  • File:
  • Line:
  • See the browser console for more details

    " +"how-to-open-the-javascript-console-in-different-browsers\" " +"target=\"_blank\">browser console for more details

    " msgstr "" "
    • Fichero:
    • Línea:
    • Mira la consola web para más detalles

      " +"how-to-open-the-javascript-console-in-different-browsers\" " +"target=\"_blank\">consola web para más detalles

      " -#: static/js/catalogue/CatalogueSearchView.js:44 -msgid "Empty Marketplace!" -msgstr "Marketplace vacío!" - -#: static/js/catalogue/CatalogueSearchView.js:45 -msgid "" -"This marketplace is empty, that is, it does not provide any resource at this " -"time." -msgstr "" -"Este marketplace está vacío, esto es, actualmente no proporciona ningún " -"recurso." - -#: static/js/catalogue/CatalogueSearchView.js:67 -msgid "

      Showing results for

      " -msgstr "

      Mostrando los resultados para

      " - -#: static/js/catalogue/CatalogueSearchView.js:95 -msgid "Connection error: No resource retrieved." -msgstr "Error en la conexión: No se han obtenido recursos." - -#: static/js/catalogue/CatalogueSearchView.js:101 -msgid "" -"

      We couldn't find anything for your search - %(keywords)s.

      Suggestions:

      • Make sure all words are spelled correctly.
      • Try different keywords.
      • Try more general keywords.
      " -msgstr "" -"

      No hemos podido encontrar resultados que coincidan con tu búsqueda (" -"%(keywords)s).

      Sugerencias:

      • Asegúrate de que todas las " -"palabras estén escritas correctamente.
      • Prueba con otras palabras " -"clave.
      • Inténtalo con palabras clave más generales.
      " - -#: static/js/catalogue/CatalogueSearchView.js:109 -msgid "Keywords..." -msgstr "Texto de búsqueda…" - -#: static/js/catalogue/CatalogueSearchView.js:124 -#: static/js/catalogue/CatalogueSearchView.js:243 -msgid "Refresh" -msgstr "Refrescar" - -#: static/js/catalogue/CatalogueSearchView.js:135 -msgid "Creation date" -msgstr "Fecha de creación" - -#: static/js/catalogue/CatalogueSearchView.js:136 -#: static/js/wirecloud/Widget.js:253 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:291 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:718 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:148 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:100 -#: static/js/wirecloud/wiring/Operator.js:164 -msgid "Title" -msgstr "Título" - -#: static/js/catalogue/CatalogueSearchView.js:137 -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:43 -msgid "Vendor" -msgstr "Distribuidor" - -#: static/js/catalogue/CatalogueSearchView.js:149 -msgid "All" -msgstr "Todo" - -#: static/js/catalogue/CatalogueSearchView.js:150 -#: static/js/wirecloud/ui/ComponentSidebar.js:56 -#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:56 -msgid "Widgets" -msgstr "Widgets" - -#: static/js/catalogue/CatalogueSearchView.js:151 -#: static/js/wirecloud/ui/ComponentSidebar.js:43 -msgid "Mashups" -msgstr "Mashups" - -#: static/js/catalogue/CatalogueSearchView.js:152 -#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:43 -msgid "Operators" -msgstr "Operadores" - -#: static/js/catalogue/CatalogueSearchView.js:241 -msgid "Clear filters" -msgstr "Quitar filtros" - -#: static/js/catalogue/CatalogueView.js:51 -msgid "Uninstall" -msgstr "Desinstalar" - -#: static/js/catalogue/CatalogueView.js:57 -msgid "Install" -msgstr "Instalar" - -#: static/js/wirecloud/LocalCatalogue.js:37 +#: static/js/wirecloud/LocalCatalogue.js:38 msgid "Unloading affected widgets" msgstr "Descargando los widgets afectados" -#: static/js/wirecloud/LocalCatalogue.js:40 +#: static/js/wirecloud/LocalCatalogue.js:41 msgid "Unloading affected operators" msgstr "Descargando los operadores afectados" -#: static/js/wirecloud/LocalCatalogue.js:75 +#: static/js/wirecloud/LocalCatalogue.js:76 msgid "Purging %(componenttype)s info" msgstr "Eliminando la información sobre el %(componenttype)s" -#: static/js/wirecloud/LocalCatalogue.js:131 +#: static/js/wirecloud/LocalCatalogue.js:128 #: static/js/wirecloud/WorkspaceCatalogue.js:81 msgid "Error loading %(resource)s metadata" msgstr "Error cargando los metadatos de %(resource)s" -#: static/js/wirecloud/LocalCatalogue.js:174 +#: static/js/wirecloud/LocalCatalogue.js:171 msgid "Deleting all versions of %(title)s (%(group_id)s)" msgstr "Desinstalando todas las versiones de %(title)s (%(group_id)s)" -#: static/js/wirecloud/LocalCatalogue.js:176 +#: static/js/wirecloud/LocalCatalogue.js:173 msgid "Uninstalling all versions of %(title)s (%(group_id)s)" msgstr "Desinstalando todas las versiones de %(title)s (%(group_id)s)" -#: static/js/wirecloud/LocalCatalogue.js:185 +#: static/js/wirecloud/LocalCatalogue.js:182 msgid "Deleting %(title)s (%(uri)s)" msgstr "Desinstalando %(title)s (%(uri)s)" -#: static/js/wirecloud/LocalCatalogue.js:187 +#: static/js/wirecloud/LocalCatalogue.js:184 msgid "Uninstalling %(title)s (%(uri)s)" msgstr "Desinstalando %(title)s (%(uri)s)" -#: static/js/wirecloud/LocalCatalogue.js:281 +#: static/js/wirecloud/LocalCatalogue.js:278 msgid "Invalid component type: %(type)s" msgstr "Typo de componente inválido: %(type)s" -#: static/js/wirecloud/LogManager.js:215 +#: static/js/wirecloud/LogManager.js:252 msgid "HTTP Error %(errorCode)s - %(errorDesc)s" msgstr "Error HTTP %(errorCode)s - %(errorDesc)s" #: static/js/wirecloud/MarketManager.js:50 #: static/js/wirecloud/MarketManager.js:81 -#: static/js/wirecloud/MarketManager.js:111 static/js/wirecloud/Wiring.js:197 -#: static/js/wirecloud/Wiring.js:262 static/js/wirecloud/Workspace.js:305 -#: static/js/wirecloud/Workspace.js:441 static/js/wirecloud/Workspace.js:496 -#: static/js/wirecloud/WorkspaceTab.js:223 -#: static/js/wirecloud/WorkspaceTab.js:268 static/js/wirecloud/core.js:57 -#: static/js/wirecloud/core.js:468 static/js/wirecloud/core.js:537 -#: static/js/wirecloud/core.js:542 -#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:99 -#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:215 +#: static/js/wirecloud/MarketManager.js:111 +#: static/js/wirecloud/Preferences.js:130 static/js/wirecloud/Wiring.js:465 +#: static/js/wirecloud/Wiring.js:530 static/js/wirecloud/Workspace.js:468 +#: static/js/wirecloud/Workspace.js:604 static/js/wirecloud/Workspace.js:659 +#: static/js/wirecloud/WorkspaceTab.js:220 +#: static/js/wirecloud/WorkspaceTab.js:265 static/js/wirecloud/core.js:158 +#: static/js/wirecloud/core.js:420 static/js/wirecloud/core.js:585 +#: static/js/wirecloud/core.js:654 static/js/wirecloud/core.js:660 +#: static/js/wirecloud/core.js:708 +#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:104 +#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:270 +#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:423 msgid "Unexpected response from server" msgstr "Respuesta inesperada del servidor" @@ -186,72 +98,56 @@ msgstr "Respuesta inesperada del servidor" msgid "Adding marketplace" msgstr "Añadiendo el marketplace" -#: static/js/wirecloud/MashableApplicationComponent.js:34 -msgid "missing vendor" -msgstr "falta el distribuidor" - -#: static/js/wirecloud/MashableApplicationComponent.js:40 -msgid "missing name" -msgstr "falta el nombre" - -#: static/js/wirecloud/MashableApplicationComponent.js:46 -msgid "missing version" -msgstr "falta la versión" - -#: static/js/wirecloud/MashableApplicationComponent.js:52 -msgid "missing type" -msgstr "falta el tipo" - -#: static/js/wirecloud/PlatformPreferences.js:38 +#: static/js/wirecloud/PlatformPreferences.js:39 msgid "Platform Preferences" msgstr "Preferencias de la plataforma" -#: static/js/wirecloud/PreferenceManager.js:41 +#: static/js/wirecloud/PreferenceManager.js:39 msgid "Language" msgstr "Idioma" -#: static/js/wirecloud/PreferenceManager.js:44 +#: static/js/wirecloud/PreferenceManager.js:42 msgid "Default setting" msgstr "Configuración por defecto" -#: static/js/wirecloud/PreferenceManager.js:45 +#: static/js/wirecloud/PreferenceManager.js:43 msgid "Detect browser language" msgstr "Detectar el idioma del navegador" -#: static/js/wirecloud/TabPreferences.js:43 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:100 +#: static/js/wirecloud/TabPreferences.js:45 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 #: static/js/wirecloud/Tutorials/BehaviourOrientedWiring.js:236 -#: static/js/wirecloud/Widget/PreferencesWindowMenu.js:30 -#: static/js/wirecloud/WorkspacePreferences.js:38 -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:85 -#: static/js/wirecloud/ui/WirecloudHeader.js:101 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:86 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:73 -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:70 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:94 +#: static/js/wirecloud/Widget/PreferencesWindowMenu.js:33 +#: static/js/wirecloud/WorkspacePreferences.js:40 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:78 +#: static/js/wirecloud/ui/WirecloudHeader.js:94 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:141 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:99 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:61 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:86 msgid "Settings" msgstr "Configurar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:66 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:64 msgid "Basic concepts" msgstr "Conceptos básicos" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:68 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:71 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:76 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:85 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:92 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:116 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:120 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:121 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:162 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:66 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:69 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:74 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:83 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:90 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:114 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:118 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:119 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:160 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:165 #: static/js/wirecloud/Tutorials/BasicConcepts.js:167 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:169 msgid "WireCloud Basic Tutorial" msgstr "Tutorial Básico de WireCloud" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:68 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:66 msgid "" "

      Welcome to WireCloud!!

      This tutorial will show you the basic " "concepts behind WireCloud.

      " @@ -259,7 +155,7 @@ msgstr "" "

      ¡¡Bienvenido a WireCloud!!

      Este tutorial pretende mostrarte los " "conceptos básico que hay detrás de WireCloud.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:71 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:69 msgid "" "

      This is the Editor view. In this view, you can use and modify " "your workspaces. Currently you are in a newly created workspace: Basic " @@ -276,7 +172,7 @@ msgstr "" "algunos widgets, así que vamos a instarlos por ti. Puedes eliminarlos sin " "peligro después de terminar con el tutorial.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:76 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:74 msgid "" "

      Ok, widgets have been installed successfuly.

      Next step is to add " "the YouTube Browser widget to the workspace.

      " @@ -284,15 +180,15 @@ msgstr "" "

      Ok, los widgets se han instalado correctamente.

      El próximo paso es " "añadir el widget YouTube Browser al entorno de trabajo.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:77 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:75 msgid "Click the Edit button" msgstr "Haz click en el botón Editar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:79 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:77 msgid "Click the Add components button" msgstr "Haz click en el botón Añadir componentes" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:81 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:79 msgid "" "By typing \"browser\" we can filter widgets that contains in their name or " "description these words" @@ -300,7 +196,7 @@ msgstr "" "Escribiendo \"browser\" filtraremos los widgets que contengan esta palabra " "en el nombre o en la descripción" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:84 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:82 msgid "" "Once you have the results, you can add the widget. So click Add to " "workspace" @@ -308,7 +204,7 @@ msgstr "" "Una vez que aparecen los resultados, puedes añadir el widget. Así que haz " "click en Añadir al entorno de trabajo" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:85 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:83 msgid "" "

      Great! That was easy, wasn't " "it?.

      Let's continue adding the Input Box widget.

      " @@ -316,19 +212,19 @@ msgstr "" "

      ¡Genial! A que ha sido fácil, " "¿no?.

      Vamos a continuar añadiendo el widget Input Box.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:86 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:84 msgid "Typing input box..." msgstr "Escribiendo input box..." -#: static/js/wirecloud/Tutorials/BasicConcepts.js:89 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:87 msgid "Click Add to workspace" msgstr "Haz click en Añadir al entorno de trabajo" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:90 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:88 msgid "Close the component sidebar" msgstr "Cierra el panel lateral" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:92 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:90 msgid "" "

      One of the main features of WireCloud is that you can edit your " "workspaces' layout not only by adding and removing widgets, but also moving, " @@ -338,33 +234,33 @@ msgstr "" "la distribución de los entornos de trabajo, no solo añadiendo y borrando " "widgets, sino moviéndolos, redimensionándolos, renombrándolos, etc.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:93 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:91 msgid "Drag & drop to resize the widget" msgstr "Arrastra y suelta para redimensionar el widget" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:94 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:92 msgid "Drag & drop to move the widget" msgstr "Arrastra y suelta para mover el widget" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:95 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:99 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:93 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:97 msgid "Open Input Box menu" msgstr "Abre el menú del Input Box" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:94 msgid "Click Rename" msgstr "Haz click en Renombrar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:57 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:66 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:63 -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:57 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:64 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:94 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:50 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:121 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:89 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:48 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:56 msgid "Rename" msgstr "Renombrar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:97 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:95 msgid "" "Enter a new name for the widget (e.g Search) and press Enter or click outside the title" @@ -372,7 +268,7 @@ msgstr "" "Escribe un nuevo nombre para el widget (por ejemplo: Búsqueda) y " "pulsa la tecla Enter o pulsa fuera del título" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 msgid "" "

      Also, some widgets can be parameterized through settings giving you the " "chance to use them for very general purporses.

      " @@ -380,37 +276,37 @@ msgstr "" "

      Además, algunos widget pueden ser parametrizados a través de preferencias " "permitiendo su uso para tareas generales.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:100 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 #: static/js/wirecloud/Tutorials/BehaviourOrientedWiring.js:236 msgid "Click Settings" msgstr "Haz click en Configurar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:104 msgid "Write a label for the input, e.g. Multimedia." msgstr "" "Escribe una etiqueta para el campo de texto, por ejemplo: Multimedia." -#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:104 msgid "Write a better placeholder text for the input, e.g. Keywords" msgstr "" "Escribe una mejor descripción para el campo de entrada, por ejemplo: " "Términos" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:104 msgid "Write a better label for the button, e.g Search." msgstr "" "Escribe una mejor etiqueta para el botón, por ejemplo Búsqueda." -#: static/js/wirecloud/Tutorials/BasicConcepts.js:108 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 msgid "Click here to submit" msgstr "Haz click aquí para enviar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:113 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:111 msgid "Click Wiring to continue" msgstr "Haz click en Wiring para continuar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:116 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:114 msgid "" "

      This is the Wiring Editor view.

      Here you can wire widgets " "and operators together turning your workspace into and application " @@ -420,15 +316,15 @@ msgstr "" "widgets y los operadores y convertir tu entorno de trabajo en una " "aplicación composicional.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:117 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:115 msgid "Click Find components to open the sidebar" msgstr "Haz click en el botón Buscar componentes para continuar" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:119 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:117 msgid "Click Widgets" msgstr "Haz click en Widgets" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:120 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:118 msgid "" "

      In this sidebar you can find all the available widgets. In our example, " "we are interested in the widgets added to the workspace: the YouTube " @@ -445,7 +341,7 @@ msgstr "" "pueden actuar como una fuente de datos, transformadores o destinos para los " "datos y cualquier combinación de estos comportamientos.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:121 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:119 msgid "" "

      In the next steps, we are going to connect the Input Box and " "YouTube Browser widgets together. This will allow you to perform " @@ -457,19 +353,19 @@ msgstr "" "searches in the YouTube Browser through the Input Box " "widget.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:127 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:125 msgid "Drag & drop the Input Box widget" msgstr "Arrastra el widget Input Box hasta la zona de trabajo" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:140 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:138 msgid "Drag & drop the YouTube Browser widget" msgstr "Arrastra el widget YouTube Browser hasta la zona de trabajo" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:148 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:146 msgid "Click Find components to close the sidebar" msgstr "Haz click en Buscar componentes para cerrar el panel lateral" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:152 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:150 msgid "" "Drag & drop a new connection from Search Box's keyword " "endpoint ..." @@ -477,26 +373,26 @@ msgstr "" "Arrastra una nueva conexión desde el endpoint de salida keyword " "(del widget Search Box) ..." -#: static/js/wirecloud/Tutorials/BasicConcepts.js:158 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:156 msgid "... to YouTube Browser's keyword endpoint" msgstr "" "... soltando en el endpoint de entrada keyword del widget " "YouTube Browser" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:162 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:160 msgid "Now it's time to test our creation." msgstr "Ahora es tiempo de probar nuestra creación." -#: static/js/wirecloud/Tutorials/BasicConcepts.js:163 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:161 #: static/js/wirecloud/Tutorials/BehaviourOrientedWiring.js:246 msgid "Click Back" msgstr "Haz click en Volver" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:165 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:163 msgid "Enter a search keyword and press Enter" msgstr "Escribe los términos de búsqueda y presiona la tecla Enter" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:167 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:165 msgid "" "

      Congratulations! you have " "finished your first application mashup.

      As you can see, the " @@ -506,7 +402,7 @@ msgstr "" "primera aplicación composicional.

      Como puedes ver, el widget " "YouTube Browser se ha actualizado correctamente.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:169 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:167 msgid "" "

      This is the end of this tutorial. Remember that you can always go to the " "Tutorial menu for others.

      " @@ -514,7 +410,7 @@ msgstr "" "

      Este es el final de este tutorial. Recuerda que siempre puedes ir al menú " "Tutoriales para buscar más tutoriales.

      " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:169 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:167 msgid "Tutorials" msgstr "Tutoriales" @@ -751,9 +647,9 @@ msgid "" "the affected components were added? That saved us some steps :).

      Anyway, you can also directly add components in a similar way clicking " "on theirs Add button (take into account that associated connections " -"are no added automatically in that case)

      The third and the fourth behaviour can be created the same way, so we are " -"going to create them for you.
      " +"are no added automatically in that case)

      The third and the fourth behaviour can be created the same way, so we " +"are going to create them for you.
      " msgstr "" "

      Genial! Ya tenemos nuestro " "primer comportamiento terminado. ¿Te has dado cuenta que cuando hemos " @@ -871,147 +767,182 @@ msgstr "" "panel de ejemplo para comprobar si este sigue los comportamientos descritos." "

      " -#: static/js/wirecloud/UserInterfaceManager.js:203 -msgid "Workspace loaded" -msgstr "Entorno de trabajo cargado" - -#: static/js/wirecloud/UserInterfaceManager.js:331 +#: static/js/wirecloud/UserInterfaceManager.js:95 msgid "%(task)s %(percentage)s%" msgstr "%(task)s %(percentage)s%" -#: static/js/wirecloud/UserInterfaceManager.js:345 +#: static/js/wirecloud/UserInterfaceManager.js:109 msgid "%(subTask)s: %(percentage)s%" msgstr "%(subTask)s: %(percentage)s%" -#: static/js/wirecloud/Widget.js:254 static/js/wirecloud/wiring/Operator.js:165 +#: static/js/wirecloud/UserInterfaceManager.js:274 +msgid "Workspace loaded" +msgstr "Entorno de trabajo cargado" + +#: static/js/wirecloud/Widget.js:366 static/js/wirecloud/Wiring.js:602 +msgid "Failed to load widget." +msgstr "Error al cargar el widget." + +#: static/js/wirecloud/Widget.js:368 +msgid "" +"

      This widget is currently not available. You or an administrator probably " +"uninstalled it.

      Suggestions:
      • Remove this widget from the " +"dashboard
      • Reinstall the appropiated version of the widget
      • Or " +"install another version of the widget and then use the Upgrade/" +"Downgrade option
      " +msgstr "" +"

      Este widget no está actualmente disponible: Posiblemente lo hayas " +"desinstalado tú o un administrador.

      Sugerencias:
      • Eliminar " +"este widget del entorno de trabajo
      • Reinstalar una versión adecuada " +"de este widget
      • O instalar otra versión de este widget y " +"posteriormente usar la opción Actualizar/Desactualizar
      " + +#: static/js/wirecloud/Widget.js:371 +msgid "Widget loaded successfully." +msgstr "Widget cargado correctamente." + +#: static/js/wirecloud/Widget.js:408 +msgid "Widget unloaded successfully." +msgstr "Widget descargado correctamente." + +#: static/js/wirecloud/Widget.js:688 +#: static/js/wirecloud/ui/CatalogueSearchView.js:150 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:272 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:87 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:73 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:45 +#: static/js/wirecloud/wiring/Operator.js:408 +msgid "Title" +msgstr "Título" + +#: static/js/wirecloud/Widget.js:689 static/js/wirecloud/wiring/Operator.js:409 msgid "Widget's title" msgstr "Titulo del widget" -#: static/js/wirecloud/Widget.js:258 +#: static/js/wirecloud/Widget.js:693 msgid "X-Position" msgstr "Posición-X" -#: static/js/wirecloud/Widget.js:259 +#: static/js/wirecloud/Widget.js:694 msgid "Specifies the x-coordinate at which the widget is placed" msgstr "Especifica la coordenada x en la que el widget está colocado" -#: static/js/wirecloud/Widget.js:263 +#: static/js/wirecloud/Widget.js:698 msgid "Y-Position" msgstr "Posición-Y" -#: static/js/wirecloud/Widget.js:264 +#: static/js/wirecloud/Widget.js:699 msgid "Specifies the y-coordinate at which the widget is placed" msgstr "Especifica la coordenada y en la que el widget está colocado" -#: static/js/wirecloud/Widget.js:268 +#: static/js/wirecloud/Widget.js:703 msgid "Z-Position" msgstr "Posición-Z" -#: static/js/wirecloud/Widget.js:269 +#: static/js/wirecloud/Widget.js:704 msgid "Specifies the z-coordinate at which the widget is placed" msgstr "Especifica la coordenada Z en la que el widget está colocado" -#: static/js/wirecloud/Widget.js:273 +#: static/js/wirecloud/Widget.js:708 msgid "Height" msgstr "Altura" -#: static/js/wirecloud/Widget.js:274 +#: static/js/wirecloud/Widget.js:709 msgid "Widget's height in layout cells" msgstr "Altura del widget en filas" -#: static/js/wirecloud/Widget.js:278 +#: static/js/wirecloud/Widget.js:713 +msgid "Visible" +msgstr "" + +#: static/js/wirecloud/Widget.js:714 +msgid "" +"Specifies if the widget is being displayed, altough the user may have to do " +"scroll to be able to see it" +msgstr "" + +#: static/js/wirecloud/Widget.js:718 msgid "Width" msgstr "Ancho" -#: static/js/wirecloud/Widget.js:279 +#: static/js/wirecloud/Widget.js:719 msgid "Widget's width in layout cells" msgstr "Ancho del widget en columnas" -#: static/js/wirecloud/Widget.js:283 +#: static/js/wirecloud/Widget.js:723 msgid "Height in pixels (deprecated)" msgstr "Altura en pixels (obsoleto)" -#: static/js/wirecloud/Widget.js:284 +#: static/js/wirecloud/Widget.js:724 msgid "Widget's height in pixels" msgstr "Altura del widget en pixels" -#: static/js/wirecloud/Widget.js:288 +#: static/js/wirecloud/Widget.js:728 msgid "Width in pixels" msgstr "Ancho en pixels" -#: static/js/wirecloud/Widget.js:289 +#: static/js/wirecloud/Widget.js:729 msgid "Widget's width in pixels" msgstr "Anchura del widget en pixels" -#: static/js/wirecloud/Widget.js:296 +#: static/js/wirecloud/Widget.js:733 +#, fuzzy +#| msgid "volatile" +msgid "Volatile" +msgstr "volátil" + +#: static/js/wirecloud/Widget.js:734 +msgid "Volatile status of the widget" +msgstr "" + +#: static/js/wirecloud/Widget.js:741 msgid "Widget created successfully." msgstr "Widget creado correctamente." -#: static/js/wirecloud/Widget.js:615 static/js/wirecloud/wiring/Operator.js:353 +#: static/js/wirecloud/Widget.js:1107 +#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:42 +msgid "Exception catched while processing preference changes" +msgstr "" +"Excepción capturada mientras se procesaba los cambios en las preferencias" + +#: static/js/wirecloud/Widget.js:1233 +#: static/js/wirecloud/wiring/Operator.js:603 msgid "The %(type)s was upgraded to v%(version)s successfully." msgstr "" "El %(type)s ha sido correctamente actualizado a la versión v%(version)s." -#: static/js/wirecloud/Widget.js:617 static/js/wirecloud/wiring/Operator.js:355 +#: static/js/wirecloud/Widget.js:1235 +#: static/js/wirecloud/wiring/Operator.js:605 msgid "The %(type)s was downgraded to v%(version)s successfully." msgstr "" "El %(type)s ha sido correctamente desactualizado a la versión v%(version)s." -#: static/js/wirecloud/Widget.js:620 static/js/wirecloud/wiring/Operator.js:358 +#: static/js/wirecloud/Widget.js:1238 +#: static/js/wirecloud/wiring/Operator.js:608 msgid "The %(type)s was replaced using v%(version)s successfully." msgstr "" "El %(type)s ha sido correctamente reemplazado usando la versión v%(version)s." -#: static/js/wirecloud/Widget.js:829 static/js/wirecloud/Wiring.js:336 -msgid "Failed to load widget." -msgstr "Error al cargar el widget." - -#: static/js/wirecloud/Widget.js:831 -msgid "" -"

      This widget is currently not available. You or an administrator probably " -"uninstalled it.

      Suggestions:
      • Remove this widget from the " -"dashboard
      • Reinstall the appropiated version of the widget
      • Or " -"install another version of the widget and then use the Upgrade/" -"Downgrade option
      " -msgstr "" -"

      Este widget no está actualmente disponible: Posiblemente lo hayas " -"desinstalado tú o un administrador.

      Sugerencias:
      • Eliminar " -"este widget del entorno de trabajo
      • Reinstalar una versión adecuada " -"de este widget
      • O instalar otra versión de este widget y " -"posteriormente usar la opción Actualizar/Desactualizar
      " - -#: static/js/wirecloud/Widget.js:834 -msgid "Widget loaded successfully." -msgstr "Widget cargado correctamente." - -#: static/js/wirecloud/Widget.js:865 -msgid "Widget unloaded successfully." -msgstr "Widget descargado correctamente." - -#: static/js/wirecloud/Widget/PreferencesWindowMenu.js:82 -#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:87 -msgid "Exception catched while processing preference changes" -msgstr "" -"Excepción capturada mientras se procesaba los cambios en las preferencias" - -#: static/js/wirecloud/WidgetMeta.js:77 +#: static/js/wirecloud/WidgetMeta.js:88 msgid "[Widget; Vendor: %(vendor)s, Name: %(name)s, Version: %(version)s]" msgstr "" "[Widget; Distribuidor: %(vendor)s, Nombre: %(name)s, Versión: %(versión)s]" -#: static/js/wirecloud/Wiring.js:331 static/js/wirecloud/wiring/Operator.js:496 +#: static/js/wirecloud/Wiring.js:597 static/js/wirecloud/wiring/Operator.js:220 msgid "Failed to load operator." msgstr "Error al cargar el operador." -#: static/js/wirecloud/Workspace.js:579 +#: static/js/wirecloud/Workspace.js:75 msgid "Tab %(index)s" msgstr "Pestaña %(index)s" -#: static/js/wirecloud/Workspace.js:585 -msgid "%(base) (%(copy)s)" +#: static/js/wirecloud/Workspace.js:82 +#, fuzzy +#| msgid "%(base) (%(copy)s)" +msgid "%(base)s (%(copy)s)" msgstr "%(base) (%(copy)s)" -#: static/js/wirecloud/WorkspaceTab.js:161 +#: static/js/wirecloud/WorkspaceTab.js:157 msgid "The destination tab (%(title)s) is readonly" msgstr "La pestaña de destino (%(title)s) es de sólo lectura" @@ -1151,51 +1082,132 @@ msgstr "No extendido" msgid "Unknown status code" msgstr "Código de error desconocido" -#: static/js/wirecloud/core.js:104 +#: static/js/wirecloud/core.js:53 static/js/wirecloud/core.js:466 +msgid "Switching active workspace" +msgstr "Cambiando el entorno de trabajo actual" + +#: static/js/wirecloud/core.js:206 msgid "Unloading WireCloud" msgstr "Cerrando WireCloud" -#: static/js/wirecloud/core.js:183 +#: static/js/wirecloud/core.js:293 msgid "Retrieving WireCloud code" msgstr "Obteniendo el código de WireCloud" -#: static/js/wirecloud/core.js:186 +#: static/js/wirecloud/core.js:296 msgid "Retrieving initial data" msgstr "Obteniendo datos iniciales" -#: static/js/wirecloud/core.js:211 +#: static/js/wirecloud/core.js:321 msgid "Error loading WireCloud" msgstr "Error cargando WireCloud" -#: static/js/wirecloud/core.js:222 +#: static/js/wirecloud/core.js:332 msgid "Loading WireCloud Platform" msgstr "Cargando la plataforma WireCloud" -#: static/js/wirecloud/core.js:291 +#: static/js/wirecloud/core.js:418 msgid "Requesting workspace data" msgstr "Solicitando los datos del entorno de trabajo" -#: static/js/wirecloud/core.js:351 static/js/wirecloud/core.js:576 -msgid "Switching active workspace" -msgstr "Cambiando el entorno de trabajo actual" - -#: static/js/wirecloud/core.js:395 +#: static/js/wirecloud/core.js:512 msgid "Missing name or title parameter" msgstr "Falta el parámetro name o title" -#: static/js/wirecloud/core.js:397 +#: static/js/wirecloud/core.js:514 msgid "Workspace and mashup options cannot be used at the same time" msgstr "Las opciones workspace y mashup no pueden ser usadas al mismo tiempo" -#: static/js/wirecloud/ui/ComponentSidebar.js:70 +#: static/js/wirecloud/ui/CatalogueSearchView.js:43 +msgid "Clear filters" +msgstr "Quitar filtros" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:45 +#: static/js/wirecloud/ui/CatalogueSearchView.js:138 +msgid "Refresh" +msgstr "Refrescar" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:64 +msgid "Empty Marketplace!" +msgstr "Marketplace vacío!" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:65 +msgid "" +"This marketplace is empty, that is, it does not provide any resource at this " +"time." +msgstr "" +"Este marketplace está vacío, esto es, actualmente no proporciona ningún " +"recurso." + +#: static/js/wirecloud/ui/CatalogueSearchView.js:86 +msgid "

      Showing results for

      " +msgstr "

      Mostrando los resultados para

      " + +#: static/js/wirecloud/ui/CatalogueSearchView.js:112 +msgid "Connection error: No resource retrieved." +msgstr "Error en la conexión: No se han obtenido recursos." + +#: static/js/wirecloud/ui/CatalogueSearchView.js:118 +msgid "" +"

      We couldn't find anything for your search - %(keywords)s.

      Suggestions:

      • Make sure all words are spelled correctly.
      • Try different keywords.
      • Try more general keywords.
      " +msgstr "" +"

      No hemos podido encontrar resultados que coincidan con tu búsqueda " +"(%(keywords)s).

      Sugerencias:

      • Asegúrate de que todas " +"las palabras estén escritas correctamente.
      • Prueba con otras palabras " +"clave.
      • Inténtalo con palabras clave más generales.
      " + +#: static/js/wirecloud/ui/CatalogueSearchView.js:126 +msgid "Keywords..." +msgstr "Texto de búsqueda…" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:149 +msgid "Creation date" +msgstr "Fecha de creación" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:151 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:46 +msgid "Vendor" +msgstr "Distribuidor" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:163 +msgid "All" +msgstr "Todo" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:164 +#: static/js/wirecloud/ui/ComponentSidebar.js:54 +#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:58 +msgid "Widgets" +msgstr "Widgets" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:165 +#: static/js/wirecloud/ui/ComponentSidebar.js:41 +msgid "Mashups" +msgstr "Mashups" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:166 +#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:45 +msgid "Operators" +msgstr "Operadores" + +#: static/js/wirecloud/ui/CatalogueView.js:61 +msgid "Uninstall" +msgstr "Desinstalar" + +#: static/js/wirecloud/ui/CatalogueView.js:67 +msgid "Install" +msgstr "Instalar" + +#: static/js/wirecloud/ui/ComponentSidebar.js:68 msgid "Add to workspace" msgstr "Añadir al entorno de trabajo" -#: static/js/wirecloud/ui/ComponentSidebar.js:70 +#: static/js/wirecloud/ui/ComponentSidebar.js:68 msgid "Merge" msgstr "Mezclar" -#: static/js/wirecloud/ui/DragboardLayout.js:236 +#: static/js/wirecloud/ui/DragboardLayout.js:246 msgid "" "the widget could not be associated with this layout as it already has an " "associated layout." @@ -1203,15 +1215,19 @@ msgstr "" "el widget no pudo ser asociado con este layout porque ya tiene asociado otro " "layout." -#: static/js/wirecloud/ui/EmbedCodeWindowMenu.js:51 +#: static/js/wirecloud/ui/EmbedCodeWindowMenu.js:53 +msgid "Auto" +msgstr "" + +#: static/js/wirecloud/ui/EmbedCodeWindowMenu.js:69 msgid "Accept" msgstr "Aceptar" -#: static/js/wirecloud/ui/LayoutInputInterface.js:34 +#: static/js/wirecloud/ui/LayoutInputInterface.js:35 msgid "Smart" msgstr "Inteligente" -#: static/js/wirecloud/ui/LayoutInputInterface.js:36 +#: static/js/wirecloud/ui/LayoutInputInterface.js:37 msgid "" "Widgets will tend to be placed on the topmost position available if this " "option is enabled. (default: enabled)" @@ -1219,34 +1235,34 @@ msgstr "" "Se intentará colocar los widget en la posición más alta posible si está " "opción está activada. (por defecto: activada)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:43 -#: static/js/wirecloud/ui/LayoutInputInterface.js:79 -#: static/js/wirecloud/ui/LayoutInputInterface.js:143 +#: static/js/wirecloud/ui/LayoutInputInterface.js:44 +#: static/js/wirecloud/ui/LayoutInputInterface.js:80 +#: static/js/wirecloud/ui/LayoutInputInterface.js:147 msgid "Columns" msgstr "Columnas" -#: static/js/wirecloud/ui/LayoutInputInterface.js:45 -#: static/js/wirecloud/ui/LayoutInputInterface.js:81 +#: static/js/wirecloud/ui/LayoutInputInterface.js:46 +#: static/js/wirecloud/ui/LayoutInputInterface.js:82 msgid "Grid columns. (default: 20 columns)" msgstr "Columnas de la rejilla. (por defecto: 20 columnas)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:52 +#: static/js/wirecloud/ui/LayoutInputInterface.js:53 msgid "Row Height (in pixels)" msgstr "Altura de las filas (en pixels)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:54 +#: static/js/wirecloud/ui/LayoutInputInterface.js:55 msgid "Row/cell height. Must be specified in pixel units. (default: 13px)" msgstr "" "Altura de la filas/celdas. Hay que indicar un valor usando pixels. (por " "defecto: 13px)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:60 -#: static/js/wirecloud/ui/LayoutInputInterface.js:96 +#: static/js/wirecloud/ui/LayoutInputInterface.js:61 +#: static/js/wirecloud/ui/LayoutInputInterface.js:97 msgid "Horizontal Margin between widgets (in pixels)" msgstr "Margen horizontal entre widgets (en pixels)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:62 -#: static/js/wirecloud/ui/LayoutInputInterface.js:98 +#: static/js/wirecloud/ui/LayoutInputInterface.js:63 +#: static/js/wirecloud/ui/LayoutInputInterface.js:99 msgid "" "Horizontal Margin between widgets. Must be specified in pixel units. " "(default: 4px)" @@ -1254,13 +1270,13 @@ msgstr "" "Margen horizontal entre widgets. Hay que indicar un valor usando pixels. " "(por defecto: 4px)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:68 -#: static/js/wirecloud/ui/LayoutInputInterface.js:104 +#: static/js/wirecloud/ui/LayoutInputInterface.js:69 +#: static/js/wirecloud/ui/LayoutInputInterface.js:105 msgid "Vertical Margin between widgets (in pixels)" msgstr "Margen vertical entre widgets (en pixels)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:70 -#: static/js/wirecloud/ui/LayoutInputInterface.js:106 +#: static/js/wirecloud/ui/LayoutInputInterface.js:71 +#: static/js/wirecloud/ui/LayoutInputInterface.js:107 msgid "" "Vertical Margin between widgets. Must be specified in pixel units. (default: " "3px)" @@ -1268,51 +1284,51 @@ msgstr "" "Margen vertical entre widgets. Hay que indicar un valor usando pixels. (por " "defecto: 3px)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:88 +#: static/js/wirecloud/ui/LayoutInputInterface.js:89 msgid "Rows" msgstr "Filas" -#: static/js/wirecloud/ui/LayoutInputInterface.js:90 +#: static/js/wirecloud/ui/LayoutInputInterface.js:91 msgid "Grid rows. (default: 12 rows)" msgstr "Filas de la rejilla. (por defecto: 12 filas)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:117 +#: static/js/wirecloud/ui/LayoutInputInterface.js:119 msgid " smart" msgstr " inteligente" -#: static/js/wirecloud/ui/LayoutInputInterface.js:121 +#: static/js/wirecloud/ui/LayoutInputInterface.js:123 msgid "%(columns)s%(smart)s columns" msgstr "%(columns)s columnas%(smart)s" -#: static/js/wirecloud/ui/LayoutInputInterface.js:124 +#: static/js/wirecloud/ui/LayoutInputInterface.js:126 msgid "%(columns)s columns x %(rows)s rows" msgstr "%(columns)s columnas x %(rows)s filas" -#: static/js/wirecloud/ui/LayoutInputInterface.js:144 +#: static/js/wirecloud/ui/LayoutInputInterface.js:148 msgid "Grid" msgstr "Rejilla" -#: static/js/wirecloud/ui/LayoutInputInterface.js:169 +#: static/js/wirecloud/ui/LayoutInputInterface.js:173 msgid "Layout configuration" msgstr "Configuración de la distribución" -#: static/js/wirecloud/ui/LogWindowMenu.js:41 -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:79 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:83 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:70 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:58 +#: static/js/wirecloud/ui/LogWindowMenu.js:34 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:72 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:138 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:96 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:310 msgid "Logs" msgstr "Registros" -#: static/js/wirecloud/ui/LogWindowMenu.js:56 +#: static/js/wirecloud/ui/LogWindowMenu.js:54 msgid "Close" msgstr "Cerrar" -#: static/js/wirecloud/ui/LogWindowMenu.js:129 +#: static/js/wirecloud/ui/LogWindowMenu.js:121 msgid "Details" msgstr "Detalles" -#: static/js/wirecloud/ui/MarketplaceView.js:55 +#: static/js/wirecloud/ui/MarketplaceView.js:52 msgid "" "

      WireCloud is not connected with any marketplace.

      Suggestions:

      • Connect WireCloud with a new marketplace.
      • Go to the my " @@ -1322,31 +1338,31 @@ msgstr "" "p>
        • Conecta WireCloud con un nuevo marketplace.
        • Ve a la vista " "de Mis Recursos.
        " -#: static/js/wirecloud/ui/MarketplaceView.js:158 -#: static/js/wirecloud/ui/MyResourcesView.js:138 -#: static/js/wirecloud/ui/MyResourcesView.js:156 -#: static/js/wirecloud/ui/WorkspaceView.js:73 +#: static/js/wirecloud/ui/MarketplaceView.js:179 +#: static/js/wirecloud/ui/MyResourcesView.js:147 +#: static/js/wirecloud/ui/MyResourcesView.js:165 +#: static/js/wirecloud/ui/WorkspaceView.js:175 msgid "My Resources" msgstr "Mis recursos" -#: static/js/wirecloud/ui/MarketplaceView.js:226 +#: static/js/wirecloud/ui/MarketplaceView.js:240 msgid "loading marketplace view..." msgstr "cargando la vista de marketplace..." -#: static/js/wirecloud/ui/MarketplaceView.js:228 +#: static/js/wirecloud/ui/MarketplaceView.js:242 msgid "marketplace list not available" msgstr "lista de marketplaces no disponible" -#: static/js/wirecloud/ui/MarketplaceView.js:252 +#: static/js/wirecloud/ui/MarketplaceView.js:264 msgid "Marketplace" msgstr "Marketplace" -#: static/js/wirecloud/ui/MarketplaceView.js:255 +#: static/js/wirecloud/ui/MarketplaceView.js:267 msgid "Marketplace - %(marketname)s" msgstr "Marketplace - %(marketname)s" #: static/js/wirecloud/ui/MarketplaceViewMenuItems.js:62 -#: static/js/wirecloud/ui/MyResourcesView.js:56 +#: static/js/wirecloud/ui/MyResourcesView.js:70 msgid "Upload" msgstr "Subir" @@ -1355,7 +1371,7 @@ msgid "Add new marketplace" msgstr "Añadir un nuevo marketplace" #: static/js/wirecloud/ui/MarketplaceViewMenuItems.js:75 -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:49 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:52 msgid "Name" msgstr "Nombre" @@ -1368,7 +1384,7 @@ msgid "Type" msgstr "Tipo" #: static/js/wirecloud/ui/MarketplaceViewMenuItems.js:94 -#: static/js/wirecloud/ui/SharingWindowMenu.js:46 +#: static/js/wirecloud/ui/SharingWindowMenu.js:159 msgid "Public" msgstr "Público" @@ -1384,38 +1400,38 @@ msgstr "Borrar marketplace" msgid "Do you really want to remove the marketplace \"%(marketName)s\"?" msgstr "¿Realmente quieres eliminar el marketplace \"%(marketName)s\"?" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:38 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:36 msgid "Missing dependencies" msgstr "Dependencias incumplidas" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:42 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:40 msgid "The following dependencies are missing:" msgstr "Las siguientes dependencias no se cumplen:" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:54 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:52 msgid "" "You will be able to continue after installing all the required dependencies." msgstr "Podrás continuar una vez todas las dependencias sean satisfechas." -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:59 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:376 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:736 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:57 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:364 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:103 msgid "Continue" msgstr "Continuar" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:68 -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:223 -#: static/js/wirecloud/ui/SharingWindowMenu.js:85 -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:137 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:737 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:66 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:235 +#: static/js/wirecloud/ui/SharingWindowMenu.js:214 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:140 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:104 msgid "Cancel" msgstr "Cancelar" -#: static/js/wirecloud/ui/MyResourcesView.js:44 +#: static/js/wirecloud/ui/MyResourcesView.js:58 msgid "Empty resource list" msgstr "Lista de recursos vacía" -#: static/js/wirecloud/ui/MyResourcesView.js:45 +#: static/js/wirecloud/ui/MyResourcesView.js:59 msgid "" "Currently, you do not have access to any component. You can get components " "using the Marketplace view or by uploading components manually using the " @@ -1425,16 +1441,16 @@ msgstr "" "usando la vista de Marketplace o subiendo recursos de forma manual usando el " "botón Subir." -#: static/js/wirecloud/ui/MyResourcesView.js:66 -#: static/js/wirecloud/ui/WorkspaceView.js:82 +#: static/js/wirecloud/ui/MyResourcesView.js:80 +#: static/js/wirecloud/ui/WorkspaceView.js:184 msgid "Get more components" msgstr "Obtener más componentes" -#: static/js/wirecloud/ui/MyResourcesView.js:153 +#: static/js/wirecloud/ui/MyResourcesView.js:162 msgid "My Resources - %(resource)s" msgstr "Mis recursos - %(resource)s" -#: static/js/wirecloud/ui/MyResourcesView.js:266 +#: static/js/wirecloud/ui/MyResourcesView.js:287 msgid "" "You have not configured any marketplace to upload this resource. Please, " "configure one on the Marketplace view." @@ -1442,7 +1458,7 @@ msgstr "" "No has configurado ningún marketplace en el que que subir este recurso. Por " "favor, configura uno en la vista Marketplace." -#: static/js/wirecloud/ui/MyResourcesView.js:352 +#: static/js/wirecloud/ui/MyResourcesView.js:371 msgid "" "Do you really want to remove the \"%(name)s\" (vendor: \"%(vendor)s\", " "version: \"%(version)s\") resource?" @@ -1450,7 +1466,7 @@ msgstr "" "¿Realmente quieres eliminar el recurso \"%(name)s\" (distribuidor: " "\"%(vendor)s\", versión: \"%(version)s\")?" -#: static/js/wirecloud/ui/MyResourcesView.js:378 +#: static/js/wirecloud/ui/MyResourcesView.js:395 msgid "" "Do you really want to remove all versions of the (vendor: \"%(vendor)s\", " "name: \"%(name)s\") resource?" @@ -1458,97 +1474,107 @@ msgstr "" "¿Realmente quieres eliminar todas las versiones del recurso (distribuidor: " "\"%(vendor)s\", nombre: \"%(name)s\")?" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:53 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:57 +msgid "Create Workspace" +msgstr "Crear entorno de trabajo" + +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:57 +#, fuzzy +#| msgid "Create Workspace" +msgid "Copy Workspace" +msgstr "Crear entorno de trabajo" + +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:60 msgid "Template" msgstr "Plantilla" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:56 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:63 msgid "Select a mashup template" msgstr "Selecciona una plantilla de mashup" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:61 -msgid "Create Workspace" -msgstr "Crear entorno de trabajo" - -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:70 -msgid "Creating a %(owner)s/%(name)s workspace using %(mashup)s as template" +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:81 +#, fuzzy +#| msgid "Creating a %(owner)s/%(name)s workspace using %(mashup)s as template" +msgid "Creating a %(owner)s/%(title)s workspace using %(mashup)s as template" msgstr "" "Creando un entorno de trabajo %(owner)s/%(name)s usando %(mashup)s como " "plantilla" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:72 -msgid "Creating a %(owner)s/%(name)s workspace" +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:83 +#, fuzzy +#| msgid "Creating a %(owner)s/%(name)s workspace" +msgid "Creating a %(owner)s/%(title)s workspace" msgstr "Creando el entorno de trabajo %(owner)s/%(name)s" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:75 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:86 msgid "Creating a new workspace using %(mashup)s as template" msgstr "Creando un nuevo entorno de trabajo usando %(mashup)s como plantilla" -#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:30 +#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:50 msgid "Operator Settings" msgstr "Configuración del operador" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:47 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:48 msgid "Parametrize" msgstr "Parametrizar" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:49 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:50 msgid "Modify" msgstr "Modificar" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:54 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:55 msgid "This value won't be editable by the user" msgstr "El usuario no podrá modificar el valor" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:57 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:58 msgid "This value will be editable by the user" msgstr "El usuario podrá modificar el valor" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:62 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:63 msgid "This value will be visible to the user" msgstr "El usuario podrá ver el valor actual" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:65 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:66 msgid "This value won't be visible to the user" msgstr "El usuario no podrá ver el valor" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:33 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:36 msgid "Normal" msgstr "Normal" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:34 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:37 msgid "Read Only" msgstr "Sólo lectura" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:38 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:41 msgid "Hidden" msgstr "Oculto" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:42 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:45 msgid "Current value" msgstr "Valor actual" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:43 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:46 msgid "Default value" msgstr "Valor por defecto" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:44 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:47 msgid "Parametrized value" msgstr "Valor parametrizado" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:48 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:51 msgid "Status" msgstr "Estado" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:49 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:52 msgid "Value source" msgstr "Fuente del valor" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:51 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:54 msgid "Value" msgstr "Valor" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:53 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:56 msgid "Parametrization" msgstr "Parametrización" @@ -1557,122 +1583,126 @@ msgid "Use current value" msgstr "Usar el valor actual" #: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:75 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:276 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:254 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:482 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:495 msgid "Add" msgstr "Añadir" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:146 -#: static/js/wirecloud/ui/WirecloudHeader.js:118 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:131 +#: static/js/wirecloud/ui/WirecloudHeader.js:116 msgid "User" msgstr "Usuario" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:150 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:135 msgid "User Name" msgstr "Nombre de Usuario" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:155 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:140 msgid "First Name" msgstr "Nombre" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:160 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:145 msgid "Last Name" msgstr "Appellidos" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:167 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:152 msgid "Context" msgstr "Contexto" -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:105 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:106 msgid "Inherit" msgstr "Heredar" -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:195 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:203 msgid "Set Defaults" msgstr "Valores por defecto" -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:215 -#: static/js/wirecloud/ui/SharingWindowMenu.js:81 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:220 +msgid "Error" +msgstr "" + +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:227 +#: static/js/wirecloud/ui/SharingWindowMenu.js:210 msgid "Save" msgstr "Guardar" -#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:37 -msgid "Upload resource" -msgstr "Subir el recurso" - -#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:62 +#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:51 msgid "Upload to" msgstr "Subir a" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:40 +#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:69 +msgid "Upload resource" +msgstr "Subir el recurso" + +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:43 msgid "General info" msgstr "Información general" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:42 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:45 msgid "Mashup Title" msgstr "Título del Mashup" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:42 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:45 msgid "Title to display on the catalogue" msgstr "Título a mostrar en el catálogo" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:43 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:46 msgid "Id of the vendor/distributor of the mashable application component" msgstr "Id del distribuidor del componente" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:44 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:47 msgid "Version" msgstr "Versión" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:45 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:48 msgid "Email" msgstr "Email" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:46 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:49 msgid "Short Description (plain text)" msgstr "Descripción corta (texto plano)" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:47 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:50 msgid "Detailed description (Markdown)" msgstr "Descripción detallada (Markdown)" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:48 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:51 msgid "Home page" msgstr "Página web" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:49 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:52 msgid "Authors" msgstr "Autores" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:54 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:57 msgid "Media" msgstr "Media" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:58 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:61 msgid "Image shown in catalogue (170x80 px)" msgstr "Imagen mostrada en el catálogo (170x80px)" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:65 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:68 msgid "Advanced" msgstr "Avanzado" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:67 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:70 msgid "Block widgets" msgstr "Bloquear los widgets" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:68 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:71 msgid "Block connections" msgstr "Bloquear las conexiones" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:69 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:72 msgid "Embed used widgets/operators" msgstr "Incrustar los widgets y los operadores usados" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:76 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:79 msgid "Upload workspace to my resources" msgstr "Subir el entorno de trabajo a mis recursos" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:82 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:85 msgid "" "Warning! Configured and stored data in your workspace " "(properties and preferences except passwords) will be shared by default!" @@ -1681,86 +1711,117 @@ msgstr "" "las preferencias y de las variables persistentes, exceptuando las " "contraseñas) serán compartidas por defecto." -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:132 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:58 -#: static/js/wirecloud/ui/WiringEditor/Component.js:48 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:50 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:78 -#: static/js/wirecloud/ui/WorkspaceTabView.js:127 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:134 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:48 +#: static/js/wirecloud/ui/WiringEditor/Component.js:90 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:269 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:330 +#: static/js/wirecloud/ui/WorkspaceTabView.js:220 msgid "Preferences" msgstr "Preferencias" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:139 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:141 msgid "Persistent variables" msgstr "Variables persistentes" -#: static/js/wirecloud/ui/RenameWindowMenu.js:32 +#: static/js/wirecloud/ui/RenameWindowMenu.js:34 msgid "New Name" msgstr "Nuevo nombre" -#: static/js/wirecloud/ui/SharingWindowMenu.js:37 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:170 +msgid "From (px):" +msgstr "Desde (px):" + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:171 +msgid "The left limit of the screen size range (in pixels)." +msgstr "El límite izquierdo del rango de tamaños de pantalla (en píxeles)." + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:197 +msgid "To (px):" +msgstr "Hasta (px):" + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:198 +msgid "" +"The right limit of the screen size range (in pixels). Use -1 for no limit." +msgstr "El límite derecho del rango de tamaños de pantalla (en píxeles). Usa -1 para sin límite." + +#: static/js/wirecloud/ui/SharingWindowMenu.js:105 +msgid "%(fullname)s (You)" +msgstr "%(fullname)s (Tú)" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:122 +msgid "Owner" +msgstr "Dueño" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:122 +msgid "Can view" +msgstr "Puede ver" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:126 +#: static/js/wirecloud/ui/WidgetView.js:309 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:53 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:275 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:493 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:504 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:320 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:507 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:519 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:67 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:102 +msgid "Remove" +msgstr "Eliminar" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:150 msgid "Sharing settings" msgstr "Configuración de compartición" -#: static/js/wirecloud/ui/SharingWindowMenu.js:42 +#: static/js/wirecloud/ui/SharingWindowMenu.js:155 msgid "Visibility options" msgstr "Opciones de visibilidad" -#: static/js/wirecloud/ui/SharingWindowMenu.js:46 +#: static/js/wirecloud/ui/SharingWindowMenu.js:159 msgid "Anyone on the Internet can find and access this dashboard." msgstr "Cualquier usuario en Internet puede encontrar y acceder a este panel." -#: static/js/wirecloud/ui/SharingWindowMenu.js:47 +#: static/js/wirecloud/ui/SharingWindowMenu.js:160 +msgid "Registered User" +msgstr "" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:160 +#, fuzzy +#| msgid "Anyone on the Internet can find and access this dashboard." +msgid "" +"Anyone on the Internet can find this dashboard. Only registered users can " +"access it." +msgstr "Cualquier usuario en Internet puede encontrar y acceder a este panel." + +#: static/js/wirecloud/ui/SharingWindowMenu.js:161 msgid "Private" msgstr "Privado" -#: static/js/wirecloud/ui/SharingWindowMenu.js:47 +#: static/js/wirecloud/ui/SharingWindowMenu.js:161 msgid "Shared with specific people and organizations." msgstr "Compartido con usuarios y organizaciones específicos." -#: static/js/wirecloud/ui/SharingWindowMenu.js:57 +#: static/js/wirecloud/ui/SharingWindowMenu.js:171 msgid "Users and groups with access" msgstr "Usuarios y grupos con acceso" -#: static/js/wirecloud/ui/SharingWindowMenu.js:60 -msgid "Add a person or an organization" +#: static/js/wirecloud/ui/SharingWindowMenu.js:174 +#, fuzzy +#| msgid "Add a person or an organization" +msgid "Add a person, a group or an organization" msgstr "Añade una persona o una organización" -#: static/js/wirecloud/ui/SharingWindowMenu.js:167 -msgid "%(fullname)s (You)" -msgstr "%(fullname)s (Tú)" - -#: static/js/wirecloud/ui/SharingWindowMenu.js:183 -msgid "Owner" -msgstr "Dueño" - -#: static/js/wirecloud/ui/SharingWindowMenu.js:185 -msgid "Can view" -msgstr "Puede ver" - -#: static/js/wirecloud/ui/SharingWindowMenu.js:191 -#: static/js/wirecloud/ui/WidgetView.js:117 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:65 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:57 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:287 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:298 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:68 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:266 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:278 -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:76 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:101 -msgid "Remove" -msgstr "Eliminar" - -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:44 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:45 msgid "Upgrade" msgstr "Actualizar" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:50 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:51 msgid "Downgrade" msgstr "Desactualizar" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:70 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:71 msgid "" "There is not change information between versions %(from_version)s and " "%(to_version)s" @@ -1768,97 +1829,187 @@ msgstr "" "No hay información sobre los cambios entre las versiones %(from_version)s y " "%(to_version)s" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:75 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:76 msgid "Unable to retrieve change log information" msgstr "Imposible obtener la información del registro de cambios" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:91 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:92 msgid "Available versions" msgstr "Versiones disponibles" -#: static/js/wirecloud/ui/WidgetView.js:151 -msgid "Menu" -msgstr "Menú" - -#: static/js/wirecloud/ui/WidgetView.js:162 -#: static/js/wirecloud/ui/WidgetView.js:329 -msgid "Minimize" -msgstr "Minimizar" +#: static/js/wirecloud/ui/WidgetView.js:42 +#, fuzzy +#| msgid "Drag & drop to move the widget" +msgid "Disallow to move this widget" +msgstr "Arrastra y suelta para mover el widget" -#: static/js/wirecloud/ui/WidgetView.js:319 -msgid "Maximize" -msgstr "Maximizar" +#: static/js/wirecloud/ui/WidgetView.js:42 +#, fuzzy +#| msgid "Drag & drop to move the widget" +msgid "Allow to move this widget" +msgstr "Arrastra y suelta para mover el widget" -#: static/js/wirecloud/ui/WidgetView.js:368 +#: static/js/wirecloud/ui/WidgetView.js:48 msgid "Hide title" msgstr "Ocultar título" -#: static/js/wirecloud/ui/WidgetView.js:368 +#: static/js/wirecloud/ui/WidgetView.js:48 msgid "Show title" msgstr "Mostrar título" -#: static/js/wirecloud/ui/WidgetView.js:725 +#: static/js/wirecloud/ui/WidgetView.js:207 msgid "%(errorCount)s error" msgid_plural "%(errorCount)s errors" msgstr[0] "%(errorCount)s error" msgstr[1] "%(errorCount)s errores" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:64 +#: static/js/wirecloud/ui/WidgetView.js:351 +msgid "Menu" +msgstr "Menú" + +#: static/js/wirecloud/ui/WidgetView.js:362 +#: static/js/wirecloud/ui/WidgetView.js:560 +msgid "Minimize" +msgstr "Minimizar" + +#: static/js/wirecloud/ui/WidgetView.js:545 +msgid "Maximize" +msgstr "Maximizar" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:57 msgid "Reload" msgstr "Recargar" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:71 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:79 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:66 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:64 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:134 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:92 msgid "Upgrade/Downgrade" msgstr "Actualizar/Desactualizar" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:92 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:85 msgid "User's Manual" msgstr "Manual de usuario" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:96 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:89 msgid "Documentation" msgstr "Documentación" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:105 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:104 +msgid "Left" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:116 +msgid "Center" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:128 +#, fuzzy +#| msgid "Height" +msgid "Right" +msgstr "Altura" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:143 +msgid "Top" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:155 +msgid "Bottom" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:168 +msgid "Fixed x" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:168 +msgid "Relative x" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:183 +msgid "Fixed y" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:183 +msgid "Relative y" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:198 +msgid "Fixed width" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:198 +msgid "Relative width" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:212 +msgid "Fixed height" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:212 +msgid "Relative height" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:229 msgid "Exit Full Dragboard" msgstr "Salir de panel completo" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:108 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:232 msgid "Full Dragboard" msgstr "Panel completo" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:122 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:249 +msgid "Extract from grid" +msgstr "Extraer de la rejilla" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:258 msgid "Snap to grid" msgstr "Ajustar a la rejilla" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:125 -msgid "Extract from grid" -msgstr "Extraer de la rejilla" +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:267 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the top sidebar" +msgstr "Cierra el panel lateral" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:276 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the right sidebar" +msgstr "Cierra el panel lateral" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:285 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the bottom sidebar" +msgstr "Cierra el panel lateral" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:294 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the left sidebar" +msgstr "Cierra el panel lateral" -#: static/js/wirecloud/ui/WirecloudHeader.js:109 +#: static/js/wirecloud/ui/WirecloudHeader.js:102 msgid "Django Admin panel" msgstr "Panel de administración de Django" -#: static/js/wirecloud/ui/WirecloudHeader.js:117 -#: static/js/wirecloud/ui/WirecloudHeader.js:118 +#: static/js/wirecloud/ui/WirecloudHeader.js:115 +#: static/js/wirecloud/ui/WirecloudHeader.js:116 msgid "Switch User" msgstr "Cambiar usuario" -#: static/js/wirecloud/ui/WirecloudHeader.js:142 +#: static/js/wirecloud/ui/WirecloudHeader.js:133 +msgid "Back to %(user)s" +msgstr "" + +#: static/js/wirecloud/ui/WirecloudHeader.js:139 msgid "Sign out" msgstr "Salir" -#: static/js/wirecloud/ui/WiringEditor.js:169 -msgid "%(workspace_title)s - Wiring" -msgstr "%(workspace_title)s - Wiring" - -#: static/js/wirecloud/ui/WiringEditor.js:390 +#: static/js/wirecloud/ui/WiringEditor.js:171 msgid "Hello, welcome to the Wiring Editor view!" msgstr "Hola, ¡Bienvenido al Editor del Wiring!" -#: static/js/wirecloud/ui/WiringEditor.js:391 +#: static/js/wirecloud/ui/WiringEditor.js:172 msgid "" "In this view you can connect all the components of your dashboard in a " "visual way." @@ -1866,7 +2017,7 @@ msgstr "" "En esta vista puedes conectar todos los componentes del panel de una forma " "visual." -#: static/js/wirecloud/ui/WiringEditor.js:397 +#: static/js/wirecloud/ui/WiringEditor.js:178 msgid "" "Open the sidebar using the Find components button and drag & " "drop components (operators/widgets) from the sidebar for being able to " @@ -1876,15 +2027,15 @@ msgstr "" "arrastrar y soltar componentes (operadores/widgets) desde el panel lateral y " "poder conectarlos como quieras." -#: static/js/wirecloud/ui/WiringEditor.js:404 +#: static/js/wirecloud/ui/WiringEditor.js:185 msgid "Find components" msgstr "Buscar componentes" -#: static/js/wirecloud/ui/WiringEditor.js:417 +#: static/js/wirecloud/ui/WiringEditor.js:198 msgid "List behaviours" msgstr "Listar comportamientos" -#: static/js/wirecloud/ui/WiringEditor.js:653 +#: static/js/wirecloud/ui/WiringEditor.js:429 msgid "" "The connection will also be modified for the rest of behaviours, would you " "like to continue?" @@ -1892,34 +2043,28 @@ msgstr "" "La conexión será modificada también en el resto de comportamientos. ¿Desea " "continuar?" -#: static/js/wirecloud/ui/WiringEditor.js:729 +#: static/js/wirecloud/ui/WiringEditor.js:505 msgid "Behaviour" msgstr "Comportamiento" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:120 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:721 -msgid "New behaviour" -msgstr "Nuevo comportamiento" - -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:121 -#: static/js/wirecloud/ui/WiringEditor/Endpoint.js:125 -msgid "No description provided." -msgstr "No se ha proporcionado una descripción." +#: static/js/wirecloud/ui/WiringEditor.js:786 +msgid "%(workspace_title)s - Wiring" +msgstr "%(workspace_title)s - Wiring" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:272 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:254 msgid "%(behaviour_title)s's logs" msgstr "Registros de %(behaviour_title)s" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:292 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:719 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:273 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:88 msgid "Description" msgstr "Descripción" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:294 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:275 msgid "Behaviour settings" msgstr "Configuración del comportamiento" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:372 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:360 msgid "" "The following operation is irreversible and removes the behaviour " "completely. Would you like to continue?" @@ -1927,49 +2072,16 @@ msgstr "" "Esta operación es irreversible y eliminirá el comportamiento por completo. " "¿Desea continuar?" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:377 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:365 msgid "No, thank you" msgstr "No, gracias" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:46 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:128 -msgid "Enable" -msgstr "Activar" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:53 -msgid "Create behaviour" -msgstr "Crear comportamiento" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:60 -msgid "Order behaviours" -msgstr "Ordenar los comportamientos" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:84 -msgid "New feature" -msgstr "Nueva funcionalidad" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:85 -msgid "Enable the behaviours to enjoy with a new way to handle connections." -msgstr "" -"Activa los comportamientos para disfrutar de una nueva forma de manejar las " -"conexiones." - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:88 -msgid "" -"Click here for a quick guide/tutorial on how to use this new feature." -msgstr "" -"Haz click aquí para una guía rápida/tutorial sobre como usar esta " -"nueva funcionalidad." - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:114 -msgid "Disable" -msgstr "Desactivar" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:402 -msgid "The behaviour (%(title)s) was loaded." -msgstr "El comportamiento (%(title)s) ha sido cargado correctamente." +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:87 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:90 +msgid "New behaviour" +msgstr "Nuevo comportamiento" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:733 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:100 msgid "" "The behaviours will be removed but the components and connections will still " "exist, would you like to continue?" @@ -1977,18 +2089,24 @@ msgstr "" "Los comportamientos serán eliminados pero los componentes y las conexiones " "seguirán existiendo. ¿Desea continuar?" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:801 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:111 +#, fuzzy +#| msgid "List behaviours" +msgid "Initial behaviour" +msgstr "Listar comportamientos" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:166 msgid "" "The will be removed, would you like to " "continue?" msgstr "" "El será borrado. ¿Desea continuar?" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:821 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:184 msgid "
      • The .
      • " msgstr "
      • El .
      • " -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:827 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:190 msgid "" "

        These components only exist within the current behaviour :

        Would you like to continue?

        " @@ -1997,7 +2115,7 @@ msgstr "" ":

        ¿Desea continuar?" "

        " -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:848 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:207 msgid "" "The will be definitely removed, would you like to continue?" @@ -2005,191 +2123,237 @@ msgstr "" "El será borrado de forma " "definitiva. ¿Desea continuar?" -#: static/js/wirecloud/ui/WiringEditor/Component.js:135 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:339 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:415 +msgid "Enable" +msgstr "Activar" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:346 +msgid "Create behaviour" +msgstr "Crear comportamiento" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:353 +msgid "Order behaviours" +msgstr "Ordenar los comportamientos" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:377 +msgid "New feature" +msgstr "Nueva funcionalidad" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:378 +msgid "Enable the behaviours to enjoy with a new way to handle connections." +msgstr "" +"Activa los comportamientos para disfrutar de una nueva forma de manejar las " +"conexiones." + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:381 +msgid "" +"Click here for a quick guide/tutorial on how to use this new feature." +msgstr "" +"Haz click aquí para una guía rápida/tutorial sobre como usar esta " +"nueva funcionalidad." + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:401 +msgid "Disable" +msgstr "Desactivar" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:691 +msgid "The behaviour (%(title)s) was loaded." +msgstr "El comportamiento (%(title)s) ha sido cargado correctamente." + +#: static/js/wirecloud/ui/WiringEditor/Component.js:32 msgid "volatile" msgstr "volátil" -#: static/js/wirecloud/ui/WiringEditor/Component.js:138 +#: static/js/wirecloud/ui/WiringEditor/Component.js:35 msgid "missing" msgstr "ausente" -#: static/js/wirecloud/ui/WiringEditor/Component.js:141 +#: static/js/wirecloud/ui/WiringEditor/Component.js:38 msgid "in use" msgstr "en uso" -#: static/js/wirecloud/ui/WiringEditor/Component.js:144 +#: static/js/wirecloud/ui/WiringEditor/Component.js:41 msgid "no endpoints" msgstr "sin conectores" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:703 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:179 msgid "Missing" msgstr "Ausente" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:705 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:181 msgid "%(count)s error" msgid_plural "%(count)s errors" msgstr[0] "%(count)s error" msgstr[1] "%(count)s errores" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:92 -msgid "Delete cascade" -msgstr "Borrar en cascada" - -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:132 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:56 msgid "Expand" msgstr "Expandir" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:134 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:58 msgid "Collapse" msgstr "Contraer" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:140 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:64 msgid "Stop ordering" msgstr "Dejar de ordenar" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:142 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:66 msgid "Order endpoints" msgstr "Ordenar conectores" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:150 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:102 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:75 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:47 msgid "Rename %(type)s" msgstr "Renombrar %(type)s" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:36 -msgid "Create" -msgstr "Crear" +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:147 +msgid "Delete cascade" +msgstr "Borrar en cascada" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:106 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:39 msgid "No description provided" msgstr "No se ha proporcionado una descripción" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:128 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:61 msgid "No image available" msgstr "Imagen no disponible" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:137 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:70 msgid "%(version)s (latest)" msgstr "%(version)s (última)" -#: static/js/wirecloud/ui/WiringEditor/ConnectionHandle.js:72 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:84 +msgid "Create" +msgstr "Crear" + +#: static/js/wirecloud/ui/WiringEditor/ConnectionHandle.js:70 msgid "Drag & Drop" msgstr "Arrastrar & soltar" -#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:83 -msgid "Restore defaults" -msgstr "Restaurar" - -#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:104 +#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:39 msgid "Stop customizing" msgstr "Dejar de personalizar" -#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:104 +#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:39 msgid "Customize" msgstr "Personalizar" +#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:91 +msgid "Restore defaults" +msgstr "Restaurar" + +#: static/js/wirecloud/ui/WiringEditor/Endpoint.js:171 +msgid "No description provided." +msgstr "No se ha proporcionado una descripción." + #: static/js/wirecloud/ui/WorkspaceListItems.js:46 msgid "Empty workspace list" msgstr "Lista de entornos de trabajo vacía" -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:58 +#: static/js/wirecloud/ui/WorkspaceTabView.js:354 +msgid "Currently editing for screen sizes %(interval)s" +msgstr "Actualmente editando para los tamaños de pantalla %(interval)s" + +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:49 msgid "Rename Workspace Tab" msgstr "Renombrar pestaña" -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:63 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:54 msgid "Set as initial" msgstr "Configurar como inicial" -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:78 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:69 msgid "The tab's widgets will also be removed. Would you like to continue?" msgstr "Los widgets de la pestaña serán también eliminados. ¿Desea continuar?" -#: static/js/wirecloud/ui/WorkspaceView.js:64 +#: static/js/wirecloud/ui/WorkspaceView.js:166 msgid "Wiring" msgstr "Wiring" -#: static/js/wirecloud/ui/WorkspaceView.js:271 +#: static/js/wirecloud/ui/WorkspaceView.js:370 msgid "New tab" msgstr "Nueva pestaña" -#: static/js/wirecloud/ui/WorkspaceView.js:286 -#: static/js/wirecloud/ui/WorkspaceView.js:297 +#: static/js/wirecloud/ui/WorkspaceView.js:385 +#: static/js/wirecloud/ui/WorkspaceView.js:396 msgid "Full screen" msgstr "Ver a pantalla completa" -#: static/js/wirecloud/ui/WorkspaceView.js:293 +#: static/js/wirecloud/ui/WorkspaceView.js:392 msgid "Exit full screen" msgstr "Salir de pantalla completa" -#: static/js/wirecloud/ui/WorkspaceView.js:333 +#: static/js/wirecloud/ui/WorkspaceView.js:432 msgid "Add components" msgstr "Añadir componentes" -#: static/js/wirecloud/ui/WorkspaceView.js:392 -#: static/js/wirecloud/ui/WorkspaceView.js:406 +#: static/js/wirecloud/ui/WorkspaceView.js:490 +#: static/js/wirecloud/ui/WorkspaceView.js:504 msgid "loading..." msgstr "cargando..." -#: static/js/wirecloud/ui/WorkspaceView.js:445 +#: static/js/wirecloud/ui/WorkspaceView.js:542 msgid "The requested workspace is no longer available (it was deleted)." msgstr "" "El entorno de trabajo solicitado ya no está disponible (ha sido borrado)." -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:58 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:50 msgid "New workspace" msgstr "Nuevo entorno de trabajo" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:65 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:57 msgid "Rename Workspace" msgstr "Renombrar el entorno de trabajo" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:71 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:63 msgid "Share" msgstr "Compartir" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:77 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:69 msgid "Upload to my resources" msgstr "Subir a mis recursos" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:88 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:80 msgid "Embed" msgstr "Incrustar" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:89 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:81 msgid "Embed Code" msgstr "Código a incrustar" -#: static/js/wirecloud/wiring/Connection.js:101 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:93 +msgid "Duplicate" +msgstr "" + +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:95 +msgid "Copy of %(title)s" +msgstr "" + +#: static/js/wirecloud/wiring/Connection.js:80 msgid "The connection ('%(source)s'-'%(target)s') was established." msgstr "" "La conexión (‘%(source)s’-‘%(target)s’) se ha establecido correctamente." -#: static/js/wirecloud/wiring/Connection.js:110 +#: static/js/wirecloud/wiring/Connection.js:89 msgid "The connection ('%(source)s'-'%(target)s') was detached." msgstr "La conexión (‘%(source)s’-‘%(target)s’) se ha eliminado." -#: static/js/wirecloud/wiring/Connection.js:137 +#: static/js/wirecloud/wiring/Connection.js:116 msgid "The connection ('%(source)s'-'%(target)s') has a missing endpoint." msgstr "" "La conexión (‘%(source)s’-‘%(target)s’) implica a un conector inexistente." -#: static/js/wirecloud/wiring/Connection.js:177 +#: static/js/wirecloud/wiring/Connection.js:156 msgid "Connection's logs" msgstr "Registros de la conexión" -#: static/js/wirecloud/wiring/Endpoint.js:66 +#: static/js/wirecloud/wiring/Endpoint.js:61 msgid "Unimplemented function: %(funcName)s" msgstr "Función no implementada: %(funcName)s" -#: static/js/wirecloud/wiring/Operator.js:179 -msgid "Operator created successfully." -msgstr "Operador creado correctamente." - -#: static/js/wirecloud/wiring/Operator.js:286 -msgid "%(operator_title)s's logs" -msgstr "Registros de %(operator_title)s" - -#: static/js/wirecloud/wiring/Operator.js:498 +#: static/js/wirecloud/wiring/Operator.js:222 msgid "" "

        This operator is currently not available. You or an administrator " "probably uninstalled it.

        Suggestions:
        • Remove the operator." @@ -2203,23 +2367,31 @@ msgstr "" "li>
        • O instalar otra versión de este operador y posteriormente usar la " "opción Actualizar/Desactualizar
        " -#: static/js/wirecloud/wiring/Operator.js:501 +#: static/js/wirecloud/wiring/Operator.js:225 msgid "Operator loaded successfully." msgstr "Operador cargado correctamente." -#: static/js/wirecloud/wiring/Operator.js:525 +#: static/js/wirecloud/wiring/Operator.js:261 msgid "Operator unloaded successfully." msgstr "Operador descargado correctamente." -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:67 -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:69 +#: static/js/wirecloud/wiring/Operator.js:426 +msgid "Operator created successfully." +msgstr "Operador creado correctamente." + +#: static/js/wirecloud/wiring/Operator.js:536 +msgid "%(operator_title)s's logs" +msgstr "Registros de %(operator_title)s" + +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:75 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:77 msgid "Use in %(endpointName)s" msgstr "Usar en %(endpointName)s" -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:83 -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:95 -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:86 -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:98 +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:90 +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:105 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:94 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:106 msgid "" "Exception catched while processing an event that reached the " "\"%(inputendpoint)s\" input endpoint" @@ -2227,10 +2399,22 @@ msgstr "" "Excepción capturada mientras se procesaba un evento que llego al endpoint de " "entrada \"%(inputendpoint)s\"" -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:85 +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:94 msgid "Operator has not registered a callback for this input endpoint" msgstr "El operador no ha registrado un callback para este punto de entrada" -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:88 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:96 msgid "Widget has not registered a callback for this input endpoint" msgstr "El widget no ha registrado un callback para este endpoint de entrada" + +#~ msgid "missing vendor" +#~ msgstr "falta el distribuidor" + +#~ msgid "missing name" +#~ msgstr "falta el nombre" + +#~ msgid "missing version" +#~ msgstr "falta la versión" + +#~ msgid "missing type" +#~ msgstr "falta el tipo" diff --git a/src/wirecloud/platform/locale/ja/LC_MESSAGES/django.po b/src/wirecloud/platform/locale/ja/LC_MESSAGES/django.po index 3fe85574fa..2495f432b6 100644 --- a/src/wirecloud/platform/locale/ja/LC_MESSAGES/django.po +++ b/src/wirecloud/platform/locale/ja/LC_MESSAGES/django.po @@ -10,18 +10,18 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-15 00:00+0900\n" +"POT-Creation-Date: 2024-05-27 11:24+0200\n" "PO-Revision-Date: 2019-03-15 00:00+0900\n" +"Last-Translator: Kazuhito Suda \n" +"Language-Team: Kazuhito Suda \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"Last-Translator: Kazuhito Suda \n" -"Language-Team: Kazuhito Suda \n" "X-Generator: Poedit 2.2.1\n" -#: admin.py:64 +#: admin.py:71 msgid "Edit" msgstr "編集" @@ -34,74 +34,84 @@ msgstr "コンセプト" msgid "Value" msgstr "値" -#: core/catalogue_manager.py:58 +#: core/catalogue_manager.py:49 #, python-format msgid "Resource already exists %(resource_id)s" msgstr "リソースは既に存在します %(resource_id)s" -#: core/plugins.py:266 +#: core/plugins.py:283 msgid "Language" msgstr "言語" -#: core/plugins.py:267 +#: core/plugins.py:284 msgid "Current language used in the platform" msgstr "プラットフォームで使用されている現在の言語" -#: core/plugins.py:270 +#: core/plugins.py:287 msgid "Username" msgstr "ユーザ名" -#: core/plugins.py:271 +#: core/plugins.py:288 msgid "User name of the current logged user" msgstr "現在ログインしているユーザのユーザ名" -#: core/plugins.py:274 +#: core/plugins.py:291 msgid "Full name" msgstr "氏名" -#: core/plugins.py:275 +#: core/plugins.py:292 msgid "Full name of the logged user" msgstr "ログインしているユーザの氏名" -#: core/plugins.py:278 +#: core/plugins.py:295 msgid "Avatar" msgstr "アバター" -#: core/plugins.py:279 +#: core/plugins.py:296 msgid "URL of the avatar" msgstr "アバターの URL" -#: core/plugins.py:282 +#: core/plugins.py:299 msgid "Is Anonymous" msgstr "匿名か" -#: core/plugins.py:283 +#: core/plugins.py:300 msgid "Boolean. Designates whether current user is logged in the system." msgstr "" "ブール値。 現在のユーザがシステムにログインしているかどうかを指定します。" -#: core/plugins.py:286 +#: core/plugins.py:303 msgid "Is Staff" msgstr "スタッフか" -#: core/plugins.py:287 +#: core/plugins.py:304 msgid "Boolean. Designates whether current user can access the admin site." msgstr "" "ブール値。 現在のユーザが管理サイトにアクセスできるかどうかを指定します。" -#: core/plugins.py:290 +#: core/plugins.py:307 msgid "Is Superuser" msgstr "スーパーユーザか" -#: core/plugins.py:291 +#: core/plugins.py:308 msgid "Boolean. Designates whether current user is a super user." msgstr "ブール値。 現在のユーザがスーパーユーザーかどうかを指定します。" -#: core/plugins.py:294 +#: core/plugins.py:311 +#, fuzzy +#| msgid "Groups" +msgid "User Groups" +msgstr "グループ" + +#: core/plugins.py:312 +msgid "List of the groups the user belongs to." +msgstr "" + +#: core/plugins.py:315 msgid "Mode" msgstr "モード" -#: core/plugins.py:295 +#: core/plugins.py:316 msgid "" "Rendering mode used by the platform (available modes: classic, smartphone " "and embedded)" @@ -109,35 +119,55 @@ msgstr "" "プラットフォームで使用されるレンダリングモード (使用可能なモード: classic, " "smartphone および embedded)" -#: core/plugins.py:298 +#: core/plugins.py:319 +msgid "User Organizations" +msgstr "" + +#: core/plugins.py:320 +msgid "List of the organizations the user belongs to." +msgstr "" + +#: core/plugins.py:323 msgid "Orientation" msgstr "向き" -#: core/plugins.py:299 +#: core/plugins.py:324 msgid "Current screen orientation" msgstr "現在の画面の向き" -#: core/plugins.py:302 +#: core/plugins.py:327 +#, fuzzy +#| msgid "Username" +msgid "Real User Username" +msgstr "ユーザ名" + +#: core/plugins.py:328 +#, fuzzy +#| msgid "User name of the current logged user" +msgid "User name of the real logged user" +msgstr "現在ログインしているユーザのユーザ名" + +#: core/plugins.py:331 msgid "Theme" msgstr "テーマ" -#: core/plugins.py:303 +#: core/plugins.py:332 msgid "Name of the theme used by the platform" msgstr "プラットフォームによって使用されるテーマの名前" -#: core/plugins.py:306 +#: core/plugins.py:335 msgid "Version" msgstr "バージョン" -#: core/plugins.py:307 +#: core/plugins.py:336 msgid "Version of the platform" msgstr "プラットフォームのバージョン" -#: core/plugins.py:310 +#: core/plugins.py:339 msgid "Version Hash" msgstr "バージョン・ハッシュ" -#: core/plugins.py:311 +#: core/plugins.py:340 msgid "" "Hash for the current version of the platform. This hash changes when the " "platform is updated or when an addon is added or removed" @@ -145,59 +175,69 @@ msgstr "" "現在のバージョンのプラットフォームのハッシュ。 このハッシュは、プラットフォー" "ムが更新されたとき、またはアドオンが追加または削除されたときに変更されます" -#: core/plugins.py:322 +#: core/plugins.py:351 msgid "Anonymous" msgstr "匿名" -#: core/plugins.py:343 workspace/models.py:38 workspace/models.py:104 +#: core/plugins.py:378 workspace/models.py:49 +msgid "Description" +msgstr "説明" + +#: core/plugins.py:379 +msgid "Short description of the workspace without formating" +msgstr "書式設定なしのワークスペースの簡単な説明" + +#: core/plugins.py:382 +msgid "Editing mode" +msgstr "" + +#: core/plugins.py:383 +#, fuzzy +#| msgid "Boolean. Designates whether current user is a super user." +msgid "Boolean. Designates whether the workspace is in editing mode." +msgstr "ブール値。 現在のユーザがスーパーユーザーかどうかを指定します。" + +#: core/plugins.py:386 workspace/models.py:39 workspace/models.py:125 msgid "Title" msgstr "タイトル" -#: core/plugins.py:344 +#: core/plugins.py:387 msgid "Current title of the workspace" msgstr "現在のワークスペースのタイトル" -#: core/plugins.py:347 iwidget/models.py:31 markets/models.py:29 +#: core/plugins.py:390 iwidget/models.py:31 markets/models.py:29 #: markets/models.py:46 preferences/models.py:29 preferences/models.py:43 -#: preferences/models.py:58 workspace/models.py:36 workspace/models.py:103 +#: preferences/models.py:58 workspace/models.py:37 workspace/models.py:124 msgid "Name" msgstr "名前" -#: core/plugins.py:348 +#: core/plugins.py:391 msgid "Current name of the workspace" msgstr "現在のワークスペースの名前" -#: core/plugins.py:351 +#: core/plugins.py:394 msgid "Owner" msgstr "オーナー" -#: core/plugins.py:352 +#: core/plugins.py:395 msgid "Workspace's owner username" msgstr "ワークスペースの所有者のユーザ名" -#: core/plugins.py:355 workspace/models.py:47 -msgid "Description" -msgstr "説明" - -#: core/plugins.py:356 -msgid "Short description of the workspace without formating" -msgstr "書式設定なしのワークスペースの簡単な説明" - -#: core/plugins.py:359 workspace/models.py:48 +#: core/plugins.py:398 workspace/models.py:50 msgid "Long description" msgstr "長い説明" -#: core/plugins.py:360 +#: core/plugins.py:399 msgid "" "Detailed workspace's description. This description can contain formatting." msgstr "" "詳細なワークスペースの説明。 この説明には書式設定を含めることができます。" -#: core/plugins.py:375 markets/models.py:30 +#: core/plugins.py:408 markets/models.py:30 msgid "Public" msgstr "パブリック" -#: core/plugins.py:378 +#: core/plugins.py:411 msgid "" "Allow any user to open this workspace (in read-only mode). (default: " "disabled)" @@ -205,31 +245,52 @@ msgstr "" "任意のユーザーが読み取り専用モードでこのワークスペースを開くことを許可します " "(デフォルト:無効)" -#: core/plugins.py:383 +#: core/plugins.py:416 +msgid "Required registered user" +msgstr "" + +#: core/plugins.py:419 +msgid "" +"Require users to be logged in to access the workspace (This option has only " +"effect if the workspace is public). (default: disabled)" +msgstr "" + +#: core/plugins.py:424 msgid "Share list" msgstr "共有リスト" -#: core/plugins.py:386 +#: core/plugins.py:427 msgid "List of users with access to this workspace. (default: [])" msgstr "このワークスペースにアクセスできるユーザーのリスト。(デフォルト: [])" -#: core/plugins.py:391 +#: core/plugins.py:432 msgid "Default layout" msgstr "デフォルト・レイアウト" -#: core/plugins.py:394 +#: core/plugins.py:435 msgid "Base" msgstr "ベース" -#: core/plugins.py:395 +#: core/plugins.py:436 msgid "Free" msgstr "フリー" -#: core/plugins.py:397 +#: core/plugins.py:438 msgid "Default layout for the new widgets." msgstr "新しいウィジェットのデフォルト・レイアウト。" -#: core/plugins.py:409 +#: core/plugins.py:449 +msgid "Screen sizes" +msgstr "" + +#: core/plugins.py:451 +msgid "" +"List of screen sizes supported by the workspace. Each screen size is defined " +"by a range of screen widths and different widget configurations are " +"associated with it." +msgstr "" + +#: core/plugins.py:463 msgid "Base layout" msgstr "ベース・レイアウト" @@ -237,11 +298,11 @@ msgstr "ベース・レイアウト" msgid "Widget" msgstr "ウィジェット" -#: iwidget/models.py:39 +#: iwidget/models.py:30 msgid "Widget URI" msgstr "ウィジェット URI" -#: iwidget/models.py:32 workspace/utils.py:472 workspace/views.py:61 +#: iwidget/models.py:32 workspace/utils.py:422 workspace/views.py:62 msgid "Tab" msgstr "タブ" @@ -249,32 +310,44 @@ msgstr "タブ" msgid "Layout" msgstr "レイアウト" -#: iwidget/models.py:35 +#: iwidget/models.py:36 msgid "Read Only" msgstr "読み取り専用" -#: iwidget/utils.py:70 +#: iwidget/utils.py:71 #, python-format msgid "Field %(field)s must contain a boolean value" msgstr "フィールド %(field)s にはブール値を含める必要があります" -#: iwidget/utils.py:81 iwidget/utils.py:94 +#: iwidget/utils.py:80 iwidget/utils.py:93 iwidget/utils.py:106 #, python-format msgid "Field %(field)s must contain a number value" msgstr "フィールド %(field)s には数値を含める必要があります" -#: iwidget/utils.py:84 iwidget/utils.py:97 +#: iwidget/utils.py:83 iwidget/utils.py:96 iwidget/utils.py:109 #, python-format msgid "Invalid value for %(field)s" msgstr "%(field)s の値が無効です" -#: iwidget/utils.py:137 +#: iwidget/utils.py:119 +#, fuzzy +#| msgid "Field %(field)s must contain a number value" +msgid "anchor field must contain a string value" +msgstr "フィールド %(field)s には数値を含める必要があります" + +#: iwidget/utils.py:122 +#, fuzzy +#| msgid "Invalid value for %(field)s" +msgid "Invalid value for anchor field" +msgstr "%(field)s の値が無効です" + +#: iwidget/utils.py:225 #, python-format msgid "%(uri)s is not a widget" msgstr "%(uri)s はウィジェットではありません" -#: iwidget/views.py:42 iwidget/views.py:214 iwidget/views.py:282 -#: wiring/views.py:404 workspace/views.py:187 workspace/views.py:304 +#: iwidget/views.py:42 iwidget/views.py:217 iwidget/views.py:283 +#: wiring/views.py:407 workspace/views.py:160 workspace/views.py:277 msgid "You don't have permission to access this workspace" msgstr "このワークスペースにアクセスする権限がありません" @@ -314,7 +387,7 @@ msgstr "ワークスペースからウィジェットを削除する権限があ msgid "IWidget cannot be deleted" msgstr "ウィジェットは削除できません" -#: iwidget/views.py:182 iwidget/views.py:227 +#: iwidget/views.py:182 iwidget/views.py:230 msgid "Missing widget variables cannot be updated" msgstr "欠落しているウィジェット変数は更新できません" @@ -328,17 +401,17 @@ msgstr "無効な設定: \"%s\"" msgid "\"%s\" preference is read only." msgstr "\"%s\" 設定は読み取り専用です。" -#: iwidget/views.py:201 +#: iwidget/views.py:200 iwidget/views.py:204 msgid "" "You have not enough permission for updating the preferences of the iwidget" msgstr "ウィジェットの設定を更新する権限がありません" -#: iwidget/views.py:257 +#: iwidget/views.py:260 #, python-format msgid "Invalid persistent variable: \"%s\"" msgstr "無効な永続変数: \"%s\"" -#: iwidget/views.py:264 iwidget/views.py:269 +#: iwidget/views.py:266 iwidget/views.py:270 msgid "" "You have not enough permission for updating the persistent variables of this " "widget" @@ -379,8 +452,10 @@ msgid "You are not allowed allow to install components to other users" msgstr "他のユーザにコンポーネントをインストールすることを許可されていません" #: localcatalogue/views.py:183 -msgid "" -"You are not allowed allow to install components to non-owned organizations" +#, fuzzy +#| msgid "" +#| "You are not allowed allow to install components to non-owned organizations" +msgid "You are not allowed to install components to non-owned organizations" msgstr "" "コンポーネントを所有していない組織にインストールすることは許可されていません" @@ -412,7 +487,7 @@ msgstr "リソースを削除することを許可されていません" msgid "You don't have access to this workspace" msgstr "このワークスペースにアクセスできません" -#: markets/models.py:30 markets/models.py:45 +#: markets/models.py:28 markets/models.py:45 msgid "User" msgstr "ユーザ" @@ -424,20 +499,20 @@ msgstr "オプション" msgid "Market" msgstr "マーケット" -#: markets/views.py:76 +#: markets/views.py:77 msgid "invalid user option" msgstr "無効なユーザ・オプション" -#: markets/views.py:79 +#: markets/views.py:80 msgid "" "You don't have permissions for adding marketplaces in name of other user" msgstr "他のユーザの名前でマーケットプレイスを追加する権限がありません" -#: markets/views.py:101 markets/views.py:104 markets/views.py:131 +#: markets/views.py:102 markets/views.py:105 markets/views.py:132 msgid "You are not allowed to delete this market" msgstr "このマーケットを削除することは許可されていません" -#: markets/views.py:148 markets/views.py:150 +#: markets/views.py:149 markets/views.py:151 msgid "Something went wrong (see details for more info)" msgstr "何かが間違っていました (詳細を参照)" @@ -445,14 +520,32 @@ msgstr "何かが間違っていました (詳細を参照)" msgid "Inherit" msgstr "継承" -#: preferences/views.py:220 preferences/views.py:273 +#: preferences/views.py:221 preferences/views.py:265 preferences/views.py:357 +msgid "Invalid payload: root type must be object" +msgstr "" + +#: preferences/views.py:225 preferences/views.py:269 preferences/views.py:361 +msgid "Invalid type for pref value: {}" +msgstr "" + +#: preferences/views.py:227 preferences/views.py:271 preferences/views.py:363 +msgid "Invalid structure for pref: {}" +msgstr "" + +#: preferences/views.py:230 preferences/views.py:274 preferences/views.py:366 +#, fuzzy +#| msgid "Invalid value for %(field)s" +msgid "Invalid value for pref: {}" +msgstr "%(field)s の値が無効です" + +#: preferences/views.py:247 preferences/views.py:339 msgid "You are not allowed to read this workspace" msgstr "このワークスペースを読むことはできません" -#: preferences/views.py:234 preferences/views.py:287 wiring/views.py:72 -#: wiring/views.py:102 wiring/views.py:129 wiring/views.py:293 -#: wiring/views.py:348 workspace/views.py:203 workspace/views.py:316 -#: workspace/views.py:320 workspace/views.py:398 +#: preferences/views.py:261 preferences/views.py:353 wiring/views.py:76 +#: wiring/views.py:106 wiring/views.py:133 wiring/views.py:297 +#: wiring/views.py:351 workspace/views.py:176 workspace/views.py:289 +#: workspace/views.py:367 msgid "You are not allowed to update this workspace" msgstr "このワークスペースを更新することはできません" @@ -505,53 +598,53 @@ msgstr "" msgid "Error processing widget code" msgstr "ウィジェット・コードの処理エラー" -#: wiring/views.py:125 wiring/views.py:267 +#: wiring/views.py:129 wiring/views.py:271 msgid "Read only properties cannot be updated" msgstr "読み取り専用のプロパティは更新できません" -#: wiring/views.py:156 wiring/views.py:160 +#: wiring/views.py:160 wiring/views.py:164 msgid "You are not allowed to remove or update read only connections" msgstr "読み取り専用接続を削除または更新することはできません" -#: wiring/views.py:197 +#: wiring/views.py:201 msgid "Read only and hidden preferences cannot be created using this API" msgstr "" "この API を使用して、読み取り専用と非表示のプリファレンスを作成することはでき" "ません" -#: wiring/views.py:211 +#: wiring/views.py:215 msgid "Read only and hidden preferences cannot be removed" msgstr "読み取り専用と非表示の設定は削除できません" -#: wiring/views.py:224 wiring/views.py:264 +#: wiring/views.py:228 wiring/views.py:268 msgid "Read only and hidden status cannot be changed using this API" msgstr "" "この API を使用して、読み取り専用と非表示のステータスを変更することはできませ" "ん" -#: wiring/views.py:227 +#: wiring/views.py:231 msgid "Read only preferences cannot be updated" msgstr "読み取り専用の設定は更新できません" -#: wiring/views.py:239 +#: wiring/views.py:243 msgid "Read only and hidden properties cannot be created using this API" msgstr "" "この API を使用して、読み取り専用プロパティと非表示プロパティを作成することは" "できません" -#: wiring/views.py:248 +#: wiring/views.py:252 msgid "Read only and hidden properties cannot be removed" msgstr "読み取り専用プロパティと隠しプロパティは削除できません" -#: wiring/views.py:320 wiring/views.py:341 +#: wiring/views.py:320 wiring/views.py:344 msgid "Invalid JSON patch" msgstr "無効な JSON パッチ" -#: wiring/views.py:334 +#: wiring/views.py:337 msgid "Missing operators variables cannot be updated" msgstr "不足している演算子変数は更新できません" -#: wiring/views.py:339 +#: wiring/views.py:342 msgid "Failed to apply patch" msgstr "パッチの適用に失敗しました" @@ -559,164 +652,171 @@ msgstr "パッチの適用に失敗しました" msgid "Missing dependencies" msgstr "不足している依存関係" -#: workspace/mashupTemplateParser.py:361 +#: workspace/mashupTemplateParser.py:363 msgid "Original wiring" msgstr "オリジナルのワイヤーリング" -#: workspace/mashupTemplateParser.py:361 +#: workspace/mashupTemplateParser.py:363 msgid "This is the wiring description of the original workspace" msgstr "これは元のワークスペースのワイヤーリング記述です" -#: workspace/mashupTemplateParser.py:364 +#: workspace/mashupTemplateParser.py:366 msgid "Merged wiring" msgstr "統合されたワイヤーリング" -#: workspace/mashupTemplateParser.py:364 +#: workspace/mashupTemplateParser.py:366 msgid "This is the wiring description of the merged mashup." msgstr "これは、マージされたマッシュアップのワイヤーリング記述です。" -#: workspace/models.py:35 +#: workspace/models.py:36 msgid "Creator" msgstr "作成者" -#: workspace/models.py:40 +#: workspace/models.py:41 msgid "Creation Date" msgstr "作成日付" -#: workspace/models.py:41 +#: workspace/models.py:42 msgid "Last Modification Date" msgstr "最終更新日" -#: workspace/models.py:43 +#: workspace/models.py:44 msgid "Searchable" msgstr "検索可能" -#: workspace/models.py:44 +#: workspace/models.py:45 msgid "Available to all users" msgstr "すべてのユーザが利用可能" -#: workspace/models.py:45 +#: workspace/models.py:46 +msgid "" +"Require users to be logged in to access the workspace (This option has only " +"effect if the workspace is public)" +msgstr "" + +#: workspace/models.py:47 msgid "Users" msgstr "ユーザ" -#: workspace/models.py:46 +#: workspace/models.py:48 msgid "Groups" msgstr "グループ" -#: workspace/models.py:90 -msgid "Manager" -msgstr "マネージャ" - -#: workspace/models.py:91 -msgid "Reason Ref" -msgstr "理由の参照" - -#: workspace/models.py:91 -msgid "" -"Reference to the reason why it was added. Used by Workspace Managers to sync " -"workspaces" +#: workspace/models.py:111 +msgid "Access Level" msgstr "" -"それが追加された理由を参照してください。 ワークスペースマネージャがワークス" -"ペースを同期するために使用されます" -#: workspace/models.py:106 +#: workspace/models.py:127 msgid "Visible" msgstr "ビジブル" -#: workspace/models.py:108 +#: workspace/models.py:129 msgid "Workspace" msgstr "ワークスペース" -#: workspace/utils.py:630 workspace/views.py:119 workspace/views.py:413 +#: workspace/utils.py:594 workspace/views.py:382 msgid "invalid mashup id" msgstr "無効なマッシュアップ id" -#: workspace/utils.py:638 +#: workspace/utils.py:602 #, python-format msgid "Mashup not found: %(mashup)s" msgstr "マッシュアップが見つかりませんでした: %(mashup)s" -#: workspace/views.py:94 +#: workspace/views.py:95 msgid "Missing name or title parameter" msgstr "名前またはタイトル・パラメータがありません" -#: workspace/views.py:96 workspace/views.py:408 +#: workspace/views.py:97 workspace/views.py:377 msgid "Workspace and mashup parameters cannot be used at the same time" msgstr "作業領域とマッシュアップ・パラメータを同時に使用することはできません" -#: workspace/views.py:104 +#: workspace/views.py:105 msgid "invalid workspace name" msgstr "無効なワークスペース名" -#: workspace/views.py:112 workspace/views.py:164 workspace/views.py:224 +#: workspace/views.py:113 workspace/views.py:134 workspace/views.py:197 msgid "A workspace with the given name already exists" msgstr "指定された名前のワークスペースがすでに存在します" -#: workspace/views.py:127 workspace/views.py:421 -#, python-format -msgid "Mashup not found: %(mashup_id)s" -msgstr "マッシュアップが見つかりませんでした: %(mashup_id)s" - -#: workspace/views.py:137 workspace/views.py:431 +#: workspace/views.py:122 workspace/views.py:400 #, python-format msgid "You are not allowed to read from workspace %s" msgstr "ワークスペース %s から読み込むことができません" -#: workspace/views.py:235 +#: workspace/views.py:208 msgid "You are not allowed to delete this workspace" msgstr "このワークスペースを削除することはできません" -#: workspace/views.py:257 +#: workspace/views.py:230 msgid "Malformed tab JSON: expecting tab name or title." msgstr "不正なタブ JSON: タブの名前またはタイトルが必要です。" -#: workspace/views.py:260 workspace/views.py:283 +#: workspace/views.py:233 workspace/views.py:256 msgid "You are not allowed to create new tabs for this workspace" msgstr "このワークスペースの新しいタブを作成することはできません" -#: workspace/views.py:268 workspace/views.py:349 +#: workspace/views.py:241 workspace/views.py:318 msgid "A tab with the given name already exists for the workspace" msgstr "指定された名前のタブがすでにワークスペースに存在しています" -#: workspace/views.py:329 workspace/views.py:332 +#: workspace/views.py:298 workspace/views.py:301 msgid "Invalid visible value" msgstr "無効なビジブル値" -#: workspace/views.py:361 +#: workspace/views.py:330 msgid "You are not allowed to remove this tab" msgstr "このタブを削除することはできません" -#: workspace/views.py:365 +#: workspace/views.py:334 msgid "Tab cannot be deleted as workspaces need at least one tab" msgstr "タブには少なくとも1つのタブが必要なため、削除することはできません" -#: workspace/views.py:369 +#: workspace/views.py:338 msgid "Tab cannot be deleted as it contains widgets that cannot be deleted" msgstr "" "タブには削除できないウィジェットが含まれているため、削除することはできません" -#: workspace/views.py:406 +#: workspace/views.py:375 msgid "Missing workspace or mashup parameter" msgstr "ワークスペースまたはマッシュアップ・パラメータがありません" -#: workspace/views.py:490 +#: workspace/views.py:390 +#, python-format +msgid "Mashup not found: %(mashup_id)s" +msgstr "マッシュアップが見つかりませんでした: %(mashup_id)s" + +#: workspace/views.py:459 #, python-format msgid "malformed json data: %s" msgstr "不正な形式の json データ: %s" -#: workspace/views.py:495 +#: workspace/views.py:464 #, python-format msgid "Malformed JSON. The following field(s) are missing: %(fields)s." msgstr "不正な形式のJSON。 次のフィールドはありません: %(fields)s。" -#: workspace/views.py:498 +#: workspace/views.py:467 msgid "Invalid vendor" msgstr "無効なベンダー" -#: workspace/views.py:501 +#: workspace/views.py:470 msgid "Invalid name" msgstr "無効な名前" -#: workspace/views.py:504 +#: workspace/views.py:473 msgid "Invalid version number" msgstr "無効なバージョン番号" + +#~ msgid "Manager" +#~ msgstr "マネージャ" + +#~ msgid "Reason Ref" +#~ msgstr "理由の参照" + +#~ msgid "" +#~ "Reference to the reason why it was added. Used by Workspace Managers to " +#~ "sync workspaces" +#~ msgstr "" +#~ "それが追加された理由を参照してください。 ワークスペースマネージャがワーク" +#~ "スペースを同期するために使用されます" diff --git a/src/wirecloud/platform/locale/ja/LC_MESSAGES/djangojs.po b/src/wirecloud/platform/locale/ja/LC_MESSAGES/djangojs.po index df5e24ff08..06038ea83e 100644 --- a/src/wirecloud/platform/locale/ja/LC_MESSAGES/djangojs.po +++ b/src/wirecloud/platform/locale/ja/LC_MESSAGES/djangojs.po @@ -10,175 +10,89 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-15 00:00+0900\n" +"POT-Creation-Date: 2024-05-27 11:24+0200\n" "PO-Revision-Date: 2019-03-15 00:00+0900\n" +"Last-Translator: Kazuhito Suda \n" +"Language-Team: Kazuhito Suda \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"Last-Translator: Kazuhito Suda \n" -"Language-Team: Kazuhito Suda \n" "X-Generator: Poedit 2.2.1\n" -#: static/js/WirecloudAPI/DashboardManagementAPI.js:154 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:103 +#: static/js/WirecloudAPI/DashboardManagementAPI.js:148 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:104 msgid "Do you really want to remove the \"%(name)s\" workspace?" msgstr "本当にワークスペース \"%(name)s\" を削除しますか?" -#: static/js/WirecloudAPI/WirecloudAPICommon.js:226 +#: static/js/WirecloudAPI/WirecloudAPICommon.js:234 msgid "" "
        • File:
        • Line:
        • See the browser console for more details

          " +"how-to-open-the-javascript-console-in-different-browsers\" " +"target=\"_blank\">browser console for more details

          " msgstr "" "
          • ファイル:
          • ライン:
          • 詳細については、ブラウザのコンソール を参照してください。

            " -#: static/js/catalogue/CatalogueSearchView.js:44 -msgid "Empty Marketplace!" -msgstr "空のマーケットプレイス!" - -#: static/js/catalogue/CatalogueSearchView.js:45 -msgid "" -"This marketplace is empty, that is, it does not provide any resource at this " -"time." -msgstr "このマーケットプレイスは空です。現時点ではリソースを提供していません。" - -#: static/js/catalogue/CatalogueSearchView.js:67 -msgid "

            Showing results for

            " -msgstr "

            の結果を表示します。

            " - -#: static/js/catalogue/CatalogueSearchView.js:95 -msgid "Connection error: No resource retrieved." -msgstr "接続エラー: リソースが取得されませんでした." - -#: static/js/catalogue/CatalogueSearchView.js:101 -msgid "" -"

            We couldn't find anything for your search - %(keywords)s.

            Suggestions:

            • Make sure all words are spelled correctly.
            • Try different keywords.
            • Try more general keywords.
            " -msgstr "" -"

            検索で何も見つかりませんでした - %(keywords)s.

            対処:

            • すべての単語のスペルが正しいことを確認してください
            • 異なる" -"キーワードを試してみてください
            • より一般的なキーワードを試してください" -"
            " - -#: static/js/catalogue/CatalogueSearchView.js:109 -msgid "Keywords..." -msgstr "キーワード..." - -#: static/js/catalogue/CatalogueSearchView.js:124 -#: static/js/catalogue/CatalogueSearchView.js:243 -msgid "Refresh" -msgstr "リフレッシュ" - -#: static/js/catalogue/CatalogueSearchView.js:135 -msgid "Creation date" -msgstr "作成日" - -#: static/js/catalogue/CatalogueSearchView.js:136 -#: static/js/wirecloud/Widget.js:253 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:291 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:718 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:148 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:100 -#: static/js/wirecloud/wiring/Operator.js:164 -msgid "Title" -msgstr "タイトル" - -#: static/js/catalogue/CatalogueSearchView.js:137 -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:43 -msgid "Vendor" -msgstr "ベンダー" - -#: static/js/catalogue/CatalogueSearchView.js:149 -msgid "All" -msgstr "全て" - -#: static/js/catalogue/CatalogueSearchView.js:150 -#: static/js/wirecloud/ui/ComponentSidebar.js:56 -#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:56 -msgid "Widgets" -msgstr "ウィジェット" - -#: static/js/catalogue/CatalogueSearchView.js:151 -#: static/js/wirecloud/ui/ComponentSidebar.js:43 -msgid "Mashups" -msgstr "マッシュアップ" - -#: static/js/catalogue/CatalogueSearchView.js:152 -#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:43 -msgid "Operators" -msgstr "オペレータ" - -#: static/js/catalogue/CatalogueSearchView.js:241 -msgid "Clear filters" -msgstr "フィルターをクリア" - -#: static/js/catalogue/CatalogueView.js:51 -msgid "Uninstall" -msgstr "アンインストール" - -#: static/js/catalogue/CatalogueView.js:57 -msgid "Install" -msgstr "インストール" - -#: static/js/wirecloud/LocalCatalogue.js:37 +#: static/js/wirecloud/LocalCatalogue.js:38 msgid "Unloading affected widgets" msgstr "影響を受けるウィジェットをアンロード" -#: static/js/wirecloud/LocalCatalogue.js:40 +#: static/js/wirecloud/LocalCatalogue.js:41 msgid "Unloading affected operators" msgstr "影響を受けるオペレータをアンロード" -#: static/js/wirecloud/LocalCatalogue.js:75 +#: static/js/wirecloud/LocalCatalogue.js:76 msgid "Purging %(componenttype)s info" msgstr "%(componenttype)s の情報をパージ" -#: static/js/wirecloud/LocalCatalogue.js:137 +#: static/js/wirecloud/LocalCatalogue.js:128 #: static/js/wirecloud/WorkspaceCatalogue.js:81 msgid "Error loading %(resource)s metadata" msgstr "%(resource)s のメタデータの読み込み中にエラーが発生しました" -#: static/js/wirecloud/LocalCatalogue.js:174 +#: static/js/wirecloud/LocalCatalogue.js:171 msgid "Deleting all versions of %(title)s (%(group_id)s)" msgstr "%(title)s (%(group_id)s) のすべてのバージョンを削除" -#: static/js/wirecloud/LocalCatalogue.js:176 +#: static/js/wirecloud/LocalCatalogue.js:173 msgid "Uninstalling all versions of %(title)s (%(group_id)s)" msgstr "%(title)s (%(group_id)s) のすべてのバージョンをアンインストール" -#: static/js/wirecloud/LocalCatalogue.js:185 +#: static/js/wirecloud/LocalCatalogue.js:182 msgid "Deleting %(title)s (%(uri)s)" msgstr "%(title)s (%(uri)s) を削除" -#: static/js/wirecloud/LocalCatalogue.js:187 +#: static/js/wirecloud/LocalCatalogue.js:184 msgid "Uninstalling %(title)s (%(uri)s)" msgstr "%(title)s (%(uri)s) をアンインストール" -#: static/js/wirecloud/LocalCatalogue.js:281 +#: static/js/wirecloud/LocalCatalogue.js:278 msgid "Invalid component type: %(type)s" msgstr "無効なコンポーネントタイプ: %(type)s" -#: static/js/wirecloud/LogManager.js:215 +#: static/js/wirecloud/LogManager.js:252 msgid "HTTP Error %(errorCode)s - %(errorDesc)s" msgstr "HTTPエラー %(errorCode)s - %(errorDesc)s" #: static/js/wirecloud/MarketManager.js:50 #: static/js/wirecloud/MarketManager.js:81 -#: static/js/wirecloud/MarketManager.js:111 static/js/wirecloud/Wiring.js:197 -#: static/js/wirecloud/Wiring.js:262 static/js/wirecloud/Workspace.js:305 -#: static/js/wirecloud/Workspace.js:441 static/js/wirecloud/Workspace.js:496 -#: static/js/wirecloud/WorkspaceTab.js:223 -#: static/js/wirecloud/WorkspaceTab.js:268 static/js/wirecloud/core.js:57 -#: static/js/wirecloud/core.js:468 static/js/wirecloud/core.js:537 -#: static/js/wirecloud/core.js:542 -#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:99 -#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:215 +#: static/js/wirecloud/MarketManager.js:111 +#: static/js/wirecloud/Preferences.js:130 static/js/wirecloud/Wiring.js:465 +#: static/js/wirecloud/Wiring.js:530 static/js/wirecloud/Workspace.js:468 +#: static/js/wirecloud/Workspace.js:604 static/js/wirecloud/Workspace.js:659 +#: static/js/wirecloud/WorkspaceTab.js:220 +#: static/js/wirecloud/WorkspaceTab.js:265 static/js/wirecloud/core.js:158 +#: static/js/wirecloud/core.js:420 static/js/wirecloud/core.js:585 +#: static/js/wirecloud/core.js:654 static/js/wirecloud/core.js:660 +#: static/js/wirecloud/core.js:708 +#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:104 +#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:270 +#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:423 msgid "Unexpected response from server" msgstr "サーバからの予期しない応答" @@ -186,72 +100,56 @@ msgstr "サーバからの予期しない応答" msgid "Adding marketplace" msgstr "マーケットプレイスの追加" -#: static/js/wirecloud/MashableApplicationComponent.js:34 -msgid "missing vendor" -msgstr "ベンダーがありません" - -#: static/js/wirecloud/MashableApplicationComponent.js:40 -msgid "missing name" -msgstr "名前がありません" - -#: static/js/wirecloud/MashableApplicationComponent.js:46 -msgid "missing version" -msgstr "バージョンがありません" - -#: static/js/wirecloud/MashableApplicationComponent.js:52 -msgid "missing type" -msgstr "タイプがありません" - -#: static/js/wirecloud/PlatformPreferences.js:38 +#: static/js/wirecloud/PlatformPreferences.js:39 msgid "Platform Preferences" msgstr "プラットフォームの設定" -#: static/js/wirecloud/PreferenceManager.js:41 +#: static/js/wirecloud/PreferenceManager.js:39 msgid "Language" msgstr "言語" -#: static/js/wirecloud/PreferenceManager.js:44 +#: static/js/wirecloud/PreferenceManager.js:42 msgid "Default setting" msgstr "デフォルト設定" -#: static/js/wirecloud/PreferenceManager.js:45 +#: static/js/wirecloud/PreferenceManager.js:43 msgid "Detect browser language" msgstr "ブラウザ言語を検出" -#: static/js/wirecloud/TabPreferences.js:43 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:100 +#: static/js/wirecloud/TabPreferences.js:45 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 #: static/js/wirecloud/Tutorials/BehaviourOrientedWiring.js:236 -#: static/js/wirecloud/Widget/PreferencesWindowMenu.js:30 -#: static/js/wirecloud/WorkspacePreferences.js:38 -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:85 -#: static/js/wirecloud/ui/WirecloudHeader.js:101 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:86 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:73 -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:70 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:94 +#: static/js/wirecloud/Widget/PreferencesWindowMenu.js:33 +#: static/js/wirecloud/WorkspacePreferences.js:40 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:78 +#: static/js/wirecloud/ui/WirecloudHeader.js:94 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:141 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:99 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:61 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:86 msgid "Settings" msgstr "設定" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:66 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:64 msgid "Basic concepts" msgstr "基本概念" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:68 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:71 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:76 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:85 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:92 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:116 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:120 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:121 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:162 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:66 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:69 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:74 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:83 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:90 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:114 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:118 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:119 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:160 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:165 #: static/js/wirecloud/Tutorials/BasicConcepts.js:167 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:169 msgid "WireCloud Basic Tutorial" msgstr "WireCloud 基本チュートリアル" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:68 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:66 msgid "" "

            Welcome to WireCloud!!

            This tutorial will show you the basic " "concepts behind WireCloud.

            " @@ -259,7 +157,7 @@ msgstr "" "

            WireCloudへようこそ!!

            このチュートリアルでは、WireCloudの基本概念" "を紹介します。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:71 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:69 msgid "" "

            This is the Editor view. In this view, you can use and modify " "your workspaces. Currently you are in a newly created workspace: Basic " @@ -268,14 +166,14 @@ msgid "" "some widgets, so we are going to install them for you. You can safely " "uninstall these widgets after finishing the tutorial.

            " msgstr "" -"

            これはエディタ ビューです。このビューではワークスペースを使用お" -"よび変更できます。 現在、あなたは新しく作成されたワークスペースにいます: " -"基本概念のチュートリアル. このワークショップは空なので、最初にウィジェッ" -"トを追加します。

            次のステップではいくつ" -"かのウィジェットが必要なので、それらをインストールします。 チュートリアルの終" -"了後、これらのウィジェットを安全にアンインストールできます。

            " +"

            これはエディタ ビューです。このビューではワークスペースを使用およ" +"び変更できます。 現在、あなたは新しく作成されたワークスペースにいます: 基" +"本概念のチュートリアル. このワークショップは空なので、最初にウィジェット" +"を追加します。

            次のステップではいくつか" +"のウィジェットが必要なので、それらをインストールします。 チュートリアルの終了" +"後、これらのウィジェットを安全にアンインストールできます。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:76 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:74 msgid "" "

            Ok, widgets have been installed successfuly.

            Next step is to add " "the YouTube Browser widget to the workspace.

            " @@ -283,15 +181,15 @@ msgstr "" "

            ウィジェットは正常にインストールされました。

            次のステップは、" "YouTube Browserウィジェットをワークスペースに追加することです。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:77 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:75 msgid "Click the Edit button" msgstr "編集 ボタンをクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:79 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:77 msgid "Click the Add components button" msgstr "コンポーネントを追加 ボタンをクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:81 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:79 msgid "" "By typing \"browser\" we can filter widgets that contains in their name or " "description these words" @@ -299,7 +197,7 @@ msgstr "" "\"browser\" と入力すると、名前や説明にこれらの単語を含むウィジェットをフィル" "タリングできます" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:84 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:82 msgid "" "Once you have the results, you can add the widget. So click Add to " "workspace" @@ -307,27 +205,27 @@ msgstr "" "結果が得られたら、ウィジェットを追加することができます。 ワークスペースに" "追加をクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:85 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:83 msgid "" "

            Great! That was easy, wasn't " "it?.

            Let's continue adding the Input Box widget.

            " msgstr "" -"

            すばらしい! 簡単でした" -"ね。

            入力ボックス ウィジェットを追加しましょう

            " +"

            すばらしい! 簡単でしたね。

            入力ボックス ウィジェットを追加しましょう

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:86 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:84 msgid "Typing input box..." msgstr "input boxと入力します..." -#: static/js/wirecloud/Tutorials/BasicConcepts.js:89 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:87 msgid "Click Add to workspace" msgstr "ワークスペースを追加をクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:90 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:88 msgid "Close the component sidebar" msgstr "コンポーネントのサイドバーを閉じる" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:92 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:90 msgid "" "

            One of the main features of WireCloud is that you can edit your " "workspaces' layout not only by adding and removing widgets, but also moving, " @@ -337,33 +235,33 @@ msgstr "" "イズ変更、名前の変更など、ワークスペースのレイアウトを編集できることです。" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:93 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:91 msgid "Drag & drop to resize the widget" msgstr "ウィジェットのサイズを変更するためにドラック&ドロップ" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:94 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:92 msgid "Drag & drop to move the widget" msgstr "ウィジェットを移動するためにドラック&ドロップ" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:95 -#: static/js/wirecloud/Tutorials/BasicConcepts.js:99 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:93 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:97 msgid "Open Input Box menu" msgstr "入力ボックス のメニューを開きます" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:94 msgid "Click Rename" msgstr "リネームをクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:57 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:66 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:63 -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:57 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:64 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:94 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:50 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:121 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:89 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:48 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:56 msgid "Rename" msgstr "リネーム" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:97 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:95 msgid "" "Enter a new name for the widget (e.g Search) and press Enter or click outside the title" @@ -371,7 +269,7 @@ msgstr "" "ウィジェットの新しい名前を入力し (例 Search) Enter を押す" "か、タイトルの外側をクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:96 msgid "" "

            Also, some widgets can be parameterized through settings giving you the " "chance to use them for very general purporses.

            " @@ -379,32 +277,32 @@ msgstr "" "

            また、いくつかのウィジェットは、非常に一般的な目的のためにそれらを使用する" "機会を与える設定を介してパラメータ化することができます。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:100 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:98 #: static/js/wirecloud/Tutorials/BehaviourOrientedWiring.js:236 msgid "Click Settings" msgstr "設定 をクリック" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:104 msgid "Write a label for the input, e.g. Multimedia." msgstr "入力のラベルを書き込みます。例: Multimedia。" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:104 msgid "Write a better placeholder text for the input, e.g. Keywords" msgstr "入力用のプレースホルダテキストを書き込みます。例: Keywords" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:104 msgid "Write a better label for the button, e.g Search." msgstr "ボタンのより良いラベルを書き込みます。 例: Search。" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:108 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:106 msgid "Click here to submit" msgstr "ここをクリックして設定してください" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:113 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:111 msgid "Click Wiring to continue" msgstr "続行するには ワイヤーリング をクリックしてください" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:116 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:114 msgid "" "

            This is the Wiring Editor view.

            Here you can wire widgets " "and operators together turning your workspace into and application " @@ -414,15 +312,15 @@ msgstr "" "レータを一緒にワイヤーリングして、ワークスペースとアプリケーション・マッ" "シュアップを組み立てることができます。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:117 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:115 msgid "Click Find components to open the sidebar" msgstr "サイドバーを開くには、コンポーネントを検索をクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:119 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:117 msgid "Click Widgets" msgstr "ウィジェット をクリックしてください" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:120 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:118 msgid "" "

            In this sidebar you can find all the available widgets. In our example, " "we are interested in the widgets added to the workspace: the YouTube " @@ -438,7 +336,7 @@ msgstr "" "ポーネントは、これらのビヘイビアの組み合わせと同様に、ソース、トランスフォー" "マ、またはデータ・ターゲットとして機能します。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:121 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:119 msgid "" "

            In the next steps, we are going to connect the Input Box and " "YouTube Browser widgets together. This will allow you to perform " @@ -449,19 +347,19 @@ msgstr "" "ジェットを一緒に接続します。 これにより、入力ボックス ウィジェットか" "ら YouTube Browser で検索を実行できます。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:127 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:125 msgid "Drag & drop the Input Box widget" msgstr "入力ボックス ウィジェットをドラック&ドロップします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:140 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:138 msgid "Drag & drop the YouTube Browser widget" msgstr "YouTube Browser ウィジェットをドラック&ドロップします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:148 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:146 msgid "Click Find components to close the sidebar" msgstr "サイドバーを閉じるには コンポーネントを検索 をクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:152 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:150 msgid "" "Drag & drop a new connection from Search Box's keyword " "endpoint ..." @@ -469,24 +367,24 @@ msgstr "" "検索ボックスキーワード エンドポイントから新しい接続をド" "ロップ&ドロップする..." -#: static/js/wirecloud/Tutorials/BasicConcepts.js:158 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:156 msgid "... to YouTube Browser's keyword endpoint" msgstr "YouTube Browserキーワード エンドポイントに" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:162 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:160 msgid "Now it's time to test our creation." msgstr "作成したアプリケーション・マッシュアップをテストしましょう" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:163 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:161 #: static/js/wirecloud/Tutorials/BehaviourOrientedWiring.js:246 msgid "Click Back" msgstr "戻るをクリックします" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:165 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:163 msgid "Enter a search keyword and press Enter" msgstr "検索キーワードを入力し、 Enter を押します" -#: static/js/wirecloud/Tutorials/BasicConcepts.js:167 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:165 msgid "" "

            Congratulations! you have " "finished your first application mashup.

            As you can see, the " @@ -496,7 +394,7 @@ msgstr "" "ケーション・マッシュアップが完了しました。

            ご覧のとおり、" "YouTube Browser ウィジェットが正常に更新されました。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:169 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:167 msgid "" "

            This is the end of this tutorial. Remember that you can always go to the " "Tutorial menu for others.

            " @@ -504,7 +402,7 @@ msgstr "" "

            これはこのチュートリアルの最後です。 いつでも他のチュートリアル・メニュー" "に行くことができます。

            " -#: static/js/wirecloud/Tutorials/BasicConcepts.js:169 +#: static/js/wirecloud/Tutorials/BasicConcepts.js:167 msgid "Tutorials" msgstr "チュートリアル" @@ -738,9 +636,9 @@ msgid "" "the affected components were added? That saved us some steps :).

            Anyway, you can also directly add components in a similar way clicking " "on theirs Add button (take into account that associated connections " -"are no added automatically in that case)

            The third and the fourth behaviour can be created the same way, so we are " -"going to create them for you.
            " +"are no added automatically in that case)

            The third and the fourth behaviour can be created the same way, so we " +"are going to create them for you.
            " msgstr "" "

            すばらしい! 私たちは最初のビヘ" "イビアを終えました。 接続を追加したときにも、影響を受けるコンポーネントが追加" @@ -832,8 +730,8 @@ msgstr "" "

            すばらしい! 私たちはこのビヘイ" "ビアを正常にクリーンアップしました。 影響を受けた接続も削除されていることに気" "付きましたか? それは私たちをもう一度、いくつかのステップを救いました:)。

            とにかく、削除 ボタンをクリックして同様の方法で直接接続を削除" -"することもできます (その場合、関連コンポーネントは自動的に削除されません)

            " +"p>

            とにかく、削除 ボタンをクリックして同様の方法で直接接続を削除す" +"ることもできます (その場合、関連コンポーネントは自動的に削除されません)

            " #: static/js/wirecloud/Tutorials/BehaviourOrientedWiring.js:247 msgid "Try It Yourself" @@ -851,143 +749,178 @@ msgstr "" "の最後ですが、例のダッシュボードを試して、説明されているビヘイビアに従ってい" "るかどうかを確認できます。

            " -#: static/js/wirecloud/UserInterfaceManager.js:203 -msgid "Workspace loaded" -msgstr "ワークスペースが読み込まれました" - -#: static/js/wirecloud/UserInterfaceManager.js:331 +#: static/js/wirecloud/UserInterfaceManager.js:95 msgid "%(task)s %(percentage)s%" msgstr "%(task)s %(percentage)s%" -#: static/js/wirecloud/UserInterfaceManager.js:345 +#: static/js/wirecloud/UserInterfaceManager.js:109 msgid "%(subTask)s: %(percentage)s%" msgstr "%(subTask)s: %(percentage)s%" -#: static/js/wirecloud/Widget.js:241 static/js/wirecloud/wiring/Operator.js:165 +#: static/js/wirecloud/UserInterfaceManager.js:274 +msgid "Workspace loaded" +msgstr "ワークスペースが読み込まれました" + +#: static/js/wirecloud/Widget.js:366 static/js/wirecloud/Wiring.js:602 +msgid "Failed to load widget." +msgstr "ウィジェットをロードできませんでした。" + +#: static/js/wirecloud/Widget.js:368 +msgid "" +"

            This widget is currently not available. You or an administrator probably " +"uninstalled it.

            Suggestions:
            • Remove this widget from the " +"dashboard
            • Reinstall the appropiated version of the widget
            • Or " +"install another version of the widget and then use the Upgrade/" +"Downgrade option
            " +msgstr "" +"

            このウィジェットは現在利用できません。 管理者または管理者がおそらくアンイ" +"ンストールしました。

            対処:
            • このウィジェットをダッシュボー" +"ドから削除します
            • ウィジェットの適切なバージョンを再インストールしてく" +"ださい
            • または、別のバージョンのウィジェットをインストールしてから、" +"アップグレード/ダウングレードオプションを使用してください
            " + +#: static/js/wirecloud/Widget.js:371 +msgid "Widget loaded successfully." +msgstr "ウィジェットが正常に読み込まれました。" + +#: static/js/wirecloud/Widget.js:408 +msgid "Widget unloaded successfully." +msgstr "ウィジェットが正常にアンロードされました。" + +#: static/js/wirecloud/Widget.js:688 +#: static/js/wirecloud/ui/CatalogueSearchView.js:150 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:272 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:87 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:73 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:45 +#: static/js/wirecloud/wiring/Operator.js:408 +msgid "Title" +msgstr "タイトル" + +#: static/js/wirecloud/Widget.js:689 static/js/wirecloud/wiring/Operator.js:409 msgid "Widget's title" msgstr "ウィジェットのタイトル" -#: static/js/wirecloud/Widget.js:248 +#: static/js/wirecloud/Widget.js:693 msgid "X-Position" msgstr "X ポジション" -#: static/js/wirecloud/Widget.js:259 +#: static/js/wirecloud/Widget.js:694 msgid "Specifies the x-coordinate at which the widget is placed" msgstr "ウィジェットが配置される x 座標を指定します" -#: static/js/wirecloud/Widget.js:263 +#: static/js/wirecloud/Widget.js:698 msgid "Y-Position" msgstr "Y ポジション" -#: static/js/wirecloud/Widget.js:264 +#: static/js/wirecloud/Widget.js:699 msgid "Specifies the y-coordinate at which the widget is placed" msgstr "ウィジェットが配置される y 座標を指定します" -#: static/js/wirecloud/Widget.js:268 +#: static/js/wirecloud/Widget.js:703 msgid "Z-Position" msgstr "Z ポジション" -#: static/js/wirecloud/Widget.js:269 +#: static/js/wirecloud/Widget.js:704 msgid "Specifies the z-coordinate at which the widget is placed" msgstr "ウィジェットが配置される z 座標を指定します" -#: static/js/wirecloud/Widget.js:273 +#: static/js/wirecloud/Widget.js:708 msgid "Height" msgstr "高さ" -#: static/js/wirecloud/Widget.js:274 +#: static/js/wirecloud/Widget.js:709 msgid "Widget's height in layout cells" msgstr "レイアウト・セル内のウィジェットの高さ" -#: static/js/wirecloud/Widget.js:278 +#: static/js/wirecloud/Widget.js:713 +msgid "Visible" +msgstr "" + +#: static/js/wirecloud/Widget.js:714 +msgid "" +"Specifies if the widget is being displayed, altough the user may have to do " +"scroll to be able to see it" +msgstr "" + +#: static/js/wirecloud/Widget.js:718 msgid "Width" msgstr "幅" -#: static/js/wirecloud/Widget.js:279 +#: static/js/wirecloud/Widget.js:719 msgid "Widget's width in layout cells" msgstr "レイアウト・セル内のウィジェットの幅" -#: static/js/wirecloud/Widget.js:283 +#: static/js/wirecloud/Widget.js:723 msgid "Height in pixels (deprecated)" msgstr "高さ (ピクセル単位) (非推奨)" -#: static/js/wirecloud/Widget.js:284 +#: static/js/wirecloud/Widget.js:724 msgid "Widget's height in pixels" msgstr "ピクセル単位でのウィジェットの高さ" -#: static/js/wirecloud/Widget.js:288 +#: static/js/wirecloud/Widget.js:728 msgid "Width in pixels" msgstr "ピクセル単位の幅" -#: static/js/wirecloud/Widget.js:289 +#: static/js/wirecloud/Widget.js:729 msgid "Widget's width in pixels" msgstr "ピクセル単位のウィジェットの幅" -#: static/js/wirecloud/Widget.js:296 +#: static/js/wirecloud/Widget.js:733 +#, fuzzy +#| msgid "volatile" +msgid "Volatile" +msgstr "揮発性" + +#: static/js/wirecloud/Widget.js:734 +msgid "Volatile status of the widget" +msgstr "" + +#: static/js/wirecloud/Widget.js:741 msgid "Widget created successfully." msgstr "ウィジェットが正常に作成されました。" -#: static/js/wirecloud/Widget.js:615 static/js/wirecloud/wiring/Operator.js:353 +#: static/js/wirecloud/Widget.js:1107 +#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:42 +msgid "Exception catched while processing preference changes" +msgstr "環境設定の変更を処理中に例外がキャッチされました" + +#: static/js/wirecloud/Widget.js:1233 +#: static/js/wirecloud/wiring/Operator.js:603 msgid "The %(type)s was upgraded to v%(version)s successfully." msgstr "%(type)s は v%(version)s に正常にアップグレードされました。" -#: static/js/wirecloud/Widget.js:617 static/js/wirecloud/wiring/Operator.js:355 +#: static/js/wirecloud/Widget.js:1235 +#: static/js/wirecloud/wiring/Operator.js:605 msgid "The %(type)s was downgraded to v%(version)s successfully." msgstr "%(type)s は v%(version)s に正常にダウングレードされました。" -#: static/js/wirecloud/Widget.js:620 static/js/wirecloud/wiring/Operator.js:358 +#: static/js/wirecloud/Widget.js:1238 +#: static/js/wirecloud/wiring/Operator.js:608 msgid "The %(type)s was replaced using v%(version)s successfully." msgstr "%(type)sは v%(version)s を使用して正常に置き換えられました。" -#: static/js/wirecloud/Widget.js:829 static/js/wirecloud/Wiring.js:336 -msgid "Failed to load widget." -msgstr "ウィジェットをロードできませんでした。" - -#: static/js/wirecloud/Widget.js:831 -msgid "" -"

            This widget is currently not available. You or an administrator probably " -"uninstalled it.

            Suggestions:
            • Remove this widget from the " -"dashboard
            • Reinstall the appropiated version of the widget
            • Or " -"install another version of the widget and then use the Upgrade/" -"Downgrade option
            " -msgstr "" -"

            このウィジェットは現在利用できません。 管理者または管理者がおそらくアンイ" -"ンストールしました。

            対処:
            • このウィジェットをダッシュボー" -"ドから削除します
            • ウィジェットの適切なバージョンを再インストールしてく" -"ださい
            • または、別のバージョンのウィジェットをインストールしてから、" -"アップグレード/ダウングレードオプションを使用してください
            " - -#: static/js/wirecloud/Widget.js:834 -msgid "Widget loaded successfully." -msgstr "ウィジェットが正常に読み込まれました。" - -#: static/js/wirecloud/Widget.js:865 -msgid "Widget unloaded successfully." -msgstr "ウィジェットが正常にアンロードされました。" - -#: static/js/wirecloud/Widget/PreferencesWindowMenu.js:82 -#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:87 -msgid "Exception catched while processing preference changes" -msgstr "環境設定の変更を処理中に例外がキャッチされました" - -#: static/js/wirecloud/WidgetMeta.js:77 +#: static/js/wirecloud/WidgetMeta.js:88 msgid "[Widget; Vendor: %(vendor)s, Name: %(name)s, Version: %(version)s]" msgstr "" "[ウィジェット; ベンダー: %(vendor)s, 名前: %(name)s, パージョン: %(version)s]" -#: static/js/wirecloud/Wiring.js:331 static/js/wirecloud/wiring/Operator.js:496 +#: static/js/wirecloud/Wiring.js:597 static/js/wirecloud/wiring/Operator.js:220 msgid "Failed to load operator." msgstr "オペレータを読み込めませんでした。" -#: static/js/wirecloud/Workspace.js:579 +#: static/js/wirecloud/Workspace.js:75 msgid "Tab %(index)s" msgstr "タブ %(index)s" -#: static/js/wirecloud/Workspace.js:585 -msgid "%(base) (%(copy)s)" +#: static/js/wirecloud/Workspace.js:82 +#, fuzzy +#| msgid "%(base) (%(copy)s)" +msgid "%(base)s (%(copy)s)" msgstr "%(base) (%(copy)s)" -#: static/js/wirecloud/WorkspaceTab.js:161 +#: static/js/wirecloud/WorkspaceTab.js:157 msgid "The destination tab (%(title)s) is readonly" msgstr "宛先のタブ (%(title)s) は読み取り専用です" @@ -1127,51 +1060,130 @@ msgstr "拡張されていない" msgid "Unknown status code" msgstr "不明なステータスコード" -#: static/js/wirecloud/core.js:104 +#: static/js/wirecloud/core.js:53 static/js/wirecloud/core.js:466 +msgid "Switching active workspace" +msgstr "アクティブなワークスペースの切り替え" + +#: static/js/wirecloud/core.js:206 msgid "Unloading WireCloud" msgstr "WireCloud のアンロード" -#: static/js/wirecloud/core.js:183 +#: static/js/wirecloud/core.js:293 msgid "Retrieving WireCloud code" msgstr "WireCloud コードの取得" -#: static/js/wirecloud/core.js:186 +#: static/js/wirecloud/core.js:296 msgid "Retrieving initial data" msgstr "初期データの取得" -#: static/js/wirecloud/core.js:211 +#: static/js/wirecloud/core.js:321 msgid "Error loading WireCloud" msgstr "WireCloud の読み込みエラー" -#: static/js/wirecloud/core.js:222 +#: static/js/wirecloud/core.js:332 msgid "Loading WireCloud Platform" msgstr "WireCloud プラットフォームの読み込み" -#: static/js/wirecloud/core.js:291 +#: static/js/wirecloud/core.js:418 msgid "Requesting workspace data" msgstr "ワークスペース・データの要求" -#: static/js/wirecloud/core.js:351 static/js/wirecloud/core.js:576 -msgid "Switching active workspace" -msgstr "アクティブなワークスペースの切り替え" - -#: static/js/wirecloud/core.js:395 +#: static/js/wirecloud/core.js:512 msgid "Missing name or title parameter" msgstr "名前またはタイトル・パラメータがありません" -#: static/js/wirecloud/core.js:397 +#: static/js/wirecloud/core.js:514 msgid "Workspace and mashup options cannot be used at the same time" msgstr "ワークスペースとマッシュアップ・オプションは同時に使用できません" -#: static/js/wirecloud/ui/ComponentSidebar.js:70 +#: static/js/wirecloud/ui/CatalogueSearchView.js:43 +msgid "Clear filters" +msgstr "フィルターをクリア" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:45 +#: static/js/wirecloud/ui/CatalogueSearchView.js:138 +msgid "Refresh" +msgstr "リフレッシュ" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:64 +msgid "Empty Marketplace!" +msgstr "空のマーケットプレイス!" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:65 +msgid "" +"This marketplace is empty, that is, it does not provide any resource at this " +"time." +msgstr "このマーケットプレイスは空です。現時点ではリソースを提供していません。" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:86 +msgid "

            Showing results for

            " +msgstr "

            の結果を表示します。

            " + +#: static/js/wirecloud/ui/CatalogueSearchView.js:112 +msgid "Connection error: No resource retrieved." +msgstr "接続エラー: リソースが取得されませんでした." + +#: static/js/wirecloud/ui/CatalogueSearchView.js:118 +msgid "" +"

            We couldn't find anything for your search - %(keywords)s.

            Suggestions:

            • Make sure all words are spelled correctly.
            • Try different keywords.
            • Try more general keywords.
            " +msgstr "" +"

            検索で何も見つかりませんでした - %(keywords)s.

            対処:

            • すべての単語のスペルが正しいことを確認してください
            • 異なる" +"キーワードを試してみてください
            • より一般的なキーワードを試してください" +"
            " + +#: static/js/wirecloud/ui/CatalogueSearchView.js:126 +msgid "Keywords..." +msgstr "キーワード..." + +#: static/js/wirecloud/ui/CatalogueSearchView.js:149 +msgid "Creation date" +msgstr "作成日" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:151 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:46 +msgid "Vendor" +msgstr "ベンダー" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:163 +msgid "All" +msgstr "全て" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:164 +#: static/js/wirecloud/ui/ComponentSidebar.js:54 +#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:58 +msgid "Widgets" +msgstr "ウィジェット" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:165 +#: static/js/wirecloud/ui/ComponentSidebar.js:41 +msgid "Mashups" +msgstr "マッシュアップ" + +#: static/js/wirecloud/ui/CatalogueSearchView.js:166 +#: static/js/wirecloud/ui/WiringEditor/ComponentShowcase.js:45 +msgid "Operators" +msgstr "オペレータ" + +#: static/js/wirecloud/ui/CatalogueView.js:61 +msgid "Uninstall" +msgstr "アンインストール" + +#: static/js/wirecloud/ui/CatalogueView.js:67 +msgid "Install" +msgstr "インストール" + +#: static/js/wirecloud/ui/ComponentSidebar.js:68 msgid "Add to workspace" msgstr "ワークスペースに追加" -#: static/js/wirecloud/ui/ComponentSidebar.js:70 +#: static/js/wirecloud/ui/ComponentSidebar.js:68 msgid "Merge" msgstr "マージ" -#: static/js/wirecloud/ui/DragboardLayout.js:236 +#: static/js/wirecloud/ui/DragboardLayout.js:246 msgid "" "the widget could not be associated with this layout as it already has an " "associated layout." @@ -1179,15 +1191,19 @@ msgstr "" "ウィジェットは既に関連付けられたレイアウトを持っているため、このレイアウトに" "関連付けることはできませんでした。" -#: static/js/wirecloud/ui/EmbedCodeWindowMenu.js:51 +#: static/js/wirecloud/ui/EmbedCodeWindowMenu.js:53 +msgid "Auto" +msgstr "" + +#: static/js/wirecloud/ui/EmbedCodeWindowMenu.js:69 msgid "Accept" msgstr "設定" -#: static/js/wirecloud/ui/LayoutInputInterface.js:34 +#: static/js/wirecloud/ui/LayoutInputInterface.js:35 msgid "Smart" msgstr "スマート" -#: static/js/wirecloud/ui/LayoutInputInterface.js:36 +#: static/js/wirecloud/ui/LayoutInputInterface.js:37 msgid "" "Widgets will tend to be placed on the topmost position available if this " "option is enabled. (default: enabled)" @@ -1195,33 +1211,33 @@ msgstr "" "このオプションが有効になっている場合、ウィジェットは利用可能な一番上の位置に" "配置される傾向があります。(デフォルト: 有効)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:43 -#: static/js/wirecloud/ui/LayoutInputInterface.js:79 -#: static/js/wirecloud/ui/LayoutInputInterface.js:143 +#: static/js/wirecloud/ui/LayoutInputInterface.js:44 +#: static/js/wirecloud/ui/LayoutInputInterface.js:80 +#: static/js/wirecloud/ui/LayoutInputInterface.js:147 msgid "Columns" msgstr "列" -#: static/js/wirecloud/ui/LayoutInputInterface.js:45 -#: static/js/wirecloud/ui/LayoutInputInterface.js:81 +#: static/js/wirecloud/ui/LayoutInputInterface.js:46 +#: static/js/wirecloud/ui/LayoutInputInterface.js:82 msgid "Grid columns. (default: 20 columns)" msgstr "グリッド列 (デフォルト: 20桁)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:52 +#: static/js/wirecloud/ui/LayoutInputInterface.js:53 msgid "Row Height (in pixels)" msgstr "行の高さ (ピクセル単位)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:54 +#: static/js/wirecloud/ui/LayoutInputInterface.js:55 msgid "Row/cell height. Must be specified in pixel units. (default: 13px)" msgstr "" "行/セルの高さ。 ピクセル単位で指定する必要があります (デフォルト: 13px)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:60 -#: static/js/wirecloud/ui/LayoutInputInterface.js:96 +#: static/js/wirecloud/ui/LayoutInputInterface.js:61 +#: static/js/wirecloud/ui/LayoutInputInterface.js:97 msgid "Horizontal Margin between widgets (in pixels)" msgstr "ウィジェット間の水平マージン (ピクセル単位)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:62 -#: static/js/wirecloud/ui/LayoutInputInterface.js:98 +#: static/js/wirecloud/ui/LayoutInputInterface.js:63 +#: static/js/wirecloud/ui/LayoutInputInterface.js:99 msgid "" "Horizontal Margin between widgets. Must be specified in pixel units. " "(default: 4px)" @@ -1229,13 +1245,13 @@ msgstr "" "ウィジェット間の水平マージン。ピクセル単位で指定する必要があります (デフォル" "ト: 4px)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:68 -#: static/js/wirecloud/ui/LayoutInputInterface.js:104 +#: static/js/wirecloud/ui/LayoutInputInterface.js:69 +#: static/js/wirecloud/ui/LayoutInputInterface.js:105 msgid "Vertical Margin between widgets (in pixels)" msgstr "ウィジェット間の垂直マージン (ピクセル単位)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:70 -#: static/js/wirecloud/ui/LayoutInputInterface.js:106 +#: static/js/wirecloud/ui/LayoutInputInterface.js:71 +#: static/js/wirecloud/ui/LayoutInputInterface.js:107 msgid "" "Vertical Margin between widgets. Must be specified in pixel units. (default: " "3px)" @@ -1243,51 +1259,51 @@ msgstr "" "ウィジェット間の垂直マージン。ピクセル単位で指定する必要があります (デフォル" "ト: 3px)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:88 +#: static/js/wirecloud/ui/LayoutInputInterface.js:89 msgid "Rows" msgstr "行" -#: static/js/wirecloud/ui/LayoutInputInterface.js:90 +#: static/js/wirecloud/ui/LayoutInputInterface.js:91 msgid "Grid rows. (default: 12 rows)" msgstr "グリッドの行。(デフォルト: 12行)" -#: static/js/wirecloud/ui/LayoutInputInterface.js:117 +#: static/js/wirecloud/ui/LayoutInputInterface.js:119 msgid " smart" msgstr " スマート" -#: static/js/wirecloud/ui/LayoutInputInterface.js:121 +#: static/js/wirecloud/ui/LayoutInputInterface.js:123 msgid "%(columns)s%(smart)s columns" msgstr "%(columns)s%(smart)s 列" -#: static/js/wirecloud/ui/LayoutInputInterface.js:124 +#: static/js/wirecloud/ui/LayoutInputInterface.js:126 msgid "%(columns)s columns x %(rows)s rows" msgstr "%(columns)s columns x %(rows)s 行" -#: static/js/wirecloud/ui/LayoutInputInterface.js:144 +#: static/js/wirecloud/ui/LayoutInputInterface.js:148 msgid "Grid" msgstr "グリッド" -#: static/js/wirecloud/ui/LayoutInputInterface.js:169 +#: static/js/wirecloud/ui/LayoutInputInterface.js:173 msgid "Layout configuration" msgstr "レイアウト設定" -#: static/js/wirecloud/ui/LogWindowMenu.js:41 -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:79 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:83 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:70 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:58 +#: static/js/wirecloud/ui/LogWindowMenu.js:34 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:72 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:138 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:96 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:310 msgid "Logs" msgstr "ログ" -#: static/js/wirecloud/ui/LogWindowMenu.js:56 +#: static/js/wirecloud/ui/LogWindowMenu.js:54 msgid "Close" msgstr "クローズ" -#: static/js/wirecloud/ui/LogWindowMenu.js:129 +#: static/js/wirecloud/ui/LogWindowMenu.js:121 msgid "Details" msgstr "詳細" -#: static/js/wirecloud/ui/MarketplaceView.js:55 +#: static/js/wirecloud/ui/MarketplaceView.js:52 msgid "" "

            WireCloud is not connected with any marketplace.

            Suggestions:

            • Connect WireCloud with a new marketplace.
            • Go to the my " @@ -1297,31 +1313,31 @@ msgstr "" "p>
              • WireCloudを新しいマーケットプレイスに接続します。
              • 代わりに" "自分のリソースビューに移動する
              " -#: static/js/wirecloud/ui/MarketplaceView.js:158 -#: static/js/wirecloud/ui/MyResourcesView.js:138 -#: static/js/wirecloud/ui/MyResourcesView.js:156 -#: static/js/wirecloud/ui/WorkspaceView.js:73 +#: static/js/wirecloud/ui/MarketplaceView.js:179 +#: static/js/wirecloud/ui/MyResourcesView.js:147 +#: static/js/wirecloud/ui/MyResourcesView.js:165 +#: static/js/wirecloud/ui/WorkspaceView.js:175 msgid "My Resources" msgstr "マイ・リソース" -#: static/js/wirecloud/ui/MarketplaceView.js:226 +#: static/js/wirecloud/ui/MarketplaceView.js:240 msgid "loading marketplace view..." msgstr "マーケットプレイス・ビューを読み込む..." -#: static/js/wirecloud/ui/MarketplaceView.js:228 +#: static/js/wirecloud/ui/MarketplaceView.js:242 msgid "marketplace list not available" msgstr "マーケットプレイス・リストは利用できません" -#: static/js/wirecloud/ui/MarketplaceView.js:252 +#: static/js/wirecloud/ui/MarketplaceView.js:264 msgid "Marketplace" msgstr "マーケットプレイス" -#: static/js/wirecloud/ui/MarketplaceView.js:255 +#: static/js/wirecloud/ui/MarketplaceView.js:267 msgid "Marketplace - %(marketname)s" msgstr "マーケットプレイス - %(marketname)s" #: static/js/wirecloud/ui/MarketplaceViewMenuItems.js:62 -#: static/js/wirecloud/ui/MyResourcesView.js:56 +#: static/js/wirecloud/ui/MyResourcesView.js:70 msgid "Upload" msgstr "アップロード" @@ -1330,7 +1346,7 @@ msgid "Add new marketplace" msgstr "新しいマーケットプレイスを追加" #: static/js/wirecloud/ui/MarketplaceViewMenuItems.js:75 -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:49 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:52 msgid "Name" msgstr "名前" @@ -1343,7 +1359,7 @@ msgid "Type" msgstr "タイプ" #: static/js/wirecloud/ui/MarketplaceViewMenuItems.js:94 -#: static/js/wirecloud/ui/SharingWindowMenu.js:46 +#: static/js/wirecloud/ui/SharingWindowMenu.js:159 msgid "Public" msgstr "パブリック" @@ -1359,38 +1375,38 @@ msgstr "マーケットプレイスを削除" msgid "Do you really want to remove the marketplace \"%(marketName)s\"?" msgstr "本当にマーケットプレイス \"%(marketName)s\" を削除したいですか?" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:38 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:36 msgid "Missing dependencies" msgstr "不足している依存関係" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:42 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:40 msgid "The following dependencies are missing:" msgstr "以下の依存関係はありません:" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:54 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:52 msgid "" "You will be able to continue after installing all the required dependencies." msgstr "必要なすべての依存関係をインストールした後に続行することができます。" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:59 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:376 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:736 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:57 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:364 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:103 msgid "Continue" msgstr "続ける" -#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:68 -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:222 -#: static/js/wirecloud/ui/SharingWindowMenu.js:85 -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:137 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:737 +#: static/js/wirecloud/ui/MissingDependenciesWindowMenu.js:66 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:235 +#: static/js/wirecloud/ui/SharingWindowMenu.js:214 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:140 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:104 msgid "Cancel" msgstr "キャンセル" -#: static/js/wirecloud/ui/MyResourcesView.js:44 +#: static/js/wirecloud/ui/MyResourcesView.js:58 msgid "Empty resource list" msgstr "空のリソース・リスト" -#: static/js/wirecloud/ui/MyResourcesView.js:45 +#: static/js/wirecloud/ui/MyResourcesView.js:59 msgid "" "Currently, you do not have access to any component. You can get components " "using the Marketplace view or by uploading components manually using the " @@ -1400,16 +1416,16 @@ msgstr "" "ス・ビューを使用するか、\"アップロード\" ボタンを使用してコンポーネントを手動" "でアップロードしてコンポーネントを取得できます。" -#: static/js/wirecloud/ui/MyResourcesView.js:66 -#: static/js/wirecloud/ui/WorkspaceView.js:82 +#: static/js/wirecloud/ui/MyResourcesView.js:80 +#: static/js/wirecloud/ui/WorkspaceView.js:184 msgid "Get more components" msgstr "より多くのコンポーネントを入手" -#: static/js/wirecloud/ui/MyResourcesView.js:153 +#: static/js/wirecloud/ui/MyResourcesView.js:162 msgid "My Resources - %(resource)s" msgstr "マイ・リソース - %(resource)s" -#: static/js/wirecloud/ui/MyResourcesView.js:266 +#: static/js/wirecloud/ui/MyResourcesView.js:287 msgid "" "You have not configured any marketplace to upload this resource. Please, " "configure one on the Marketplace view." @@ -1417,7 +1433,7 @@ msgstr "" "このリソースをアップロードするマーケットプレイスを設定していません。マーケッ" "トプレイス・ビューで設定してください。" -#: static/js/wirecloud/ui/MyResourcesView.js:352 +#: static/js/wirecloud/ui/MyResourcesView.js:371 msgid "" "Do you really want to remove the \"%(name)s\" (vendor: \"%(vendor)s\", " "version: \"%(version)s\") resource?" @@ -1425,7 +1441,7 @@ msgstr "" "本当に \"%(name)s\" (ベンダー: \"%(vendor)s\", バージョン \"%(version)s\") リ" "ソースを削除しますか?" -#: static/js/wirecloud/ui/MyResourcesView.js:378 +#: static/js/wirecloud/ui/MyResourcesView.js:395 msgid "" "Do you really want to remove all versions of the (vendor: \"%(vendor)s\", " "name: \"%(name)s\") resource?" @@ -1433,98 +1449,108 @@ msgstr "" "本当に (ベンダー: \"%(vendor)s\", 名前: \"%(name)s\") リソースのすべてのバー" "ジョンを削除しますか?" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:53 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:57 +msgid "Create Workspace" +msgstr "ワークスペースの作成" + +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:57 +#, fuzzy +#| msgid "Create Workspace" +msgid "Copy Workspace" +msgstr "ワークスペースの作成" + +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:60 msgid "Template" msgstr "テンプレート" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:56 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:63 msgid "Select a mashup template" msgstr "マッシュアップ・テンプレートを選択" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:61 -msgid "Create Workspace" -msgstr "ワークスペースの作成" - -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:70 -msgid "Creating a %(owner)s/%(name)s workspace using %(mashup)s as template" +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:81 +#, fuzzy +#| msgid "Creating a %(owner)s/%(name)s workspace using %(mashup)s as template" +msgid "Creating a %(owner)s/%(title)s workspace using %(mashup)s as template" msgstr "" "%(mashup)s をテンプレートとして使用して %(owner)s/%(name)s のワークスペースを" "作成します" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:72 -msgid "Creating a %(owner)s/%(name)s workspace" +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:83 +#, fuzzy +#| msgid "Creating a %(owner)s/%(name)s workspace" +msgid "Creating a %(owner)s/%(title)s workspace" msgstr "%(owner)s/%(name)s のワークスペースの作成します" -#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:75 +#: static/js/wirecloud/ui/NewWorkspaceWindowMenu.js:86 msgid "Creating a new workspace using %(mashup)s as template" msgstr "" "%(mashup)s をテンプレートとして使用して新しいワークスペースを作成します" -#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:30 +#: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:50 msgid "Operator Settings" msgstr "オペレーターの設定" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:47 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:48 msgid "Parametrize" msgstr "パラメータ設定" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:49 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:50 msgid "Modify" msgstr "変更" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:54 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:55 msgid "This value won't be editable by the user" msgstr "この値はユーザが編集できません" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:57 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:58 msgid "This value will be editable by the user" msgstr "この値はユーザが編集可能です" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:62 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:63 msgid "This value will be visible to the user" msgstr "この値はユーザに表示されます" -#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:65 +#: static/js/wirecloud/ui/ParametrizableValueInputInterface.js:66 msgid "This value won't be visible to the user" msgstr "この値はユーザに表示されません" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:33 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:36 msgid "Normal" msgstr "ノーマル" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:34 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:37 msgid "Read Only" msgstr "読み取り専用" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:38 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:41 msgid "Hidden" msgstr "隠された" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:42 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:45 msgid "Current value" msgstr "現在の値" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:43 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:46 msgid "Default value" msgstr "デフォルト値" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:44 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:47 msgid "Parametrized value" msgstr "パラメータ化された値" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:48 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:51 msgid "Status" msgstr "ステータス" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:49 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:52 msgid "Value source" msgstr "値のソース" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:51 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:54 msgid "Value" msgstr "値" -#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:53 +#: static/js/wirecloud/ui/ParametrizeWindowMenu.js:56 msgid "Parametrization" msgstr "パラメータ化" @@ -1533,124 +1559,128 @@ msgid "Use current value" msgstr "現在の値を使用" #: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:75 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:276 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:254 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:482 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:495 msgid "Add" msgstr "追加" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:146 -#: static/js/wirecloud/ui/WirecloudHeader.js:118 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:131 +#: static/js/wirecloud/ui/WirecloudHeader.js:116 msgid "User" msgstr "ユーザ" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:150 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:135 msgid "User Name" msgstr "ユーザ名" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:155 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:140 msgid "First Name" msgstr "名" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:160 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:145 msgid "Last Name" msgstr "姓" -#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:167 +#: static/js/wirecloud/ui/ParametrizedTextInputInterface.js:152 msgid "Context" msgstr "コンテキスト" -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:105 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:106 msgid "Inherit" msgstr "継承" -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:195 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:203 msgid "Set Defaults" msgstr "デフォルトを設定" -#: static/js/wirecloud/ui/PreferencesWindowMenu.js:215 -#: static/js/wirecloud/ui/SharingWindowMenu.js:81 +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:220 +msgid "Error" +msgstr "" + +#: static/js/wirecloud/ui/PreferencesWindowMenu.js:227 +#: static/js/wirecloud/ui/SharingWindowMenu.js:210 msgid "Save" msgstr "保存" -#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:37 -msgid "Upload resource" -msgstr "リソースをアップロード" - -#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:62 +#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:51 msgid "Upload to" msgstr "アップロード先" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:40 +#: static/js/wirecloud/ui/PublishResourceWindowMenu.js:69 +msgid "Upload resource" +msgstr "リソースをアップロード" + +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:43 msgid "General info" msgstr "一般的な情報" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:42 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:45 msgid "Mashup Title" msgstr "マッシュアップのタイトル" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:42 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:45 msgid "Title to display on the catalogue" msgstr "カタログに表示するタイトル" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:43 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:46 msgid "Id of the vendor/distributor of the mashable application component" msgstr "" "マッシュアップ・アプリケーション・コンポーネントのベンダー/ディストリビュータ" "の Id" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:44 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:47 msgid "Version" msgstr "バージョン" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:45 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:48 msgid "Email" msgstr "Eメール" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:46 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:49 msgid "Short Description (plain text)" msgstr "簡単な説明 (テキスト)" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:47 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:50 msgid "Detailed description (Markdown)" msgstr "詳細な説明 (Markdown)" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:48 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:51 msgid "Home page" msgstr "ホームページ" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:49 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:52 msgid "Authors" msgstr "著者" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:54 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:57 msgid "Media" msgstr "メディア" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:58 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:61 msgid "Image shown in catalogue (170x80 px)" msgstr "カタログに表示される画像 (170x80 px)" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:65 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:68 msgid "Advanced" msgstr "アドバンスド" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:67 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:70 msgid "Block widgets" msgstr "ウィジェットをブロック" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:68 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:71 msgid "Block connections" msgstr "接続をブロック" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:69 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:72 msgid "Embed used widgets/operators" msgstr "使用されたウィジェット/オペレータを埋め込む" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:76 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:79 msgid "Upload workspace to my resources" msgstr "マイ・リソースにワークスペースをアップロード" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:82 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:85 msgid "" "Warning! Configured and stored data in your workspace " "(properties and preferences except passwords) will be shared by default!" @@ -1658,86 +1688,117 @@ msgstr "" "警告! あなたのワークスペースに設定され、保存されたデータ (パ" "スワード以外のプロパティと設定) は、デフォルトで共有されます!" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:132 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:58 -#: static/js/wirecloud/ui/WiringEditor/Component.js:48 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:50 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:78 -#: static/js/wirecloud/ui/WorkspaceTabView.js:127 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:134 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:48 +#: static/js/wirecloud/ui/WiringEditor/Component.js:90 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:269 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:330 +#: static/js/wirecloud/ui/WorkspaceTabView.js:220 msgid "Preferences" msgstr "設定" -#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:139 +#: static/js/wirecloud/ui/PublishWorkspaceWindowMenu.js:141 msgid "Persistent variables" msgstr "永続変数" -#: static/js/wirecloud/ui/RenameWindowMenu.js:32 +#: static/js/wirecloud/ui/RenameWindowMenu.js:34 msgid "New Name" msgstr "新しい名前" -#: static/js/wirecloud/ui/SharingWindowMenu.js:37 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:170 +msgid "From (px):" +msgstr "" + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:171 +msgid "The left limit of the screen size range (in pixels)." +msgstr "" + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:197 +msgid "To (px):" +msgstr "" + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:198 +msgid "" +"The right limit of the screen size range (in pixels). Use -1 for no limit." +msgstr "" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:105 +msgid "%(fullname)s (You)" +msgstr "%(fullname)s (あなた)" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:122 +msgid "Owner" +msgstr "オーナー" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:122 +msgid "Can view" +msgstr "見ることができる" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:126 +#: static/js/wirecloud/ui/WidgetView.js:309 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:53 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:275 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:493 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:504 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:320 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:507 +#: static/js/wirecloud/ui/WiringEditor/Connection.js:519 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:67 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:102 +msgid "Remove" +msgstr "削除" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:150 msgid "Sharing settings" msgstr "共有設定" -#: static/js/wirecloud/ui/SharingWindowMenu.js:42 +#: static/js/wirecloud/ui/SharingWindowMenu.js:155 msgid "Visibility options" msgstr "可視性オプション" -#: static/js/wirecloud/ui/SharingWindowMenu.js:46 +#: static/js/wirecloud/ui/SharingWindowMenu.js:159 msgid "Anyone on the Internet can find and access this dashboard." msgstr "インターネット上の誰でもこのダッシュボードを見つけてアクセスできます。" -#: static/js/wirecloud/ui/SharingWindowMenu.js:47 +#: static/js/wirecloud/ui/SharingWindowMenu.js:160 +msgid "Registered User" +msgstr "" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:160 +#, fuzzy +#| msgid "Anyone on the Internet can find and access this dashboard." +msgid "" +"Anyone on the Internet can find this dashboard. Only registered users can " +"access it." +msgstr "インターネット上の誰でもこのダッシュボードを見つけてアクセスできます。" + +#: static/js/wirecloud/ui/SharingWindowMenu.js:161 msgid "Private" msgstr "プライベート" -#: static/js/wirecloud/ui/SharingWindowMenu.js:47 +#: static/js/wirecloud/ui/SharingWindowMenu.js:161 msgid "Shared with specific people and organizations." msgstr "特定の人や組織と共有します。" -#: static/js/wirecloud/ui/SharingWindowMenu.js:57 +#: static/js/wirecloud/ui/SharingWindowMenu.js:171 msgid "Users and groups with access" msgstr "アクセス権のあるユーザーとグループ" -#: static/js/wirecloud/ui/SharingWindowMenu.js:60 -msgid "Add a person or an organization" +#: static/js/wirecloud/ui/SharingWindowMenu.js:174 +#, fuzzy +#| msgid "Add a person or an organization" +msgid "Add a person, a group or an organization" msgstr "人や組織を追加" -#: static/js/wirecloud/ui/SharingWindowMenu.js:167 -msgid "%(fullname)s (You)" -msgstr "%(fullname)s (あなた)" - -#: static/js/wirecloud/ui/SharingWindowMenu.js:183 -msgid "Owner" -msgstr "オーナー" - -#: static/js/wirecloud/ui/SharingWindowMenu.js:185 -msgid "Can view" -msgstr "見ることができる" - -#: static/js/wirecloud/ui/SharingWindowMenu.js:191 -#: static/js/wirecloud/ui/WidgetView.js:111 -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:65 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:57 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:287 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:298 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:68 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:266 -#: static/js/wirecloud/ui/WiringEditor/Connection.js:278 -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:76 -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:101 -msgid "Remove" -msgstr "削除" - -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:44 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:45 msgid "Upgrade" msgstr "アップグレード" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:50 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:51 msgid "Downgrade" msgstr "ダウングレード" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:70 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:71 msgid "" "There is not change information between versions %(from_version)s and " "%(to_version)s" @@ -1745,103 +1806,193 @@ msgstr "" "バージョン %(from_version)s と %(to_version)s の間で情報を変更することはあり" "ません" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:75 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:76 msgid "Unable to retrieve change log information" msgstr "変更ログ情報を取得できません" -#: static/js/wirecloud/ui/UpgradeWindowMenu.js:91 +#: static/js/wirecloud/ui/UpgradeWindowMenu.js:92 msgid "Available versions" msgstr "使用可能なバージョン" -#: static/js/wirecloud/ui/WidgetView.js:151 -msgid "Menu" -msgstr "メニュー" - -#: static/js/wirecloud/ui/WidgetView.js:162 -#: static/js/wirecloud/ui/WidgetView.js:329 -msgid "Minimize" -msgstr "最小化" +#: static/js/wirecloud/ui/WidgetView.js:42 +#, fuzzy +#| msgid "Drag & drop to move the widget" +msgid "Disallow to move this widget" +msgstr "ウィジェットを移動するためにドラック&ドロップ" -#: static/js/wirecloud/ui/WidgetView.js:319 -msgid "Maximize" -msgstr "最大化" +#: static/js/wirecloud/ui/WidgetView.js:42 +#, fuzzy +#| msgid "Drag & drop to move the widget" +msgid "Allow to move this widget" +msgstr "ウィジェットを移動するためにドラック&ドロップ" -#: static/js/wirecloud/ui/WidgetView.js:368 +#: static/js/wirecloud/ui/WidgetView.js:48 msgid "Hide title" msgstr "タイトルを隠す" -#: static/js/wirecloud/ui/WidgetView.js:368 +#: static/js/wirecloud/ui/WidgetView.js:48 msgid "Show title" msgstr "タイトルを表示" -#: static/js/wirecloud/ui/WidgetView.js:725 +#: static/js/wirecloud/ui/WidgetView.js:207 msgid "%(errorCount)s error" msgid_plural "%(errorCount)s errors" msgstr[0] "%(errorCount)s エラー" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:64 +#: static/js/wirecloud/ui/WidgetView.js:351 +msgid "Menu" +msgstr "メニュー" + +#: static/js/wirecloud/ui/WidgetView.js:362 +#: static/js/wirecloud/ui/WidgetView.js:560 +msgid "Minimize" +msgstr "最小化" + +#: static/js/wirecloud/ui/WidgetView.js:545 +msgid "Maximize" +msgstr "最大化" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:57 msgid "Reload" msgstr "リロード" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:71 -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:79 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:66 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:64 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:134 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:92 msgid "Upgrade/Downgrade" msgstr "アップグレード/ダウングレード" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:92 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:85 msgid "User's Manual" msgstr "ユーザーズ・マニュアル" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:96 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:89 msgid "Documentation" msgstr "ドキュメンテーション" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:105 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:104 +msgid "Left" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:116 +msgid "Center" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:128 +#, fuzzy +#| msgid "Height" +msgid "Right" +msgstr "高さ" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:143 +msgid "Top" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:155 +msgid "Bottom" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:168 +msgid "Fixed x" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:168 +msgid "Relative x" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:183 +msgid "Fixed y" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:183 +msgid "Relative y" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:198 +msgid "Fixed width" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:198 +msgid "Relative width" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:212 +msgid "Fixed height" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:212 +msgid "Relative height" +msgstr "" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:229 msgid "Exit Full Dragboard" msgstr "フル・ドラッグボードを終了" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:108 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:232 msgid "Full Dragboard" msgstr "フル・ドラッグボード" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:122 +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:249 +msgid "Extract from grid" +msgstr "グリッドからの抽出" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:258 msgid "Snap to grid" msgstr "グリッドにスナップ" -#: static/js/wirecloud/ui/WidgetViewMenuItems.js:125 -msgid "Extract from grid" -msgstr "グリッドからの抽出" +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:267 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the top sidebar" +msgstr "コンポーネントのサイドバーを閉じる" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:276 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the right sidebar" +msgstr "コンポーネントのサイドバーを閉じる" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:285 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the bottom sidebar" +msgstr "コンポーネントのサイドバーを閉じる" + +#: static/js/wirecloud/ui/WidgetViewMenuItems.js:294 +#, fuzzy +#| msgid "Close the component sidebar" +msgid "Move to the left sidebar" +msgstr "コンポーネントのサイドバーを閉じる" -#: static/js/wirecloud/ui/WirecloudHeader.js:109 +#: static/js/wirecloud/ui/WirecloudHeader.js:102 msgid "Django Admin panel" msgstr "Django 管理パネル" -#: static/js/wirecloud/ui/WirecloudHeader.js:117 -#: static/js/wirecloud/ui/WirecloudHeader.js:118 +#: static/js/wirecloud/ui/WirecloudHeader.js:115 +#: static/js/wirecloud/ui/WirecloudHeader.js:116 msgid "Switch User" msgstr "ユーザの切り替え" -#: static/js/wirecloud/ui/WirecloudHeader.js:142 +#: static/js/wirecloud/ui/WirecloudHeader.js:133 +msgid "Back to %(user)s" +msgstr "" + +#: static/js/wirecloud/ui/WirecloudHeader.js:139 msgid "Sign out" msgstr "サインアウト" -#: static/js/wirecloud/ui/WiringEditor.js:169 -msgid "%(workspace_title)s - Wiring" -msgstr "%(workspace_title)s - ワイヤーリング" - -#: static/js/wirecloud/ui/WiringEditor.js:390 +#: static/js/wirecloud/ui/WiringEditor.js:171 msgid "Hello, welcome to the Wiring Editor view!" msgstr "ワイヤーリング・エディタ・ビューへようこそ!" -#: static/js/wirecloud/ui/WiringEditor.js:391 +#: static/js/wirecloud/ui/WiringEditor.js:172 msgid "" "In this view you can connect all the components of your dashboard in a " "visual way." msgstr "" "このビューではダッシュボードのすべてのコンポーネントを視覚的に接続できます" -#: static/js/wirecloud/ui/WiringEditor.js:397 +#: static/js/wirecloud/ui/WiringEditor.js:178 msgid "" "Open the sidebar using the Find components button and drag & " "drop components (operators/widgets) from the sidebar for being able to " @@ -1851,95 +2002,58 @@ msgstr "" "らコンポーネント (オペレータ/ウィジェット) をドラッグ&ドロップして、希望どお" "りに接続することができます。" -#: static/js/wirecloud/ui/WiringEditor.js:404 +#: static/js/wirecloud/ui/WiringEditor.js:185 msgid "Find components" msgstr "コンポーネントの検索" -#: static/js/wirecloud/ui/WiringEditor.js:417 +#: static/js/wirecloud/ui/WiringEditor.js:198 msgid "List behaviours" msgstr "ビヘイビアの一覧" -#: static/js/wirecloud/ui/WiringEditor.js:653 +#: static/js/wirecloud/ui/WiringEditor.js:429 msgid "" "The connection will also be modified for the rest of behaviours, would you " "like to continue?" msgstr "残りのビヘイビアのために接続も変更されますが、続行しますか?" -#: static/js/wirecloud/ui/WiringEditor.js:729 +#: static/js/wirecloud/ui/WiringEditor.js:505 msgid "Behaviour" msgstr "ビヘイビア" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:120 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:721 -msgid "New behaviour" -msgstr "新しいビヘイビア" - -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:121 -#: static/js/wirecloud/ui/WiringEditor/Endpoint.js:125 -msgid "No description provided." -msgstr "説明はありません。" +#: static/js/wirecloud/ui/WiringEditor.js:786 +msgid "%(workspace_title)s - Wiring" +msgstr "%(workspace_title)s - ワイヤーリング" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:272 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:254 msgid "%(behaviour_title)s's logs" msgstr "%(behaviour_title)s のログ" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:292 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:719 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:273 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:88 msgid "Description" msgstr "説明" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:294 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:275 msgid "Behaviour settings" msgstr "" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:372 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:360 msgid "" "The following operation is irreversible and removes the behaviour " "completely. Would you like to continue?" msgstr "" "次の操作は取り消しができず、ビヘイビアを完全に削除します。 続行しますか?" -#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:377 +#: static/js/wirecloud/ui/WiringEditor/Behaviour.js:365 msgid "No, thank you" msgstr "いいえ、結構です" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:46 -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:128 -msgid "Enable" -msgstr "有効化" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:53 -msgid "Create behaviour" -msgstr "ビヘイビアを作成" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:60 -msgid "Order behaviours" -msgstr "ビヘイビアを順序付ける" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:84 -msgid "New feature" -msgstr "新機能" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:85 -msgid "Enable the behaviours to enjoy with a new way to handle connections." -msgstr "ビヘイビアが新しい方法で接続を処理できるようにします。" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:88 -msgid "" -"Click here for a quick guide/tutorial on how to use this new feature." -msgstr "" -"ここをクリックして、この新機能の使用方法に関するクイックガイド/チュー" -"トリアルをご覧ください。" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:114 -msgid "Disable" -msgstr "無効化" - -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:402 -msgid "The behaviour (%(title)s) was loaded." -msgstr "ビヘイビア (%(title)s) が読み込まれました。" +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:87 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:90 +msgid "New behaviour" +msgstr "新しいビヘイビア" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:733 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:100 msgid "" "The behaviours will be removed but the components and connections will still " "exist, would you like to continue?" @@ -1947,17 +2061,23 @@ msgstr "" "ビヘイビアは削除されますが、コンポーネントと接続はまだ存在します。続行します" "か?" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:801 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:111 +#, fuzzy +#| msgid "List behaviours" +msgid "Initial behaviour" +msgstr "ビヘイビアの一覧" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:166 msgid "" "The will be removed, would you like to " "continue?" msgstr " は削除されます。続行しますか?" -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:821 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:184 msgid "
            • The .
            • " msgstr "
            • .
            • " -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:827 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:190 msgid "" "

              These components only exist within the current behaviour :

              Would you like to continue?

              " @@ -1965,7 +2085,7 @@ msgstr "" "

              これらのコンポーネントは、現在のビヘイビア :

              内にのみ存在します

              続行しますか?

              " -#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:848 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:207 msgid "" "The will be definitely removed, would you like to continue?" @@ -1973,188 +2093,231 @@ msgstr "" " は、間違いなく削除され" "ますが、続行しますか?" -#: static/js/wirecloud/ui/WiringEditor/Component.js:135 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:339 +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:415 +msgid "Enable" +msgstr "有効化" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:346 +msgid "Create behaviour" +msgstr "ビヘイビアを作成" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:353 +msgid "Order behaviours" +msgstr "ビヘイビアを順序付ける" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:377 +msgid "New feature" +msgstr "新機能" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:378 +msgid "Enable the behaviours to enjoy with a new way to handle connections." +msgstr "ビヘイビアが新しい方法で接続を処理できるようにします。" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:381 +msgid "" +"Click here for a quick guide/tutorial on how to use this new feature." +msgstr "" +"ここをクリックして、この新機能の使用方法に関するクイックガイド/チュー" +"トリアルをご覧ください。" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:401 +msgid "Disable" +msgstr "無効化" + +#: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:691 +msgid "The behaviour (%(title)s) was loaded." +msgstr "ビヘイビア (%(title)s) が読み込まれました。" + +#: static/js/wirecloud/ui/WiringEditor/Component.js:32 msgid "volatile" msgstr "揮発性" -#: static/js/wirecloud/ui/WiringEditor/Component.js:138 +#: static/js/wirecloud/ui/WiringEditor/Component.js:35 msgid "missing" msgstr "ミッシング" -#: static/js/wirecloud/ui/WiringEditor/Component.js:141 +#: static/js/wirecloud/ui/WiringEditor/Component.js:38 msgid "in use" msgstr "使用中" -#: static/js/wirecloud/ui/WiringEditor/Component.js:144 +#: static/js/wirecloud/ui/WiringEditor/Component.js:41 msgid "no endpoints" msgstr "エンドポイントなし" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:703 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:179 msgid "Missing" msgstr "ミッシング" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:705 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:181 msgid "%(count)s error" msgid_plural "%(count)s errors" msgstr[0] "%(count)s エラー" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:92 -msgid "Delete cascade" -msgstr "カスケードを削除" - -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:132 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:56 msgid "Expand" msgstr "展開" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:134 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:58 msgid "Collapse" msgstr "折り畳む" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:140 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:64 msgid "Stop ordering" msgstr "並び替えを中止" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:142 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:66 msgid "Order endpoints" msgstr "エンドポイントを並び替え" -#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:150 -#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:102 +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:75 +#: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:47 msgid "Rename %(type)s" msgstr "%(type)s の名前を変更" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:36 -msgid "Create" -msgstr "作成" +#: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:147 +msgid "Delete cascade" +msgstr "カスケードを削除" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:106 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:39 msgid "No description provided" msgstr "説明はありません" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:128 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:61 msgid "No image available" -msgstr "" -"使用可能なイメージはありません" +msgstr "使用可能なイメージはありません" -#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:137 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:70 msgid "%(version)s (latest)" msgstr "%(version)s (最新)" -#: static/js/wirecloud/ui/WiringEditor/ConnectionHandle.js:72 +#: static/js/wirecloud/ui/WiringEditor/ComponentGroup.js:84 +msgid "Create" +msgstr "作成" + +#: static/js/wirecloud/ui/WiringEditor/ConnectionHandle.js:70 msgid "Drag & Drop" msgstr "ドラッグ&ドロップ" -#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:83 -msgid "Restore defaults" -msgstr "デフォルトに戻す" - -#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:104 +#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:39 msgid "Stop customizing" msgstr "カスタマイズの停止" -#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:104 +#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:39 msgid "Customize" msgstr "カスタマイズ" +#: static/js/wirecloud/ui/WiringEditor/ConnectionPrefs.js:91 +msgid "Restore defaults" +msgstr "デフォルトに戻す" + +#: static/js/wirecloud/ui/WiringEditor/Endpoint.js:171 +msgid "No description provided." +msgstr "説明はありません。" + #: static/js/wirecloud/ui/WorkspaceListItems.js:46 msgid "Empty workspace list" msgstr "空のワークスペース・リスト" -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:58 +#: static/js/wirecloud/ui/WorkspaceTabView.js:354 +msgid "Currently editing for screen sizes %(interval)s" +msgstr "" + +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:49 msgid "Rename Workspace Tab" msgstr "ワークスペース・タブの名前を変更" -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:63 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:54 msgid "Set as initial" msgstr "初期としてセット" -#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:78 +#: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:69 msgid "The tab's widgets will also be removed. Would you like to continue?" msgstr "タブのウィジェットも削除されます。 続行しますか?" -#: static/js/wirecloud/ui/WorkspaceView.js:64 +#: static/js/wirecloud/ui/WorkspaceView.js:166 msgid "Wiring" msgstr "ワイヤーリング" -#: static/js/wirecloud/ui/WorkspaceView.js:271 +#: static/js/wirecloud/ui/WorkspaceView.js:370 msgid "New tab" msgstr "新しいタブ" -#: static/js/wirecloud/ui/WorkspaceView.js:286 -#: static/js/wirecloud/ui/WorkspaceView.js:297 +#: static/js/wirecloud/ui/WorkspaceView.js:385 +#: static/js/wirecloud/ui/WorkspaceView.js:396 msgid "Full screen" msgstr "全画面" -#: static/js/wirecloud/ui/WorkspaceView.js:293 +#: static/js/wirecloud/ui/WorkspaceView.js:392 msgid "Exit full screen" msgstr "全画面を終了" -#: static/js/wirecloud/ui/WorkspaceView.js:333 +#: static/js/wirecloud/ui/WorkspaceView.js:432 msgid "Add components" msgstr "コンポーネントを追加" -#: static/js/wirecloud/ui/WorkspaceView.js:392 -#: static/js/wirecloud/ui/WorkspaceView.js:406 +#: static/js/wirecloud/ui/WorkspaceView.js:490 +#: static/js/wirecloud/ui/WorkspaceView.js:504 msgid "loading..." msgstr "読み込んでいます..." -#: static/js/wirecloud/ui/WorkspaceView.js:445 +#: static/js/wirecloud/ui/WorkspaceView.js:542 msgid "The requested workspace is no longer available (it was deleted)." msgstr "要求されたワークスペースは使用できなくなりました (削除されました)。" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:58 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:50 msgid "New workspace" msgstr "新しいワークスペース" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:65 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:57 msgid "Rename Workspace" msgstr "ワークスペースの名前を変更" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:71 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:63 msgid "Share" msgstr "共有" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:77 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:69 msgid "Upload to my resources" msgstr "自分のリソースにアップロード" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:88 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:80 msgid "Embed" msgstr "埋め込み" -#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:89 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:81 msgid "Embed Code" msgstr "埋め込みコード" -#: static/js/wirecloud/wiring/Connection.js:101 +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:93 +msgid "Duplicate" +msgstr "" + +#: static/js/wirecloud/ui/WorkspaceViewMenuItems.js:95 +msgid "Copy of %(title)s" +msgstr "" + +#: static/js/wirecloud/wiring/Connection.js:80 msgid "The connection ('%(source)s'-'%(target)s') was established." msgstr "接続 ('%(source)s'-'%(target)s') が確立されました。" -#: static/js/wirecloud/wiring/Connection.js:110 +#: static/js/wirecloud/wiring/Connection.js:89 msgid "The connection ('%(source)s'-'%(target)s') was detached." msgstr "接続 ('%(source)s'-'%(target)s') が切り離されました。" -#: static/js/wirecloud/wiring/Connection.js:137 +#: static/js/wirecloud/wiring/Connection.js:116 msgid "The connection ('%(source)s'-'%(target)s') has a missing endpoint." msgstr "接続 ('%(source)s'-'%(target)s') には、エンドポイントがありません。" -#: static/js/wirecloud/wiring/Connection.js:177 +#: static/js/wirecloud/wiring/Connection.js:156 msgid "Connection's logs" msgstr "接続のログ" -#: static/js/wirecloud/wiring/Endpoint.js:66 +#: static/js/wirecloud/wiring/Endpoint.js:61 msgid "Unimplemented function: %(funcName)s" msgstr "実装されていない関数: %(funcName)s" -#: static/js/wirecloud/wiring/Operator.js:179 -msgid "Operator created successfully." -msgstr "オペレータが正常に作成されました。" - -#: static/js/wirecloud/wiring/Operator.js:286 -msgid "%(operator_title)s's logs" -msgstr "%(operator_title)s のログ" - -#: static/js/wirecloud/wiring/Operator.js:498 +#: static/js/wirecloud/wiring/Operator.js:222 msgid "" "

              This operator is currently not available. You or an administrator " "probably uninstalled it.

              Suggestions:
              • Remove the operator." @@ -2168,23 +2331,31 @@ msgstr "" "ペレーターの別のバージョンをインストールし、アップグレード/ダウングレード" "オプションを使用してください。
              " -#: static/js/wirecloud/wiring/Operator.js:501 +#: static/js/wirecloud/wiring/Operator.js:225 msgid "Operator loaded successfully." msgstr "オペレータが正常にロードされました。" -#: static/js/wirecloud/wiring/Operator.js:525 +#: static/js/wirecloud/wiring/Operator.js:261 msgid "Operator unloaded successfully." msgstr "オペレータが正常にアンロードされました。" -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:67 -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:69 +#: static/js/wirecloud/wiring/Operator.js:426 +msgid "Operator created successfully." +msgstr "オペレータが正常に作成されました。" + +#: static/js/wirecloud/wiring/Operator.js:536 +msgid "%(operator_title)s's logs" +msgstr "%(operator_title)s のログ" + +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:75 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:77 msgid "Use in %(endpointName)s" msgstr "%(endpointName)s で使用" -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:83 -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:95 -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:86 -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:98 +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:90 +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:105 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:94 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:106 msgid "" "Exception catched while processing an event that reached the " "\"%(inputendpoint)s\" input endpoint" @@ -2192,11 +2363,23 @@ msgstr "" "\"%(inputendpoint)s\" 入力エンドポイントに達したイベントを処理中に例外が" "キャッチされました" -#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:85 +#: static/js/wirecloud/wiring/OperatorTargetEndpoint.js:94 msgid "Operator has not registered a callback for this input endpoint" msgstr "" "オペレータはこの入力エンドポイントに対してコールバックを登録していません" -#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:88 +#: static/js/wirecloud/wiring/WidgetTargetEndpoint.js:96 msgid "Widget has not registered a callback for this input endpoint" msgstr "ウィジェットがこの入力エンドポイントのコールバックを登録していません" + +#~ msgid "missing vendor" +#~ msgstr "ベンダーがありません" + +#~ msgid "missing name" +#~ msgstr "名前がありません" + +#~ msgid "missing version" +#~ msgstr "バージョンがありません" + +#~ msgid "missing type" +#~ msgstr "タイプがありません" diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js index 7fece5f863..c4e9a0b2a7 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ColumnLayout.js @@ -536,7 +536,7 @@ } else { iWidgetsToReinsert.push(widget); } - }) + }); const modified = iWidgetsToReinsert.length > 0; // Reinsert the iwidgets that didn't fit in their positions diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js index 715126cf28..25e8b307fd 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js @@ -288,6 +288,15 @@ return new Set(); } + /** + * Removes all event listeners associated with the widget + * + * @param {WidgetView} widget + */ + removeWidgetEventListeners(widget) { + widget.removeEventListener('remove', this._on_remove_widget_bound); + } + /** * Moves all widget in this layout to another layout. * diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/LayoutInputInterface.js b/src/wirecloud/platform/static/js/wirecloud/ui/LayoutInputInterface.js index 8399eac8e2..6e0d9984c4 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/LayoutInputInterface.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/LayoutInputInterface.js @@ -207,7 +207,7 @@ this.buttonElement.setDisabled(disabled); } - epaint() { + repaint() { this.wrapperElement.repaint(); } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/PreferencesWindowMenu.js b/src/wirecloud/platform/static/js/wirecloud/ui/PreferencesWindowMenu.js index 6407a531f7..0746dc23d9 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/PreferencesWindowMenu.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/PreferencesWindowMenu.js @@ -118,7 +118,7 @@ this.windowContent.insertBefore(table, this.msgElement); }; - const save_preferences = function save_preferences() { + const save_preferences = function save_preferences(callback) { const modifiedValues = {}; let newInheritanceSetting; @@ -156,10 +156,14 @@ modifiedValues[pref_name] = changes; } - this.manager.set(modifiedValues); + this.manager.set(modifiedValues).then(() => { + if (typeof callback === 'function') { + callback(); + } + }); }; - const _executeOperation = function _executeOperation() { + const _executeOperation = function _executeOperation(callback) { // Validate input fields const validationManager = new StyledElements.ValidationErrorManager(); for (let pref_name in this.interfaces) { @@ -171,11 +175,12 @@ // Show error message if needed if (errorMsg.length !== 0) { - // FIXME - this.setMsg(errorMsg[0]); + this.alertMsg.setMessage(errorMsg[0]); + this.alertMsg.show(); } else { - save_preferences.call(this); + save_preferences.call(this, callback); this.hide(); + this.alertMsg.hide(); } }; @@ -212,6 +217,10 @@ }.bind(this)); this.resetButton.insertInto(this.windowBottom); + this.alertMsg = new se.Alert({state: 'error', title: utils.gettext('Error')}); + this.alertMsg.insertInto(this.windowContent); + this.alertMsg.hide(); + // Accept button this.acceptButton = new se.Button({ class: 'btn-accept btn-primary', @@ -252,6 +261,7 @@ this.interfaces[pref_name].inherit.setValue(this.manager.preferences[pref_name].inherit); this.interfaces[pref_name].base.setDisabled(this.manager.preferences[pref_name].inherit); } + this.interfaces[pref_name].base.addEventListener('requestSave', _executeOperation.bind(this)); } Wirecloud.ui.WindowMenu.prototype.show.call(this, parentWindow); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js new file mode 100644 index 0000000000..78216adafc --- /dev/null +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2024 Future Internet Consulting and Development Solutions S.L. + * + * This file is part of Wirecloud Platform. + * + * Wirecloud Platform is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * Wirecloud 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 Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Wirecloud Platform. If not, see + * . + * + */ + +/* globals StyledElements, Wirecloud */ + +(function (ns, se, utils) { + + 'use strict'; + + ns.ScreenSizesInputInterface = class ScreenSizesInputInterface extends se.InputInterface { + + constructor(fieldId, options) { + super(fieldId, options); + + this.value = options.defaultValue || []; + this.enabledStatus = true; + + this.wrapperElement = new StyledElements.Container({class: 'se-screen-size-field'}); + this.addButton = new StyledElements.Button({ + iconClass: 'fas fa-plus' + }); + + this.addButton.addEventListener('click', this.on_addScreenSize.bind(this)); + + this.screenSizesInputs = {}; + + this.wrapperElement.appendChild(this.addButton); + + this._update(this.value); + this.addButton.setDisabled(!this.enabledStatus); + } + + on_addScreenSize() { + const screenSizes = utils.clone(this.value); + + // Get max id + let maxId = 0; + screenSizes.forEach((screenSize) => { + if (screenSize.id > maxId) { + maxId = screenSize.id; + } + }); + + screenSizes.sort((a, b) => a.moreOrEqual - b.moreOrEqual); + + const newScreenSize = { + id: maxId + 1, + moreOrEqual: screenSizes[screenSizes.length - 1].lessOrEqual + 1, + lessOrEqual: -1 + }; + + screenSizes.push(newScreenSize); + + this._update(screenSizes, false); + } + + on_deleteScreenSize(screenSizeId) { + const screenSizes = utils.clone(this.value); + + const index = screenSizes.findIndex((screenSize) => screenSize.id === screenSizeId); + screenSizes.splice(index, 1); + + this._update(screenSizes, false); + } + + on_valueChange(screenSizeId, from, value, update = true) { + const screenSizes = utils.clone(this.value); + + const screenSize = screenSizes.find((screenSize) => screenSize.id === screenSizeId); + screenSize[from] = value; + + if (update) { + this._update(screenSizes, false); + } + } + + static parse(value) { + return JSON.parse(value); + } + + static stringify(value) { + return JSON.stringify(value); + } + + _normalize(value) { + return value; + } + + _checkValue(newValue) { + // Check that the newValue covers all integers from [0, +inf) without gaps or overlaps + const screenSizes = utils.clone(newValue); + screenSizes.sort((a, b) => a.moreOrEqual - b.moreOrEqual); + + let lastLessOrEqual = -1; + for (let i = 0; i < screenSizes.length; i++) { + if (screenSizes[i].moreOrEqual != lastLessOrEqual + 1 || (i != screenSizes.length - 1 && screenSizes[i].lessOrEqual <= screenSizes[i].moreOrEqual)) { + return se.InputValidationError.SCREEN_SIZES_ERROR; + } + + lastLessOrEqual = screenSizes[i].lessOrEqual; + } + + if (lastLessOrEqual != -1) { + return se.InputValidationError.SCREEN_SIZES_ERROR; + } + + return se.InputValidationError.NO_ERROR; + } + + getValue() { + return this.value; + } + + setDisabled(disabled) { + this.enabledStatus = !disabled; + + this.addButton.setDisabled(!this.enabledStatus); + this._update(); + } + + repaint() { + this.wrapperElement.repaint(); + } + + _setValue(newValue) { + this._update(newValue); + } + + _update(newValue, sort = true) { + if (newValue) { + this.value = newValue; + } else { + newValue = this.value; + } + + Object.entries(this.screenSizesInputs).forEach((screenSizeContainer) => { + this.wrapperElement.removeChild(screenSizeContainer[1]); + }); + + if (sort) { + // Sort by moreOrEqual + newValue.sort((a, b) => a.moreOrEqual - b.moreOrEqual); + } + + const newContainers = []; + + this.screenSizesInputs = {}; + newValue.forEach((screenSize, i) => { + const screenSizeContainer = new StyledElements.Container(); + + const fromAddon = new se.Addon({ + text: utils.gettext('From (px):'), + title: utils.gettext('The left limit of the screen size range (in pixels).') + }); + fromAddon.setDisabled(i === 0 || !this.enabledStatus); + + const moreOrEqualVal = (i === 0) ? 0 : screenSize.moreOrEqual; + const moreOrEqualInput = new se.NumericField({ + name: 'moreOrEqual', + initialValue: moreOrEqualVal, + min: 0, + inc: 10 + }); + + if (moreOrEqualVal !== screenSize.moreOrEqual) { + this.on_valueChange(screenSize.id, 'moreOrEqual', moreOrEqualVal, false); + } + + moreOrEqualInput.setDisabled(i === 0 || !this.enabledStatus); + moreOrEqualInput.addEventListener('change', () => { + this.on_valueChange(screenSize.id, 'moreOrEqual', moreOrEqualInput.getValue()); + }); + + const fromContainer = new se.Container({class: 'se-input-group se-screen-size-from'}); + fromContainer.appendChild(fromAddon); + fromContainer.appendChild(moreOrEqualInput); + + const toAddon = new se.Addon({ + text: utils.gettext('To (px):'), + title: utils.gettext('The right limit of the screen size range (in pixels). Use -1 for no limit.') + }); + toAddon.setDisabled(i === newValue.length - 1 || !this.enabledStatus); + + const lessOrEqualVal = (i === newValue.length - 1) ? -1 : screenSize.lessOrEqual; + const lessOrEqualInput = new se.NumericField({ + name: 'lessOrEqual', + initialValue: lessOrEqualVal, + min: -1, + inc: 10 + }); + + if (lessOrEqualVal !== screenSize.lessOrEqual) { + this.on_valueChange(screenSize.id, 'lessOrEqual', lessOrEqualVal, false); + } + + lessOrEqualInput.setDisabled(i === newValue.length - 1 || !this.enabledStatus); + lessOrEqualInput.addEventListener('change', () => { + this.on_valueChange(screenSize.id, 'lessOrEqual', lessOrEqualInput.getValue()); + }); + + const toContainer = new se.Container({class: 'se-input-group se-screen-size-to'}); + toContainer.appendChild(toAddon); + toContainer.appendChild(lessOrEqualInput); + + const deleteButton = new se.Button({ + class: 'btn-danger', + iconClass: 'fas fa-trash' + }); + const editScreenSizeButton = new se.Button({ + iconClass: 'fas fa-edit' + }); + + editScreenSizeButton.addEventListener('click', () => { + const err = !(this._checkValue(this.value) === se.InputValidationError.NO_ERROR); + this._callEvent('requestSave', () => { + if (!err) { + Wirecloud.activeWorkspace.view.activeTab.quitEditingInterval(); + Wirecloud.activeWorkspace.view.activeTab.setEditingInterval(screenSize.moreOrEqual, screenSize.lessOrEqual); + } + }); + }); + + deleteButton.setDisabled(newValue.length === 1 || !this.enabledStatus); + deleteButton.addEventListener('click', this.on_deleteScreenSize.bind(this, screenSize.id)); + + const buttonContainer = new se.Container({class: 'se-input-group se-screen-size-buttons'}); + buttonContainer.appendChild(editScreenSizeButton); + buttonContainer.appendChild(deleteButton); + + screenSizeContainer.appendChild(fromContainer); + screenSizeContainer.appendChild(toContainer); + screenSizeContainer.appendChild(buttonContainer); + + this.screenSizesInputs[screenSize.id] = screenSizeContainer; + newContainers.push(screenSizeContainer); + }); + + for (let i = newContainers.length - 1; i >= 0; i--) { + this.wrapperElement.prependChild(newContainers[i]); + } + } + + _setError(error) { + + } + + insertInto(element) { + this.wrapperElement.insertInto(element); + } + + }; + +})(Wirecloud.ui, StyledElements, Wirecloud.Utils); \ No newline at end of file diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js index 6389acce9a..ee36fe8700 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js @@ -106,7 +106,6 @@ const getUpdatedLayoutConfigurations = function getUpdatedLayoutConfigurations(newLayout) { const layoutConfigurations = this.model.layoutConfigurations; - // const updatedLayoutConfigurations = []; const priv = privates.get(this); const tabChange = priv.tab !== newLayout.dragboard.tab; @@ -155,10 +154,7 @@ if (dragboardChange && !(newLayout instanceof Wirecloud.ui.FreeLayout)) { const matrix = Wirecloud.Utils.getLayoutMatrix(newLayout, newLayout.dragboard.widgets, avgScreenSize); - console.log(newLayout); const newposition = newLayout._searchFreeSpace2(newLayoutConfiguration.width, newLayoutConfiguration.height, matrix); - console.log("newposition", newposition); - console.log("matrix", matrix); newposition.relx = true; newposition.rely = true; newposition.anchor = "top-left"; @@ -196,11 +192,7 @@ }); } } - - // updatedLayoutConfigurations.push(newLayoutConfiguration); }); - - // return updatedLayoutConfigurations; }; // ========================================================================= @@ -710,7 +702,6 @@ return this; } - // MARK Adrian Quizá esto sea importante moveToLayout(newLayout) { if (this.layout === newLayout) { return Promise.resolve(); @@ -850,7 +841,8 @@ height: this.model.shape.height }; - this.layout.removeWidget(this, false); + this.layout.removeWidgetEventListeners(this); + this.layout = null; this.setPosition(newPos, false); this.setShape(newShape, false, false, false, false); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index a39584da62..c51cebf74d 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -56,25 +56,15 @@ return widgets; }; - const get_layout_configs = function get_layout_configs(widget) { - const layoutConfigs = []; - - widget.layoutConfigurations.forEach(function (layoutConfig) { - layoutConfigs.push({ - id: layoutConfig.id, - moreOrEqual: layoutConfig.moreOrEqual, - lessOrEqual: layoutConfig.lessOrEqual - }); - }); - - return layoutConfigs; - } - // ========================================================================= // EVENT HANDLERS // ========================================================================= const on_change_preferences = function on_change_preferences(preferences, modifiedValues) { + if ('screenSizes' in modifiedValues) { + this.dragboard._updateScreenSizes(); + } + if ('baselayout' in modifiedValues) { this.dragboard._updateBaseLayout(); } @@ -125,13 +115,9 @@ }; const on_windowresize = function on_windowresize() { - this.dragboard.resetLayouts(); - this.widgets.forEach((widget) => { - widget.updateWindowSize(window.innerWidth); - }); - - this.dragboard.refreshPositionBasedOnZIndex(); - this.dragboard.paint(); + if (this.dragboard.customWidth === -1) { + this.dragboard.updateWidgetScreenSize(window.innerWidth); + } }; ns.WorkspaceTabView = class WorkspaceTabView extends se.Tab { @@ -272,21 +258,7 @@ * resolved, or an Error if rejected. */ createWidget(resource, options) { - let layoutConfigs = [] - if (this.widgets.length > 0) { - // All widgets SHOULD have the same layout configuration sizes. If - // this is not the case something has gonw wrong or manual modifications - // have been made to the layout configurations, but we will use the first - // widget as reference. - layoutConfigs = get_layout_configs(this.widgets[0].model); - } else { - // TODO Adrian this should come from the UI defined sizes, which are not yet available - layoutConfigs.push({ - id: 0, - moreOrEqual: 0, - lessOrEqual: -1 - }); - } + const layoutConfigs = utils.clone(this.model.preferences.get('screenSizes')); options = utils.merge({ commit: true, @@ -371,6 +343,44 @@ ); } + setEditingInterval(moreOrEqual, lessOrEqual) { + let avgScreenSize = Math.floor((moreOrEqual + lessOrEqual) / 2); + if (lessOrEqual === -1) { + avgScreenSize = moreOrEqual; + } + this.dragboard.setCustomDragboardWidth(avgScreenSize); + + const intervalString = "[" + moreOrEqual + ", " + (lessOrEqual === -1 ? "+∞)" : lessOrEqual + "]"); + const text = utils.interpolate(utils.gettext("Currently editing for screen sizes %(interval)s"), {interval: intervalString}); + + const div = document.createElement('div'); + div.className = 'wc-editing-interval'; + const span = document.createElement('span'); + span.textContent = text; + div.appendChild(span); + + const a = document.createElement('a'); + a.className = 'far fa-times-circle wc-editing-interval-close'; + a.href = '#'; + a.addEventListener('click', () => { + this.quitEditingInterval(); + }); + div.appendChild(a); + + this.intervalEditionIndicator = div; + + this.wrapperElement.appendChild(div); + } + + quitEditingInterval() { + this.dragboard.restoreDragboardWidth(); + + if (this.intervalEditionIndicator != null) { + this.intervalEditionIndicator.remove(); + this.intervalEditionIndicator = null; + } + } + /** * Highlights this tab */ diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index 01b14b517e..c6ada260f1 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -57,15 +57,9 @@ // TODO or initialized with the scroll bar's real with? this.dragboardWidth = 800; this.dragboardHeight = 600; + this.customWidth = -1; this.widgetToMove = null; - this.painted = false; - this.fulldragboardLayout = new Wirecloud.ui.FullDragboardLayout(this); - this.baseLayout = this._buildLayoutFromPreferences(); - this.freeLayout = new Wirecloud.ui.FreeLayout(this); - this.leftLayout = new Wirecloud.ui.SidebarLayout(this); - this.rightLayout = new Wirecloud.ui.SidebarLayout(this, {position: "right"}); - this.bottomLayout = new Wirecloud.ui.SidebarLayout(this, {position: "bottom"}); - this.topLayout = new Wirecloud.ui.SidebarLayout(this, {position: "top"}); + this.resetLayouts(); Object.defineProperties(this, { layouts: { get: () => { @@ -229,6 +223,15 @@ this.topLayout = new Wirecloud.ui.SidebarLayout(this, {position: "top"}); } + updateWidgetScreenSize(screenSize) { + this.resetLayouts(); + this.widgets.forEach((widget) => { + widget.updateWindowSize(screenSize); + }); + this.refreshPositionBasedOnZIndex(); + this.paint(); + } + /** * */ @@ -257,8 +260,6 @@ return widget.toJSON('update', allLayoutConfigurations); }); - console.log('Updating widgets:', content); - return Wirecloud.io.makeRequest(url, { method: 'PUT', requestHeaders: {'Accept': 'application/json'}, @@ -294,7 +295,7 @@ } /** - * TODO, used by WorkspaceTabView to when the user changes the preferences + * Used by WorkspaceTabView to when the user changes the preferences * for the base layout. */ _updateBaseLayout() { @@ -308,6 +309,136 @@ oldBaseLayout.moveTo(newBaseLayout); } + /** + * Used by WorkspaceTabView to when the user changes the preferences + * for the screen sizes. + */ + _updateScreenSizes() { + if (this.customWidth !== -1) { + this.tab.quitEditingInterval(); + } + + const updatedScreenSizes = this.tab.model.preferences.get('screenSizes'); + const reqData = []; + + this.resetLayouts(); + this.widgets.forEach((widget) => { + const currentConfigs = widget.model.layoutConfigurations; + + const widgetReqData = { + id: widget.model.id, + layoutConfigurations: [] + }; + + const indexesToDelete = []; + currentConfigs.forEach((config, i) => { + if (updatedScreenSizes.findIndex((screenSize) => screenSize.id === config.id) === -1) { + widgetReqData.layoutConfigurations.push({ + id: config.id, + action: 'delete' + }); + indexesToDelete.push(i); + } + }); + + indexesToDelete.sort((a, b) => b - a); + indexesToDelete.forEach((index) => { + currentConfigs.splice(index, 1); + }); + + const lastExistingScreenSize = currentConfigs[currentConfigs.length - 1]; + updatedScreenSizes.forEach((screenSize) => { + const currentConfig = currentConfigs.find((config) => config.id === screenSize.id); + if (!currentConfig) { + const newConfig = { + id: screenSize.id, + anchor: lastExistingScreenSize.anchor, + width: lastExistingScreenSize.width, + height: lastExistingScreenSize.height, + relwidth: lastExistingScreenSize.relwidth, + relheight: lastExistingScreenSize.relheight, + left: lastExistingScreenSize.left, + top: lastExistingScreenSize.top, + zIndex: lastExistingScreenSize.zIndex, + relx: lastExistingScreenSize.relx, + rely: lastExistingScreenSize.rely, + titlevisible: lastExistingScreenSize.titlevisible, + fulldragboard: lastExistingScreenSize.fulldragboard, + minimized: lastExistingScreenSize.minimized, + moreOrEqual: screenSize.moreOrEqual, + lessOrEqual: screenSize.lessOrEqual + }; + + currentConfigs.push(newConfig); + + const reqNewConfig = utils.clone(newConfig); + reqNewConfig.action = 'update'; + + widgetReqData.layoutConfigurations.push(reqNewConfig); + } else { + let requiresUpdate = false; + const updatedConfig = { + id: screenSize.id, + action: 'update' + }; + + if (currentConfig.moreOrEqual !== screenSize.moreOrEqual) { + updatedConfig.moreOrEqual = currentConfig.moreOrEqual = screenSize.moreOrEqual; + requiresUpdate = true; + } + + if (currentConfig.lessOrEqual !== screenSize.lessOrEqual) { + updatedConfig.lessOrEqual = currentConfig.lessOrEqual = screenSize.lessOrEqual; + requiresUpdate = true; + } + + if (requiresUpdate) { + widgetReqData.layoutConfigurations.push(updatedConfig); + } + } + }); + + // After modifying all the layoutConfigurations, we need to sort them by moreOrEqual and call the updateWindowSize method + // to refresh the current layout + currentConfigs.sort((a, b) => a.moreOrEqual - b.moreOrEqual); + widget.updateWindowSize(window.innerWidth); + + reqData.push(widgetReqData); + }); + this.refreshPositionBasedOnZIndex(); + this.paint(); + + const url = Wirecloud.URLs.IWIDGET_COLLECTION.evaluate({ + workspace_id: this.tab.workspace.model.id, + tab_id: this.tab.model.id + }); + + return Wirecloud.io.makeRequest(url, { + method: 'PUT', + requestHeaders: {'Accept': 'application/json'}, + contentType: 'application/json', + postBody: JSON.stringify(reqData) + }).then((response) => { + if ([204, 401, 403, 404, 500].indexOf(response.status) === -1) { + return Promise.reject(utils.gettext("Unexpected response from server")); + } else if ([401, 403, 404, 500].indexOf(response.status) !== -1) { + return Promise.reject(Wirecloud.GlobalLogManager.parseErrorResponse(response)); + } + + return Promise.resolve(this); + }); + } + + setCustomDragboardWidth(width) { + this.customWidth = width; + this.updateWidgetScreenSize(width); + } + + restoreDragboardWidth() { + this.customWidth = -1; + this.updateWidgetScreenSize(window.innerWidth); + } + _addWidget(widget) { const z = widget.position.z; diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js index 882a675ed4..5a4ed93e68 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js @@ -139,6 +139,9 @@ if (!button.active) { this.walletButton.active = false; this.layout.slideOut(); + this.tabs.forEach((tab) => { + tab.quitEditingInterval(); + }); } this.activeTab.dragboard._updateIWidgetSizes(true, true); }); From bc7e8dc76bdaec656420f8ec8787ab0ab37ec78b Mon Sep 17 00:00:00 2001 From: oxixes Date: Wed, 29 May 2024 12:05:43 +0200 Subject: [PATCH 03/28] Improve UX when editing screen sizes. --- .../js/wirecloud/ui/ScreenSizesInputInterface.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js index 78216adafc..c54de587c6 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js @@ -59,8 +59,6 @@ } }); - screenSizes.sort((a, b) => a.moreOrEqual - b.moreOrEqual); - const newScreenSize = { id: maxId + 1, moreOrEqual: screenSizes[screenSizes.length - 1].lessOrEqual + 1, @@ -84,8 +82,14 @@ on_valueChange(screenSizeId, from, value, update = true) { const screenSizes = utils.clone(this.value); - const screenSize = screenSizes.find((screenSize) => screenSize.id === screenSizeId); - screenSize[from] = value; + const screenSizeIdx = screenSizes.findIndex((screenSize) => screenSize.id === screenSizeId); + screenSizes[screenSizeIdx][from] = value; + + if (from === 'moreOrEqual' && screenSizeIdx > 0) { + screenSizes[screenSizeIdx - 1].lessOrEqual = value - 1; + } else if (from === 'lessOrEqual' && screenSizeIdx < screenSizes.length - 1) { + screenSizes[screenSizeIdx + 1].moreOrEqual = value + 1; + } if (update) { this._update(screenSizes, false); From b073a2b8f7042d7c57a5f2ef0adba6e441114849 Mon Sep 17 00:00:00 2001 From: oxixes Date: Thu, 13 Jun 2024 11:22:26 +0200 Subject: [PATCH 04/28] Progress (xml and json import / export, fix sidebar layout) --- .../static/js/StyledElements/CodeArea.js | 1 + .../commons/utils/template/parsers/json.py | 39 ++++++-- .../commons/utils/template/parsers/xml.py | 95 ++++++++++++++----- .../utils/template/schemas/xml_schema.xsd | 56 +++++++++-- .../commons/utils/template/writers/xml.py | 49 ++++++---- .../static/css/workspace/dragboard.scss | 1 + .../static/js/wirecloud/ui/SidebarLayout.js | 6 +- .../static/js/wirecloud/ui/WidgetView.js | 3 + .../workspace/mashupTemplateGenerator.py | 50 ++++++---- .../workspace/mashupTemplateParser.py | 35 ++++--- 10 files changed, 242 insertions(+), 93 deletions(-) diff --git a/src/wirecloud/commons/static/js/StyledElements/CodeArea.js b/src/wirecloud/commons/static/js/StyledElements/CodeArea.js index 164a133b11..dcc4bae4c0 100644 --- a/src/wirecloud/commons/static/js/StyledElements/CodeArea.js +++ b/src/wirecloud/commons/static/js/StyledElements/CodeArea.js @@ -148,6 +148,7 @@ if (!window.monaco) { // If monaco is not available, use the TextArea class se.CodeArea = se.TextArea; + se.__Testing__CodeArea = CodeAreaClass; // For testing purposes } else { se.CodeArea = CodeAreaClass; } diff --git a/src/wirecloud/commons/utils/template/parsers/json.py b/src/wirecloud/commons/utils/template/parsers/json.py index 0c1fe5af64..c2723d8927 100644 --- a/src/wirecloud/commons/utils/template/parsers/json.py +++ b/src/wirecloud/commons/utils/template/parsers/json.py @@ -242,16 +242,35 @@ def _init(self): self._check_string_fields(('title',), place=tab, required=False) self._check_array_fields(('resources',), place=tab) for widget in tab['resources']: - rendering = widget.get('rendering', {}) - self._check_integer_fields(('layout',), place=rendering, default=0, allow_cast=True) - layout = rendering['layout'] - self._check_boolean_fields(('relwidth',), place=rendering, default=True) - self._check_boolean_fields(('relheight',), place=rendering, default=(layout != 1)) - - position = widget.get('position', {}) - self._check_string_fields(('anchor',), place=position, default="top-left") - self._check_boolean_fields(('relx',), place=position, default=True) - self._check_boolean_fields(('rely',), place=position, default=(layout != 1)) + screenSizes = widget.get('screenSizes', None) + if screenSizes is None: + screenSizes = [ + { + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'id': 0, + 'rendering': widget.get('rendering', {}), + 'position': widget.get('position', {}) + } + ] + + layout = screenSizes[0]['rendering'].get('layout', 0) + widget['layout'] = layout + else: + layout = widget.get('layout', 0) + + for screenSize in screenSizes: + self._check_integer_fields(('moreOrEqual', 'lessOrEqual', 'id'), place=screenSize, required=True) + + rendering = screenSize.get('rendering', {}) + self._check_integer_fields(('layout',), place=rendering, default=0, allow_cast=True) + self._check_boolean_fields(('relwidth',), place=rendering, default=True) + self._check_boolean_fields(('relheight',), place=rendering, default=(layout != 1)) + + position = screenSize.get('position', {}) + self._check_string_fields(('anchor',), place=position, default="top-left") + self._check_boolean_fields(('relx',), place=position, default=True) + self._check_boolean_fields(('rely',), place=position, default=(layout != 1)) for preference in self._info['params']: self._check_string_fields(('name', 'type'), place=preference, required=True) diff --git a/src/wirecloud/commons/utils/template/parsers/xml.py b/src/wirecloud/commons/utils/template/parsers/xml.py index 62d31d1750..e69d674ea2 100644 --- a/src/wirecloud/commons/utils/template/parsers/xml.py +++ b/src/wirecloud/commons/utils/template/parsers/xml.py @@ -75,6 +75,7 @@ TAB_XPATH = 't:tab' RESOURCE_XPATH = 't:resource' POSITION_XPATH = 't:position' +SCREEN_SIZES_XPATH = 't:screensizes' RENDERING_XPATH = 't:rendering' PARAM_XPATH = 't:preferences/t:preference' EMBEDDEDRESOURCE_XPATH = 't:embedded/t:resource' @@ -568,10 +569,21 @@ def _parse_workspace_info(self): } for widget in self._xpath(RESOURCE_XPATH, tab): - position = self.get_xpath(POSITION_XPATH, widget) - rendering = self.get_xpath(RENDERING_XPATH, widget) + position = self.get_xpath(POSITION_XPATH, widget, required=False) + screenSizes = self.get_xpath(SCREEN_SIZES_XPATH, widget, required=False) + rendering = self.get_xpath(RENDERING_XPATH, widget, required=False) + + if (position is None or rendering is None) and screenSizes is None: + raise TemplateParseException(_("Missing position/rendering or screensizes element")) + + if (rendering is None and not widget.get('layout')): + raise TemplateParseException(_("Missing layout in resource or rendering element")) + + if rendering is None: + layout = int(str(widget.get('layout'))) + else: + layout = int(str(rendering.get('layout'))) - layout = int(str(rendering.get('layout'))) widget_info = { 'id': str(widget.get('id')), 'name': str(widget.get('name')), @@ -579,28 +591,67 @@ def _parse_workspace_info(self): 'version': str(widget.get('version')), 'title': str(widget.get('title')), 'readonly': widget.get('readonly', '').lower() == 'true', + 'layout': layout, 'properties': {}, - 'preferences': {}, - 'position': { - 'anchor': str(position.get('anchor', 'top-left')), - 'relx': position.get('relx', 'true').lower() == 'true', - 'rely': position.get('rely', 'true' if layout != 1 else 'false').lower() == 'true', - 'x': str(position.get('x')), - 'y': str(position.get('y')), - 'z': str(position.get('z')), - }, - 'rendering': { - 'fulldragboard': rendering.get('fulldragboard', 'false').lower() == 'true', - 'minimized': rendering.get('minimized', 'false').lower() == 'true', - 'relwidth': rendering.get('relwidth', 'true').lower() == 'true', - 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true', - 'width': str(rendering.get('width')), - 'height': str(rendering.get('height')), - 'layout': layout, - 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true', - }, + 'preferences': {} } + if screenSizes is not None: + widget_info['screenSizes'] = [] + for screenSize in screenSizes: + position = self.get_xpath(POSITION_XPATH, screenSize) + rendering = self.get_xpath(RENDERING_XPATH, screenSize) + screen_size_info = { + 'moreOrEqual': int(screenSize.get('moreOrEqual')), + 'lessOrEqual': int(screenSize.get('lessOrEqual')), + 'id': int(screenSize.get('id')), + 'position': { + 'anchor': str(position.get('anchor', 'top-left')), + 'relx': position.get('relx', 'true').lower() == 'true', + 'rely': position.get('rely', 'true' if layout != 1 else 'false').lower() == 'true', + 'x': int(float(position.get('x'))), + 'y': int(float(position.get('y'))), + 'z': int(float(position.get('z'))), + }, + 'rendering': { + 'fulldragboard': rendering.get('fulldragboard', 'false').lower() == 'true', + 'minimized': rendering.get('minimized', 'false').lower() == 'true', + 'relwidth': rendering.get('relwidth', 'true').lower() == 'true', + 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true', + 'width': int(float(rendering.get('width'))), + 'height': int(float(rendering.get('height'))), + 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true', + } + } + + widget_info['screenSizes'].append(screen_size_info) + else: + widget_info['screenSizes'] = [ + { + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'id': 0, + 'position': { + 'anchor': str(position.get('anchor', 'top-left')), + 'relx': position.get('relx', 'true').lower() == 'true', + 'rely': position.get('rely', 'true' if layout != 1 else 'false').lower() == 'true', + 'x': str(position.get('x')), + 'y': str(position.get('y')), + 'z': str(position.get('z')), + }, + 'rendering': { + 'fulldragboard': rendering.get('fulldragboard', 'false').lower() == 'true', + 'minimized': rendering.get('minimized', 'false').lower() == 'true', + 'relwidth': rendering.get('relwidth', 'true').lower() == 'true', + 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true', + 'width': str(rendering.get('width')), + 'height': str(rendering.get('height')), + 'layout': layout, + 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true', + } + } + ] + for prop in self._xpath(PROPERTIES_XPATH, widget): prop_value = prop.get('value') widget_info['properties'][str(prop.get('name'))] = { diff --git a/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd b/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd index 0d292c03c9..6ea79f0f82 100644 --- a/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd +++ b/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd @@ -51,6 +51,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -762,19 +791,25 @@ - - + - - - - - - - - + + + + + + + + + + + + + + + @@ -792,6 +827,7 @@ + diff --git a/src/wirecloud/commons/utils/template/writers/xml.py b/src/wirecloud/commons/utils/template/writers/xml.py index 241a2b26ae..d49c878dc8 100644 --- a/src/wirecloud/commons/utils/template/writers/xml.py +++ b/src/wirecloud/commons/utils/template/writers/xml.py @@ -78,7 +78,7 @@ def addPreferenceValues(resource, preferences): addAttribute(pref, element, 'value', type='string', default=None, required=False) addAttributes(pref, element, ('readonly', 'hidden'), default='false', type='boolean') - +# TODO Adrian handle multiple screen sizes def write_mashup_tree(doc, resources, options): # Params @@ -122,24 +122,35 @@ def write_mashup_tree(doc, resources, options): if iwidget.get('readonly', False): resource.set('readonly', 'true') - layout = iwidget['rendering']['layout'] - - position = etree.SubElement( - resource, - 'position', - anchor=str(iwidget['position']['anchor']), - x=str(iwidget['position']['x']), - y=str(iwidget['position']['y']), - z=str(iwidget['position']['z']) - ) - addAttributes(iwidget['position'], position, ('relx',), default='true', type='boolean') - addAttributes(iwidget['position'], position, ('rely',), default=('true' if layout != 1 else 'false'), type='boolean') - - rendering = etree.SubElement(resource, 'rendering') - addAttributes(iwidget['rendering'], rendering, ('height', 'width', 'layout'), required=True) - addAttributes(iwidget['rendering'], rendering, ('minimized', 'fulldragboard'), default='false', type='boolean') - addAttributes(iwidget['rendering'], rendering, ('relwidth', 'titlevisible'), default='true', type='boolean') - addAttributes(iwidget['rendering'], rendering, ('relheight',), default=('true' if layout != 1 else 'false'), type='boolean') + layout = iwidget['layout'] + + addAttributes(iwidget, resource, ('layout',), required=True) + + screenSizesElem = etree.SubElement(resource, 'screensizes') + for screenSize in iwidget.get('screenSizes', []): + screenSizeElem = etree.SubElement(screenSizesElem, + 'screensize', + moreOrEqual=str(screenSize['moreOrEqual']), + lessOrEqual=str(screenSize['lessOrEqual']), + id=str(screenSize['id'])) + + position = etree.SubElement( + screenSizeElem, + 'position', + anchor=str(screenSize['position']['anchor']), + x=str(int(float(screenSize['position']['x']))), + y=str(int(float(screenSize['position']['y']))), + z=str(int(float(screenSize['position']['z']))) + ) + addAttributes(screenSize['position'], position, ('relx',), default='true', type='boolean') + addAttributes(screenSize['position'], position, ('rely',), default=('true' if layout != 1 else 'false'), type='boolean') + + rendering = etree.SubElement(screenSizeElem, 'rendering', + height=str(int(float(screenSize['rendering']['height']))), + width=str(int(float(screenSize['rendering']['width'])))), + addAttributes(screenSize['rendering'], rendering, ('minimized', 'fulldragboard'), default='false', type='boolean') + addAttributes(screenSize['rendering'], rendering, ('relwidth', 'titlevisible'), default='true', type='boolean') + addAttributes(screenSize['rendering'], rendering, ('relheight',), default=('true' if layout != 1 else 'false'), type='boolean') addPreferenceValues(resource, iwidget['preferences']) diff --git a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss index 71a3d3c4d3..264c2c126a 100644 --- a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss +++ b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss @@ -123,6 +123,7 @@ padding: 10px; border-radius: 7px; right: 50px; + top: 39px; } .wc-editing-interval-close { diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js index f852c7ef79..118b25b58e 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js @@ -136,6 +136,10 @@ return result; } + removeHandle() { + this.handle.remove(); + } + removeWidget(widget, affectsDragboard) { const result = super.removeWidget(widget, affectsDragboard); @@ -205,7 +209,7 @@ } else { offset = 0; } - element.style.left = this.getColumnOffset(widget.position, true); + element.style.left = this.getColumnOffset(widget.position, null, true); element.style.right = ""; if (this.position === "top") { element.style.top = offset + "px"; diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js index ee36fe8700..7f15b8ae11 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js @@ -842,6 +842,9 @@ }; this.layout.removeWidgetEventListeners(this); + if ('removeHandle' in this.layout) { + this.layout.removeHandle(); + } this.layout = null; this.setPosition(newPos, false); diff --git a/src/wirecloud/platform/workspace/mashupTemplateGenerator.py b/src/wirecloud/platform/workspace/mashupTemplateGenerator.py index 224584ecd4..cd1380bc22 100644 --- a/src/wirecloud/platform/workspace/mashupTemplateGenerator.py +++ b/src/wirecloud/platform/workspace/mashupTemplateGenerator.py @@ -41,6 +41,7 @@ def get_workspace_description(workspace): return get_iwidgets_description(included_iwidgets) +# TODO Adrian handle multiple screen sizes def process_iwidget(workspace, iwidget, wiring, parametrization, readOnlyWidgets, cache_manager): widget = iwidget.widget @@ -136,35 +137,46 @@ def process_iwidget(workspace, iwidget, wiring, parametrization, readOnlyWidgets 'value': value, } - return { + screenSizes = [] + for configuration in iwidget.positions['configurations']: + screenSizes.append({ + 'moreOrEqual': configuration['moreOrEqual'], + 'lessOrEqual': configuration['lessOrEqual'], + 'id': configuration['id'], + 'position': { + 'anchor': configuration['widget'].get('anchor', 'top-left'), + 'relx': configuration['widget'].get('relx', True), + 'rely': configuration['widget'].get('rely', True if iwidget.layout != 1 else False), + 'x': str(configuration['widget']['left']), + 'y': str(configuration['widget']['top']), + 'z': str(configuration['widget']['zIndex']) + }, + 'rendering': { + 'relwidth': configuration['widget'].get('relwidth', True), + 'relheight': configuration['widget'].get('relheight', True if iwidget.layout != 1 else False), + 'width': str(configuration['widget']['width']), + 'height': str(configuration['widget']['height']), + 'fulldragboard': bool(configuration['widget']['fulldragboard']), + 'minimized': bool(configuration['widget']['minimized']), + 'titlevisible': bool(configuration['widget'].get('titlevisible', True)), + }, + }) + + iwidget_data = { 'id': iwidget_id, 'vendor': iwidget.widget.resource.vendor, 'name': iwidget.widget.resource.short_name, 'version': iwidget.widget.resource.version, 'title': iwidget.name, + 'layout': iwidget.layout, 'readonly': readOnlyWidgets, 'properties': properties, 'preferences': preferences, - 'position': { - 'anchor': iwidget.positions['widget'].get('anchor', 'top-left'), - 'relx': iwidget.positions['widget'].get('relx', True), - 'rely': iwidget.positions['widget'].get('rely', True if iwidget.layout != 1 else False), - 'x': str(iwidget.positions['widget']['left']), - 'y': str(iwidget.positions['widget']['top']), - 'z': str(iwidget.positions['widget']['zIndex']), - }, - 'rendering': { - 'relwidth': iwidget.positions['widget'].get('relwidth', True), - 'relheight': iwidget.positions['widget'].get('relheight', True if iwidget.layout != 1 else False), - 'width': str(iwidget.positions['widget']['width']), - 'height': str(iwidget.positions['widget']['height']), - 'layout': iwidget.layout, - 'fulldragboard': bool(iwidget.positions['widget']['fulldragboard']), - 'minimized': bool(iwidget.positions['widget']['minimized']), - 'titlevisible': bool(iwidget.positions['widget'].get('titlevisible', True)), - }, + 'screenSizes': screenSizes } + return iwidget_data + def build_json_template_from_workspace(options, workspace, user): options['type'] = 'mashup' diff --git a/src/wirecloud/platform/workspace/mashupTemplateParser.py b/src/wirecloud/platform/workspace/mashupTemplateParser.py index d280035de4..034d95de4a 100644 --- a/src/wirecloud/platform/workspace/mashupTemplateParser.py +++ b/src/wirecloud/platform/workspace/mashupTemplateParser.py @@ -225,27 +225,38 @@ def fillWorkspaceUsingTemplate(workspace, template): for resource in tab_entry['resources']: - position = resource['position'] - rendering = resource['rendering'] - widget = get_or_add_widget_from_catalogue(resource.get('vendor'), resource.get('name'), resource.get('version'), user) iwidget_data = { "widget": widget.uri, "title": resource.get('title'), - "left": float(position.get('x')), - "top": float(position.get('y')), "icon_left": 0, "icon_top": 0, - "zIndex": int(position.get('z')), - "width": float(rendering.get('width')), - "height": float(rendering.get('height')), - "layout": int(rendering.get('layout')), - "minimized": rendering['minimized'], - "fulldragboard": rendering['fulldragboard'], - "titlevisible": rendering['titlevisible'], + "layout": int(resource.get('layout')), + "layoutConfigurations": [] } + for configuration in resource["screenSizes"]: + position = configuration['position'] + rendering = configuration['rendering'] + + iwidget_layoutConfig = { + 'moreOrEqual': configuration['moreOrEqual'], + 'lessOrEqual': configuration['lessOrEqual'], + 'id': configuration['id'], + "left": float(position.get('x')), + "top": float(position.get('y')), + "zIndex": int(position.get('z')), + "width": float(rendering.get('width')), + "height": float(rendering.get('height')), + "minimized": rendering['minimized'], + "fulldragboard": rendering['fulldragboard'], + "titlevisible": rendering['titlevisible'], + 'action': 'update' + } + + iwidget_data['layoutConfigurations'].append(iwidget_layoutConfig) + iwidget = SaveIWidget(iwidget_data, user, tab, commit=False) if resource.get('readonly'): iwidget.readOnly = True From 3ae1941af291d2b90ef57f8ea92e2e3bd63d69d4 Mon Sep 17 00:00:00 2001 From: oxixes Date: Mon, 17 Jun 2024 12:47:32 +0200 Subject: [PATCH 05/28] Fix sidebars resetting their active state on window resize --- src/wirecloud/commons/middleware.py | 2 ++ .../platform/static/js/wirecloud/ui/SidebarLayout.js | 11 ++++++++--- .../js/wirecloud/ui/WorkspaceTabViewDragboard.js | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/wirecloud/commons/middleware.py b/src/wirecloud/commons/middleware.py index 5103b8c30e..5daffbe695 100644 --- a/src/wirecloud/commons/middleware.py +++ b/src/wirecloud/commons/middleware.py @@ -157,6 +157,8 @@ class LocaleMiddleware(MiddlewareMixin): def process_request(self, request): if 'lang' in request.GET and translation.check_for_language(request.GET['lang']): language = request.GET['lang'] + elif 'lang' in request.COOKIES and translation.check_for_language(request.COOKIES['lang']): + language = request.COOKIES['lang'] else: language = translation.get_language_from_request(request, check_path=False) translation.activate(language) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js index 118b25b58e..3e1284bb3c 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js @@ -79,7 +79,8 @@ constructor(dragboard, options) { options = utils.merge({ - position: "left" + position: "left", + active: false }, options); if (POSITIONS.indexOf(options.position) === -1) { @@ -97,7 +98,7 @@ ); privates.set(this, { - active: false + active: options.active }); Object.defineProperties(this, { @@ -115,7 +116,7 @@ this.handle = document.createElement("div"); this.handleicon = document.createElement("i"); - this.handleicon.className = "fas fa-caret-" + OPPOSITE[this.position]; + this.handleicon.className = "fas fa-caret-" + (this.active ? ICON[this.position] : OPPOSITE[this.position]); this.handle.appendChild(this.handleicon); this.handle.addEventListener("click", () => { this.active = !this.active; @@ -245,6 +246,10 @@ } } + isActive() { + return this.active; + } + } })(Wirecloud.ui, Wirecloud.Utils); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index c6ada260f1..65a1f7f6d2 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -217,10 +217,10 @@ this.fulldragboardLayout = new Wirecloud.ui.FullDragboardLayout(this); this.baseLayout = this._buildLayoutFromPreferences(); this.freeLayout = new Wirecloud.ui.FreeLayout(this); - this.leftLayout = new Wirecloud.ui.SidebarLayout(this); - this.rightLayout = new Wirecloud.ui.SidebarLayout(this, {position: "right"}); - this.bottomLayout = new Wirecloud.ui.SidebarLayout(this, {position: "bottom"}); - this.topLayout = new Wirecloud.ui.SidebarLayout(this, {position: "top"}); + this.leftLayout = new Wirecloud.ui.SidebarLayout(this, {active: (this.leftLayout) ? this.leftLayout.isActive() : false}); + this.rightLayout = new Wirecloud.ui.SidebarLayout(this, {position: "right", active: (this.rightLayout) ? this.rightLayout.isActive() : false}); + this.bottomLayout = new Wirecloud.ui.SidebarLayout(this, {position: "bottom", active: (this.bottomLayout) ? this.bottomLayout.isActive() : false}); + this.topLayout = new Wirecloud.ui.SidebarLayout(this, {position: "top", active: (this.topLayout) ? this.topLayout.isActive() : false}); } updateWidgetScreenSize(screenSize) { From 3830b439130870fc2e33399b90767919f198b6e6 Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 18 Jun 2024 11:19:21 +0200 Subject: [PATCH 06/28] Add RDF parsing and writing of screen sizes --- .../commons/utils/template/parsers/rdf.py | 79 ++++++++++++++----- .../commons/utils/template/schemas/wire-m.rdf | 37 ++++++++- .../commons/utils/template/writers/rdf.py | 53 +++++++------ 3 files changed, 125 insertions(+), 44 deletions(-) diff --git a/src/wirecloud/commons/utils/template/parsers/rdf.py b/src/wirecloud/commons/utils/template/parsers/rdf.py index 72ff10f91c..ecb068a762 100644 --- a/src/wirecloud/commons/utils/template/parsers/rdf.py +++ b/src/wirecloud/commons/utils/template/parsers/rdf.py @@ -715,8 +715,12 @@ def _parse_workspace_info(self): for widget in self._graph.objects(tab, WIRE_M['hasiWidget']): position = self._get_field(WIRE_M, 'hasPosition', widget, id_=True, required=False) rendering = self._get_field(WIRE_M, 'hasiWidgetRendering', widget, id_=True, required=False) + screenSizes = self._graph.objects(widget, WIRE_M['hasScreenSize']) vendor = self._get_field(USDL, 'hasProvider', widget, id_=True, required=True) - layout = int(self._get_field(WIRE_M, 'layout', rendering, default='0')) + if len(screenSizes) > 0: + layout = int(self._get_field(WIRE_M, 'layout', widget, required=False, default='0')) + else: + layout = int(self._get_field(WIRE_M, 'layout', rendering, default='0')) widget_info = { 'id': self._get_field(WIRE_M, 'iWidgetId', widget), @@ -725,28 +729,63 @@ def _parse_workspace_info(self): 'version': self._get_field(USDL, 'versionInfo', widget), 'title': self._get_field(DCTERMS, 'title', widget), 'readonly': self._get_field(WIRE_M, 'readonly', widget, required=False).lower() == 'true', + 'layout': layout, 'properties': {}, - 'preferences': {}, - 'position': { - 'anchor': self._get_field(WIRE_M, 'anchor', position, required=False, default="top-left"), - 'relx': self._get_field(WIRE_M, 'relx', position, required=False, default='true').lower() == 'true', - 'rely': self._get_field(WIRE_M, 'rely', position, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', - 'x': self._get_field(WIRE_M, 'x', position), - 'y': self._get_field(WIRE_M, 'y', position), - 'z': self._get_field(WIRE_M, 'z', position), - }, - 'rendering': { - 'relwidth': self._get_field(WIRE_M, 'relwidth', rendering, required=False, default='True').lower() == 'true', - 'relheight': self._get_field(WIRE_M, 'relheight', rendering, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', - 'width': self._get_field(WIRE, 'renderingWidth', rendering), - 'height': self._get_field(WIRE, 'renderingHeight', rendering), - 'layout': layout, - 'fulldragboard': self._get_field(WIRE_M, 'fullDragboard', rendering, required=False).lower() == 'true', - 'minimized': self._get_field(WIRE_M, 'minimized', rendering, required=False).lower() == 'true', - 'titlevisible': self._get_field(WIRE_M, 'titlevisible', rendering, default="true", required=False).lower() == 'true', - }, + 'preferences': {} } + widget_info['screenSizes'] = [] + if len(screenSizes) > 0: + for screenSize in screenSizes: + position = self._get_field(WIRE_M, 'hasPosition', screenSize, id_=True, required=False) + rendering = self._get_field(WIRE_M, 'hasiWidgetRendering', screenSize, id_=True, required=False) + screen_size_info = { + 'moreOrEqual': int(self._get_field(WIRE_M, 'moreOrEqual', screenSize)), + 'lessOrEqual': int(self._get_field(WIRE_M, 'lessOrEqual', screenSize)), + 'id': int(self._get_field(WIRE_M, 'screenSizeId', screenSize)), + 'position': { + 'anchor': self._get_field(WIRE_M, 'anchor', position, required=False, default="top-left"), + 'relx': self._get_field(WIRE_M, 'relx', position, required=False, default='true').lower() == 'true', + 'rely': self._get_field(WIRE_M, 'rely', position, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', + 'x': int(float(self._get_field(WIRE_M, 'x', position))), + 'y': int(float(self._get_field(WIRE_M, 'y', position))), + 'z': int(float(self._get_field(WIRE_M, 'z', position))), + }, + 'rendering': { + 'fulldragboard': self._get_field(WIRE_M, 'fullDragboard', rendering, required=False).lower() == 'true', + 'minimized': self._get_field(WIRE_M, 'minimized', rendering, required=False).lower() == 'true', + 'relwidth': self._get_field(WIRE_M, 'relwidth', rendering, required=False).lower() == 'true', + 'relheight': self._get_field(WIRE_M, 'relheight', rendering, required=False).lower() == 'true', + 'width': int(float(self._get_field(WIRE, 'renderingWidth', rendering))), + 'height': int(float(self._get_field(WIRE, 'renderingHeight', rendering))), + 'titlevisible': self._get_field(WIRE_M, 'titlevisible', rendering, default="true", required=False).lower() == 'true', + } + } + widget_info['screenSizes'].append(screen_size_info) + else: + screen_size_info = { + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'id': 0, + 'position': { + 'anchor': self._get_field(WIRE_M, 'anchor', position, required=False, default="top-left"), + 'relx': self._get_field(WIRE_M, 'relx', position, required=False, default='true').lower() == 'true', + 'rely': self._get_field(WIRE_M, 'rely', position, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', + 'x': int(float(self._get_field(WIRE_M, 'x', position))), + 'y': int(float(self._get_field(WIRE_M, 'y', position))), + 'z': int(float(self._get_field(WIRE_M, 'z', position))), + }, + 'rendering': { + 'fulldragboard': self._get_field(WIRE_M, 'fullDragboard', rendering, required=False).lower() == 'true', + 'minimized': self._get_field(WIRE_M, 'minimized', rendering, required=False).lower() == 'true', + 'relwidth': self._get_field(WIRE_M, 'relwidth', rendering, required=False).lower() == 'true', + 'relheight': self._get_field(WIRE_M, 'relheight', rendering, required=False).lower() == 'true', + 'width': int(float(self._get_field(WIRE, 'renderingWidth', rendering))), + 'height': int(float(self._get_field(WIRE, 'renderingHeight', rendering))), + 'titlevisible': self._get_field(WIRE_M, 'titlevisible', rendering, default="true", required=False).lower() == 'true', + } + } + for prop in self._graph.objects(widget, WIRE_M['hasiWidgetProperty']): widget_info['properties'][self._get_field(DCTERMS, 'title', prop)] = { 'readonly': self._get_field(WIRE_M, 'readonly', prop, required=False).lower() == 'true', diff --git a/src/wirecloud/commons/utils/template/schemas/wire-m.rdf b/src/wirecloud/commons/utils/template/schemas/wire-m.rdf index 32996529dd..2aa03579a8 100644 --- a/src/wirecloud/commons/utils/template/schemas/wire-m.rdf +++ b/src/wirecloud/commons/utils/template/schemas/wire-m.rdf @@ -1,6 +1,6 @@ -iWidget porperty properties of a wirecloud iWidget + + + + Screen Size Layout Configuration + Gives information about the position and rendering of an iWidget in a specific screen size. + @@ -208,6 +214,13 @@ + + + has screen size + an iWidget has a position and rendering in a specific screen size + + + has position @@ -267,6 +280,28 @@ + + + more or equal + a screen size start size + + + + + + less or equal + a screen size end size + + + + + + screen size id + a screen size id + + + + readonly diff --git a/src/wirecloud/commons/utils/template/writers/rdf.py b/src/wirecloud/commons/utils/template/writers/rdf.py index cd3a933d9f..512017861b 100644 --- a/src/wirecloud/commons/utils/template/writers/rdf.py +++ b/src/wirecloud/commons/utils/template/writers/rdf.py @@ -233,29 +233,36 @@ def write_mashup_resources_graph(graph, resource_uri, template_info): if iwidget.get('readonly', False): graph.add((resource, WIRE_M['readonly'], rdflib.Literal('true'))) - # iWidget position - pos = rdflib.BNode() - graph.add((pos, rdflib.RDF.type, WIRE_M['Position'])) - graph.add((resource, WIRE_M['hasPosition'], pos)) - graph.add((pos, WIRE_M['anchor'], rdflib.Literal(iwidget['position']['anchor']))) - graph.add((pos, WIRE_M['relx'], rdflib.Literal(str(iwidget['position']['relx'])))) - graph.add((pos, WIRE_M['rely'], rdflib.Literal(str(iwidget['position']['rely'])))) - graph.add((pos, WIRE_M['x'], rdflib.Literal(iwidget['position']['x']))) - graph.add((pos, WIRE_M['y'], rdflib.Literal(iwidget['position']['y']))) - graph.add((pos, WIRE_M['z'], rdflib.Literal(iwidget['position']['z']))) - - # iWidget rendering - rend = rdflib.BNode() - graph.add((rend, rdflib.RDF.type, WIRE_M['iWidgetRendering'])) - graph.add((resource, WIRE_M['hasiWidgetRendering'], rend)) - graph.add((rend, WIRE_M['relwidth'], rdflib.Literal(str(iwidget['rendering']['relwidth'])))) - graph.add((rend, WIRE_M['relheight'], rdflib.Literal(str(iwidget['rendering']['relheight'])))) - graph.add((rend, WIRE['renderingWidth'], rdflib.Literal(str(iwidget['rendering']['width'])))) - graph.add((rend, WIRE['renderingHeight'], rdflib.Literal(str(iwidget['rendering']['height'])))) - graph.add((rend, WIRE_M['layout'], rdflib.Literal(str(iwidget['rendering']['layout'])))) - graph.add((rend, WIRE_M['fullDragboard'], rdflib.Literal(str(iwidget['rendering']['fulldragboard'])))) - graph.add((rend, WIRE_M['minimized'], rdflib.Literal(str(iwidget['rendering']['minimized'])))) - graph.add((rend, WIRE_M['titlevisible'], rdflib.Literal(str(iwidget['rendering']['titlevisible'])))) + graph.add((resource, WIRE_M['layout'], rdflib.Literal(str(iwidget['layout'])))) + + for screenSize in iwidget.get('screenSizes', []): + screenSizeNode = rdflib.BNode() + graph.add((screenSizeNode, rdflib.RDF.type, WIRE_M['ScreenSize'])) + graph.add((resource, WIRE_M['hasScreenSize'], screenSizeNode)) + graph.add((screenSizeNode, WIRE_M['moreOrEqual'], rdflib.Literal(str(screenSize['moreOrEqual'])))) + graph.add((screenSizeNode, WIRE_M['lessOrEqual'], rdflib.Literal(str(screenSize['lessOrEqual'])))) + graph.add((screenSizeNode, WIRE_M['screenSizeId'], rdflib.Literal(str(screenSize['id'])))) + + pos = rdflib.BNode() + graph.add((pos, rdflib.RDF.type, WIRE_M['Position'])) + graph.add((screenSizeNode, WIRE_M['hasPosition'], pos)) + graph.add((pos, WIRE_M['anchor'], rdflib.Literal(screenSize['position']['anchor']))) + graph.add((pos, WIRE_M['relx'], rdflib.Literal(str(screenSize['position']['relx'])))) + graph.add((pos, WIRE_M['rely'], rdflib.Literal(str(screenSize['position']['rely'])))) + graph.add((pos, WIRE_M['x'], rdflib.Literal(str(int(float(screenSize['position']['x'])))))) + graph.add((pos, WIRE_M['y'], rdflib.Literal(str(int(float(screenSize['position']['y'])))))) + graph.add((pos, WIRE_M['z'], rdflib.Literal(str(int(float(screenSize['position']['z'])))))) + + rend = rdflib.BNode() + graph.add((rend, rdflib.RDF.type, WIRE_M['iWidgetRendering'])) + graph.add((screenSizeNode, WIRE_M['hasiWidgetRendering'], rend)) + graph.add((rend, WIRE_M['relwidth'], rdflib.Literal(str(screenSize['rendering']['relwidth'])))) + graph.add((rend, WIRE_M['relheight'], rdflib.Literal(str(screenSize['rendering']['relheight'])))) + graph.add((rend, WIRE['renderingWidth'], rdflib.Literal(str(int(float(screenSize['rendering']['width'])))))) + graph.add((rend, WIRE['renderingHeight'], rdflib.Literal(str(int(float(screenSize['rendering']['height'])))))) + graph.add((rend, WIRE_M['fullDragboard'], rdflib.Literal(str(screenSize['rendering']['fulldragboard'])))) + graph.add((rend, WIRE_M['minimized'], rdflib.Literal(str(screenSize['rendering']['minimized'])))) + graph.add((rend, WIRE_M['titlevisible'], rdflib.Literal(str(screenSize['rendering']['titlevisible'])))) # iWidget preferences for pref_name, pref in iwidget.get('preferences', {}).items(): From 8546910128296d6c6375f787737b5c31febe8648 Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 18 Jun 2024 12:25:35 +0200 Subject: [PATCH 07/28] Use database migrations for screen sizes --- ...020_change_json_format_for_screen_sizes.py | 31 +++++++++++++++++++ src/wirecloud/platform/workspace/utils.py | 14 +-------- 2 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 src/wirecloud/platform/migrations/0020_change_json_format_for_screen_sizes.py diff --git a/src/wirecloud/platform/migrations/0020_change_json_format_for_screen_sizes.py b/src/wirecloud/platform/migrations/0020_change_json_format_for_screen_sizes.py new file mode 100644 index 0000000000..e73f32819b --- /dev/null +++ b/src/wirecloud/platform/migrations/0020_change_json_format_for_screen_sizes.py @@ -0,0 +1,31 @@ +# Generated by Django 2.2.28 on 2024-06-18 12:04 + +from django.db import migrations + +def change_json_format_for_screen_sizes(apps, schema_editor): + # Changes all iwidget.position fields to use the new JSON format + + IWidget = apps.get_model('platform', 'IWidget') + for iwidget in IWidget.objects.all(): + if not 'configurations' in iwidget.positions and 'widget' in iwidget.positions: + iwidget.positions = { + "configurations": [ + { + "id": 0, + "moreOrEqual": 0, + "lessOrEqual": -1, + "widget": iwidget.positions["widget"] + } + ] + } + iwidget.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('platform', '0019_auto_20201130_1824'), + ] + + operations = [ + migrations.RunPython(change_json_format_for_screen_sizes), + ] diff --git a/src/wirecloud/platform/workspace/utils.py b/src/wirecloud/platform/workspace/utils.py index 24a72283f3..0758fb5788 100644 --- a/src/wirecloud/platform/workspace/utils.py +++ b/src/wirecloud/platform/workspace/utils.py @@ -532,20 +532,8 @@ def get_iwidget_data(iwidget, workspace, cache_manager=None, user=None): 'properties': {} } - # Fix old iwidget format if not 'configurations' in iwidget.positions: - iwidget.positions['configurations'] = [ - { - 'moreOrEqual': 0, - 'lessOrEqual': -1, - 'id': 0, - 'widget': iwidget.positions.get('widget') - } - ] - - del iwidget.positions['widget'] - - iwidget.save() + raise ValueError(_('Invalid iwidget format stored in the database. Please, update the iwidget positions field.')) for layoutConfiguration in iwidget.positions.get('configurations'): widget_position = layoutConfiguration.get('widget', {}) From b07899e73517fbc6ffc9489f1705393c9cbdbb6b Mon Sep 17 00:00:00 2001 From: oxixes Date: Fri, 21 Jun 2024 12:17:28 +0200 Subject: [PATCH 08/28] Fix noselenium tests --- .../fixtures/user_with_workspaces.json | 22 +- src/wirecloud/commons/tests/middleware.py | 2 +- src/wirecloud/commons/tests/template.py | 249 ++++++++++-------- .../mashup_with_behaviours_data.json | 82 +++--- .../mashup_with_behaviours_minimal_data.json | 66 +++-- ...p_with_behaviours_minimal_data_result.json | 82 +++--- .../commons/utils/template/parsers/json.py | 9 +- .../commons/utils/template/parsers/rdf.py | 41 +-- .../commons/utils/template/parsers/xml.py | 11 +- .../commons/utils/template/writers/rdf.py | 10 +- .../commons/utils/template/writers/xml.py | 2 +- .../fixtures/extra_wiring_test_data.json | 2 +- .../platform/fixtures/test_data.json | 8 +- src/wirecloud/platform/tests/rest_api.py | 24 +- src/wirecloud/platform/workspace/tests.py | 28 +- 15 files changed, 358 insertions(+), 280 deletions(-) diff --git a/src/wirecloud/commons/fixtures/user_with_workspaces.json b/src/wirecloud/commons/fixtures/user_with_workspaces.json index b9e505f106..c96fa89e68 100644 --- a/src/wirecloud/commons/fixtures/user_with_workspaces.json +++ b/src/wirecloud/commons/fixtures/user_with_workspaces.json @@ -9,7 +9,7 @@ "name": "Test 1", "tab": 101, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -23,7 +23,7 @@ "name": "Test 2", "tab": 101, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } @@ -38,7 +38,7 @@ "name": "Test 1", "tab": 102, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -52,7 +52,7 @@ "name": "Test 2", "tab": 103, "readOnly": true, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -66,7 +66,7 @@ "name": "Test 1", "tab": 104, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -80,7 +80,7 @@ "name": "Test 2", "tab": 104, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -94,7 +94,7 @@ "name": "Test (1)", "tab": 105, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":2,\"left\":12,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":2,\"left\":12,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -108,7 +108,7 @@ "name": "Test (2)", "tab": 105, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -122,7 +122,7 @@ "name": "Test (3)", "tab": 105, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -136,7 +136,7 @@ "name": "Test 1", "tab": 106, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, @@ -150,7 +150,7 @@ "name": "Test 2", "tab": 106, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"list\": {\"users\": {\"4\": \"default\"}}, \"text\": {\"users\": {\"4\": \"initial text\"}}, \"boolean\": {\"users\": {\"4\": false}}, \"password\": {\"users\": {\"4\": \"default\"}}, \"number\": {\"users\": {\"4\": 2}}}" } }, diff --git a/src/wirecloud/commons/tests/middleware.py b/src/wirecloud/commons/tests/middleware.py index 073f9c5684..109b75e4e3 100644 --- a/src/wirecloud/commons/tests/middleware.py +++ b/src/wirecloud/commons/tests/middleware.py @@ -41,7 +41,7 @@ def setUpClass(cls): @patch('wirecloud.commons.middleware.translation') def test_process_request(self, translation): - request = Mock(GET={}) + request = Mock(GET={}, COOKIES={}) self.middleware.process_request(request) translation.activate.assert_called_once_with(translation.get_language_from_request()) diff --git a/src/wirecloud/commons/tests/template.py b/src/wirecloud/commons/tests/template.py index 1510ecb737..fa63509e0c 100644 --- a/src/wirecloud/commons/tests/template.py +++ b/src/wirecloud/commons/tests/template.py @@ -590,6 +590,7 @@ def setUpClass(cls): 'version': '1.0', 'title': 'Widget title', 'readonly': False, + 'layout': 0, 'properties': { 'prop1': {'value': 'value1', 'readonly': False}, 'prop2': {'value': 'value 2', 'readonly': True} @@ -600,24 +601,28 @@ def setUpClass(cls): 'password': {'value': None, 'readonly': True, 'hidden': True}, 'boolean': {'value': None, 'readonly': True, 'hidden': False} }, - 'position': { - 'anchor': 'top-left', - 'relx': True, - 'rely': True, - 'x': '0', - 'y': '1', - 'z': '2', - }, - 'rendering': { - 'relwidth': True, - 'relheight': True, - 'width': '10', - 'height': '10', - 'layout': 0, - 'fulldragboard': False, - 'minimized': False, - 'titlevisible': True - } + 'screenSizes': [{ + 'id': 0, + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'position': { + 'anchor': 'top-left', + 'relx': True, + 'rely': True, + 'x': '0', + 'y': '1', + 'z': '2', + }, + 'rendering': { + 'relwidth': True, + 'relheight': True, + 'width': '10', + 'height': '10', + 'fulldragboard': False, + 'minimized': False, + 'titlevisible': True + } + }] }, { 'id': '2', @@ -626,6 +631,7 @@ def setUpClass(cls): 'version': '2.0', 'readonly': True, 'title': 'Widget title', + 'layout': 0, 'properties': { 'prop1': {'value': 'value1', 'readonly': False}, 'prop2': {'value': None, 'readonly': True} @@ -633,24 +639,28 @@ def setUpClass(cls): 'preferences': { 'text': {'value': 'other value', 'readonly': True, 'hidden': True} }, - 'position': { - 'anchor': 'bottom-left', - 'relx': False, - 'rely': False, - 'x': '10', - 'y': '1', - 'z': '2', - }, - 'rendering': { - 'relwidth': False, - 'relheight': False, - 'width': '10', - 'height': '10', - 'layout': 0, - 'fulldragboard': True, - 'minimized': True, - 'titlevisible': True - } + 'screenSizes': [{ + 'id': 0, + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'position': { + 'anchor': 'bottom-left', + 'relx': False, + 'rely': False, + 'x': '10', + 'y': '1', + 'z': '2', + }, + 'rendering': { + 'relwidth': False, + 'relheight': False, + 'width': '10', + 'height': '10', + 'fulldragboard': True, + 'minimized': True, + 'titlevisible': True + } + }] } ] }, @@ -809,6 +819,7 @@ def setUpClass(cls): 'version': '1.0', 'title': 'Widget title', 'readonly': False, + 'layout': 0, 'properties': { 'prop1': {'value': 'value1', 'readonly': False}, 'prop2': {'value': 'value 2', 'readonly': True} @@ -817,24 +828,28 @@ def setUpClass(cls): 'list': {'value': 'default', 'readonly': True, 'hidden': False}, 'text': {'value': 'other value', 'readonly': True, 'hidden': True} }, - 'position': { - 'anchor': 'top-left', - 'relx': True, - 'rely': True, - 'x': '0', - 'y': '1', - 'z': '2', - }, - 'rendering': { - 'relwidth': True, - 'relheight': True, - 'width': '10', - 'height': '10', - 'layout': 0, - 'fulldragboard': False, - 'minimized': False, - 'titlevisible': False - } + 'screenSizes': [{ + 'id': 0, + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'position': { + 'anchor': 'top-left', + 'relx': True, + 'rely': True, + 'x': '0', + 'y': '1', + 'z': '2', + }, + 'rendering': { + 'relwidth': True, + 'relheight': True, + 'width': '10', + 'height': '10', + 'fulldragboard': False, + 'minimized': False, + 'titlevisible': False + } + }] }, { 'id': '2', @@ -843,30 +858,35 @@ def setUpClass(cls): 'version': '2.0', 'title': 'Widget title', 'readonly': True, + 'layout': 0, 'properties': { 'prop1': {'value': 'value1', 'readonly': False} }, 'preferences': { 'text': {'value': 'other value', 'readonly': True, 'hidden': True} }, - 'position': { - 'anchor': 'top-left', - 'relx': True, - 'rely': True, - 'x': '10', - 'y': '1', - 'z': '2', - }, - 'rendering': { - 'relwidth': True, - 'relheight': True, - 'width': '10', - 'height': '10', - 'layout': 0, - 'fulldragboard': True, - 'minimized': True, - 'titlevisible': False - } + 'screenSizes': [{ + 'id': 0, + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'position': { + 'anchor': 'top-left', + 'relx': True, + 'rely': True, + 'x': '10', + 'y': '1', + 'z': '2', + }, + 'rendering': { + 'relwidth': True, + 'relheight': True, + 'width': '10', + 'height': '10', + 'fulldragboard': True, + 'minimized': True, + 'titlevisible': False + } + }] } ] }, @@ -1056,6 +1076,7 @@ def setUpClass(cls): 'version': '1.0', 'title': 'Widget title', 'readonly': False, + 'layout': 0, 'properties': { 'prop1': {'value': 'value1', 'readonly': False}, 'prop2': {'value': '%(param.param1)', 'readonly': True} @@ -1064,24 +1085,28 @@ def setUpClass(cls): 'list': {'value': '%(param.param1)', 'readonly': True, 'hidden': False}, 'text': {'value': '%(param.param2)', 'readonly': True, 'hidden': True} }, - 'position': { - 'anchor': 'top-left', - 'relx': True, - 'rely': True, - 'x': '0', - 'y': '1', - 'z': '2', - }, - 'rendering': { - 'relwidth': True, - 'relheight': True, - 'width': '10', - 'height': '10', - 'layout': 0, - 'fulldragboard': False, - 'minimized': False, - 'titlevisible': False - } + 'screenSizes': [{ + 'id': 0, + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'position': { + 'anchor': 'top-left', + 'relx': True, + 'rely': True, + 'x': '0', + 'y': '1', + 'z': '2', + }, + 'rendering': { + 'relwidth': True, + 'relheight': True, + 'width': '10', + 'height': '10', + 'fulldragboard': False, + 'minimized': False, + 'titlevisible': False + } + }] }, { 'id': '2', @@ -1090,30 +1115,35 @@ def setUpClass(cls): 'version': '2.0', 'title': 'Widget title', 'readonly': True, + 'layout': 0, 'properties': { 'prop1': {'value': 'value1', 'readonly': False} }, 'preferences': { 'text': {'value': 'other value', 'readonly': True, 'hidden': True} }, - 'position': { - 'anchor': 'top-left', - 'relx': True, - 'rely': True, - 'x': '10', - 'y': '1', - 'z': '2', - }, - 'rendering': { - 'relwidth': True, - 'relheight': True, - 'width': '10', - 'height': '10', - 'layout': 0, - 'fulldragboard': True, - 'minimized': True, - 'titlevisible': True - } + 'screenSizes': [{ + 'id': 0, + 'moreOrEqual': 0, + 'lessOrEqual': -1, + 'position': { + 'anchor': 'top-left', + 'relx': True, + 'rely': True, + 'x': '10', + 'y': '1', + 'z': '2', + }, + 'rendering': { + 'relwidth': True, + 'relheight': True, + 'width': '10', + 'height': '10', + 'fulldragboard': True, + 'minimized': True, + 'titlevisible': True + } + }] } ] }, @@ -1553,6 +1583,8 @@ def check_minimal_mashup_data(self, testname, format): template = TemplateParser(template_contents) processed_info = template.get_resource_info() + print(json.dumps(processed_info, sort_keys=True, indent=4, ensure_ascii=False)) + self.check_full_mashup(processed_info, getattr(self, testname)) def check_full_mashup(self, processed_info, expected_result): @@ -1814,6 +1846,7 @@ def test_rdf_parser_writer_mashup_with_translations(self): self.check_full_mashup(processed_info, self.mashup_with_translations_info) + def test_rdf_parser_writer_mashup_with_params(self): rdf_description = write_rdf_description(self.mashup_with_params) diff --git a/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_data.json b/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_data.json index 68aa5f093e..d254ca456b 100644 --- a/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_data.json +++ b/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_data.json @@ -46,6 +46,7 @@ "version": "1.0", "title": "Widget title", "readonly": false, + "layout": 0, "properties": { "prop1": {"value": "value1", "readonly": false}, "prop2": {"value": "value 2", "readonly": true} @@ -54,24 +55,28 @@ "list": {"value": "default", "readonly": true, "hidden": false}, "text": {"value": "other value", "readonly": true, "hidden": true} }, - "position": { - "anchor": "top-left", - "relx": true, - "rely": true, - "x": "0", - "y": "1", - "z": "2" - }, - "rendering": { - "relwidth": true, - "relheight": true, - "width": "10", - "height": "10", - "layout": 0, - "fulldragboard": false, - "minimized": false, - "titlevisible": true - } + "screenSizes": [{ + "id": 0, + "moreOrEqual": 0, + "lessOrEqual": -1, + "position": { + "anchor": "top-left", + "relx": true, + "rely": true, + "x": "0", + "y": "1", + "z": "2" + }, + "rendering": { + "relwidth": true, + "relheight": true, + "width": "10", + "height": "10", + "fulldragboard": false, + "minimized": false, + "titlevisible": true + } + }] }, { "id": "2", @@ -80,30 +85,35 @@ "version": "2.0", "readonly": true, "title": "Widget title", + "layout": 0, "properties": { "prop1": {"value": "value1", "readonly": false} }, "preferences": { "text": {"value": "other value", "readonly": true, "hidden": true} }, - "position": { - "anchor": "top-left", - "relx": true, - "rely": true, - "x": "10", - "y": "1", - "z": "2" - }, - "rendering": { - "relwidth": true, - "relheight": true, - "width": "10", - "height": "10", - "layout": 0, - "fulldragboard": true, - "minimized": true, - "titlevisible": true - } + "screenSizes": [{ + "id": 0, + "moreOrEqual": 0, + "lessOrEqual": -1, + "position": { + "anchor": "top-left", + "relx": true, + "rely": true, + "x": "10", + "y": "1", + "z": "2" + }, + "rendering": { + "relwidth": true, + "relheight": true, + "width": "10", + "height": "10", + "fulldragboard": true, + "minimized": true, + "titlevisible": true + } + }] } ] }, diff --git a/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data.json b/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data.json index 6ba093f430..c6746eb738 100644 --- a/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data.json +++ b/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data.json @@ -45,6 +45,7 @@ "version": "1.0", "title": "Widget title", "readonly": false, + "layout": 1, "properties": { "prop1": {"value": "value1", "readonly": false}, "prop2": {"value": "value 2", "readonly": true} @@ -53,19 +54,23 @@ "list": {"value": "default", "readonly": true, "hidden": false}, "text": {"value": "other value", "readonly": true, "hidden": true} }, - "position": { - "x": "0", - "y": "1", - "z": "2" - }, - "rendering": { - "width": "10", - "height": "10", - "layout": 1, - "fulldragboard": false, - "minimized": false, - "titlevisible": true - } + "screenSizes": [{ + "id": 0, + "moreOrEqual": 0, + "lessOrEqual": -1, + "position": { + "x": "0", + "y": "1", + "z": "2" + }, + "rendering": { + "width": "10", + "height": "10", + "fulldragboard": false, + "minimized": false, + "titlevisible": true + } + }] }, { "id": "2", @@ -73,6 +78,7 @@ "name": "TestWidget", "version": "2.0", "readonly": true, + "layout": "0", "title": "Widget title", "properties": { "prop1": {"value": "value1", "readonly": false} @@ -80,21 +86,25 @@ "preferences": { "text": {"value": "other value", "readonly": true, "hidden": true} }, - "position": { - "x": "10", - "y": "1", - "z": "2" - }, - "rendering": { - "relwidth": true, - "relheight": true, - "width": "10", - "height": "10", - "layout": "0", - "fulldragboard": true, - "minimized": true, - "titlevisible": true - } + "screenSizes": [{ + "id": 0, + "moreOrEqual": 0, + "lessOrEqual": -1, + "position": { + "x": "10", + "y": "1", + "z": "2" + }, + "rendering": { + "relwidth": true, + "relheight": true, + "width": "10", + "height": "10", + "fulldragboard": true, + "minimized": true, + "titlevisible": true + } + }] } ] }, diff --git a/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data_result.json b/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data_result.json index 2494c02f52..27cd064d33 100644 --- a/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data_result.json +++ b/src/wirecloud/commons/tests/test-data/mashup_with_behaviours_minimal_data_result.json @@ -46,6 +46,7 @@ "version": "1.0", "title": "Widget title", "readonly": false, + "layout": 1, "properties": { "prop1": {"value": "value1", "readonly": false}, "prop2": {"value": "value 2", "readonly": true} @@ -54,24 +55,28 @@ "list": {"value": "default", "readonly": true, "hidden": false}, "text": {"value": "other value", "readonly": true, "hidden": true} }, - "position": { - "anchor": "top-left", - "relx": true, - "rely": false, - "x": "0", - "y": "1", - "z": "2" - }, - "rendering": { - "relwidth": true, - "relheight": false, - "width": "10", - "height": "10", - "layout": 1, - "fulldragboard": false, - "minimized": false, - "titlevisible": true - } + "screenSizes": [{ + "id": 0, + "moreOrEqual": 0, + "lessOrEqual": -1, + "position": { + "anchor": "top-left", + "relx": true, + "rely": false, + "x": "0", + "y": "1", + "z": "2" + }, + "rendering": { + "relwidth": true, + "relheight": false, + "width": "10", + "height": "10", + "fulldragboard": false, + "minimized": false, + "titlevisible": true + } + }] }, { "id": "2", @@ -79,6 +84,7 @@ "name": "TestWidget", "version": "2.0", "readonly": true, + "layout": 0, "title": "Widget title", "properties": { "prop1": {"value": "value1", "readonly": false} @@ -86,24 +92,28 @@ "preferences": { "text": {"value": "other value", "readonly": true, "hidden": true} }, - "position": { - "anchor": "top-left", - "relx": true, - "rely": true, - "x": "10", - "y": "1", - "z": "2" - }, - "rendering": { - "relwidth": true, - "relheight": true, - "width": "10", - "height": "10", - "layout": 0, - "fulldragboard": true, - "minimized": true, - "titlevisible": true - } + "screenSizes": [{ + "id": 0, + "moreOrEqual": 0, + "lessOrEqual": -1, + "position": { + "anchor": "top-left", + "relx": true, + "rely": true, + "x": "10", + "y": "1", + "z": "2" + }, + "rendering": { + "relwidth": true, + "relheight": true, + "width": "10", + "height": "10", + "fulldragboard": true, + "minimized": true, + "titlevisible": true + } + }] } ] }, diff --git a/src/wirecloud/commons/utils/template/parsers/json.py b/src/wirecloud/commons/utils/template/parsers/json.py index c2723d8927..44f830747f 100644 --- a/src/wirecloud/commons/utils/template/parsers/json.py +++ b/src/wirecloud/commons/utils/template/parsers/json.py @@ -255,15 +255,18 @@ def _init(self): ] layout = screenSizes[0]['rendering'].get('layout', 0) - widget['layout'] = layout + widget['layout'] = int(layout) + if 'layout' in screenSizes[0]['rendering']: + del screenSizes[0]['rendering']['layout'] else: - layout = widget.get('layout', 0) + layout = int(widget.get('layout', 0)) + + self._check_integer_fields(('layout',), place=widget, default=0, allow_cast=True) for screenSize in screenSizes: self._check_integer_fields(('moreOrEqual', 'lessOrEqual', 'id'), place=screenSize, required=True) rendering = screenSize.get('rendering', {}) - self._check_integer_fields(('layout',), place=rendering, default=0, allow_cast=True) self._check_boolean_fields(('relwidth',), place=rendering, default=True) self._check_boolean_fields(('relheight',), place=rendering, default=(layout != 1)) diff --git a/src/wirecloud/commons/utils/template/parsers/rdf.py b/src/wirecloud/commons/utils/template/parsers/rdf.py index ecb068a762..5a967f9945 100644 --- a/src/wirecloud/commons/utils/template/parsers/rdf.py +++ b/src/wirecloud/commons/utils/template/parsers/rdf.py @@ -717,7 +717,15 @@ def _parse_workspace_info(self): rendering = self._get_field(WIRE_M, 'hasiWidgetRendering', widget, id_=True, required=False) screenSizes = self._graph.objects(widget, WIRE_M['hasScreenSize']) vendor = self._get_field(USDL, 'hasProvider', widget, id_=True, required=True) - if len(screenSizes) > 0: + for _ in screenSizes: + hasScreenSizes = True + break + else: + hasScreenSizes = False + + screenSizes = self._graph.objects(widget, WIRE_M['hasScreenSize']) + + if hasScreenSizes: layout = int(self._get_field(WIRE_M, 'layout', widget, required=False, default='0')) else: layout = int(self._get_field(WIRE_M, 'layout', rendering, default='0')) @@ -735,7 +743,7 @@ def _parse_workspace_info(self): } widget_info['screenSizes'] = [] - if len(screenSizes) > 0: + if hasScreenSizes: for screenSize in screenSizes: position = self._get_field(WIRE_M, 'hasPosition', screenSize, id_=True, required=False) rendering = self._get_field(WIRE_M, 'hasiWidgetRendering', screenSize, id_=True, required=False) @@ -747,17 +755,17 @@ def _parse_workspace_info(self): 'anchor': self._get_field(WIRE_M, 'anchor', position, required=False, default="top-left"), 'relx': self._get_field(WIRE_M, 'relx', position, required=False, default='true').lower() == 'true', 'rely': self._get_field(WIRE_M, 'rely', position, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', - 'x': int(float(self._get_field(WIRE_M, 'x', position))), - 'y': int(float(self._get_field(WIRE_M, 'y', position))), - 'z': int(float(self._get_field(WIRE_M, 'z', position))), + 'x': self._get_field(WIRE_M, 'x', position), + 'y': self._get_field(WIRE_M, 'y', position), + 'z': self._get_field(WIRE_M, 'z', position), }, 'rendering': { 'fulldragboard': self._get_field(WIRE_M, 'fullDragboard', rendering, required=False).lower() == 'true', 'minimized': self._get_field(WIRE_M, 'minimized', rendering, required=False).lower() == 'true', - 'relwidth': self._get_field(WIRE_M, 'relwidth', rendering, required=False).lower() == 'true', - 'relheight': self._get_field(WIRE_M, 'relheight', rendering, required=False).lower() == 'true', - 'width': int(float(self._get_field(WIRE, 'renderingWidth', rendering))), - 'height': int(float(self._get_field(WIRE, 'renderingHeight', rendering))), + 'relwidth': self._get_field(WIRE_M, 'relwidth', rendering, required=False, default='True').lower() == 'true', + 'relheight': self._get_field(WIRE_M, 'relheight', rendering, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', + 'width': self._get_field(WIRE, 'renderingWidth', rendering), + 'height': self._get_field(WIRE, 'renderingHeight', rendering), 'titlevisible': self._get_field(WIRE_M, 'titlevisible', rendering, default="true", required=False).lower() == 'true', } } @@ -771,20 +779,21 @@ def _parse_workspace_info(self): 'anchor': self._get_field(WIRE_M, 'anchor', position, required=False, default="top-left"), 'relx': self._get_field(WIRE_M, 'relx', position, required=False, default='true').lower() == 'true', 'rely': self._get_field(WIRE_M, 'rely', position, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', - 'x': int(float(self._get_field(WIRE_M, 'x', position))), - 'y': int(float(self._get_field(WIRE_M, 'y', position))), - 'z': int(float(self._get_field(WIRE_M, 'z', position))), + 'x': self._get_field(WIRE_M, 'x', position), + 'y': self._get_field(WIRE_M, 'y', position), + 'z': self._get_field(WIRE_M, 'z', position), }, 'rendering': { 'fulldragboard': self._get_field(WIRE_M, 'fullDragboard', rendering, required=False).lower() == 'true', 'minimized': self._get_field(WIRE_M, 'minimized', rendering, required=False).lower() == 'true', - 'relwidth': self._get_field(WIRE_M, 'relwidth', rendering, required=False).lower() == 'true', - 'relheight': self._get_field(WIRE_M, 'relheight', rendering, required=False).lower() == 'true', - 'width': int(float(self._get_field(WIRE, 'renderingWidth', rendering))), - 'height': int(float(self._get_field(WIRE, 'renderingHeight', rendering))), + 'relwidth': self._get_field(WIRE_M, 'relwidth', rendering, required=False, default='True').lower() == 'true', + 'relheight': self._get_field(WIRE_M, 'relheight', rendering, required=False, default=('true' if layout != 1 else 'false')).lower() == 'true', + 'width': self._get_field(WIRE, 'renderingWidth', rendering), + 'height': self._get_field(WIRE, 'renderingHeight', rendering), 'titlevisible': self._get_field(WIRE_M, 'titlevisible', rendering, default="true", required=False).lower() == 'true', } } + widget_info['screenSizes'].append(screen_size_info) for prop in self._graph.objects(widget, WIRE_M['hasiWidgetProperty']): widget_info['properties'][self._get_field(DCTERMS, 'title', prop)] = { diff --git a/src/wirecloud/commons/utils/template/parsers/xml.py b/src/wirecloud/commons/utils/template/parsers/xml.py index e69d674ea2..dd89aeaf1c 100644 --- a/src/wirecloud/commons/utils/template/parsers/xml.py +++ b/src/wirecloud/commons/utils/template/parsers/xml.py @@ -609,17 +609,17 @@ def _parse_workspace_info(self): 'anchor': str(position.get('anchor', 'top-left')), 'relx': position.get('relx', 'true').lower() == 'true', 'rely': position.get('rely', 'true' if layout != 1 else 'false').lower() == 'true', - 'x': int(float(position.get('x'))), - 'y': int(float(position.get('y'))), - 'z': int(float(position.get('z'))), + 'x': position.get('x'), + 'y': position.get('y'), + 'z': position.get('z'), }, 'rendering': { 'fulldragboard': rendering.get('fulldragboard', 'false').lower() == 'true', 'minimized': rendering.get('minimized', 'false').lower() == 'true', 'relwidth': rendering.get('relwidth', 'true').lower() == 'true', 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true', - 'width': int(float(rendering.get('width'))), - 'height': int(float(rendering.get('height'))), + 'width': rendering.get('width'), + 'height': rendering.get('height'), 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true', } } @@ -646,7 +646,6 @@ def _parse_workspace_info(self): 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true', 'width': str(rendering.get('width')), 'height': str(rendering.get('height')), - 'layout': layout, 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true', } } diff --git a/src/wirecloud/commons/utils/template/writers/rdf.py b/src/wirecloud/commons/utils/template/writers/rdf.py index 512017861b..c313daa9d1 100644 --- a/src/wirecloud/commons/utils/template/writers/rdf.py +++ b/src/wirecloud/commons/utils/template/writers/rdf.py @@ -249,17 +249,17 @@ def write_mashup_resources_graph(graph, resource_uri, template_info): graph.add((pos, WIRE_M['anchor'], rdflib.Literal(screenSize['position']['anchor']))) graph.add((pos, WIRE_M['relx'], rdflib.Literal(str(screenSize['position']['relx'])))) graph.add((pos, WIRE_M['rely'], rdflib.Literal(str(screenSize['position']['rely'])))) - graph.add((pos, WIRE_M['x'], rdflib.Literal(str(int(float(screenSize['position']['x'])))))) - graph.add((pos, WIRE_M['y'], rdflib.Literal(str(int(float(screenSize['position']['y'])))))) - graph.add((pos, WIRE_M['z'], rdflib.Literal(str(int(float(screenSize['position']['z'])))))) + graph.add((pos, WIRE_M['x'], rdflib.Literal(str(screenSize['position']['x'])))) + graph.add((pos, WIRE_M['y'], rdflib.Literal(str(screenSize['position']['y'])))) + graph.add((pos, WIRE_M['z'], rdflib.Literal(str(screenSize['position']['z'])))) rend = rdflib.BNode() graph.add((rend, rdflib.RDF.type, WIRE_M['iWidgetRendering'])) graph.add((screenSizeNode, WIRE_M['hasiWidgetRendering'], rend)) graph.add((rend, WIRE_M['relwidth'], rdflib.Literal(str(screenSize['rendering']['relwidth'])))) graph.add((rend, WIRE_M['relheight'], rdflib.Literal(str(screenSize['rendering']['relheight'])))) - graph.add((rend, WIRE['renderingWidth'], rdflib.Literal(str(int(float(screenSize['rendering']['width'])))))) - graph.add((rend, WIRE['renderingHeight'], rdflib.Literal(str(int(float(screenSize['rendering']['height'])))))) + graph.add((rend, WIRE['renderingWidth'], rdflib.Literal(str(screenSize['rendering']['width'])))) + graph.add((rend, WIRE['renderingHeight'], rdflib.Literal(str(screenSize['rendering']['height'])))) graph.add((rend, WIRE_M['fullDragboard'], rdflib.Literal(str(screenSize['rendering']['fulldragboard'])))) graph.add((rend, WIRE_M['minimized'], rdflib.Literal(str(screenSize['rendering']['minimized'])))) graph.add((rend, WIRE_M['titlevisible'], rdflib.Literal(str(screenSize['rendering']['titlevisible'])))) diff --git a/src/wirecloud/commons/utils/template/writers/xml.py b/src/wirecloud/commons/utils/template/writers/xml.py index d49c878dc8..beab54a650 100644 --- a/src/wirecloud/commons/utils/template/writers/xml.py +++ b/src/wirecloud/commons/utils/template/writers/xml.py @@ -147,7 +147,7 @@ def write_mashup_tree(doc, resources, options): rendering = etree.SubElement(screenSizeElem, 'rendering', height=str(int(float(screenSize['rendering']['height']))), - width=str(int(float(screenSize['rendering']['width'])))), + width=str(int(float(screenSize['rendering']['width'])))) addAttributes(screenSize['rendering'], rendering, ('minimized', 'fulldragboard'), default='false', type='boolean') addAttributes(screenSize['rendering'], rendering, ('relwidth', 'titlevisible'), default='true', type='boolean') addAttributes(screenSize['rendering'], rendering, ('relheight',), default=('true' if layout != 1 else 'false'), type='boolean') diff --git a/src/wirecloud/platform/fixtures/extra_wiring_test_data.json b/src/wirecloud/platform/fixtures/extra_wiring_test_data.json index 5e1ee9614e..042dae6fd9 100644 --- a/src/wirecloud/platform/fixtures/extra_wiring_test_data.json +++ b/src/wirecloud/platform/fixtures/extra_wiring_test_data.json @@ -28,7 +28,7 @@ "name": "Test 111", "tab": 106, "readOnly": false, - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":6,\"top\":0,\"fulldragboard\":false},\"icon\":{\"top\":0,\"left\":0}}]}", "variables": "{\"prop\": {\"users\": {\"4\": \"default\"}}, \"prop2\": {\"users\": {\"4\": \"default2\"}}}" } }, diff --git a/src/wirecloud/platform/fixtures/test_data.json b/src/wirecloud/platform/fixtures/test_data.json index d18daf6efc..21c2f212f9 100644 --- a/src/wirecloud/platform/fixtures/test_data.json +++ b/src/wirecloud/platform/fixtures/test_data.json @@ -216,7 +216,7 @@ "widget": "1", "widget_uri": "Test/Test Widget/1.0.0", "name": "Test Widget", - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}]}", "tab": "1", "variables": "{\"password\": {\"users\": {\"2\": \"test_password\"}}, \"username\": {\"users\": {\"2\": \"test_username\"}}, \"prop\": {\"users\": {\"2\": \"test_data\"}}}" } @@ -228,7 +228,7 @@ "widget": "1", "widget_uri": "Test/Test Widget/1.0.0", "name": "Test Widget 2", - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":5,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":1,\"left\":5,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}]}", "tab": "1", "variables": "{\"password\": {\"users\": {\"2\": \"test_password\"}}, \"username\": {\"users\": {\"2\": \"test_username\"}}, \"prop\": {\"users\": {\"2\": \"test_data\"}}}" } @@ -240,7 +240,7 @@ "widget": "1", "widget_uri": "Test/Test Widget/1.0.0", "name": "Secure Widget 1", - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}]}", "tab": "2", "variables": "{\"password\": {\"users\": {\"2\": \"\"}}, \"username\": {\"users\": {\"2\": \"test_username\"}}, \"prop\": {\"users\": {\"2\": \"test_data\"}}}" } @@ -252,7 +252,7 @@ "widget": "1", "widget_uri": "Test/Test Widget/1.0.0", "name": "Secure Widget 2", - "positions": "{\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}", + "positions": "{\"configurations\":[{\"id\":0,\"moreOrEqual\":0,\"lessOrEqual\":-1,\"widget\":{\"minimized\":false,\"height\":24,\"width\":6,\"zIndex\":0,\"left\":0,\"top\":0,\"fulldragboard\":false,\"anchor\":\"top-left\",\"relx\":true,\"rely\":true}}]}", "tab": "2", "variables": "{\"password\": {\"users\": {\"2\": \"test_password\"}}, \"username\": {\"users\": {\"2\": \"test_username\"}}, \"prop\": {\"users\": {\"2\": \"test_data\"}}}" } diff --git a/src/wirecloud/platform/tests/rest_api.py b/src/wirecloud/platform/tests/rest_api.py index 67edf07efe..f32d0e9c82 100644 --- a/src/wirecloud/platform/tests/rest_api.py +++ b/src/wirecloud/platform/tests/rest_api.py @@ -1951,7 +1951,11 @@ def test_iwidget_collection_post_invalid_value(self): # Make the request data = { 'widget': 'Wirecloud/Test/1.0', - 'height': False, + 'layoutConfigurations': [{ + 'id': 0, + 'height': False, + 'action': 'update' + }] } response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') self.assertEqual(response.status_code, 400) @@ -1978,8 +1982,8 @@ def test_iwidget_collection_put(self): # Make the request def place_iwidgets(): data = [ - {'id': 1, 'left': 0, 'top': 0, 'width': 10, 'height': 10}, - {'id': 2, 'left': 9.5, 'top': 10.5, 'width': 10.5, 'height': 10.5} + {'id': 1, 'layoutConfigurations': [{'moreOrEqual': 0, 'lessOrEqual': -1, 'id': 0, 'action': 'update', 'left': 0, 'top': 0, 'width': 10, 'height': 10}]}, + {'id': 2, 'layoutConfigurations': [{'moreOrEqual': 0, 'lessOrEqual': -1, 'id': 0, 'action': 'update', 'left': 9.5, 'top': 10.5, 'width': 10.5, 'height': 10.5}]} ] real_method = Workspace.save with patch('wirecloud.platform.workspace.models.Workspace.save', autospec=True, side_effect=real_method) as save_mock: @@ -1994,7 +1998,7 @@ def test_iwidget_collection_put_workspace_not_found(self): # Authenticate self.client.login(username='user_with_workspaces', password='admin') - data = [{'id': 1, 'left': 0, 'top': 0, 'width': 10, 'height': 10}] + data = [{'id': 1, 'layoutConfigurations': [{'moreOrEqual': 0, 'lessOrEqual': -1, 'id': 0, 'action': 'update', 'left': 0, 'top': 0, 'width': 10, 'height': 10}]}] check_not_found_response(self, 'put', url, json.dumps(data)) def test_iwidget_collection_put_tab_not_found(self): @@ -2003,14 +2007,14 @@ def test_iwidget_collection_put_tab_not_found(self): # Authenticate self.client.login(username='user_with_workspaces', password='admin') - data = [{'id': 1, 'left': 0, 'top': 0, 'width': 10, 'height': 10}] + data = [{'id': 1, 'layoutConfigurations': [{'moreOrEqual': 0, 'lessOrEqual': -1, 'id': 0, 'action': 'update', 'left': 0, 'top': 0, 'width': 10, 'height': 10}]}] check_not_found_response(self, 'put', url, json.dumps(data)) def test_iwidget_collection_put_requires_permission(self): url = reverse('wirecloud.iwidget_collection', kwargs={'workspace_id': 1, 'tab_id': 1}) data = [ - {'id': 1, 'left': 0} + {'id': 1, 'layoutConfigurations': [{'moreOrEqual': 0, 'lessOrEqual': -1, 'id': 0, 'action': 'update', 'left': 0}]} ] check_put_requires_permission(self, url, json.dumps(data)) @@ -2023,7 +2027,7 @@ def test_iwidget_collection_put_invalid_value(self): # Make the request data = [ - {'id': 1, 'left': -1} + {'id': 1, 'layoutConfigurations': [{'moreOrEqual': 0, 'lessOrEqual': -1, 'id': 0, 'action': 'update', 'left': -1}]} ] response = self.client.put(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') self.assertEqual(response.status_code, 422) @@ -2039,7 +2043,7 @@ def test_iwidget_collection_put_nonexistent_iwidget(self): # Make the request data = [ - {'id': 1234, 'left': 0} + {'id': 1234, 'layoutConfigurations': [{'moreOrEqual': 0, 'lessOrEqual': -1, 'id': 0, 'action': 'update', 'left': 0}]} ] response = self.client.put(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') self.assertEqual(response.status_code, 422) @@ -2406,8 +2410,8 @@ def check_iwidget_entry_post_invalid_position_value(self, field, value, error_co self.client.login(username='user_with_workspaces', password='admin') # Make the requests - data = {} - data[field] = value + data = {'layoutConfigurations': [{'id': 0, 'action': 'update'}]} + data['layoutConfigurations'][0][field] = value response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') self.assertEqual(response.status_code, error_code) diff --git a/src/wirecloud/platform/workspace/tests.py b/src/wirecloud/platform/workspace/tests.py index ed113571f3..2f92d76730 100644 --- a/src/wirecloud/platform/workspace/tests.py +++ b/src/wirecloud/platform/workspace/tests.py @@ -712,11 +712,11 @@ def test_build_xml_template_from_basic_workspace(self): self.assertXPathAttr(template, '/mashup/structure/tab[1]', 'name', 'tab') self.assertXPathCount(template, '/mashup/structure/tab[1]/resource', 2) self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]', 'readonly', 'false', optional=True) - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/rendering', 'minimized', 'false', optional=True) - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/rendering', 'fulldragboard', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/screensizes/screensize[1]/rendering', 'minimized', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/screensizes/screensize[1]/rendering', 'fulldragboard', 'false', optional=True) self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]', 'readonly', 'false', optional=True) - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/rendering', 'minimized', 'false', optional=True) - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/rendering', 'fulldragboard', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/screensizes/screensize[1]/rendering', 'minimized', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/screensizes/screensize[1]/rendering', 'fulldragboard', 'false', optional=True) self.check_workspace_xml_wiring(template) @@ -735,12 +735,12 @@ def test_build_xml_template_from_workspace_minimized_and_fulldragboard(self): # Minimize the first iwidget iwidget = IWidget.objects.get(pk=1) - iwidget.positions['widget']['minimized'] = True + iwidget.positions['configurations'][0]['widget']['minimized'] = True iwidget.save() # Set the fulldragboard flag on the second iwidget iwidget = IWidget.objects.get(pk=2) - iwidget.positions['widget']['fulldragboard'] = True + iwidget.positions['configurations'][0]['widget']['fulldragboard'] = True iwidget.save() template = build_xml_template_from_workspace(options, self.workspace_with_iwidgets, self.user, raw=True) @@ -756,11 +756,11 @@ def test_build_xml_template_from_workspace_minimized_and_fulldragboard(self): # order depends on the database backend) widgets = {widget.get('id'): widget for widget in template.xpath('/mashup/structure/tab[1]/resource')} self.assertXPathAttr(widgets["1"], '.', 'readonly', 'false', optional=True) - self.assertXPathAttr(widgets["1"], 'rendering', 'minimized', 'true') - self.assertXPathAttr(widgets["1"], 'rendering', 'fulldragboard', 'false', optional=True) + self.assertXPathAttr(widgets["1"], 'screensizes/screensize[1]/rendering', 'minimized', 'true') + self.assertXPathAttr(widgets["1"], 'screensizes/screensize[1]/rendering', 'fulldragboard', 'false', optional=True) self.assertXPathAttr(widgets["2"], '.', 'readonly', 'false', optional=True) - self.assertXPathAttr(widgets["2"], 'rendering', 'minimized', 'false', optional=True) - self.assertXPathAttr(widgets["2"], 'rendering', 'fulldragboard', 'true') + self.assertXPathAttr(widgets["2"], 'screensizes/screensize[1]/rendering', 'minimized', 'false', optional=True) + self.assertXPathAttr(widgets["2"], 'screensizes/screensize[1]/rendering', 'fulldragboard', 'true') self.check_workspace_xml_wiring(template) @@ -785,11 +785,11 @@ def test_build_xml_template_from_workspace_read_only_widgets(self): self.assertXPathAttr(template, '/mashup/structure/tab[1]', 'name', 'tab') self.assertXPathCount(template, '/mashup/structure/tab[1]/resource', 2) self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]', 'readonly', 'true') - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/rendering', 'minimized', 'false', optional=True) - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/rendering', 'fulldragboard', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/screensizes/screensize[1]/rendering', 'minimized', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[1]/screensizes/screensize[1]/rendering', 'fulldragboard', 'false', optional=True) self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]', 'readonly', 'true') - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/rendering', 'minimized', 'false', optional=True) - self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/rendering', 'fulldragboard', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/screensizes/screensize[1]/rendering', 'minimized', 'false', optional=True) + self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[2]/screensizes/screensize[1]/rendering', 'fulldragboard', 'false', optional=True) self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[@id="2"]/preferencevalue[@name="username"]', 'readonly', 'false', optional=True) self.assertXPathAttr(template, '/mashup/structure/tab[1]/resource[@id="2"]/preferencevalue[@name="username"]', 'hidden', 'false', optional=True) From 03136c7f777a860eb6bf206e0cd0eaf400bab9e7 Mon Sep 17 00:00:00 2001 From: oxixes Date: Mon, 24 Jun 2024 12:48:51 +0200 Subject: [PATCH 09/28] Fix grunt tests --- src/js_tests/wirecloud/WidgetSpec.js | 14 +- src/js_tests/wirecloud/ui/ColumnLayoutSpec.js | 10 +- src/js_tests/wirecloud/ui/FreeLayoutSpec.js | 8 +- .../wirecloud/ui/GridColumnLayoutSpec.js | 6 +- .../wirecloud/ui/SidebarLayoutSpec.js | 12 +- .../wirecloud/ui/SmartColumnLayoutSpec.js | 4 +- src/js_tests/wirecloud/ui/WidgetViewSpec.js | 132 +++++++++++------- .../ui/WorkspaceTabViewDragboardSpec.js | 9 +- .../wirecloud/ui/WorkspaceTabViewSpec.js | 29 ++-- .../static/js/StyledElements/NumericField.js | 22 --- .../platform/static/js/wirecloud/Widget.js | 28 +++- .../static/js/wirecloud/ui/FreeLayout.js | 2 +- .../static/js/wirecloud/ui/WidgetView.js | 23 ++- .../js/wirecloud/ui/WorkspaceTabView.js | 2 +- .../static/js/wirecloud/ui/WorkspaceView.js | 4 +- 15 files changed, 179 insertions(+), 126 deletions(-) diff --git a/src/js_tests/wirecloud/WidgetSpec.js b/src/js_tests/wirecloud/WidgetSpec.js index 1e31ad84d3..b1dc0826d1 100644 --- a/src/js_tests/wirecloud/WidgetSpec.js +++ b/src/js_tests/wirecloud/WidgetSpec.js @@ -1764,7 +1764,12 @@ it("updates titlevisible property", (done) => { const widget = new Wirecloud.Widget(LOCKED_WORKSPACE_TAB, EMPTY_WIDGET_META, { id: "1", - titlevisible: false + layoutConfigurations: [{ + titlevisible: false, + id: 0, + moreOrEqual: 0, + lessOrEqual: -1 + }] }); spyOn(Wirecloud.io, "makeRequest"); expect(widget.titlevisible).toBe(false); @@ -1785,7 +1790,12 @@ it("updates titlevisible property on the server", (done) => { const widget = new Wirecloud.Widget(LOCKED_WORKSPACE_TAB, EMPTY_WIDGET_META, { id: "1", - titlevisible: false + layoutConfigurations: [{ + titlevisible: false, + id: 0, + moreOrEqual: 0, + lessOrEqual: -1 + }] }); spyOn(Wirecloud.io, "makeRequest").and.callFake(function (url, options) { expect(options.method).toEqual("POST"); diff --git a/src/js_tests/wirecloud/ui/ColumnLayoutSpec.js b/src/js_tests/wirecloud/ui/ColumnLayoutSpec.js index b81f02b291..7f1abf9837 100644 --- a/src/js_tests/wirecloud/ui/ColumnLayoutSpec.js +++ b/src/js_tests/wirecloud/ui/ColumnLayoutSpec.js @@ -290,7 +290,7 @@ }); - describe("adaptColumnOffset(size)", () => { + describe("adaptColumnOffset(size[, width])", () => { it("should return 0 LU as minimum", () => { const layout = new ns.ColumnLayout({leftMargin: 4}, 4, 13, 4, 4, 10); @@ -310,7 +310,7 @@ const value = layout.adaptColumnOffset("2px"); - expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(0); + expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(0, undefined); expect(value.inPixels).toBe(0); expect(value.inLU).toBe(0); }); @@ -323,7 +323,7 @@ const value = layout.adaptColumnOffset("204px"); - expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(200); + expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(200, undefined); expect(value.inPixels).toBe(200); expect(value.inLU).toBe(1); }); @@ -563,7 +563,7 @@ }); - describe("getColumnOffset(cells[, css])", () => { + describe("getColumnOffset(cells[, width, css])", () => { it("should work", () => { const dragboard = { @@ -579,7 +579,7 @@ 10 ); expect(layout.getColumnOffset({x: 2})).toBe(400 + 4 + 2); - expect(layout.getColumnOffset({x: 2}, true)).toBe("406px"); + expect(layout.getColumnOffset({x: 2}, undefined, true)).toBe("406px"); }); }); diff --git a/src/js_tests/wirecloud/ui/FreeLayoutSpec.js b/src/js_tests/wirecloud/ui/FreeLayoutSpec.js index 18d6647918..656ea22c4e 100644 --- a/src/js_tests/wirecloud/ui/FreeLayoutSpec.js +++ b/src/js_tests/wirecloud/ui/FreeLayoutSpec.js @@ -36,7 +36,7 @@ }); - describe("adaptColumnOffset(value)", () => { + describe("adaptColumnOffset(value[, width])", () => { it("should floor cells", () => { const layout = new ns.FreeLayout({}); @@ -435,7 +435,7 @@ leftMargin: 4, rightMargin: 7 }); - expect(layout.getColumnOffset({relx: true, anchor: "top-left", x: 500000}, true)).toBe("calc(50% + -1.5px)"); + expect(layout.getColumnOffset({relx: true, anchor: "top-left", x: 500000}, undefined, true)).toBe("calc(50% + -1.5px)"); }); it("should work with relative positions (from right)", () => { @@ -453,7 +453,7 @@ rightMargin: 3, leftMargin: 7 }); - expect(layout.getColumnOffset({relx: true, anchor: "top-right", x: 500000}, true)).toBe("calc(50% + -2px)"); + expect(layout.getColumnOffset({relx: true, anchor: "top-right", x: 500000}, undefined, true)).toBe("calc(50% + -2px)"); }); it("should work with absolute positions (from left)", () => { @@ -482,7 +482,7 @@ rightMargin: 3, topMargin: 7, }); - expect(layout.getColumnOffset({relx: false, anchor: "top-right", x: 400}, true)).toBe("403px"); + expect(layout.getColumnOffset({relx: false, anchor: "top-right", x: 400}, undefined, true)).toBe("403px"); }); }); diff --git a/src/js_tests/wirecloud/ui/GridColumnLayoutSpec.js b/src/js_tests/wirecloud/ui/GridColumnLayoutSpec.js index 4a1a7e0d26..9a0cc9fc42 100644 --- a/src/js_tests/wirecloud/ui/GridColumnLayoutSpec.js +++ b/src/js_tests/wirecloud/ui/GridColumnLayoutSpec.js @@ -294,7 +294,7 @@ }); - describe("adaptColumnOffset(size)", () => { + describe("adaptColumnOffset(size[, width])", () => { it("should return 0 LU as minimum", () => { const layout = new ns.GridLayout({leftMargin: 4}, 4, 13, 4, 4, 10); @@ -314,7 +314,7 @@ const value = layout.adaptColumnOffset("2px"); - expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(0); + expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(0, undefined); expect(value.inPixels).toBe(0); expect(value.inLU).toBe(0); }); @@ -327,7 +327,7 @@ const value = layout.adaptColumnOffset("204px"); - expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(202); + expect(layout.fromPixelsToHCells).toHaveBeenCalledWith(202, undefined); expect(value.inPixels).toBe(200); expect(value.inLU).toBe(1); }); diff --git a/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js b/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js index 8e81e46536..1a4c8f5289 100644 --- a/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js +++ b/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js @@ -113,7 +113,7 @@ }); - describe("adaptColumnOffset(value)", () => { + describe("adaptColumnOffset(value[, width])", () => { it("should call parent method for top sidebars", () => { const result = {}; @@ -122,7 +122,7 @@ const value = layout.adaptColumnOffset(50); - expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptColumnOffset).toHaveBeenCalledWith(50); + expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptColumnOffset).toHaveBeenCalledWith(50, undefined); expect(value).toBe(result); }); @@ -133,7 +133,7 @@ const value = layout.adaptColumnOffset(50); - expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptColumnOffset).toHaveBeenCalledWith(50); + expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptColumnOffset).toHaveBeenCalledWith(50, undefined); expect(value).toBe(result); }); @@ -245,7 +245,7 @@ }); - describe("adaptWidth(size)", () => { + describe("adaptWidth(size[, width])", () => { it("should call parent method for top sidebars", () => { const result = {}; @@ -254,7 +254,7 @@ const value = layout.adaptWidth(50); - expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptWidth).toHaveBeenCalledWith(50); + expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptWidth).toHaveBeenCalledWith(50, undefined); expect(value).toBe(result); }); @@ -265,7 +265,7 @@ const value = layout.adaptWidth(50); - expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptWidth).toHaveBeenCalledWith(50); + expect(Wirecloud.ui.SmartColumnLayout.prototype.adaptWidth).toHaveBeenCalledWith(50, undefined); expect(value).toBe(result); }); diff --git a/src/js_tests/wirecloud/ui/SmartColumnLayoutSpec.js b/src/js_tests/wirecloud/ui/SmartColumnLayoutSpec.js index da2f903811..a09a48f651 100644 --- a/src/js_tests/wirecloud/ui/SmartColumnLayoutSpec.js +++ b/src/js_tests/wirecloud/ui/SmartColumnLayoutSpec.js @@ -99,7 +99,9 @@ 10 ); spyOn(ns.ColumnLayout.prototype, "initialize").and.returnValue(false); - spyOn(layout, "moveSpaceUp").and.returnValue(true); + const affectedWidgets = new Set(); + affectedWidgets.add("1"); + spyOn(layout, "moveSpaceUp").and.returnValue(affectedWidgets); const widget = { id: "1", addEventListener: jasmine.createSpy("addEventListener"), diff --git a/src/js_tests/wirecloud/ui/WidgetViewSpec.js b/src/js_tests/wirecloud/ui/WidgetViewSpec.js index ed29584540..54a8d6bd84 100644 --- a/src/js_tests/wirecloud/ui/WidgetViewSpec.js +++ b/src/js_tests/wirecloud/ui/WidgetViewSpec.js @@ -85,6 +85,9 @@ if ("_searchFreeSpace" in klass.prototype) { layout._searchFreeSpace = jasmine.createSpy("_searchFreeSpace"); } + if ("_searchFreeSpace2" in klass.prototype) { + layout._searchFreeSpace2 = jasmine.createSpy("_searchFreeSpace2"); + } return layout; }; @@ -120,19 +123,41 @@ const create_widget_mock = function create_widget_mock(options) { options = options != null ? options : {}; + + const layoutConfigurations = [{ + id: 0, + moreOrEqual: 0, + lessOrEqual: -1, + anchor: options.anchor != null ? options.anchor : "topleft", + relx: options.relx != null ? options.relx : true, + left: 3, + rely: options.rely != null ? options.rely : true, + top: 0, + zIndex: 0, + relwidth: options.relwidth != null ? options.relwidth : true, + width: 5, + relheight: options.relheight != null ? options.relheight : true, + height: 1, + fulldragboard: !!options.fulldragboard, + titlevisible: true, + minimized: false + }]; + return { addEventListener: jasmine.createSpy("addEventListener"), changeTab: jasmine.createSpy("changeTab").and.returnValue(Promise.resolve()), contextManager: { modify: jasmine.createSpy("modify") }, - fulldragboard: !!options.fulldragboard, + fulldragboard: layoutConfigurations[0].fulldragboard, id: "23", isAllowed: jasmine.createSpy("isAllowed").and.returnValue(true), layout: (options.layout != null ? options.layout : 2), logManager: { addEventListener: jasmine.createSpy("addEventListener") }, + layoutConfigurations: layoutConfigurations, + currentLayoutConfig: layoutConfigurations[0], permissions: { editor: { move: true, @@ -141,30 +166,21 @@ move: false } }, - position: { - anchor: options.anchor != null ? options.anchor : "topleft", - relx: options.relx != null ? options.relx : true, - x: 3, - rely: options.rely != null ? options.rely : true, - y: 0, - z: 0 - }, + position: layoutConfigurations[0], reload: jasmine.createSpy("reload"), - shape: { - relwidth: options.relwidth != null ? options.relwidth : true, - width: 5, - relheight: options.relheight != null ? options.relheight : true, - height: 1 - }, + shape: layoutConfigurations[0], remove: jasmine.createSpy("remove"), setPosition: jasmine.createSpy("setPosition"), + setLayoutPosition: jasmine.createSpy("setLayoutPostion"), setPermissions: jasmine.createSpy("setPermissions").and.returnValue(new Wirecloud.Task("", () => {})), setShape: jasmine.createSpy("setShape"), + setLayoutShape: jasmine.createSpy("setLayoutShape"), setTitleVisibility: jasmine.createSpy("setTitleVisibility").and.returnValue(new Wirecloud.Task("", () => {})), + setLayoutMinimizedStatus: jasmine.createSpy("setLayoutMinimizedStatus"), showLogs: jasmine.createSpy("showLogs"), showSettings: jasmine.createSpy("showSettings"), title: "My Widget", - titlevisible: true, + titlevisible: layoutConfigurations[0].titlevisible, volatile: !!options.volatile, wrapperElement: document.createElement('div') }; @@ -214,7 +230,7 @@ widget.moveToLayout(newLayout); setTimeout(() => { - expect(newLayout.dragboard.update).toHaveBeenCalledWith(["23"]); + expect(newLayout.dragboard.update).toHaveBeenCalledWith(["23"], true); done(); }); }); @@ -236,7 +252,7 @@ widget.moveToLayout(newLayout); setTimeout(() => { expect(widget.layout).toBe(newLayout); - expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23", "1"]); + expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23", "1"], true); done(); }); }); @@ -262,8 +278,8 @@ expect(widget.model.changeTab).toHaveBeenCalledWith(tab2.model); expect(widget.tab).toBe(tab2); expect(widget.layout).toBe(newLayout); - expect(oldLayout.dragboard.update).toHaveBeenCalledWith(["1"]); - expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23"]); + expect(oldLayout.dragboard.update).toHaveBeenCalledWith(["1"], true); + expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23"], true); done(); }); }); @@ -288,8 +304,8 @@ widget.moveToLayout(newLayout); setTimeout(() => { expect(widget.layout).toBe(newLayout); - expect(oldLayout.dragboard.update).toHaveBeenCalledWith(["1"]); - expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23"]); + expect(oldLayout.dragboard.update).toHaveBeenCalledWith(["1"], true); + expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23"], true); done(); }); }); @@ -309,13 +325,15 @@ widget.layout = this; return new Set(["3", "4"]); }); + Wirecloud.Utils.getLayoutMatrix = jasmine.createSpy("getLayoutMatrix"); + newLayout._searchFreeSpace2.and.returnValue({relx: true, rely: true, relwidth: true, relheight: true, anchor: "top-left", x: 1, y: 2}); newLayout._searchFreeSpace.and.returnValue({relx: true, rely: true, relwidth: true, relheight: true, anchor: "top-left", x: 1, y: 2}); widget.moveToLayout(newLayout); setTimeout(() => { expect(widget.layout).toBe(newLayout); - expect(oldLayout.dragboard.update).toHaveBeenCalledWith(["1"]); - expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23"]); + expect(oldLayout.dragboard.update).toHaveBeenCalledWith(["1"], true); + expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "4", "23"], true); done(); }); }); @@ -333,7 +351,7 @@ widget.moveToLayout(newLayout); setTimeout(() => { expect(widget.layout).toBe(newLayout); - expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "5", "23"]); + expect(newLayout.dragboard.update).toHaveBeenCalledWith(["3", "5", "23"], true); done(); }); }); @@ -544,19 +562,25 @@ id: "23", tab: "123", layout: 0, - minimized: false, - anchor: "topleft", - relx: true, - rely: true, - top: 0, - left: 3, - zIndex: 0, - relwidth: true, - width: 5, - relheight: true, - height: 1, - fulldragboard: false, - titlevisible: true + layoutConfigurations: [{ + id: 0, + moreOrEqual: 0, + lessOrEqual: -1, + action: 'update', + minimized: false, + anchor: "topleft", + relx: true, + rely: true, + top: 0, + left: 3, + zIndex: 0, + relwidth: true, + width: 5, + relheight: true, + height: 1, + fulldragboard: false, + titlevisible: true + }] }); }); @@ -569,19 +593,25 @@ id: "23", tab: "123", layout: 0, - minimized: false, - anchor: "topleft", - relx: true, - rely: true, - top: 0, - left: 3, - zIndex: 0, - relwidth: true, - width: 5, - relheight: true, - height: 1, - fulldragboard: true, - titlevisible: true + layoutConfigurations: [{ + id: 0, + moreOrEqual: 0, + lessOrEqual: -1, + action: 'update', + minimized: false, + anchor: "topleft", + relx: true, + rely: true, + top: 0, + left: 3, + zIndex: 0, + relwidth: true, + width: 5, + relheight: true, + height: 1, + fulldragboard: true, + titlevisible: true + }] }); }); diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js index db61b4846a..4d36b00525 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js @@ -74,7 +74,8 @@ }, setPosition: jasmine.createSpy("setPosition").and.callFake(function (options) { this.position.z = options.z; - }) + }), + toJSON: function () {} }; }; @@ -341,11 +342,11 @@ expect(dragboard.widgets).toEqual([widget1, widget3]); expect(widget1.setPosition).toHaveBeenCalledWith({ - z: 0 - }); + z: 0, + }, false); expect(widget3.setPosition).toHaveBeenCalledWith({ z: 1 - }); + }, false); }); it("should do nothing if already painted", () => { diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js index b277a01921..5c41c88efa 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js @@ -43,7 +43,13 @@ createWidget: jasmine.createSpy("createWidget"), id: "8", preferences: { - get: jasmine.createSpy("get"), + get: jasmine.createSpy("get").and.callFake(function (key) { + if (options && key in options.customPreferences) { + return options.customPreferences[key]; + } else if (key === "screenSizes") { + return [{id: 0, moreOrEqual: 0, lessOrEqual: -1}]; + } + }), addEventListener: jasmine.createSpy("addEventListener") }, title: "Tab Title", @@ -317,16 +323,20 @@ it("should honour initiallayout preference", (done) => { const workspace = create_workspace(); - const model = create_tab(); - model.preferences.get.and.returnValue("Free"); + const tabOptions = { + customPreferences: { + initiallayout: "Free" + } + }; + const model = create_tab(tabOptions); const tab = new ns.WorkspaceTabView("1", notebook, { model: model, workspace: workspace }); const widgetmodel = {id: 80}; model.createWidget.and.callFake((resource, options) => { - expect(options.left).toEqual(1); - expect(options.top).toEqual(2); + expect(options.layoutConfigurations[0].left).toEqual(1); + expect(options.layoutConfigurations[0].top).toEqual(2); return Promise.resolve(widgetmodel); }); const widget = {id: 80}; @@ -334,7 +344,10 @@ expect(id).toBe(80); return widget; }); - tab.dragboard.freeLayout._searchFreeSpace = jasmine.createSpy("_searchFreeSpace").and.returnValue({x: 1, y: 2}); + tab.dragboard.freeLayout._searchFreeSpace2 = jasmine.createSpy("_searchFreeSpace2").and.returnValue({x: 1, y: 2}); + tab.dragboard.freeLayout.dragboard = { + widgets: [] + }; const p = tab.createWidget({ default_height: "120px", @@ -356,8 +369,8 @@ }); const widgetmodel = {id: 80}; model.createWidget.and.callFake((resource, options) => { - expect(options.left).toEqual(0); - expect(options.top).toEqual(0); + expect(options.layoutConfigurations[0].left).toEqual(0); + expect(options.layoutConfigurations[0].top).toEqual(0); return Promise.resolve(widgetmodel); }); const widget = {id: 80}; diff --git a/src/wirecloud/commons/static/js/StyledElements/NumericField.js b/src/wirecloud/commons/static/js/StyledElements/NumericField.js index 1d34e0a441..33ae0f6688 100644 --- a/src/wirecloud/commons/static/js/StyledElements/NumericField.js +++ b/src/wirecloud/commons/static/js/StyledElements/NumericField.js @@ -27,28 +27,6 @@ "use strict"; - const update = function update(inc) { - let value = this.getValue(); - if (!isNaN(value)) { - value = Math.round((value + inc) * 100) / 100; - - // Check for max & min values - if (value > this.options.max) { - value = this.options.max; - } else if (value < this.options.min) { - value = this.options.min; - } - } else if (inc > 0 && this.options.min !== Number.NEGATIVE_INFINITY) { - value = this.options.min; - } else if (inc < 0 && this.options.max !== Number.POSITIVE_INFINITY) { - value = this.options.max; - } else { - value = 0; - } - - this.inputElement.value = value; - }; - const onfocus = function onfocus() { this.wrapperElement.classList.add('focus'); this.dispatchEvent('focus'); diff --git a/src/wirecloud/platform/static/js/wirecloud/Widget.js b/src/wirecloud/platform/static/js/wirecloud/Widget.js index cb47f96a5a..990716d1dd 100644 --- a/src/wirecloud/platform/static/js/wirecloud/Widget.js +++ b/src/wirecloud/platform/static/js/wirecloud/Widget.js @@ -252,9 +252,9 @@ const _getCurrentLayoutConfiguration = function _getCurrentLayoutConfiguration(layoutConfigurations, windowSize) { let currentLayoutConfiguration; for (const i in layoutConfigurations) { - const isValid = (layoutConfigurations[i]["moreOrEqual"] != -1 && layoutConfigurations[i]["lessOrEqual"] == -1 && layoutConfigurations[i].moreOrEqual <= windowSize) || - (layoutConfigurations[i]["moreOrEqual"] == -1 && layoutConfigurations[i]["lessOrEqual"] != -1 && layoutConfigurations[i].lessOrEqual >= windowSize) || - (layoutConfigurations[i]["moreOrEqual"] != -1 && layoutConfigurations[i]["lessOrEqual"] != -1 && layoutConfigurations[i].moreOrEqual <= windowSize && layoutConfigurations[i].lessOrEqual >= windowSize); + const isValid = (layoutConfigurations[i].moreOrEqual !== -1 && layoutConfigurations[i].lessOrEqual === -1 && layoutConfigurations[i].moreOrEqual <= windowSize) || + (layoutConfigurations[i].moreOrEqual === -1 && layoutConfigurations[i].lessOrEqual !== -1 && layoutConfigurations[i].lessOrEqual >= windowSize) || + (layoutConfigurations[i].moreOrEqual !== -1 && layoutConfigurations[i].lessOrEqual !== -1 && layoutConfigurations[i].moreOrEqual <= windowSize && layoutConfigurations[i].lessOrEqual >= windowSize); if (isValid) { currentLayoutConfiguration = layoutConfigurations[i]; @@ -446,6 +446,24 @@ title: meta.title, preferences: {}, properties: {}, + layoutConfigurations: [{ + id: 0, + moreOrEqual: 0, + lessOrEqual: -1, + anchor: 'top-left', + relx: true, + rely: true, + left: 0, + top: 0, + zIndex: 0, + relheight: true, + relwidth: true, + height: 1, + width: 1, + minimized: false, + fulldragboard: false, + titlevisible: true + }], titlevisible: true }, data); @@ -637,10 +655,10 @@ * @type {Boolean} */ minimized: { - get: function() { + get: function () { return privates.get(this).currentLayoutConfiguration.minimized; }, - set: function(value) { + set: function (value) { privates.get(this).currentLayoutConfiguration.minimized = value; } }, diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js index 6c0d796c6d..b201c68f28 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js @@ -139,7 +139,7 @@ offsetInLU = Math.round(parsedSize[0]); } else { if (parsedSize[1] === '%') { - pixels = Math.round((parsedSize[0] * width || this.getWidth()) / 100); + pixels = Math.round((parsedSize[0] * (width || this.getWidth())) / 100); } else { pixels = parsedSize[0] < this.dragboard.leftMargin ? 0 : parsedSize[0] - this.dragboard.leftMargin; } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js index 7f15b8ae11..84f7fd568e 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js @@ -111,6 +111,10 @@ const tabChange = priv.tab !== newLayout.dragboard.tab; const dragboardChange = this.layout.dragboard !== newLayout.dragboard || tabChange; + if (!('layoutConfigurations' in this.model)) { // Tests may not have this method + return; + } + layoutConfigurations.forEach((layoutConfiguration) => { if (this.layout instanceof Wirecloud.ui.FullDragboardLayout || newLayout instanceof Wirecloud.ui.FullDragboardLayout) { // Skip if coming from or going to a FullDragboardLayout @@ -143,13 +147,6 @@ relheight: true, height: newLayout.adaptHeight(previousHeight + 'px').inLU }); - - console.log("newShape", { - relwidth: true, - width: newLayout.adaptWidth(previousWidth + 'px', avgScreenSize).inLU, - relheight: true, - height: newLayout.adaptHeight(previousHeight + 'px').inLU - }); } if (dragboardChange && !(newLayout instanceof Wirecloud.ui.FreeLayout)) { @@ -258,8 +255,10 @@ set: function (new_layout) { privates.get(this).layout = new_layout; const fulldragboard = new_layout instanceof Wirecloud.ui.FullDragboardLayout; - this.model.setLayoutFulldragboard(fulldragboard); - if (!fulldragboard && new_layout != null) { + if ('setLayoutFulldragboard' in this.model) { // Tests may not have this method + this.model.setLayoutFulldragboard(fulldragboard); + } + if (!fulldragboard && new_layout != null && 'setLayoutIndex' in this.model) { this.model.setLayoutIndex(new_layout.dragboard.layouts.indexOf(new_layout)); } update.call(this); @@ -461,8 +460,8 @@ // Init minimized and title visibility options let wrapperHeight = this.wrapperElement.offsetHeight; - wrapperHeight = (wrapperHeight === 0) ? 42 : wrapperHeight; // On first load, the height is 0. This is a workaround to avoid this issue - // and set the correct height to the widget + // On first load, the height is 0. This is a workaround to avoid this issue and set the correct height to the widget + wrapperHeight = (wrapperHeight === 0) ? 42 : wrapperHeight; this._setMinimizeStatusStyle(model.minimized, layout, wrapperHeight); layout.addWidget(this, true); @@ -865,7 +864,7 @@ } } - toJSON(action, allLayoutConfigurations) { + toJSON(action = 'update', allLayoutConfigurations = false) { const fulldragboard = this.layout === this.tab.dragboard.fulldragboardLayout; // We keep all or only the current layout configuration and then we clone it to add the action diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index c51cebf74d..01aae8a6bb 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -316,7 +316,7 @@ } if (layoutConfig.left == null || layoutConfig.top == null) { - if (layoutConfig.refposition && "searchBestPosition" in layout) { + if (options.refposition && "searchBestPosition" in layout) { layout.searchBestPosition(layoutConfig, avgScreenSize); } else if ("_searchFreeSpace2" in layout) { const matrix = Wirecloud.Utils.getLayoutMatrix(layout, layout.dragboard.widgets, avgScreenSize); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js index 5a4ed93e68..27228f751c 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js @@ -140,7 +140,9 @@ this.walletButton.active = false; this.layout.slideOut(); this.tabs.forEach((tab) => { - tab.quitEditingInterval(); + if (tab.quitEditingInterval) { + tab.quitEditingInterval(); + } }); } this.activeTab.dragboard._updateIWidgetSizes(true, true); From d063cb686b23b81a1c9f16930a431f8a2e77e0d9 Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 25 Jun 2024 11:10:44 +0200 Subject: [PATCH 10/28] Fix small bug and selenium tests --- .../platform/static/js/wirecloud/ui/WorkspaceTabView.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index 01aae8a6bb..414e55425e 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -258,7 +258,7 @@ * resolved, or an Error if rejected. */ createWidget(resource, options) { - const layoutConfigs = utils.clone(this.model.preferences.get('screenSizes')); + const layoutConfigs = utils.clone(this.model.preferences.get('screenSizes'), true); options = utils.merge({ commit: true, @@ -266,6 +266,7 @@ }, options); layoutConfigs.forEach((layoutConfig) => { + Wirecloud.Utils.merge(layoutConfig, { action: 'update', width: resource.default_width, From 64d36d45b80344774d4eca98501de029b98962f7 Mon Sep 17 00:00:00 2001 From: oxixes Date: Fri, 28 Jun 2024 11:02:37 +0200 Subject: [PATCH 11/28] Some work on tests --- src/GruntFile.js | 2 +- src/js_tests/styledelements/AlertSpec.js | 17 + src/js_tests/wirecloud/WidgetSpec.js | 210 ++++++++++++ .../ui/ScreenSizesInputInterfaceSpec.js | 319 ++++++++++++++++++ src/js_tests/wirecloud/ui/WidgetViewSpec.js | 179 +++++++++- .../ui/WorkspaceTabViewDragboardSpec.js | 46 ++- .../wirecloud/ui/WorkspaceTabViewSpec.js | 48 ++- .../commons/static/js/StyledElements/Alert.js | 1 - .../js/StyledElements/InputInterface.js | 8 +- .../static/js/wirecloud/ui/WindowMenu.js | 4 +- .../js/wirecloud/UserInterfaceManager.js | 8 +- .../static/js/wirecloud/ui/DragboardLayout.js | 10 +- .../wirecloud/ui/ScreenSizesInputInterface.js | 21 +- .../static/js/wirecloud/ui/WidgetView.js | 14 +- .../js/wirecloud/ui/WorkspaceTabView.js | 4 + .../wirecloud/ui/WorkspaceTabViewDragboard.js | 18 +- .../workspace/mashupTemplateGenerator.py | 2 - 17 files changed, 858 insertions(+), 53 deletions(-) create mode 100644 src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js diff --git a/src/GruntFile.js b/src/GruntFile.js index ed0f9f33aa..15397c8a7f 100644 --- a/src/GruntFile.js +++ b/src/GruntFile.js @@ -150,7 +150,7 @@ var WirecloudFiles = [ 'wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js', 'wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js', 'wirecloud/platform/static/js/wirecloud/ui/SharingWindowMenu.js', - + 'wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js', 'wirecloud/platform/static/js/wirecloud/DragboardPosition.js', 'wirecloud/platform/static/js/wirecloud/ui/DragboardCursor.js', 'wirecloud/platform/static/js/wirecloud/ui/MultiValuedSize.js', diff --git a/src/js_tests/styledelements/AlertSpec.js b/src/js_tests/styledelements/AlertSpec.js index 571d1ef87f..0c22be8090 100644 --- a/src/js_tests/styledelements/AlertSpec.js +++ b/src/js_tests/styledelements/AlertSpec.js @@ -43,6 +43,23 @@ expect(element.body).toEqual(jasmine.any(se.Container)); }); + it("should allow changing the message", () => { + const element = new se.Alert(); + element.setMessage("New message"); + + expect(element.body.wrapperElement.textContent).toEqual("New message"); + }); + + it("should allow to show and hide the alert", () => { + const element = new se.Alert(); + element.hide(); + + expect(element.wrapperElement.style.display).toEqual("none"); + + element.show(); + expect(element.wrapperElement.style.display).toEqual(""); + }); + }); }); diff --git a/src/js_tests/wirecloud/WidgetSpec.js b/src/js_tests/wirecloud/WidgetSpec.js index b1dc0826d1..d57dbb8140 100644 --- a/src/js_tests/wirecloud/WidgetSpec.js +++ b/src/js_tests/wirecloud/WidgetSpec.js @@ -238,6 +238,61 @@ }; Object.freeze(WIDGET_META_PREFS); + const WIDGET_LAYOUT_CONFIGS = [{ + id: 0, + moreOrEqual: 0, + lessOrEqual: 800, + anchor: 'top-left', + relx: true, + rely: true, + left: 0, + top: 0, + zIndex: 0, + relheight: true, + relwidth: true, + height: 1, + width: 1, + minimized: false, + fulldragboard: false, + titlevisible: true + }, { + id: 1, + moreOrEqual: 801, + lessOrEqual: 999, + anchor: 'top-right', + relx: true, + rely: true, + left: 1, + top: 0, + zIndex: 1, + relheight: true, + relwidth: true, + height: 2, + width: 1, + minimized: false, + fulldragboard: true, + titlevisible: true + }, + { + id: 2, + moreOrEqual: 1000, + lessOrEqual: -1, + anchor: 'top-left', + relx: true, + rely: true, + left: 0, + top: 0, + zIndex: 0, + relheight: true, + relwidth: true, + height: 1, + width: 1, + minimized: false, + fulldragboard: false, + titlevisible: true + }]; + Object.freeze(WIDGET_LAYOUT_CONFIGS); + describe("Wirecloud.Widget", function () { beforeAll(() => { @@ -1776,6 +1831,7 @@ const p = widget.setTitleVisibility(true, false); expect(widget.titlevisible).toBe(true); + expect(widget.currentLayoutConfig.titlevisible).toBe(true); expect(Wirecloud.io.makeRequest).not.toHaveBeenCalled(); p.then( (value) => { @@ -1806,6 +1862,7 @@ }); }); expect(widget.titlevisible).toBe(false); + expect(widget.currentLayoutConfig.titlevisible).toBe(false); const p = widget.setTitleVisibility(true, true); p.then( @@ -2249,6 +2306,159 @@ }); + describe("updateWindowSize(windowSize)", () => { + + it("should update the widget information accordingly", () => { + + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { + id: "1", + layoutConfigurations: WIDGET_LAYOUT_CONFIGS + }); + + expect(widget.layoutConfigurations).toBe(WIDGET_LAYOUT_CONFIGS); + + expect(widget.updateWindowSize(800)).toBe(false); + expect(widget.updateWindowSize(900)).toBe(true); + + expect(widget.currentLayoutConfig).toBe(widget.layoutConfigurations[1]); + + expect(widget.fulldragboard).toBe(true); + expect(widget.position.z).toBe(1); + expect(widget.shape.height).toBe(2); + + expect(widget.updateWindowSize(800)).toBe(true); + + expect(widget.currentLayoutConfig).toBe(widget.layoutConfigurations[0]); + + expect(widget.fulldragboard).toBe(false); + expect(widget.position.z).toBe(0); + expect(widget.shape.height).toBe(1); + + }); + + }); + + describe("setLayoutPosition(layoutPosition)", () => { + + it("should update the current layout position accordingly", () => { + + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { + id: "1", + layoutConfigurations: WIDGET_LAYOUT_CONFIGS + }); + + expect(widget.setLayoutPosition({ + anchor: 'top-left', + relx: false, + rely: true, + x: 1, + y: 0, + z: 0 + })).toBe(widget); + + expect(widget.currentLayoutConfig.left).toBe(1); + expect(widget.currentLayoutConfig.relx).toBe(false); + + expect(widget.position.x).toBe(0); + expect(widget.position.relx).toBe(true); + + }); + + }); + + describe("setLayoutShape(layoutShape)", () => { + + it("should update the current layout shape accordingly", () => { + + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { + id: "1", + layoutConfigurations: WIDGET_LAYOUT_CONFIGS + }); + + expect(widget.setLayoutShape({ + relwidth: false, + relheight: true, + width: 1, + height: 2 + })).toBe(widget); + + expect(widget.currentLayoutConfig.height).toBe(2); + expect(widget.currentLayoutConfig.relwidth).toBe(false); + + expect(widget.shape.height).toBe(1); + expect(widget.shape.relwidth).toBe(true); + + }); + + }); + + describe("setLayoutIndex(index)", () => { + + it("should update the layout accordingly", () => { + + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { + id: "1", + layoutConfigurations: WIDGET_LAYOUT_CONFIGS + }); + + expect(widget.setLayoutIndex(3)).toBe(widget); + expect(widget.layout).toBe(3); + + widget.setLayoutIndex(1); + expect(widget.layout).toBe(1); + }); + + }); + + describe("setLayoutFulldragboard(fulldragboard)", () => { + + it("should update the fulldragboard property of the layout accordingly", () => { + + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { + id: "1", + layoutConfigurations: WIDGET_LAYOUT_CONFIGS + }); + + expect(widget.setLayoutFulldragboard(true)).toBe(widget); + expect(widget.currentLayoutConfig.fulldragboard).toBe(true); + expect(widget.fulldragboard).toBe(false); + }); + + }); + + describe("setLayoutMinimizedStatus(minimized)", () => { + + it("should update the minimized property of the layout accordingly", () => { + + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { + id: "1", + layoutConfigurations: WIDGET_LAYOUT_CONFIGS + }); + + expect(widget.setLayoutMinimizedStatus(true)).toBe(widget); + expect(widget.minimized).toBe(widget.currentLayoutConfig.minimized); + expect(widget.currentLayoutConfig.minimized).toBe(true); + }); + + }); + + describe("getLayoutConfigBySize(size)", () => { + + it("should return the layout configuration that fits the given size", () => { + + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { + id: "1", + layoutConfigurations: WIDGET_LAYOUT_CONFIGS + }); + + expect(widget.getLayoutConfigBySize(800)).toBe(widget.layoutConfigurations[0]); + expect(widget.getLayoutConfigBySize(900)).toBe(widget.layoutConfigurations[1]); + expect(widget.getLayoutConfigBySize(1000)).toBe(widget.layoutConfigurations[2]); + + }); + + }); + }); })(); diff --git a/src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js b/src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js new file mode 100644 index 0000000000..d015a54527 --- /dev/null +++ b/src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2024 Future Internet Consulting and Development Solutions S.L. + * + * This file is part of Wirecloud Platform. + * + * Wirecloud Platform is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * Wirecloud 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 Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Wirecloud Platform. If not, see + * . + * + */ + +/* globals StyledElements, Wirecloud */ + +(function (ns, se, utils) { + + "use strict"; + + describe('ScreenSizesInputInterface', function () { + + it("is a class constructor", () => { + expect(() => { + ns.ScreenSizesInputInterface("pass", {}); // eslint-disable-line new-cap + }).toThrowError(TypeError); + }); + + it("requires fieldId and description parameters", () => { + expect(() => { + new ns.ScreenSizesInputInterface(); + }).toThrowError(TypeError); + }); + + it("should work by providing the minimum details", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + expect(field.id).toBe("code"); + expect(field).toEqual(jasmine.any(se.InputInterface)); + }); + + }); + + describe("ScreenSizesInputInterface.parse(value)", () => { + + it("should return the JSON parsed value", () => { + expect(ns.ScreenSizesInputInterface.parse(1)).toBe(1); + }); + + }); + + describe("ScreenSizesInputInterface.stringify(value)", () => { + + it("should return the JSON stringified value", () => { + expect(ns.ScreenSizesInputInterface.stringify("value")).toBe('"value"'); + }); + + }); + + describe("ScreenSizesInputInterface._normalize()", () => { + + it("should return the value as is", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + expect(field._normalize("value")).toBe("value"); + }); + + }); + + describe("ScreenSizesInputInterface.insertInto()", () => { + + it("should insert the input element into the provided container", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + const container = document.createElement("div"); + field.insertInto(container); + expect(container.children.length).toBe(1); + }); + + }); + + describe("ScreenSizesInputInterface.repaint()", () => { + + it("should repaint the input element", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + field.wrapperElement.repaint = jasmine.createSpy("repaint"); + field.repaint(); + expect(field.wrapperElement.repaint).toHaveBeenCalled(); + }); + + }); + + describe("ScreenSizesInputInterface.setDisabled()", () => { + + it("should set the disabled state of the input element", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + field.addButton.setDisabled = jasmine.createSpy("setDisabled"); + + field.setDisabled(true); + expect(field.addButton.setDisabled).toHaveBeenCalledWith(true); + + field.setDisabled(false); + expect(field.addButton.setDisabled).toHaveBeenCalledWith(false); + }); + + }); + + describe("ScreenSizesInputInterface._checkValue()", () => { + + it("should return an error if the value is not a valid screen size", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + expect(field._checkValue("value")).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + expect(field._checkValue({})).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + expect(field._checkValue([])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + expect(field._checkValue([{ + "moreOrEqual": 0, + "lessOrEqual": -1, + "id": 0 + }, { + "moreOrEqual": 0, + "lessOrEqual": -1, + "id": 1 + }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + + expect(field._checkValue([{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }, { + "moreOrEqual": 802, + "lessOrEqual": -1, + "id": 1 + }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + + expect(field._checkValue([{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }, { + "moreOrEqual": 700, + "lessOrEqual": -1, + "id": 1 + }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + + expect(field._checkValue([{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + + expect(field._checkValue([{ + "moreOrEqual": 1, + "lessOrEqual": -1, + "id": 0 + }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); + }); + + it("should return no error if the value is a valid screen size", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + expect(field._checkValue([{ + "moreOrEqual": 0, + "lessOrEqual": -1, + "id": 0 + }])).toBe(se.InputValidationError.NO_ERROR); + + expect(field._checkValue([{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }, { + "moreOrEqual": 801, + "lessOrEqual": -1, + "id": 1 + }])).toBe(se.InputValidationError.NO_ERROR); + }); + + }); + + describe("ScreenSizesInputInterface._update()", () => { + + it("should update the input element", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + const value = [{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }, { + "moreOrEqual": 801, + "lessOrEqual": -1, + "id": 1 + }]; + + field.setValue(value); + expect(field.getValue()).toBe(value); + }); + + it("should sort the screen sizes", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + const value = [{ + "moreOrEqual": 801, + "lessOrEqual": -1, + "id": 1 + }, { + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }]; + + field.setValue(value); + expect(field.getValue()).toEqual([{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }, { + "moreOrEqual": 801, + "lessOrEqual": -1, + "id": 1 + }]); + }); + + }); + + describe("ScreenSizesInputInterface.on_addScreenSize()", () => { + + it("should add a screen size accordingly", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + field._setValue([{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }]); + + field.on_addScreenSize(); + + expect(field.getValue()).toEqual([{ + "moreOrEqual": 0, + "lessOrEqual": -1, + "id": 0 + }, { + "moreOrEqual": 0, + "lessOrEqual": -1, + "id": 1 + }]); + }); + + }); + + describe("ScreenSizesInputInterface.on_deleteScreenSize()", () => { + + it("should delete a screen size accordingly", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + field.setValue([{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }, { + "moreOrEqual": 801, + "lessOrEqual": -1, + "id": 1 + }]); + + field.on_deleteScreenSize(0); + + expect(field.getValue()).toEqual([{ + "moreOrEqual": 0, + "lessOrEqual": -1, + "id": 1 + }]); + }); + + }); + + describe("ScreenSizesInputInterface.on_valueChange()", () => { + + it("should update the input element", () => { + const field = new ns.ScreenSizesInputInterface("code", {}); + const value = [{ + "moreOrEqual": 0, + "lessOrEqual": 800, + "id": 0 + }, { + "moreOrEqual": 801, + "lessOrEqual": -1, + "id": 1 + }]; + + field.setValue(value); + field.on_valueChange(1, "moreOrEqual", 100); + + expect(JSON.stringify(field.getValue())).toBe(JSON.stringify([{ + "moreOrEqual": 0, + "lessOrEqual": 99, + "id": 0 + }, { + "moreOrEqual": 100, + "lessOrEqual": -1, + "id": 1 + }])); + + field.on_valueChange(0, "lessOrEqual", 1000); + + expect(field.getValue()).toEqual([{ + "moreOrEqual": 0, + "lessOrEqual": 1000, + "id": 0 + }, { + "moreOrEqual": 1001, + "lessOrEqual": -1, + "id": 1 + }]); + }); + + }); + +})(Wirecloud.ui, StyledElements, StyledElements.Utils); \ No newline at end of file diff --git a/src/js_tests/wirecloud/ui/WidgetViewSpec.js b/src/js_tests/wirecloud/ui/WidgetViewSpec.js index 54a8d6bd84..97639f4490 100644 --- a/src/js_tests/wirecloud/ui/WidgetViewSpec.js +++ b/src/js_tests/wirecloud/ui/WidgetViewSpec.js @@ -127,7 +127,7 @@ const layoutConfigurations = [{ id: 0, moreOrEqual: 0, - lessOrEqual: -1, + lessOrEqual: 800, anchor: options.anchor != null ? options.anchor : "topleft", relx: options.relx != null ? options.relx : true, left: 3, @@ -141,6 +141,24 @@ fulldragboard: !!options.fulldragboard, titlevisible: true, minimized: false + }, + { + id: 1, + moreOrEqual: 801, + lessOrEqual: -1, + anchor: "topleft", + relx: true, + left: 10, + rely: true, + top: 2, + zIndex: 0, + relwidth: true, + width: 6, + relheight: false, + height: 2, + fulldragboard: true, + titlevisible: true, + minimized: false }]; return { @@ -177,6 +195,9 @@ setLayoutShape: jasmine.createSpy("setLayoutShape"), setTitleVisibility: jasmine.createSpy("setTitleVisibility").and.returnValue(new Wirecloud.Task("", () => {})), setLayoutMinimizedStatus: jasmine.createSpy("setLayoutMinimizedStatus"), + setLayoutFulldragboard: jasmine.createSpy("setLayoutFulldragboard"), + setLayoutIndex: jasmine.createSpy("setLayoutIndex"), + updateWindowSize: jasmine.createSpy("updateWindowSize"), showLogs: jasmine.createSpy("showLogs"), showSettings: jasmine.createSpy("showSettings"), title: "My Widget", @@ -358,6 +379,106 @@ }); + describe("updateWindowSize(windowSize)", () => { + + it("should update the window size going to a non-full dragboard layout", () => { + const tab = create_tab_mock(); + const model = create_widget_mock({layout: 0}); + const widget = new ns.WidgetView(tab, model); + + model.updateWindowSize.and.callFake(() => { + model.position = { + x: 1, + y: 2, + z: 3, + relx: true, + rely: true, + anchor: "top-left" + }; + model.shape = { + relwidth: true, + relheight: true, + width: 4, + height: 5 + } + }); + + widget.layout.removeWidgetEventListeners = jasmine.createSpy("removeWidgetEventListeners"); + widget.setPosition = jasmine.createSpy("setPosition"); + widget.setShape = jasmine.createSpy("setShape"); + + widget.updateWindowSize(900); + expect(model.updateWindowSize).toHaveBeenCalledWith(900); + expect(widget.layout.removeWidgetEventListeners).toHaveBeenCalledWith(widget); + expect(widget.setPosition).toHaveBeenCalledWith({ + x: 1, + y: 2, + z: 3, + relx: true, + rely: true, + anchor: "top-left" + }, false); + expect(widget.setShape).toHaveBeenCalledWith({ + relwidth: true, + relheight: true, + width: 4, + height: 5 + }, false, false, false, false); + expect(tab.dragboard.layouts[0].addWidget).toHaveBeenCalledWith(widget, false); + }); + + it("should update the window size going to a full dragboard layout", () => { + const tab = create_tab_mock(); + const model = create_widget_mock({layout: 2, fulldragboard: false}); + const widget = new ns.WidgetView(tab, model); + + model.updateWindowSize.and.callFake(() => { + model.position = { + x: 1, + y: 2, + z: 3, + relx: true, + rely: true, + anchor: "top-left" + }; + model.shape = { + relwidth: true, + relheight: true, + width: 4, + height: 5 + }; + model.fulldragboard = true; + }); + + tab.dragboard.layouts[2].removeWidgetEventListeners = jasmine.createSpy("removeWidgetEventListeners"); + tab.dragboard.layouts[2].removeHandle = jasmine.createSpy("removeHandle"); + widget.setPosition = jasmine.createSpy("setPosition"); + widget.setShape = jasmine.createSpy("setShape"); + + widget.updateWindowSize(900); + expect(model.updateWindowSize).toHaveBeenCalledWith(900); + expect(tab.dragboard.layouts[2].removeWidgetEventListeners).toHaveBeenCalledWith(widget); + expect(tab.dragboard.layouts[2].removeHandle).toHaveBeenCalled(); + + expect(widget.setPosition).toHaveBeenCalledWith({ + x: 1, + y: 2, + z: 3, + relx: true, + rely: true, + anchor: "top-left" + }, false); + expect(widget.setShape).toHaveBeenCalledWith({ + relwidth: true, + relheight: true, + width: 4, + height: 5 + }, false, false, false, false); + expect(tab.dragboard.fulldragboardLayout.addWidget).toHaveBeenCalledWith(widget, false); + }); + + }); + describe("togglePermission(permission, persitence)", () => { it("should work for enabling a permission", () => { @@ -551,7 +672,7 @@ }); - describe("toJSON()", () => { + describe("toJSON([action, allLayoutConfigurations])", () => { it("should work on normal widgets", () => { const tab = create_tab_mock(); @@ -565,7 +686,7 @@ layoutConfigurations: [{ id: 0, moreOrEqual: 0, - lessOrEqual: -1, + lessOrEqual: 800, action: 'update', minimized: false, anchor: "topleft", @@ -596,7 +717,7 @@ layoutConfigurations: [{ id: 0, moreOrEqual: 0, - lessOrEqual: -1, + lessOrEqual: 800, action: 'update', minimized: false, anchor: "topleft", @@ -615,6 +736,56 @@ }); }); + it("should list all layout configurations if specified", () => { + const tab = create_tab_mock(); + const model = create_widget_mock({layout: 0}); + const widget = new ns.WidgetView(tab, model); + + expect(widget.toJSON('update', true)).toEqual({ + id: "23", + tab: "123", + layout: 0, + layoutConfigurations: [{ + id: 0, + moreOrEqual: 0, + lessOrEqual: 800, + action: 'update', + minimized: false, + anchor: "topleft", + relx: true, + rely: true, + top: 0, + left: 3, + zIndex: 0, + relwidth: true, + width: 5, + relheight: true, + height: 1, + fulldragboard: false, + titlevisible: true + }, + { + id: 1, + moreOrEqual: 801, + lessOrEqual: -1, + anchor: "topleft", + action: 'update', + relx: true, + left: 10, + rely: true, + top: 2, + zIndex: 0, + relwidth: true, + width: 6, + relheight: false, + height: 2, + fulldragboard: true, + titlevisible: true, + minimized: false + }] + }); + }); + }); describe("events", () => { diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js index 4d36b00525..21fb0d3d8b 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js @@ -45,7 +45,8 @@ id: 8 }, restricted: false - } + }, + quitEditingInterval: jasmine.createSpy("quitEditingInterval") }; }; @@ -571,7 +572,7 @@ }); - describe("update([ids])", () => { + describe("update([ids, allLayoutConfigurations])", () => { let dragboard, widget1, widget2, widget3; @@ -662,6 +663,24 @@ }, fail); }); + it("should honor the allLayoutConfigurations parameter", (done) => { + spyOn(Wirecloud.io, "makeRequest").and.callFake((url, options) => { + return new Wirecloud.Task("Sending request", (resolve) => {resolve({status: 204});}); + }); + + dragboard.tab.widgetsById["1"].toJSON = jasmine.createSpy("toJSON").and.returnValue({"hello": "world"}); + + const p = dragboard.update(null, true); + expect(dragboard.tab.widgetsById["1"].toJSON).toHaveBeenCalledWith('update', true); + + p.then(() => { + expect(Wirecloud.io.makeRequest).toHaveBeenCalled(); + const body = JSON.parse(Wirecloud.io.makeRequest.calls.argsFor(0)[1].postBody); + expect(body.length).toBe(3); + done(); + }, fail); + }); + it("handles unexpected responses", (done) => { spyOn(Wirecloud.io, "makeRequest").and.callFake(function (url, options) { @@ -714,6 +733,29 @@ }); + describe("refreshPositionBasedOnZIndex()", () => { + + it("should sort widgets by z-index", () => { + const tab = create_tab(); + const dragboard = new ns.WorkspaceTabViewDragboard(tab); + + Array.prototype.push.apply(dragboard.widgets, [ + {position: {z: 2}}, + {position: {z: 1}}, + {position: {z: 3}} + ]); + + dragboard.refreshPositionBasedOnZIndex(); + + expect(dragboard.widgets).toEqual([ + {position: {z: 1}}, + {position: {z: 2}}, + {position: {z: 3}} + ]); + }); + + }); + }); })(Wirecloud.ui, StyledElements.Utils); diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js index 5c41c88efa..7a8c9e328d 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js @@ -304,7 +304,7 @@ expect(id).toBe(80); return widget; }); - tab.dragboard.freeLayout.searchBestPosition = jasmine.createSpy("searchBestPosition").and.returnValue({x: 1, y: 2}); + tab.dragboard.freeLayout.searchBestPosition = jasmine.createSpy("searchBestPosition"); const created_widget = tab.createWidget( { @@ -584,6 +584,52 @@ }); }); + it("should define all screen sizes when creating a widget", (done) => { + const workspace = create_workspace(); + const model = create_tab({ + customPreferences: { + screenSizes: [ + {id: 0, moreOrEqual: 0, lessOrEqual: 800}, + {id: 1, moreOrEqual: 801, lessOrEqual: 1000}, + {id: 2, moreOrEqual: 1001, lessOrEqual: -1} + ] + } + }); + const tab = new ns.WorkspaceTabView("1", notebook, { + model: model, + workspace: workspace + }); + + const widgetmodel = {id: 80}; + model.createWidget.and.returnValue(Promise.resolve(widgetmodel)); + const widget = {id: 80}; + spyOn(tab, "findWidget").and.callFake((id) => { + expect(id).toBe(80); + return widget; + }); + + tab.dragboard.freeLayout.searchBestPosition = jasmine.createSpy("searchBestPosition"); + + const p = tab.createWidget( + { + default_height: "120px", + default_width: "120px" + }, { + layout: 1, + refposition: document.createElement('div') + } + ); + + p.then((created_widget) => { + expect(created_widget).toBe(widget); + expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledTimes(3); + expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), 800); + expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), 900.5); + expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), 1001); + done(); + }); + }); + }); describe("highlight()", () => { diff --git a/src/wirecloud/commons/static/js/StyledElements/Alert.js b/src/wirecloud/commons/static/js/StyledElements/Alert.js index 928ea4c8c0..a50539d15e 100644 --- a/src/wirecloud/commons/static/js/StyledElements/Alert.js +++ b/src/wirecloud/commons/static/js/StyledElements/Alert.js @@ -73,7 +73,6 @@ class: "se-alert-body" }); body.appendChild(options.message).insertInto(this.wrapperElement); - this.body = body; Object.defineProperties(this, { heading: {value: heading}, diff --git a/src/wirecloud/commons/static/js/StyledElements/InputInterface.js b/src/wirecloud/commons/static/js/StyledElements/InputInterface.js index 6abd1e034b..cd0aa66001 100644 --- a/src/wirecloud/commons/static/js/StyledElements/InputInterface.js +++ b/src/wirecloud/commons/static/js/StyledElements/InputInterface.js @@ -136,20 +136,20 @@ } /** - * @private - * * Must be implemented by child classes. This method checks that the given value * is valid for this InputInterface. Things as checking if the * value is empty but required is out of scope of this method. + * + * @private */ _checkValue(newValue) { return se.InputValidationError.NO_ERROR; } /** - * @private - * * Calls the event listeners for the given event type. + * + * @private */ _callEvent(type, event) { if (type in this._eventListeners) { diff --git a/src/wirecloud/commons/static/js/wirecloud/ui/WindowMenu.js b/src/wirecloud/commons/static/js/wirecloud/ui/WindowMenu.js index cedc0d3194..e3f5a39f57 100644 --- a/src/wirecloud/commons/static/js/wirecloud/ui/WindowMenu.js +++ b/src/wirecloud/commons/static/js/wirecloud/ui/WindowMenu.js @@ -184,9 +184,9 @@ } /** - * @private - * * Click Listener for the close button. + * + * @private */ _closeListener(e) { this.hide(); diff --git a/src/wirecloud/platform/static/js/wirecloud/UserInterfaceManager.js b/src/wirecloud/platform/static/js/wirecloud/UserInterfaceManager.js index b9b9ab58e2..b2e6231664 100644 --- a/src/wirecloud/platform/static/js/wirecloud/UserInterfaceManager.js +++ b/src/wirecloud/platform/static/js/wirecloud/UserInterfaceManager.js @@ -360,9 +360,9 @@ }; /** - * @private - * * Only meant to be used by {Wirecloud.ui.WindowMenu} + * + * @private */ UserInterfaceManager._unregisterRootWindowMenu = function _unregisterRootWindowMenu(window_menu) { if (currentWindowMenu === window_menu) { @@ -375,9 +375,9 @@ }; /** - * @private - * * Only meant to be used by {Wirecloud.ui.WindowMenu} + * + * @private */ UserInterfaceManager._registerRootWindowMenu = function _registerRootWindowMenu(window_menu) { if (!(window_menu instanceof Wirecloud.ui.WindowMenu)) { diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js index 25e8b307fd..ac086da820 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/DragboardLayout.js @@ -35,10 +35,10 @@ }; /** - * @private - * * Checks that the given widget has a minimal size. This check is performed using * widget content size. + * + * @private */ const ensureMinimalSize = function ensureMinimalSize(widget, persist) { const minWidth = Math.ceil(this.fromPixelsToHCells(80)); @@ -260,10 +260,10 @@ } /** - * @private - * * This function should be called at the end of the implementation of addWidget. - */ + * + * @private + */ _adaptIWidget(widget) { if (widget.element != null) { ensureMinimalSize.call(this, widget, false); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js index c54de587c6..ed5df2ded2 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js @@ -49,7 +49,7 @@ } on_addScreenSize() { - const screenSizes = utils.clone(this.value); + const screenSizes = utils.clone(this.value, true); // Get max id let maxId = 0; @@ -61,7 +61,7 @@ const newScreenSize = { id: maxId + 1, - moreOrEqual: screenSizes[screenSizes.length - 1].lessOrEqual + 1, + moreOrEqual: (screenSizes.length > 0) ? screenSizes[screenSizes.length - 1].lessOrEqual + 1 : 0, lessOrEqual: -1 }; @@ -71,7 +71,7 @@ } on_deleteScreenSize(screenSizeId) { - const screenSizes = utils.clone(this.value); + const screenSizes = utils.clone(this.value, true); const index = screenSizes.findIndex((screenSize) => screenSize.id === screenSizeId); screenSizes.splice(index, 1); @@ -80,7 +80,7 @@ } on_valueChange(screenSizeId, from, value, update = true) { - const screenSizes = utils.clone(this.value); + const screenSizes = utils.clone(this.value, true); const screenSizeIdx = screenSizes.findIndex((screenSize) => screenSize.id === screenSizeId); screenSizes[screenSizeIdx][from] = value; @@ -110,19 +110,24 @@ _checkValue(newValue) { // Check that the newValue covers all integers from [0, +inf) without gaps or overlaps - const screenSizes = utils.clone(newValue); + const screenSizes = utils.clone(newValue, true); + + if (!Array.isArray(screenSizes) || screenSizes.length === 0) { + return se.InputValidationError.SCREEN_SIZES_ERROR; + } + screenSizes.sort((a, b) => a.moreOrEqual - b.moreOrEqual); let lastLessOrEqual = -1; for (let i = 0; i < screenSizes.length; i++) { - if (screenSizes[i].moreOrEqual != lastLessOrEqual + 1 || (i != screenSizes.length - 1 && screenSizes[i].lessOrEqual <= screenSizes[i].moreOrEqual)) { + if (screenSizes[i].moreOrEqual !== lastLessOrEqual + 1 || (i !== screenSizes.length - 1 && screenSizes[i].lessOrEqual <= screenSizes[i].moreOrEqual)) { return se.InputValidationError.SCREEN_SIZES_ERROR; } lastLessOrEqual = screenSizes[i].lessOrEqual; } - if (lastLessOrEqual != -1) { + if (lastLessOrEqual !== -1) { return se.InputValidationError.SCREEN_SIZES_ERROR; } @@ -186,6 +191,7 @@ if (moreOrEqualVal !== screenSize.moreOrEqual) { this.on_valueChange(screenSize.id, 'moreOrEqual', moreOrEqualVal, false); + screenSize.moreOrEqual = moreOrEqualVal; } moreOrEqualInput.setDisabled(i === 0 || !this.enabledStatus); @@ -213,6 +219,7 @@ if (lessOrEqualVal !== screenSize.lessOrEqual) { this.on_valueChange(screenSize.id, 'lessOrEqual', lessOrEqualVal, false); + screenSize.lessOrEqual = lessOrEqualVal; } lessOrEqualInput.setDisabled(i === newValue.length - 1 || !this.enabledStatus); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js index 84f7fd568e..3fcd1d9496 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js @@ -111,17 +111,12 @@ const tabChange = priv.tab !== newLayout.dragboard.tab; const dragboardChange = this.layout.dragboard !== newLayout.dragboard || tabChange; - if (!('layoutConfigurations' in this.model)) { // Tests may not have this method - return; - } - layoutConfigurations.forEach((layoutConfiguration) => { if (this.layout instanceof Wirecloud.ui.FullDragboardLayout || newLayout instanceof Wirecloud.ui.FullDragboardLayout) { // Skip if coming from or going to a FullDragboardLayout return; } - // const newLayoutConfiguration = StyledElements.Utils.clone(layoutConfiguration, true); const newLayoutConfiguration = layoutConfiguration; let avgScreenSize = layoutConfiguration.lessOrEqual + (layoutConfiguration.moreOrEqual - layoutConfiguration.lessOrEqual) / 2; @@ -255,10 +250,8 @@ set: function (new_layout) { privates.get(this).layout = new_layout; const fulldragboard = new_layout instanceof Wirecloud.ui.FullDragboardLayout; - if ('setLayoutFulldragboard' in this.model) { // Tests may not have this method - this.model.setLayoutFulldragboard(fulldragboard); - } - if (!fulldragboard && new_layout != null && 'setLayoutIndex' in this.model) { + this.model.setLayoutFulldragboard(fulldragboard); + if (!fulldragboard && new_layout != null) { this.model.setLayoutIndex(new_layout.dragboard.layouts.indexOf(new_layout)); } update.call(this); @@ -869,8 +862,7 @@ // We keep all or only the current layout configuration and then we clone it to add the action const configs = this.model.layoutConfigurations.reduce((result, layoutConfig) => { - if ((allLayoutConfigurations && layoutConfig.id !== this.model.currentLayoutConfig.id) || - layoutConfig.id === this.model.currentLayoutConfig.id) { + if (allLayoutConfigurations || layoutConfig.id === this.model.currentLayoutConfig.id) { const config = StyledElements.Utils.clone(layoutConfig, true); config.action = action; result.push(config); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index 414e55425e..3caa8e7260 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -283,6 +283,10 @@ avgScreenSize = layoutConfig.moreOrEqual; } + if (window.innerWidth >= layoutConfig.moreOrEqual && (layoutConfig.lessOrEqual === -1 || window.innerWidth <= layoutConfig.lessOrEqual)) { + avgScreenSize = window.innerWidth; + } + const layouts = [ this.dragboard.baseLayout, this.dragboard.freeLayout, diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index 65a1f7f6d2..b44823570a 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -492,11 +492,11 @@ } /** - * @private - * * This function is slow. Please, only call it when really necessary. * * Updates the width and height info for this dragboard. + * + * @private */ _recomputeSize() { const cssStyle = document.defaultView.getComputedStyle(this.tab.wrapperElement, null); @@ -505,23 +505,23 @@ } // Read padding values - this.topMargin = cssStyle.getPropertyCSSValue("padding-top").getFloatValue(CSSPrimitiveValue.CSS_PX); - this.bottomMargin = cssStyle.getPropertyCSSValue("padding-bottom").getFloatValue(CSSPrimitiveValue.CSS_PX); - this.leftMargin = cssStyle.getPropertyCSSValue("padding-left").getFloatValue(CSSPrimitiveValue.CSS_PX); - this.rightMargin = cssStyle.getPropertyCSSValue("padding-right").getFloatValue(CSSPrimitiveValue.CSS_PX); + this.topMargin = parseFloat(cssStyle.getPropertyValue("padding-top")); + this.bottomMargin = parseFloat(cssStyle.getPropertyValue("padding-bottom")); + this.leftMargin = parseFloat(cssStyle.getPropertyValue("padding-left")); + this.rightMargin = parseFloat(cssStyle.getPropertyValue("padding-right")); this.dragboardWidth = parseInt(this.tab.wrapperElement.offsetWidth, 10) - this.leftMargin - this.rightMargin; this.dragboardHeight = parseInt(this.tab.wrapperElement.parentNode.clientHeight, 10) - this.topMargin - this.bottomMargin; } /** - * @private - * * This method forces recomputing of the iWidgets' sizes. * * @param {boolean} widthChanged * @param {boolean} heightChanged - */ + * + * @private + */ _updateIWidgetSizes(widthChanged, heightChanged) { this.baseLayout._notifyWindowResizeEvent(widthChanged, heightChanged); this.freeLayout._notifyWindowResizeEvent(widthChanged, heightChanged); diff --git a/src/wirecloud/platform/workspace/mashupTemplateGenerator.py b/src/wirecloud/platform/workspace/mashupTemplateGenerator.py index cd1380bc22..096ec70858 100644 --- a/src/wirecloud/platform/workspace/mashupTemplateGenerator.py +++ b/src/wirecloud/platform/workspace/mashupTemplateGenerator.py @@ -40,8 +40,6 @@ def get_workspace_description(workspace): return get_iwidgets_description(included_iwidgets) - -# TODO Adrian handle multiple screen sizes def process_iwidget(workspace, iwidget, wiring, parametrization, readOnlyWidgets, cache_manager): widget = iwidget.widget From 2fcc4ca1ee69084665fdca951aaf0df39094845f Mon Sep 17 00:00:00 2001 From: oxixes Date: Fri, 28 Jun 2024 11:26:06 +0200 Subject: [PATCH 12/28] Remove unused CSSPrimitiveValue import in WorkspaceTabViewDragboard.js --- .../static/js/wirecloud/ui/WorkspaceTabViewDragboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index b44823570a..9ee9424f13 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -20,7 +20,7 @@ * */ -/* globals CSSPrimitiveValue, Wirecloud */ +/* globals Wirecloud */ (function (ns, utils) { From f18d405df0896d8fe4e7317dff535886d059e791 Mon Sep 17 00:00:00 2001 From: oxixes Date: Fri, 28 Jun 2024 11:36:54 +0200 Subject: [PATCH 13/28] Make sure the screen size is 800x600 in js tests --- src/GruntFile.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/GruntFile.js b/src/GruntFile.js index 15397c8a7f..ed8a97a9d6 100644 --- a/src/GruntFile.js +++ b/src/GruntFile.js @@ -210,7 +210,13 @@ module.exports = function (grunt) { options: { frameworks: ['jasmine'], reporters: ['progress', 'coverage'], - browsers: ["ChromeHeadless"], + browsers: ["ChromeHeadlessCustom"], + customLaunchers: { + ChromeHeadlessCustom: { + base: 'ChromeHeadless', + flags: ['--window-size=800,600'] + } + }, singleRun: true }, styledelements: { From 71a2b6c7228dc8e117c3c0a6c78a1d6ccbf66dc9 Mon Sep 17 00:00:00 2001 From: oxixes Date: Fri, 28 Jun 2024 11:54:12 +0200 Subject: [PATCH 14/28] Try to fix test now --- src/GruntFile.js | 8 +------- src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js | 5 +++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/GruntFile.js b/src/GruntFile.js index ed8a97a9d6..15397c8a7f 100644 --- a/src/GruntFile.js +++ b/src/GruntFile.js @@ -210,13 +210,7 @@ module.exports = function (grunt) { options: { frameworks: ['jasmine'], reporters: ['progress', 'coverage'], - browsers: ["ChromeHeadlessCustom"], - customLaunchers: { - ChromeHeadlessCustom: { - base: 'ChromeHeadless', - flags: ['--window-size=800,600'] - } - }, + browsers: ["ChromeHeadless"], singleRun: true }, styledelements: { diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js index 7a8c9e328d..51d7a0324e 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js @@ -585,6 +585,11 @@ }); it("should define all screen sizes when creating a widget", (done) => { + Object.defineProperty(window, 'innerWidth', { + value: 800, + writable: true + }); + const workspace = create_workspace(); const model = create_tab({ customPreferences: { From 3a58927220c952c7215b8a2a8d99df44e4f1a165 Mon Sep 17 00:00:00 2001 From: oxixes Date: Fri, 28 Jun 2024 17:18:26 +0200 Subject: [PATCH 15/28] Add name to screen sizes --- .../ui/ScreenSizesInputInterfaceSpec.js | 29 +++ .../commons/locale/es/LC_MESSAGES/djangojs.po | 119 +++++------ .../static/js/StyledElements/NumericField.js | 2 +- src/wirecloud/platform/core/plugins.py | 1 + .../locale/es/LC_MESSAGES/djangojs.po | 188 +++++++++--------- .../wirecloud/ui/ScreenSizesInputInterface.js | 38 +++- .../js/wirecloud/ui/WorkspaceTabView.js | 5 +- 7 files changed, 224 insertions(+), 158 deletions(-) diff --git a/src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js b/src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js index d015a54527..17530d5f21 100644 --- a/src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js +++ b/src/js_tests/wirecloud/ui/ScreenSizesInputInterfaceSpec.js @@ -119,42 +119,50 @@ expect(field._checkValue([{ "moreOrEqual": 0, "lessOrEqual": -1, + "name": "Default", "id": 0 }, { "moreOrEqual": 0, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); expect(field._checkValue([{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }, { "moreOrEqual": 802, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); expect(field._checkValue([{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }, { "moreOrEqual": 700, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); expect(field._checkValue([{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); expect(field._checkValue([{ "moreOrEqual": 1, "lessOrEqual": -1, + "name": "Default-1", "id": 0 }])).toBe(se.InputValidationError.SCREEN_SIZES_ERROR); }); @@ -164,16 +172,19 @@ expect(field._checkValue([{ "moreOrEqual": 0, "lessOrEqual": -1, + "name": "Default", "id": 0 }])).toBe(se.InputValidationError.NO_ERROR); expect(field._checkValue([{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }, { "moreOrEqual": 801, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }])).toBe(se.InputValidationError.NO_ERROR); }); @@ -187,10 +198,12 @@ const value = [{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }, { "moreOrEqual": 801, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }]; @@ -203,10 +216,12 @@ const value = [{ "moreOrEqual": 801, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }, { "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }]; @@ -214,10 +229,12 @@ expect(field.getValue()).toEqual([{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }, { "moreOrEqual": 801, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }]); }); @@ -231,6 +248,7 @@ field._setValue([{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }]); @@ -239,10 +257,12 @@ expect(field.getValue()).toEqual([{ "moreOrEqual": 0, "lessOrEqual": -1, + "name": "Default", "id": 0 }, { "moreOrEqual": 0, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }]); }); @@ -256,10 +276,12 @@ field.setValue([{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }, { "moreOrEqual": 801, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }]); @@ -268,6 +290,7 @@ expect(field.getValue()).toEqual([{ "moreOrEqual": 0, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }]); }); @@ -281,10 +304,12 @@ const value = [{ "moreOrEqual": 0, "lessOrEqual": 800, + "name": "Default", "id": 0 }, { "moreOrEqual": 801, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }]; @@ -294,10 +319,12 @@ expect(JSON.stringify(field.getValue())).toBe(JSON.stringify([{ "moreOrEqual": 0, "lessOrEqual": 99, + "name": "Default", "id": 0 }, { "moreOrEqual": 100, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }])); @@ -306,10 +333,12 @@ expect(field.getValue()).toEqual([{ "moreOrEqual": 0, "lessOrEqual": 1000, + "name": "Default", "id": 0 }, { "moreOrEqual": 1001, "lessOrEqual": -1, + "name": "Default-1", "id": 1 }]); }); diff --git a/src/wirecloud/commons/locale/es/LC_MESSAGES/djangojs.po b/src/wirecloud/commons/locale/es/LC_MESSAGES/djangojs.po index cbc91548ef..cd510e3bfc 100644 --- a/src/wirecloud/commons/locale/es/LC_MESSAGES/djangojs.po +++ b/src/wirecloud/commons/locale/es/LC_MESSAGES/djangojs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-06-04 10:28+0200\n" +"POT-Creation-Date: 2024-06-28 17:13+0200\n" "PO-Revision-Date: 2018-10-24 12:55+0200\n" "Last-Translator: Álvaro Arranz García \n" "Language-Team: Español/España\n" @@ -19,146 +19,146 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.2\n" -#: static/js/StyledElements/FileField.js:107 -#: static/js/wirecloud/ui/MACSelectionWindowMenu.js:35 +#: static/js/StyledElements/FileField.js:101 +#: static/js/wirecloud/ui/MACSelectionWindowMenu.js:38 msgid "Select" msgstr "Seleccionar" -#: static/js/StyledElements/Form.js:71 +#: static/js/StyledElements/Form.js:223 msgid "Set Defaults" msgstr "Valores por defecto" -#: static/js/StyledElements/Form.js:82 +#: static/js/StyledElements/Form.js:234 msgid "Reset" msgstr "Reiniciar" -#: static/js/StyledElements/Form.js:94 -#: static/js/wirecloud/ui/MessageWindowMenu.js:43 +#: static/js/StyledElements/Form.js:246 +#: static/js/wirecloud/ui/MessageWindowMenu.js:45 msgid "Accept" msgstr "Aceptar" -#: static/js/StyledElements/Form.js:105 -#: static/js/wirecloud/ui/ExternalProcessWindowMenu.js:106 -#: static/js/wirecloud/ui/Tutorial/SimpleDescription.js:102 +#: static/js/StyledElements/Form.js:257 +#: static/js/wirecloud/ui/Tutorial/SimpleDescription.js:140 msgid "Cancel" msgstr "Cancelar" -#: static/js/StyledElements/InputInterfaces.js:70 +#: static/js/StyledElements/InputInterfaces.js:73 msgid "The following required fields are empty: %(fields)s." msgstr "Los siguientes campos obligatorios están vacíos: %(fields)s." -#: static/js/StyledElements/InputInterfaces.js:73 +#: static/js/StyledElements/InputInterfaces.js:76 msgid "The following fields do not contain a valid URL: %(fields)s." msgstr "Los siguientes campos no contienen una URL válida: %(fields)s." -#: static/js/StyledElements/InputInterfaces.js:76 +#: static/js/StyledElements/InputInterfaces.js:79 msgid "The following fields do not contain a valid E-Mail address: %(fields)s." msgstr "Los siguientes campos no continene un e-mail válido: %(fields)s." -#: static/js/StyledElements/InputInterfaces.js:79 +#: static/js/StyledElements/InputInterfaces.js:82 msgid "The following field do not contain a valid version number: %(fields)s." msgstr "" "Los siguientes campos no continen un número de versión válido: %(fields)s." -#: static/js/StyledElements/InputInterfaces.js:82 +#: static/js/StyledElements/InputInterfaces.js:85 msgid "The following fields contain invalid characters: %(fields)s." msgstr "Los siguientes campos contienen carácteres inválidos: %(fields)s." -#: static/js/StyledElements/InputInterfaces.js:85 +#: static/js/StyledElements/InputInterfaces.js:88 msgid "The following fields do not contain a valid color value: %(fields)s." msgstr "" "Los siguientes campos no contienen un valor de color válido: %(fields)s." -#: static/js/StyledElements/InputInterfaces.js:88 +#: static/js/StyledElements/InputInterfaces.js:91 msgid "The following fields does contain an out of range value: %(fields)s." msgstr "Los siguientes campos contienen un valor fuera de rango: %(fields)s." -#: static/js/StyledElements/ModelTable.js:54 +#: static/js/StyledElements/InputInterfaces.js:94 +msgid "" +"The sceen sizes are not correct. They must cover the whole range of possible " +"screen sizes without gaps or overlaps." +msgstr "" +"Los tamaños de pantalla no son correctos. Deben cubrir todo el rango de " +"posibles tamaños de pantalla sin huecos ni solapamientos." + +#: static/js/StyledElements/ModelTable.js:58 msgid "Sort by %(column_name)s" msgstr "Ordenar por %(column_name)s" -#: static/js/StyledElements/ModelTable.js:204 +#: static/js/StyledElements/ModelTable.js:453 msgid "No data available" msgstr "No hay datos disponibles" -#: static/js/StyledElements/Notebook.js:108 -#: static/js/StyledElements/Notebook.js:111 +#: static/js/StyledElements/Notebook.js:168 +#: static/js/StyledElements/Notebook.js:171 msgid "Add Tab" msgstr "Añadir pestaña" -#: static/js/StyledElements/PaginationInterface.js:82 +#: static/js/StyledElements/PaginationInterface.js:68 msgid "" -"
              Page: /
              " +"
              Page: /
              " msgstr "" -"
              Página: /
              " +"
              Página: /
              " -#: static/js/StyledElements/Typeahead.js:174 +#: static/js/StyledElements/Typeahead.js:89 msgid "No results found for " msgstr "No se han encontrado resultados para " -#: static/js/StyledElements/Utils.js:511 +#: static/js/StyledElements/Utils.js:510 msgid "N/A" msgstr "N/A" -#: static/js/wirecloud/ui/AlertWindowMenu.js:50 +#: static/js/wirecloud/ui/AlertWindowMenu.js:77 msgid "Yes" msgstr "Sí" -#: static/js/wirecloud/ui/AlertWindowMenu.js:51 +#: static/js/wirecloud/ui/AlertWindowMenu.js:78 msgid "No" msgstr "No" -#: static/js/wirecloud/ui/AlertWindowMenu.js:59 +#: static/js/wirecloud/ui/AlertWindowMenu.js:85 #: static/js/wirecloud/ui/MessageWindowMenu.js:29 msgid "Warning" msgstr "Atención" -#: static/js/wirecloud/ui/ExternalProcessWindowMenu.js:93 -msgid "Start" -msgstr "Iniciar" - -#: static/js/wirecloud/ui/HTMLWindowMenu.js:48 -#: static/js/wirecloud/ui/MACSelectionWindowMenu.js:45 -#: static/js/wirecloud/ui/Tutorial/SimpleDescription.js:145 -#: static/js/wirecloud/ui/WindowMenu.js:61 +#: static/js/wirecloud/ui/HTMLWindowMenu.js:45 +#: static/js/wirecloud/ui/MACSelectionWindowMenu.js:48 +#: static/js/wirecloud/ui/Tutorial/SimpleDescription.js:180 +#: static/js/wirecloud/ui/WindowMenu.js:127 msgid "Close" msgstr "Cerrar" -#: static/js/wirecloud/ui/MACField.js:88 +#: static/js/wirecloud/ui/MACField.js:89 msgid "Clear current selection" msgstr "Borrar la seleccion actual" -#: static/js/wirecloud/ui/MACField.js:99 +#: static/js/wirecloud/ui/MACField.js:100 msgid "Search" msgstr "Buscar" -#: static/js/wirecloud/ui/MACSearch.js:64 -msgid "Keywords..." -msgstr "Texto de búsqueda…" - -#: static/js/wirecloud/ui/MACSearch.js:157 +#: static/js/wirecloud/ui/MACSearch.js:50 msgid "Connection error: No resource retrieved" msgstr "Problema de conexión: No se ha recibido ningún recurso" -#: static/js/wirecloud/ui/MACSearch.js:227 +#: static/js/wirecloud/ui/MACSearch.js:120 msgid "

              Showing results for

              " msgstr "

              Mostrando los resultados para

              " -#: static/js/wirecloud/ui/MACSearch.js:244 +#: static/js/wirecloud/ui/MACSearch.js:137 msgid "" "

              We couldn't find anything for your search - %(keywords)s.

              Suggestions:

              • Make sure all words are spelled correctly.
              • Try different keywords.
              • Try more general keywords.
              " msgstr "" -"

              No hemos podido encontrar resultados que coincidan con tu búsqueda (" -"%(keywords)s).

              Sugerencias:

              • Asegúrate de que todas las " -"palabras estén escritas correctamente.
              • Prueba con otras palabras " +"

                No hemos podido encontrar resultados que coincidan con tu búsqueda " +"(%(keywords)s).

                Sugerencias:

                • Asegúrate de que todas " +"las palabras estén escritas correctamente.
                • Prueba con otras palabras " "clave.
                • Inténtalo con palabras clave más generales.
                " -#: static/js/wirecloud/ui/MACSearch.js:247 +#: static/js/wirecloud/ui/MACSearch.js:140 msgid "" "

                Currently, you do not have access to any %(scope)s component. You can get " "components using the Marketplace view or by uploading components manually " @@ -169,7 +169,7 @@ msgstr "" "recursos de forma manual usando el botón Subir en la vista de Mis Recursos." -#: static/js/wirecloud/ui/MACSearch.js:250 +#: static/js/wirecloud/ui/MACSearch.js:143 msgid "" "

                Currently, you do not have access to any component. You can get " "components using the Marketplace view or by uploading components manually " @@ -179,6 +179,10 @@ msgstr "" "componentes usando la vista de Marketplace o subiendo recursos de forma " "manual usando el botón Subir en la vista de Mis Recursos.

                " +#: static/js/wirecloud/ui/MACSearch.js:183 +msgid "Keywords..." +msgstr "Texto de búsqueda…" + #: static/js/wirecloud/ui/MessageWindowMenu.js:29 msgid "Error" msgstr "Error" @@ -187,7 +191,7 @@ msgstr "Error" msgid "Info" msgstr "Detalles" -#: static/js/wirecloud/ui/Tutorial/SimpleDescription.js:83 +#: static/js/wirecloud/ui/Tutorial/SimpleDescription.js:123 msgid "Next" msgstr "Siguiente" @@ -195,6 +199,9 @@ msgstr "Siguiente" msgid "If you prefer, you can follow some of these tutorials:" msgstr "Si lo prefieres, puedes seguir alguno de los siguientes tutoriales:" -#: static/js/wirecloud/ui/TutorialSubMenu.js:32 +#: static/js/wirecloud/ui/TutorialSubMenu.js:33 msgid "Tutorials" msgstr "Tutoriales" + +#~ msgid "Start" +#~ msgstr "Iniciar" diff --git a/src/wirecloud/commons/static/js/StyledElements/NumericField.js b/src/wirecloud/commons/static/js/StyledElements/NumericField.js index 33ae0f6688..4e2325707e 100644 --- a/src/wirecloud/commons/static/js/StyledElements/NumericField.js +++ b/src/wirecloud/commons/static/js/StyledElements/NumericField.js @@ -100,7 +100,7 @@ this.inputElement.addEventListener("blur", onblur.bind(this), true); this.inputElement.addEventListener("keydown", utils.stopInputKeydownPropagationListener, false); - this.inputElement.addEventListener("change", (e) => { + this.inputElement.addEventListener("input", (e) => { this.dispatchEvent('change', e); }); diff --git a/src/wirecloud/platform/core/plugins.py b/src/wirecloud/platform/core/plugins.py index 44601e5e13..d3dda4c551 100644 --- a/src/wirecloud/platform/core/plugins.py +++ b/src/wirecloud/platform/core/plugins.py @@ -447,6 +447,7 @@ def get_workspace_preferences(self): { "moreOrEqual": 0, "lessOrEqual": -1, + "name": "Default", "id": 0 } ], diff --git a/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po b/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po index 25de779e9e..5d584896ca 100644 --- a/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po +++ b/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-27 11:22+0200\n" +"POT-Creation-Date: 2024-06-28 17:10+0200\n" "PO-Revision-Date: 2019-06-04 10:40+0200\n" "Last-Translator: Álvaro Arranz García \n" "Language-Team: Español/España\n" @@ -84,10 +84,10 @@ msgstr "Error HTTP %(errorCode)s - %(errorDesc)s" #: static/js/wirecloud/Wiring.js:530 static/js/wirecloud/Workspace.js:468 #: static/js/wirecloud/Workspace.js:604 static/js/wirecloud/Workspace.js:659 #: static/js/wirecloud/WorkspaceTab.js:220 -#: static/js/wirecloud/WorkspaceTab.js:265 static/js/wirecloud/core.js:158 -#: static/js/wirecloud/core.js:420 static/js/wirecloud/core.js:585 -#: static/js/wirecloud/core.js:654 static/js/wirecloud/core.js:660 -#: static/js/wirecloud/core.js:708 +#: static/js/wirecloud/WorkspaceTab.js:265 static/js/wirecloud/core.js:193 +#: static/js/wirecloud/core.js:456 static/js/wirecloud/core.js:621 +#: static/js/wirecloud/core.js:690 static/js/wirecloud/core.js:696 +#: static/js/wirecloud/core.js:744 #: static/js/wirecloud/ui/PublishResourceWindowMenu.js:104 #: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:270 #: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:423 @@ -779,11 +779,11 @@ msgstr "%(subTask)s: %(percentage)s%" msgid "Workspace loaded" msgstr "Entorno de trabajo cargado" -#: static/js/wirecloud/Widget.js:366 static/js/wirecloud/Wiring.js:602 +#: static/js/wirecloud/Widget.js:371 static/js/wirecloud/Wiring.js:602 msgid "Failed to load widget." msgstr "Error al cargar el widget." -#: static/js/wirecloud/Widget.js:368 +#: static/js/wirecloud/Widget.js:373 msgid "" "

                This widget is currently not available. You or an administrator probably " "uninstalled it.

                Suggestions:
                • Remove this widget from the " @@ -797,138 +797,138 @@ msgstr "" "de este widget
                • O instalar otra versión de este widget y " "posteriormente usar la opción Actualizar/Desactualizar
                " -#: static/js/wirecloud/Widget.js:371 +#: static/js/wirecloud/Widget.js:376 msgid "Widget loaded successfully." msgstr "Widget cargado correctamente." -#: static/js/wirecloud/Widget.js:408 +#: static/js/wirecloud/Widget.js:413 msgid "Widget unloaded successfully." msgstr "Widget descargado correctamente." -#: static/js/wirecloud/Widget.js:688 +#: static/js/wirecloud/Widget.js:711 #: static/js/wirecloud/ui/CatalogueSearchView.js:150 #: static/js/wirecloud/ui/WiringEditor/Behaviour.js:272 #: static/js/wirecloud/ui/WiringEditor/BehaviourEngine.js:87 #: static/js/wirecloud/ui/WiringEditor/ComponentDraggablePrefs.js:73 #: static/js/wirecloud/ui/WiringEditor/ComponentPrefs.js:45 -#: static/js/wirecloud/wiring/Operator.js:408 +#: static/js/wirecloud/wiring/Operator.js:413 msgid "Title" msgstr "Título" -#: static/js/wirecloud/Widget.js:689 static/js/wirecloud/wiring/Operator.js:409 +#: static/js/wirecloud/Widget.js:712 static/js/wirecloud/wiring/Operator.js:414 msgid "Widget's title" msgstr "Titulo del widget" -#: static/js/wirecloud/Widget.js:693 +#: static/js/wirecloud/Widget.js:716 msgid "X-Position" msgstr "Posición-X" -#: static/js/wirecloud/Widget.js:694 +#: static/js/wirecloud/Widget.js:717 msgid "Specifies the x-coordinate at which the widget is placed" msgstr "Especifica la coordenada x en la que el widget está colocado" -#: static/js/wirecloud/Widget.js:698 +#: static/js/wirecloud/Widget.js:721 msgid "Y-Position" msgstr "Posición-Y" -#: static/js/wirecloud/Widget.js:699 +#: static/js/wirecloud/Widget.js:722 msgid "Specifies the y-coordinate at which the widget is placed" msgstr "Especifica la coordenada y en la que el widget está colocado" -#: static/js/wirecloud/Widget.js:703 +#: static/js/wirecloud/Widget.js:726 msgid "Z-Position" msgstr "Posición-Z" -#: static/js/wirecloud/Widget.js:704 +#: static/js/wirecloud/Widget.js:727 msgid "Specifies the z-coordinate at which the widget is placed" msgstr "Especifica la coordenada Z en la que el widget está colocado" -#: static/js/wirecloud/Widget.js:708 +#: static/js/wirecloud/Widget.js:731 msgid "Height" msgstr "Altura" -#: static/js/wirecloud/Widget.js:709 +#: static/js/wirecloud/Widget.js:732 msgid "Widget's height in layout cells" msgstr "Altura del widget en filas" -#: static/js/wirecloud/Widget.js:713 +#: static/js/wirecloud/Widget.js:736 msgid "Visible" msgstr "" -#: static/js/wirecloud/Widget.js:714 +#: static/js/wirecloud/Widget.js:737 msgid "" "Specifies if the widget is being displayed, altough the user may have to do " "scroll to be able to see it" msgstr "" -#: static/js/wirecloud/Widget.js:718 +#: static/js/wirecloud/Widget.js:741 msgid "Width" msgstr "Ancho" -#: static/js/wirecloud/Widget.js:719 +#: static/js/wirecloud/Widget.js:742 msgid "Widget's width in layout cells" msgstr "Ancho del widget en columnas" -#: static/js/wirecloud/Widget.js:723 +#: static/js/wirecloud/Widget.js:746 msgid "Height in pixels (deprecated)" msgstr "Altura en pixels (obsoleto)" -#: static/js/wirecloud/Widget.js:724 +#: static/js/wirecloud/Widget.js:747 msgid "Widget's height in pixels" msgstr "Altura del widget en pixels" -#: static/js/wirecloud/Widget.js:728 +#: static/js/wirecloud/Widget.js:751 msgid "Width in pixels" msgstr "Ancho en pixels" -#: static/js/wirecloud/Widget.js:729 +#: static/js/wirecloud/Widget.js:752 msgid "Widget's width in pixels" msgstr "Anchura del widget en pixels" -#: static/js/wirecloud/Widget.js:733 +#: static/js/wirecloud/Widget.js:756 #, fuzzy #| msgid "volatile" msgid "Volatile" msgstr "volátil" -#: static/js/wirecloud/Widget.js:734 +#: static/js/wirecloud/Widget.js:757 msgid "Volatile status of the widget" msgstr "" -#: static/js/wirecloud/Widget.js:741 +#: static/js/wirecloud/Widget.js:764 msgid "Widget created successfully." msgstr "Widget creado correctamente." -#: static/js/wirecloud/Widget.js:1107 +#: static/js/wirecloud/Widget.js:1130 #: static/js/wirecloud/ui/OperatorPreferencesWindowMenu.js:42 msgid "Exception catched while processing preference changes" msgstr "" "Excepción capturada mientras se procesaba los cambios en las preferencias" -#: static/js/wirecloud/Widget.js:1233 -#: static/js/wirecloud/wiring/Operator.js:603 +#: static/js/wirecloud/Widget.js:1256 +#: static/js/wirecloud/wiring/Operator.js:608 msgid "The %(type)s was upgraded to v%(version)s successfully." msgstr "" "El %(type)s ha sido correctamente actualizado a la versión v%(version)s." -#: static/js/wirecloud/Widget.js:1235 -#: static/js/wirecloud/wiring/Operator.js:605 +#: static/js/wirecloud/Widget.js:1258 +#: static/js/wirecloud/wiring/Operator.js:610 msgid "The %(type)s was downgraded to v%(version)s successfully." msgstr "" "El %(type)s ha sido correctamente desactualizado a la versión v%(version)s." -#: static/js/wirecloud/Widget.js:1238 -#: static/js/wirecloud/wiring/Operator.js:608 +#: static/js/wirecloud/Widget.js:1261 +#: static/js/wirecloud/wiring/Operator.js:613 msgid "The %(type)s was replaced using v%(version)s successfully." msgstr "" "El %(type)s ha sido correctamente reemplazado usando la versión v%(version)s." -#: static/js/wirecloud/WidgetMeta.js:88 +#: static/js/wirecloud/WidgetMeta.js:84 msgid "[Widget; Vendor: %(vendor)s, Name: %(name)s, Version: %(version)s]" msgstr "" "[Widget; Distribuidor: %(vendor)s, Nombre: %(name)s, Versión: %(versión)s]" -#: static/js/wirecloud/Wiring.js:597 static/js/wirecloud/wiring/Operator.js:220 +#: static/js/wirecloud/Wiring.js:597 static/js/wirecloud/wiring/Operator.js:225 msgid "Failed to load operator." msgstr "Error al cargar el operador." @@ -1082,39 +1082,39 @@ msgstr "No extendido" msgid "Unknown status code" msgstr "Código de error desconocido" -#: static/js/wirecloud/core.js:53 static/js/wirecloud/core.js:466 +#: static/js/wirecloud/core.js:79 static/js/wirecloud/core.js:502 msgid "Switching active workspace" msgstr "Cambiando el entorno de trabajo actual" -#: static/js/wirecloud/core.js:206 +#: static/js/wirecloud/core.js:241 msgid "Unloading WireCloud" msgstr "Cerrando WireCloud" -#: static/js/wirecloud/core.js:293 +#: static/js/wirecloud/core.js:328 msgid "Retrieving WireCloud code" msgstr "Obteniendo el código de WireCloud" -#: static/js/wirecloud/core.js:296 +#: static/js/wirecloud/core.js:331 msgid "Retrieving initial data" msgstr "Obteniendo datos iniciales" -#: static/js/wirecloud/core.js:321 +#: static/js/wirecloud/core.js:357 msgid "Error loading WireCloud" msgstr "Error cargando WireCloud" -#: static/js/wirecloud/core.js:332 +#: static/js/wirecloud/core.js:368 msgid "Loading WireCloud Platform" msgstr "Cargando la plataforma WireCloud" -#: static/js/wirecloud/core.js:418 +#: static/js/wirecloud/core.js:454 msgid "Requesting workspace data" msgstr "Solicitando los datos del entorno de trabajo" -#: static/js/wirecloud/core.js:512 +#: static/js/wirecloud/core.js:548 msgid "Missing name or title parameter" msgstr "Falta el parámetro name o title" -#: static/js/wirecloud/core.js:514 +#: static/js/wirecloud/core.js:550 msgid "Workspace and mashup options cannot be used at the same time" msgstr "Las opciones workspace y mashup no pueden ser usadas al mismo tiempo" @@ -1339,25 +1339,25 @@ msgstr "" "de Mis Recursos.
              " #: static/js/wirecloud/ui/MarketplaceView.js:179 -#: static/js/wirecloud/ui/MyResourcesView.js:147 -#: static/js/wirecloud/ui/MyResourcesView.js:165 -#: static/js/wirecloud/ui/WorkspaceView.js:175 +#: static/js/wirecloud/ui/MyResourcesView.js:148 +#: static/js/wirecloud/ui/MyResourcesView.js:166 +#: static/js/wirecloud/ui/WorkspaceView.js:177 msgid "My Resources" msgstr "Mis recursos" -#: static/js/wirecloud/ui/MarketplaceView.js:240 +#: static/js/wirecloud/ui/MarketplaceView.js:241 msgid "loading marketplace view..." msgstr "cargando la vista de marketplace..." -#: static/js/wirecloud/ui/MarketplaceView.js:242 +#: static/js/wirecloud/ui/MarketplaceView.js:243 msgid "marketplace list not available" msgstr "lista de marketplaces no disponible" -#: static/js/wirecloud/ui/MarketplaceView.js:264 +#: static/js/wirecloud/ui/MarketplaceView.js:265 msgid "Marketplace" msgstr "Marketplace" -#: static/js/wirecloud/ui/MarketplaceView.js:267 +#: static/js/wirecloud/ui/MarketplaceView.js:268 msgid "Marketplace - %(marketname)s" msgstr "Marketplace - %(marketname)s" @@ -1442,15 +1442,15 @@ msgstr "" "botón Subir." #: static/js/wirecloud/ui/MyResourcesView.js:80 -#: static/js/wirecloud/ui/WorkspaceView.js:184 +#: static/js/wirecloud/ui/WorkspaceView.js:186 msgid "Get more components" msgstr "Obtener más componentes" -#: static/js/wirecloud/ui/MyResourcesView.js:162 +#: static/js/wirecloud/ui/MyResourcesView.js:163 msgid "My Resources - %(resource)s" msgstr "Mis recursos - %(resource)s" -#: static/js/wirecloud/ui/MyResourcesView.js:287 +#: static/js/wirecloud/ui/MyResourcesView.js:288 msgid "" "You have not configured any marketplace to upload this resource. Please, " "configure one on the Marketplace view." @@ -1458,7 +1458,7 @@ msgstr "" "No has configurado ningún marketplace en el que que subir este recurso. Por " "favor, configura uno en la vista Marketplace." -#: static/js/wirecloud/ui/MyResourcesView.js:371 +#: static/js/wirecloud/ui/MyResourcesView.js:372 msgid "" "Do you really want to remove the \"%(name)s\" (vendor: \"%(vendor)s\", " "version: \"%(version)s\") resource?" @@ -1466,7 +1466,7 @@ msgstr "" "¿Realmente quieres eliminar el recurso \"%(name)s\" (distribuidor: " "\"%(vendor)s\", versión: \"%(version)s\")?" -#: static/js/wirecloud/ui/MyResourcesView.js:395 +#: static/js/wirecloud/ui/MyResourcesView.js:396 msgid "" "Do you really want to remove all versions of the (vendor: \"%(vendor)s\", " "name: \"%(name)s\") resource?" @@ -1728,22 +1728,32 @@ msgstr "Variables persistentes" msgid "New Name" msgstr "Nuevo nombre" -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:170 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:178 +msgid "Name:" +msgstr "Nombre:" + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:179 +msgid "Name of the screen size range." +msgstr "Nombre del rango de tamaños de pantalla." + +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:198 msgid "From (px):" msgstr "Desde (px):" -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:171 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:199 msgid "The left limit of the screen size range (in pixels)." msgstr "El límite izquierdo del rango de tamaños de pantalla (en píxeles)." -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:197 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:226 msgid "To (px):" msgstr "Hasta (px):" -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:198 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:227 msgid "" "The right limit of the screen size range (in pixels). Use -1 for no limit." -msgstr "El límite derecho del rango de tamaños de pantalla (en píxeles). Usa -1 para sin límite." +msgstr "" +"El límite derecho del rango de tamaños de pantalla (en píxeles). Usa -1 para " +"sin límite." #: static/js/wirecloud/ui/SharingWindowMenu.js:105 msgid "%(fullname)s (You)" @@ -1758,7 +1768,7 @@ msgid "Can view" msgstr "Puede ver" #: static/js/wirecloud/ui/SharingWindowMenu.js:126 -#: static/js/wirecloud/ui/WidgetView.js:309 +#: static/js/wirecloud/ui/WidgetView.js:301 #: static/js/wirecloud/ui/WiringEditor/Behaviour.js:53 #: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:275 #: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:493 @@ -1857,22 +1867,22 @@ msgstr "Ocultar título" msgid "Show title" msgstr "Mostrar título" -#: static/js/wirecloud/ui/WidgetView.js:207 +#: static/js/wirecloud/ui/WidgetView.js:199 msgid "%(errorCount)s error" msgid_plural "%(errorCount)s errors" msgstr[0] "%(errorCount)s error" msgstr[1] "%(errorCount)s errores" -#: static/js/wirecloud/ui/WidgetView.js:351 +#: static/js/wirecloud/ui/WidgetView.js:343 msgid "Menu" msgstr "Menú" -#: static/js/wirecloud/ui/WidgetView.js:362 -#: static/js/wirecloud/ui/WidgetView.js:560 +#: static/js/wirecloud/ui/WidgetView.js:354 +#: static/js/wirecloud/ui/WidgetView.js:552 msgid "Minimize" msgstr "Minimizar" -#: static/js/wirecloud/ui/WidgetView.js:545 +#: static/js/wirecloud/ui/WidgetView.js:537 msgid "Maximize" msgstr "Maximizar" @@ -2252,9 +2262,9 @@ msgstr "No se ha proporcionado una descripción." msgid "Empty workspace list" msgstr "Lista de entornos de trabajo vacía" -#: static/js/wirecloud/ui/WorkspaceTabView.js:354 -msgid "Currently editing for screen sizes %(interval)s" -msgstr "Actualmente editando para los tamaños de pantalla %(interval)s" +#: static/js/wirecloud/ui/WorkspaceTabView.js:358 +msgid "Currently editing for screen size %(name)s" +msgstr "Actualmente editando para los tamaños de pantalla %(name)s" #: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:49 msgid "Rename Workspace Tab" @@ -2268,33 +2278,33 @@ msgstr "Configurar como inicial" msgid "The tab's widgets will also be removed. Would you like to continue?" msgstr "Los widgets de la pestaña serán también eliminados. ¿Desea continuar?" -#: static/js/wirecloud/ui/WorkspaceView.js:166 +#: static/js/wirecloud/ui/WorkspaceView.js:168 msgid "Wiring" msgstr "Wiring" -#: static/js/wirecloud/ui/WorkspaceView.js:370 +#: static/js/wirecloud/ui/WorkspaceView.js:372 msgid "New tab" msgstr "Nueva pestaña" -#: static/js/wirecloud/ui/WorkspaceView.js:385 -#: static/js/wirecloud/ui/WorkspaceView.js:396 +#: static/js/wirecloud/ui/WorkspaceView.js:387 +#: static/js/wirecloud/ui/WorkspaceView.js:398 msgid "Full screen" msgstr "Ver a pantalla completa" -#: static/js/wirecloud/ui/WorkspaceView.js:392 +#: static/js/wirecloud/ui/WorkspaceView.js:394 msgid "Exit full screen" msgstr "Salir de pantalla completa" -#: static/js/wirecloud/ui/WorkspaceView.js:432 +#: static/js/wirecloud/ui/WorkspaceView.js:434 msgid "Add components" msgstr "Añadir componentes" -#: static/js/wirecloud/ui/WorkspaceView.js:490 -#: static/js/wirecloud/ui/WorkspaceView.js:504 +#: static/js/wirecloud/ui/WorkspaceView.js:493 +#: static/js/wirecloud/ui/WorkspaceView.js:507 msgid "loading..." msgstr "cargando..." -#: static/js/wirecloud/ui/WorkspaceView.js:542 +#: static/js/wirecloud/ui/WorkspaceView.js:545 msgid "The requested workspace is no longer available (it was deleted)." msgstr "" "El entorno de trabajo solicitado ya no está disponible (ha sido borrado)." @@ -2353,7 +2363,7 @@ msgstr "Registros de la conexión" msgid "Unimplemented function: %(funcName)s" msgstr "Función no implementada: %(funcName)s" -#: static/js/wirecloud/wiring/Operator.js:222 +#: static/js/wirecloud/wiring/Operator.js:227 msgid "" "

              This operator is currently not available. You or an administrator " "probably uninstalled it.

              Suggestions:
              • Remove the operator." @@ -2367,19 +2377,19 @@ msgstr "" "li>
              • O instalar otra versión de este operador y posteriormente usar la " "opción Actualizar/Desactualizar
              " -#: static/js/wirecloud/wiring/Operator.js:225 +#: static/js/wirecloud/wiring/Operator.js:230 msgid "Operator loaded successfully." msgstr "Operador cargado correctamente." -#: static/js/wirecloud/wiring/Operator.js:261 +#: static/js/wirecloud/wiring/Operator.js:266 msgid "Operator unloaded successfully." msgstr "Operador descargado correctamente." -#: static/js/wirecloud/wiring/Operator.js:426 +#: static/js/wirecloud/wiring/Operator.js:431 msgid "Operator created successfully." msgstr "Operador creado correctamente." -#: static/js/wirecloud/wiring/Operator.js:536 +#: static/js/wirecloud/wiring/Operator.js:541 msgid "%(operator_title)s's logs" msgstr "Registros de %(operator_title)s" diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js index ed5df2ded2..d896b3aa07 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js @@ -61,6 +61,7 @@ const newScreenSize = { id: maxId + 1, + name: "Default-" + (maxId + 1), moreOrEqual: (screenSizes.length > 0) ? screenSizes[screenSizes.length - 1].lessOrEqual + 1 : 0, lessOrEqual: -1 }; @@ -79,20 +80,18 @@ this._update(screenSizes, false); } - on_valueChange(screenSizeId, from, value, update = true) { - const screenSizes = utils.clone(this.value, true); + on_valueChange(screenSizeId, from, value) { + const screenSizes = this.value; const screenSizeIdx = screenSizes.findIndex((screenSize) => screenSize.id === screenSizeId); screenSizes[screenSizeIdx][from] = value; if (from === 'moreOrEqual' && screenSizeIdx > 0) { screenSizes[screenSizeIdx - 1].lessOrEqual = value - 1; + this.screenSizesInputs[screenSizes[screenSizeIdx - 1].id].children[2].children[1].inputElement.value = value - 1; } else if (from === 'lessOrEqual' && screenSizeIdx < screenSizes.length - 1) { screenSizes[screenSizeIdx + 1].moreOrEqual = value + 1; - } - - if (update) { - this._update(screenSizes, false); + this.screenSizesInputs[screenSizes[screenSizeIdx + 1].id].children[1].children[1].inputElement.value = value + 1; } } @@ -175,6 +174,26 @@ newValue.forEach((screenSize, i) => { const screenSizeContainer = new StyledElements.Container(); + const nameAddon = new se.Addon({ + text: utils.gettext('Name:'), + title: utils.gettext('Name of the screen size range.') + }); + nameAddon.setDisabled(!this.enabledStatus); + + const nameInput = new se.TextField({ + name: 'name', + initialValue: ('name' in screenSize) ? screenSize.name : 'Default-' + screenSize.id + }); + nameInput.setDisabled(!this.enabledStatus); + + nameInput.addEventListener('change', () => { + this.on_valueChange(screenSize.id, 'name', nameInput.getValue()); + }); + + const nameContainer = new se.Container({class: 'se-input-group se-screen-size-name'}); + nameContainer.appendChild(nameAddon); + nameContainer.appendChild(nameInput); + const fromAddon = new se.Addon({ text: utils.gettext('From (px):'), title: utils.gettext('The left limit of the screen size range (in pixels).') @@ -190,7 +209,7 @@ }); if (moreOrEqualVal !== screenSize.moreOrEqual) { - this.on_valueChange(screenSize.id, 'moreOrEqual', moreOrEqualVal, false); + this.on_valueChange(screenSize.id, 'moreOrEqual', moreOrEqualVal); screenSize.moreOrEqual = moreOrEqualVal; } @@ -218,7 +237,7 @@ }); if (lessOrEqualVal !== screenSize.lessOrEqual) { - this.on_valueChange(screenSize.id, 'lessOrEqual', lessOrEqualVal, false); + this.on_valueChange(screenSize.id, 'lessOrEqual', lessOrEqualVal); screenSize.lessOrEqual = lessOrEqualVal; } @@ -244,7 +263,7 @@ this._callEvent('requestSave', () => { if (!err) { Wirecloud.activeWorkspace.view.activeTab.quitEditingInterval(); - Wirecloud.activeWorkspace.view.activeTab.setEditingInterval(screenSize.moreOrEqual, screenSize.lessOrEqual); + Wirecloud.activeWorkspace.view.activeTab.setEditingInterval(screenSize.moreOrEqual, screenSize.lessOrEqual, screenSize.name); } }); }); @@ -256,6 +275,7 @@ buttonContainer.appendChild(editScreenSizeButton); buttonContainer.appendChild(deleteButton); + screenSizeContainer.appendChild(nameContainer); screenSizeContainer.appendChild(fromContainer); screenSizeContainer.appendChild(toContainer); screenSizeContainer.appendChild(buttonContainer); diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index 3caa8e7260..61e86d24d0 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -348,15 +348,14 @@ ); } - setEditingInterval(moreOrEqual, lessOrEqual) { + setEditingInterval(moreOrEqual, lessOrEqual, name) { let avgScreenSize = Math.floor((moreOrEqual + lessOrEqual) / 2); if (lessOrEqual === -1) { avgScreenSize = moreOrEqual; } this.dragboard.setCustomDragboardWidth(avgScreenSize); - const intervalString = "[" + moreOrEqual + ", " + (lessOrEqual === -1 ? "+∞)" : lessOrEqual + "]"); - const text = utils.interpolate(utils.gettext("Currently editing for screen sizes %(interval)s"), {interval: intervalString}); + const text = utils.interpolate(utils.gettext("Currently editing for screen size %(name)s"), {name: name}); const div = document.createElement('div'); div.className = 'wc-editing-interval'; From 3a18c756c6911d1cb2cf42af03acd6f2ba950327 Mon Sep 17 00:00:00 2001 From: oxixes Date: Mon, 1 Jul 2024 12:18:12 +0200 Subject: [PATCH 16/28] More tests and better UX when defining screen sizes --- .../wirecloud/ui/SidebarLayoutSpec.js | 28 +- .../ui/WorkspaceTabViewDragboardSpec.js | 301 +++++++++++++++++- .../wirecloud/ui/WorkspaceTabViewSpec.js | 55 ++++ .../static/css/screen_size_field.css | 2 +- .../wirecloud/ui/ScreenSizesInputInterface.js | 11 + .../wirecloud/ui/WorkspaceTabViewDragboard.js | 16 +- 6 files changed, 405 insertions(+), 8 deletions(-) diff --git a/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js b/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js index 1a4c8f5289..3cca4ed8d0 100644 --- a/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js +++ b/src/js_tests/wirecloud/ui/SidebarLayoutSpec.js @@ -41,7 +41,7 @@ const layout = new ns.SidebarLayout(dragboard); // Check initial values - expect(layout.active).toBe(false); + expect(layout.isActive()).toBe(false); expect(layout.position).toBe("left"); }); @@ -56,10 +56,19 @@ const layout = new ns.SidebarLayout(dragboard, {position: "right"}); // Should init in inactive mode - expect(layout.active).toBe(false); + expect(layout.isActive()).toBe(false); expect(layout.position).toBe("right"); }); + it("should accept the active option", () => { + const dragboard = {}; + const layout = new ns.SidebarLayout(dragboard, {active: true}); + + // Should init in active mode + expect(layout.isActive()).toBe(true); + expect(layout.position).toBe("left"); + }); + }); describe("active property", () => { @@ -640,6 +649,21 @@ }); + describe("removeHandle()", () => { + + it("should work", () => { + const layout = new ns.SidebarLayout({}); + layout.handle = { + remove: jasmine.createSpy("remove") + } + + layout.removeHandle(); + + expect(layout.handle.remove).toHaveBeenCalled(); + }); + + }); + }); })(Wirecloud.ui, StyledElements.Utils); diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js index 21fb0d3d8b..0cffd4d48e 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js @@ -67,7 +67,9 @@ return { id: options.id, model: { - volatile: !!options.volatile + volatile: !!options.volatile, + layoutConfigurations: options.layoutConfigurations || [], + id: options.id }, persist: jasmine.createSpy("persist"), position: { @@ -76,6 +78,7 @@ setPosition: jasmine.createSpy("setPosition").and.callFake(function (options) { this.position.z = options.z; }), + updateWindowSize: jasmine.createSpy("updateWindowSize"), toJSON: function () {} }; }; @@ -83,6 +86,7 @@ const layout_constructor = function () { this.initialize = jasmine.createSpy("initialize"); this.moveTo = jasmine.createSpy("moveTo"); + this.isActive = jasmine.createSpy("isActive").and.returnValue(true); this._notifyWindowResizeEvent = jasmine.createSpy("_notifyWindowResizeEvent"); }; @@ -572,6 +576,301 @@ }); + describe("_updateScreenSizes", () => { + + it("should delete non-existent screen sizes, update those that exist and add new ones", (done) => { + spyOn(Wirecloud.io, "makeRequest").and.callFake((url, options) => { + return new Wirecloud.Task("Sending request", (resolve) => {resolve({status: 204});}); + }); + + const tab = create_tab(); + const dragboard = new ns.WorkspaceTabViewDragboard(tab); + + dragboard.resetLayouts = jasmine.createSpy("resetLayouts"); + dragboard.refreshPositionBasedOnZIndex = jasmine.createSpy("refreshPositionBasedOnZIndex"); + dragboard.paint = jasmine.createSpy("paint"); + + const widget = create_widget({ + id: 3, + layoutConfigurations: [ + { + id: 0, + moreOrEqual: 0, + lessOrEqual: 800, + anchor: "top-left", + width: 10, + height: 10, + relwidth: true, + relheight: true, + left: 0, + top: 0, + zIndex: 0, + relx: true, + rely: true, + titlevisible: true, + fulldragboard: false, + minimized: false + }, + { + id: 1, + moreOrEqual: 801, + lessOrEqual: -1, + anchor: "top-left", + width: 10, + height: 10, + relwidth: true, + relheight: true, + left: 0, + top: 0, + zIndex: 0, + relx: true, + rely: true, + titlevisible: true, + fulldragboard: false, + minimized: false + } + ] + }); + + dragboard._addWidget(widget); + + tab.model.preferences.get = jasmine.createSpy("get").and.returnValue([ + { + id: 1, + moreOrEqual: 0, + lessOrEqual: 800, + name: "Default-1" + }, + { + id: 2, + moreOrEqual: 801, + lessOrEqual: -1, + name: "Default-2" + } + ]); + + const p = dragboard._updateScreenSizes(); + + p.then(() => { + expect(Wirecloud.io.makeRequest).toHaveBeenCalled(); + expect(dragboard.resetLayouts).toHaveBeenCalled(); + expect(dragboard.refreshPositionBasedOnZIndex).toHaveBeenCalled(); + expect(dragboard.paint).toHaveBeenCalled(); + const body = JSON.parse(Wirecloud.io.makeRequest.calls.argsFor(0)[1].postBody); + expect(body).toEqual([{ + id: 3, + layoutConfigurations: [ + { + id: 0, + action: 'delete' + }, + { + id: 1, + action: 'update', + moreOrEqual: 0, + lessOrEqual: 800 + }, + { + id: 2, + action: 'update', + moreOrEqual: 801, + lessOrEqual: -1, + anchor: "top-left", + width: 10, + height: 10, + relwidth: true, + relheight: true, + left: 0, + top: 0, + zIndex: 0, + relx: true, + rely: true, + titlevisible: true, + fulldragboard: false, + minimized: false + } + ] + }]); + done(); + }); + }); + + it("should not update a layout configuration if it has not changed", (done) => { + spyOn(Wirecloud.io, "makeRequest").and.callFake((url, options) => { + return new Wirecloud.Task("Sending request", (resolve) => {resolve({status: 204});}); + }); + + const tab = create_tab(); + const dragboard = new ns.WorkspaceTabViewDragboard(tab); + + dragboard.resetLayouts = jasmine.createSpy("resetLayouts"); + dragboard.refreshPositionBasedOnZIndex = jasmine.createSpy("refreshPositionBasedOnZIndex"); + dragboard.paint = jasmine.createSpy("paint"); + + const widget = create_widget({ + id: 3, + layoutConfigurations: [ + { + id: 0, + moreOrEqual: 0, + lessOrEqual: 800, + anchor: "top-left", + width: 10, + height: 10, + relwidth: true, + relheight: true, + left: 0, + top: 0, + zIndex: 0, + relx: true, + rely: true, + titlevisible: true, + fulldragboard: false, + minimized: false + } + ] + }); + + dragboard._addWidget(widget); + + tab.model.preferences.get = jasmine.createSpy("get").and.returnValue([ + { + id: 0, + moreOrEqual: 0, + lessOrEqual: 800, + name: "Default-1" + } + ]); + + const p = dragboard._updateScreenSizes(); + + p.then(() => { + expect(Wirecloud.io.makeRequest).toHaveBeenCalled(); + expect(dragboard.resetLayouts).toHaveBeenCalled(); + expect(dragboard.refreshPositionBasedOnZIndex).toHaveBeenCalled(); + expect(dragboard.paint).toHaveBeenCalled(); + const body = JSON.parse(Wirecloud.io.makeRequest.calls.argsFor(0)[1].postBody); + expect(body).toEqual([{ + id: 3, + layoutConfigurations: [] + }]); + done(); + }); + }); + + it("should quit the editing interval if custom screen sizes are used", (done) => { + spyOn(Wirecloud.io, "makeRequest").and.callFake((url, options) => { + return new Wirecloud.Task("Sending request", (resolve) => {resolve({status: 204});}); + }); + + const tab = create_tab(); + const dragboard = new ns.WorkspaceTabViewDragboard(tab); + dragboard.customWidth = 800; + + dragboard.resetLayouts = jasmine.createSpy("resetLayouts"); + dragboard.refreshPositionBasedOnZIndex = jasmine.createSpy("refreshPositionBasedOnZIndex"); + dragboard.paint = jasmine.createSpy("paint"); + + const widget = create_widget({ + id: 3, + layoutConfigurations: [ + { + id: 0, + moreOrEqual: 0, + lessOrEqual: 800, + anchor: "top-left", + width: 10, + height: 10, + relwidth: true, + relheight: true, + left: 0, + top: 0, + zIndex: 0, + relx: true, + rely: true, + titlevisible: true, + fulldragboard: false, + minimized: false + } + ] + }); + + dragboard._addWidget(widget); + + tab.model.preferences.get = jasmine.createSpy("get").and.returnValue([ + { + id: 1, + moreOrEqual: 0, + lessOrEqual: 800, + name: "Default-1" + } + ]); + + const p = dragboard._updateScreenSizes(); + + p.then(() => { + expect(tab.quitEditingInterval).toHaveBeenCalled(); + done(); + }); + }); + + it("should handle unexpected responses", (done) => { + spyOn(Wirecloud.io, "makeRequest").and.callFake(function (url, options) { + expect(options.method).toEqual("PUT"); + return new Wirecloud.Task("Sending request", function (resolve) { + resolve({ + status: 201 + }); + }); + }); + + const tab = create_tab(); + const dragboard = new ns.WorkspaceTabViewDragboard(tab); + dragboard.paint = jasmine.createSpy("paint"); + + const task = dragboard._updateScreenSizes(); + + task.then( + (value) => { + fail("success callback called"); + }, + (error) => { + expect(Wirecloud.io.makeRequest).toHaveBeenCalled(); + done(); + } + ); + }); + + it("should handle error responses", (done) => { + spyOn(Wirecloud.io, "makeRequest").and.callFake(function (url, options) { + expect(options.method).toEqual("PUT"); + return new Wirecloud.Task("Sending request", function (resolve) { + resolve({ + status: 403 + }); + }); + }); + + const tab = create_tab(); + const dragboard = new ns.WorkspaceTabViewDragboard(tab); + dragboard.paint = jasmine.createSpy("paint"); + + const task = dragboard._updateScreenSizes(); + + task.then( + (value) => { + fail("success callback called"); + }, + (error) => { + expect(Wirecloud.io.makeRequest).toHaveBeenCalled(); + done(); + } + ); + + }); + + }); + describe("update([ids, allLayoutConfigurations])", () => { let dragboard, widget1, widget2, widget3; diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js index 51d7a0324e..4fcdbc2cad 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js @@ -935,6 +935,61 @@ }); + describe("setEditingInterval(moreOrEqual, lessOrEqual, name)", () => { + + it("should set the editing interval", () => { + const workspace = create_workspace(); + const model = create_tab(); + const tab = new ns.WorkspaceTabView("1", notebook, { + model: model, + workspace: workspace + }); + + tab.dragboard.setCustomDragboardWidth = jasmine.createSpy("setCustomDragboardWidth"); + + tab.setEditingInterval(0, 10, "name"); + expect(tab.dragboard.setCustomDragboardWidth).toHaveBeenCalledWith(5); + tab.quitEditingInterval = jasmine.createSpy("quitEditingInterval"); + + tab.intervalEditionIndicator.querySelector(".wc-editing-interval-close").click(); + + expect(tab.quitEditingInterval).toHaveBeenCalled(); + + tab.setEditingInterval(10, -1, "name"); + expect(tab.dragboard.setCustomDragboardWidth).toHaveBeenCalledWith(10); + }); + + }); + + describe("quitEditingInterval()", () => { + + it("should quit the editing interval", () => { + const workspace = create_workspace(); + const model = create_tab(); + const tab = new ns.WorkspaceTabView("1", notebook, { + model: model, + workspace: workspace + }); + + tab.dragboard.restoreDragboardWidth = jasmine.createSpy("restoreDragboardWidth"); + + tab.quitEditingInterval(); + + expect(tab.dragboard.restoreDragboardWidth).toHaveBeenCalled(); + + const intervalEditionIndicator = { + remove: jasmine.createSpy("remove") + }; + + tab.intervalEditionIndicator = intervalEditionIndicator; + tab.quitEditingInterval(); + + expect(intervalEditionIndicator.remove).toHaveBeenCalled(); + expect(tab.intervalEditionIndicator).toBe(null); + }); + + }); + }); })(Wirecloud.ui, StyledElements.Utils); diff --git a/src/wirecloud/defaulttheme/static/css/screen_size_field.css b/src/wirecloud/defaulttheme/static/css/screen_size_field.css index c5e3b79497..f0ce372693 100644 --- a/src/wirecloud/defaulttheme/static/css/screen_size_field.css +++ b/src/wirecloud/defaulttheme/static/css/screen_size_field.css @@ -7,7 +7,7 @@ flex-grow: 1; } -.se-screen-size-from { +.se-screen-size-name { margin-left: 0; } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js index d896b3aa07..08886eefc1 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js @@ -46,6 +46,8 @@ this._update(this.value); this.addButton.setDisabled(!this.enabledStatus); + + this.highestIdUsed = 0; } on_addScreenSize() { @@ -59,6 +61,8 @@ } }); + maxId = Math.max(maxId, this.highestIdUsed); + const newScreenSize = { id: maxId + 1, name: "Default-" + (maxId + 1), @@ -66,6 +70,8 @@ lessOrEqual: -1 }; + this.highestIdUsed = newScreenSize.id; + screenSizes.push(newScreenSize); this._update(screenSizes, false); @@ -150,6 +156,11 @@ _setValue(newValue) { this._update(newValue); + newValue.forEach((screenSize) => { + if (screenSize.id > this.highestIdUsed) { + this.highestIdUsed = screenSize.id; + } + }); } _update(newValue, sort = true) { diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index 9ee9424f13..5afa58c06d 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -330,7 +330,7 @@ layoutConfigurations: [] }; - const indexesToDelete = []; + let indexesToDelete = []; currentConfigs.forEach((config, i) => { if (updatedScreenSizes.findIndex((screenSize) => screenSize.id === config.id) === -1) { widgetReqData.layoutConfigurations.push({ @@ -342,9 +342,13 @@ }); indexesToDelete.sort((a, b) => b - a); - indexesToDelete.forEach((index) => { - currentConfigs.splice(index, 1); - }); + + if (indexesToDelete.length !== currentConfigs.length) { + indexesToDelete.forEach((index) => { + currentConfigs.splice(index, 1); + }); + indexesToDelete = []; + } const lastExistingScreenSize = currentConfigs[currentConfigs.length - 1]; updatedScreenSizes.forEach((screenSize) => { @@ -398,6 +402,10 @@ } }); + indexesToDelete.forEach((index) => { + currentConfigs.splice(index, 1); + }); + // After modifying all the layoutConfigurations, we need to sort them by moreOrEqual and call the updateWindowSize method // to refresh the current layout currentConfigs.sort((a, b) => a.moreOrEqual - b.moreOrEqual); From 1cb100b71fd217e7be24f63e9094bc868314adb4 Mon Sep 17 00:00:00 2001 From: oxixes Date: Mon, 1 Jul 2024 13:25:53 +0200 Subject: [PATCH 17/28] More django tests --- src/wirecloud/platform/iwidget/utils.py | 6 -- src/wirecloud/platform/tests/rest_api.py | 83 ++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/wirecloud/platform/iwidget/utils.py b/src/wirecloud/platform/iwidget/utils.py index f33ab5694d..2c143c09d2 100644 --- a/src/wirecloud/platform/iwidget/utils.py +++ b/src/wirecloud/platform/iwidget/utils.py @@ -127,9 +127,6 @@ def check_intervals(data): # The screen size intervals should cover the interval [0, +inf) and should not overlap nor have gaps, # each interval is defined by the properties 'moreOrEqual' and 'lessOrEqual' - if not isinstance(data, list) or not all(isinstance(i, dict) and ('moreOrEqual' in i and 'lessOrEqual' in i) for i in data): - raise ValueError('data must be a list of dictionaries with "moreOrEqual" and "lessOrEqual" keys') - data.sort(key=lambda x: x.get('moreOrEqual', float('-inf'))) if data[0].get('moreOrEqual') != 0: @@ -143,9 +140,6 @@ def check_intervals(data): raise ValueError('The last interval must extend to infinity') def update_position(iwidget, key, data): - if not 'layoutConfigurations' in data: - raise ValueError('Missing layoutConfigurations field') - # Check if we have duplicate ids in the layoutConfigurations ids = set() for layoutConfig in data["layoutConfigurations"]: diff --git a/src/wirecloud/platform/tests/rest_api.py b/src/wirecloud/platform/tests/rest_api.py index f32d0e9c82..4feda1dee7 100644 --- a/src/wirecloud/platform/tests/rest_api.py +++ b/src/wirecloud/platform/tests/rest_api.py @@ -2403,6 +2403,89 @@ def test_iwidget_entry_post_upgrade_operator(self): response_data = json.loads(response.content.decode('utf-8')) self.assertTrue(isinstance(response_data, dict)) + def test_iwidget_entry_post_invalid_screen_size(self): + url = reverse('wirecloud.iwidget_entry', kwargs={'workspace_id': 2, 'tab_id': 101, 'iwidget_id': 2}) + + # Authenticate + self.client.login(username='user_with_workspaces', password='admin') + + # Make the requests + data = {'layoutConfigurations': [{'id': 0, 'action': 'update', 'moreOrEqual': -3}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + data = {'layoutConfigurations': [{'id': 0, 'action': 'update', 'moreOrEqual': 'notavalidvalue'}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 400) + + data = {'layoutConfigurations': [{'id': 0, 'action': 'update', 'moreOrEqual': 1}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + data = {'layoutConfigurations': [{'id': 0, 'action': 'update', 'lessOrEqual': 1}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + data = {'layoutConfigurations': [{'action': 'update'}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + data = {'layoutConfigurations': [{'id': 0, 'lessOrEqual': 1}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + data = {'layoutConfigurations': [{'id': 0, 'action': 'add', 'lessOrEqual': 1}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + data = {'layoutConfigurations': [{'id': 0, 'action': 'update'}, {'id': 0, 'action': 'update'}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + def test_iwidget_entry_post_delete_screen_size(self): + url = reverse('wirecloud.iwidget_entry', kwargs={'workspace_id': 2, 'tab_id': 101, 'iwidget_id': 2}) + data = {'layoutConfigurations': [ + {'id': 0, 'action': 'update', 'moreOrEqual': 0, 'lessOrEqual': 800}, + {'id': 1, 'action': 'update', 'moreOrEqual': 801, 'lessOrEqual': -1} + ]} + + # Authenticate + self.client.login(username='user_with_workspaces', password='admin') + + # Make the requests + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 204) + + data = {'layoutConfigurations': [{'id': 0, 'action': 'update', 'lessOrEqual': -1}, {'id': 1, 'action': 'delete'}]} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 204) + + + def test_iwidget_entry_post_invalid_layout(self): + url = reverse('wirecloud.iwidget_entry', kwargs={'workspace_id': 2, 'tab_id': 101, 'iwidget_id': 2}) + + # Authenticate + self.client.login(username='user_with_workspaces', password='admin') + + # Make the requests + data = {'layout': -3} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 422) + + def test_iwidget_entry_post_valid_layout(self): + url = reverse('wirecloud.iwidget_entry', kwargs={'workspace_id': 2, 'tab_id': 101, 'iwidget_id': 2}) + + # Authenticate + self.client.login(username='user_with_workspaces', password='admin') + + # Make the requests + data = {'layout': 0} + response = self.client.post(url, json.dumps(data), content_type='application/json; charset=UTF-8', HTTP_ACCEPT='application/json') + self.assertEqual(response.status_code, 204) + + iwidget = IWidget.objects.get(pk=2) + self.assertEqual(iwidget.layout, 0) + def check_iwidget_entry_post_invalid_position_value(self, field, value, error_code): url = reverse('wirecloud.iwidget_entry', kwargs={'workspace_id': 2, 'tab_id': 101, 'iwidget_id': 2}) From ece1ade52c8e62318c2f1566ee25f155f1607423 Mon Sep 17 00:00:00 2001 From: oxixes Date: Mon, 1 Jul 2024 15:20:20 +0200 Subject: [PATCH 18/28] Exclude non-relevant files from search indexers tests --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cab77cba3a..23cbf46d7d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -157,7 +157,7 @@ jobs: curl "http://localhost:8983/solr/admin/cores?action=RELOAD&core=tester" fi python manage.py collectstatic -v 0 -c --noinput - coverage run -a --branch --source wirecloud --omit="*/wirecloud/semanticwiring/*,*/wirecloud/guidebuilder/*,*/tests/*,*/tests.py,*/wirecloud/commons/utils/template/*" manage.py test --noinput --nologcapture -v 2 -a tags='wirecloud-search-api' + coverage run -a --branch --source wirecloud --omit="*/wirecloud/semanticwiring/*,*/wirecloud/guidebuilder/*,*/tests/*,*/tests.py,*/wirecloud/commons/utils/template/*,*/wirecloud/platform/workspace/*,*/wirecloud/platform/iwidget/*" manage.py test --noinput --nologcapture -v 2 -a tags='wirecloud-search-api' - name: Coveralls Parallel uses: AndreMiras/coveralls-python-action@develop with: From 20e3c8017df45fde191dde6d5127b4d5fdece429 Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 2 Jul 2024 12:33:04 +0200 Subject: [PATCH 19/28] Fix bug and add selenium tests --- .../wirecloud/ui/ScreenSizesInputInterface.js | 4 +- .../js/wirecloud/ui/WorkspaceTabView.js | 3 +- src/wirecloud/platform/tests/selenium.py | 60 +++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js index 08886eefc1..8ebd3ad2bd 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/ScreenSizesInputInterface.js @@ -87,7 +87,7 @@ } on_valueChange(screenSizeId, from, value) { - const screenSizes = this.value; + const screenSizes = utils.clone(this.value, true); const screenSizeIdx = screenSizes.findIndex((screenSize) => screenSize.id === screenSizeId); screenSizes[screenSizeIdx][from] = value; @@ -99,6 +99,8 @@ screenSizes[screenSizeIdx + 1].moreOrEqual = value + 1; this.screenSizesInputs[screenSizes[screenSizeIdx + 1].id].children[1].children[1].inputElement.value = value + 1; } + + this.value = screenSizes; } static parse(value) { diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index 61e86d24d0..1bc143e82e 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -366,7 +366,8 @@ const a = document.createElement('a'); a.className = 'far fa-times-circle wc-editing-interval-close'; a.href = '#'; - a.addEventListener('click', () => { + a.addEventListener('click', (e) => { + e.preventDefault(); this.quitEditingInterval(); }); div.appendChild(a); diff --git a/src/wirecloud/platform/tests/selenium.py b/src/wirecloud/platform/tests/selenium.py index 582092c042..8128dd74e1 100644 --- a/src/wirecloud/platform/tests/selenium.py +++ b/src/wirecloud/platform/tests/selenium.py @@ -94,6 +94,66 @@ def test_basic_workspace_operations(self): # wirecloud org first) self.open_menu().check(('New workspace',), must_be_disabled=('Rename', 'Settings', 'Remove')) + def test_basic_screen_sizes(self): + + original_browser_size = self.driver.get_window_size() + # Change the browser width to 1000 px + self.driver.set_window_size(1000, 600) + + self.login(username="user_with_workspaces", next="/user_with_workspaces/pending-events") + + # Open the workspace settings + with self.edit_mode: + self.open_menu().click_entry('Settings') + workspace_preferences_dialog = FormModalTester(self, self.wait_element_visible('.wc-workspace-preferences-modal')) + + # Find the screen sizes field + screen_sizes_field = workspace_preferences_dialog.body.find_element(By.CSS_SELECTOR, '.se-screen-size-field') + add_button_field = screen_sizes_field.find_element(By.CSS_SELECTOR, 'div.se-btn > i.fa-plus') + + # Add a new screen size + add_button_field.click() + + workspace_preferences_dialog.accept() + + # Make sure an error appears (check display is not none) + self.assertTrue(workspace_preferences_dialog.error_message.is_displayed()) + + # Change the screen size + + # Get the first input with name 'lessOrEqual' + lessOrEqual_input = screen_sizes_field.find_element(By.CSS_SELECTOR, 'input[name="lessOrEqual"]') + + # Input 900 + lessOrEqual_input.clear() + lessOrEqual_input.send_keys('900') + + # Click the edit button + edit_button = screen_sizes_field.find_element(By.CSS_SELECTOR, 'div.se-btn > i.fa-edit') + edit_button.click() + + # Wait for the changes to be saved and the editing message to appear + self.wait_element_visible('.wc-editing-interval') + + # Move the widget to the right + iwidget = self.find_tab(id="102").widgets[0] + original_position = iwidget.position['x'] + ActionChains(self.driver).click_and_hold(iwidget.title_element).move_by_offset(400, 0).release().perform() + + self.wait_element_visible('.wc-editing-interval-close').click() + + # Make sure the widget has returned to its original position + time.sleep(1) + self.assertEqual(iwidget.position['x'], original_position) + + self.driver.set_window_size(600, 600) + + # Make sure the widget has moved + time.sleep(1) + self.assertNotEqual(iwidget.position['x'], original_position) + + self.driver.set_window_size(original_browser_size['width'], original_browser_size['height']) + def test_move_iwidget_between_tabs(self): self.login(username='user_with_workspaces', next='/user_with_workspaces/pending-events') From f9702d03af89731db8277775e400c0f714c07b08 Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 2 Jul 2024 12:37:24 +0200 Subject: [PATCH 20/28] Fix identation --- src/wirecloud/platform/tests/selenium.py | 80 ++++++++++++------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/wirecloud/platform/tests/selenium.py b/src/wirecloud/platform/tests/selenium.py index 8128dd74e1..2faf612d06 100644 --- a/src/wirecloud/platform/tests/selenium.py +++ b/src/wirecloud/platform/tests/selenium.py @@ -96,63 +96,63 @@ def test_basic_workspace_operations(self): def test_basic_screen_sizes(self): - original_browser_size = self.driver.get_window_size() - # Change the browser width to 1000 px - self.driver.set_window_size(1000, 600) + original_browser_size = self.driver.get_window_size() + # Change the browser width to 1000 px + self.driver.set_window_size(1000, 600) - self.login(username="user_with_workspaces", next="/user_with_workspaces/pending-events") + self.login(username="user_with_workspaces", next="/user_with_workspaces/pending-events") - # Open the workspace settings - with self.edit_mode: - self.open_menu().click_entry('Settings') - workspace_preferences_dialog = FormModalTester(self, self.wait_element_visible('.wc-workspace-preferences-modal')) + # Open the workspace settings + with self.edit_mode: + self.open_menu().click_entry('Settings') + workspace_preferences_dialog = FormModalTester(self, self.wait_element_visible('.wc-workspace-preferences-modal')) - # Find the screen sizes field - screen_sizes_field = workspace_preferences_dialog.body.find_element(By.CSS_SELECTOR, '.se-screen-size-field') - add_button_field = screen_sizes_field.find_element(By.CSS_SELECTOR, 'div.se-btn > i.fa-plus') + # Find the screen sizes field + screen_sizes_field = workspace_preferences_dialog.body.find_element(By.CSS_SELECTOR, '.se-screen-size-field') + add_button_field = screen_sizes_field.find_element(By.CSS_SELECTOR, 'div.se-btn > i.fa-plus') - # Add a new screen size - add_button_field.click() + # Add a new screen size + add_button_field.click() - workspace_preferences_dialog.accept() + workspace_preferences_dialog.accept() - # Make sure an error appears (check display is not none) - self.assertTrue(workspace_preferences_dialog.error_message.is_displayed()) + # Make sure an error appears (check display is not none) + self.assertTrue(workspace_preferences_dialog.error_message.is_displayed()) - # Change the screen size + # Change the screen size - # Get the first input with name 'lessOrEqual' - lessOrEqual_input = screen_sizes_field.find_element(By.CSS_SELECTOR, 'input[name="lessOrEqual"]') + # Get the first input with name 'lessOrEqual' + lessOrEqual_input = screen_sizes_field.find_element(By.CSS_SELECTOR, 'input[name="lessOrEqual"]') - # Input 900 - lessOrEqual_input.clear() - lessOrEqual_input.send_keys('900') + # Input 900 + lessOrEqual_input.clear() + lessOrEqual_input.send_keys('900') - # Click the edit button - edit_button = screen_sizes_field.find_element(By.CSS_SELECTOR, 'div.se-btn > i.fa-edit') - edit_button.click() + # Click the edit button + edit_button = screen_sizes_field.find_element(By.CSS_SELECTOR, 'div.se-btn > i.fa-edit') + edit_button.click() - # Wait for the changes to be saved and the editing message to appear - self.wait_element_visible('.wc-editing-interval') + # Wait for the changes to be saved and the editing message to appear + self.wait_element_visible('.wc-editing-interval') - # Move the widget to the right - iwidget = self.find_tab(id="102").widgets[0] - original_position = iwidget.position['x'] - ActionChains(self.driver).click_and_hold(iwidget.title_element).move_by_offset(400, 0).release().perform() + # Move the widget to the right + iwidget = self.find_tab(id="102").widgets[0] + original_position = iwidget.position['x'] + ActionChains(self.driver).click_and_hold(iwidget.title_element).move_by_offset(400, 0).release().perform() - self.wait_element_visible('.wc-editing-interval-close').click() + self.wait_element_visible('.wc-editing-interval-close').click() - # Make sure the widget has returned to its original position - time.sleep(1) - self.assertEqual(iwidget.position['x'], original_position) + # Make sure the widget has returned to its original position + time.sleep(1) + self.assertEqual(iwidget.position['x'], original_position) - self.driver.set_window_size(600, 600) + self.driver.set_window_size(600, 600) - # Make sure the widget has moved - time.sleep(1) - self.assertNotEqual(iwidget.position['x'], original_position) + # Make sure the widget has moved + time.sleep(1) + self.assertNotEqual(iwidget.position['x'], original_position) - self.driver.set_window_size(original_browser_size['width'], original_browser_size['height']) + self.driver.set_window_size(original_browser_size['width'], original_browser_size['height']) def test_move_iwidget_between_tabs(self): From 196f94e2989c46180002f12afc1b22aeb39b0e31 Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 2 Jul 2024 16:17:59 +0200 Subject: [PATCH 21/28] Move the editing interval message to the bottom and keep it present at all times --- src/js_tests/styledelements/NotebookSpec.js | 10 +- .../wirecloud/ui/WorkspaceTabViewSpec.js | 100 +++++++++++++++--- .../wirecloud/ui/WorkspaceViewSpec.js | 9 +- .../commons/static/js/StyledElements/Addon.js | 9 +- .../static/js/StyledElements/Notebook.js | 33 ++++-- .../static/css/workspace/dragboard.scss | 15 +-- .../locale/es/LC_MESSAGES/djangojs.po | 50 +++++---- .../js/wirecloud/ui/WorkspaceTabView.js | 72 +++++++++---- .../static/js/wirecloud/ui/WorkspaceView.js | 36 ++++++- src/wirecloud/platform/wiring/tests.py | 2 + 10 files changed, 240 insertions(+), 96 deletions(-) diff --git a/src/js_tests/styledelements/NotebookSpec.js b/src/js_tests/styledelements/NotebookSpec.js index 55762184fd..ea11a7b4a1 100644 --- a/src/js_tests/styledelements/NotebookSpec.js +++ b/src/js_tests/styledelements/NotebookSpec.js @@ -468,7 +468,7 @@ }); - describe("addButton(button, position)", function () { + describe("addToEastSection(elem, position)", function () { let element; beforeEach(function () { @@ -476,24 +476,24 @@ }); it("throws an exception if button is not a button", function () { - expect(function () {element.addButton(null);}).toThrow(jasmine.any(TypeError)); + expect(function () {element.addToEastSection(null);}).toThrow(jasmine.any(TypeError)); }); it("place buttons on the right by default", function () { const button = new StyledElements.Button(); - element.addButton(button); + element.addToEastSection(button); expect(element.tabWrapper.east.children).toEqual([element.moveRightButton, button]); }); it("place buttons on the right by default", function () { const button = new StyledElements.Button(); - element.addButton(button, 'right'); + element.addToEastSection(button, 'right'); expect(element.tabWrapper.east.children).toEqual([element.moveRightButton, button]); }); it("should allow to add buttons on the left side", function () { const button = new StyledElements.Button(); - element.addButton(button, 'left'); + element.addToEastSection(button, 'left'); expect(element.tabWrapper.west.children).toEqual([button, element.moveLeftButton]); }); }); diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js index 4fcdbc2cad..4e22c4712c 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js @@ -44,10 +44,10 @@ id: "8", preferences: { get: jasmine.createSpy("get").and.callFake(function (key) { - if (options && key in options.customPreferences) { + if (options && options.customPreferences && key in options.customPreferences) { return options.customPreferences[key]; } else if (key === "screenSizes") { - return [{id: 0, moreOrEqual: 0, lessOrEqual: -1}]; + return [{id: 0, moreOrEqual: 0, lessOrEqual: -1, name: "Default"}]; } }), addEventListener: jasmine.createSpy("addEventListener") @@ -84,6 +84,7 @@ return { addEventListener: jasmine.createSpy("addEventListener"), buildAddWidgetButton: jasmine.createSpy("buildAddWidgetButton").and.returnValue(), + updateEditingInterval: jasmine.createSpy("updateEditingInterval"), model: workspace }; }; @@ -935,6 +936,47 @@ }); + describe("getEditingIntervalElement()", () => { + + it("should return the editing interval element without link if customWidth is -1", () => { + const workspace = create_workspace(); + const model = create_tab(); + const tab = new ns.WorkspaceTabView("1", notebook, { + model: model, + workspace: workspace + }); + + tab.dragboard.customWidth = -1; + + const elem = tab.getEditingIntervalElement(); + + // It should NOT contain a link + expect(elem.querySelector('a')).toBe(null); + }); + + it("should return the editing interval element with link if customWidth is not -1", () => { + const workspace = create_workspace(); + const model = create_tab(); + const tab = new ns.WorkspaceTabView("1", notebook, { + model: model, + workspace: workspace + }); + + tab.dragboard.customWidth = 10; + + const elem = tab.getEditingIntervalElement(); + + // It should contain a link + expect(elem.querySelector('a')).not.toBe(null); + + tab.quitEditingInterval = jasmine.createSpy("quitEditingInterval"); + elem.querySelector('a').click(); + + expect(tab.quitEditingInterval).toHaveBeenCalled(); + }); + + }); + describe("setEditingInterval(moreOrEqual, lessOrEqual, name)", () => { it("should set the editing interval", () => { @@ -949,11 +991,6 @@ tab.setEditingInterval(0, 10, "name"); expect(tab.dragboard.setCustomDragboardWidth).toHaveBeenCalledWith(5); - tab.quitEditingInterval = jasmine.createSpy("quitEditingInterval"); - - tab.intervalEditionIndicator.querySelector(".wc-editing-interval-close").click(); - - expect(tab.quitEditingInterval).toHaveBeenCalled(); tab.setEditingInterval(10, -1, "name"); expect(tab.dragboard.setCustomDragboardWidth).toHaveBeenCalledWith(10); @@ -976,16 +1013,51 @@ tab.quitEditingInterval(); expect(tab.dragboard.restoreDragboardWidth).toHaveBeenCalled(); + }); - const intervalEditionIndicator = { - remove: jasmine.createSpy("remove") - }; + }); - tab.intervalEditionIndicator = intervalEditionIndicator; - tab.quitEditingInterval(); + describe("updateEditingIntervalName()", () => { + + it("should update the editing interval name", () => { + const workspace = create_workspace(); + const model = create_tab({ + customPreferences: { + screenSizes: [ + {id: 0, moreOrEqual: 0, lessOrEqual: 800, name: "Default"}, + {id: 1, moreOrEqual: 801, lessOrEqual: 1000, name: "Default-1"}, + {id: 2, moreOrEqual: 1001, lessOrEqual: -1, name: "Default-2"} + ] + } + }); + const tab = new ns.WorkspaceTabView("1", notebook, { + model: model, + workspace: workspace + }); + + Object.defineProperty(window, 'innerWidth', { + value: 800, + writable: true + }); + + tab.dragboard.customWidth = -1; + + tab.updateEditingIntervalName(); + expect(tab.editingIntervalName).toBe("Default"); + + window.innerWidth = 900; + tab.updateEditingIntervalName(); + expect(tab.editingIntervalName).toBe("Default-1"); + + window.innerWidth = 1001; + tab.updateEditingIntervalName(); + expect(tab.editingIntervalName).toBe("Default-2"); + + tab.dragboard.customWidth = 10; + tab.updateEditingIntervalName(); + expect(tab.editingIntervalName).toBe("Default"); - expect(intervalEditionIndicator.remove).toHaveBeenCalled(); - expect(tab.intervalEditionIndicator).toBe(null); + window.innerWidth = 800; }); }); diff --git a/src/js_tests/wirecloud/ui/WorkspaceViewSpec.js b/src/js_tests/wirecloud/ui/WorkspaceViewSpec.js index 3c95525e2b..add185c1e0 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceViewSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceViewSpec.js @@ -112,6 +112,7 @@ this.id = "8"; this.createWidget = jasmine.createSpy("createWidget"); this.findWidget = jasmine.createSpy("findWidget"); + this.getEditingIntervalElement = jasmine.createSpy("getEditingIntervalElement").and.returnValue(document.createElement('div')); this.widgets = []; this.dragboard = { _updateIWidgetSizes: jasmine.createSpy("_updateIWidgetSizes"), @@ -757,7 +758,7 @@ const view = new ns.WorkspaceView(1); const workspace = create_workspace(); workspace.isAllowed.and.returnValue(true); - spyOn(StyledElements.Notebook.prototype, "addButton"); + spyOn(StyledElements.Notebook.prototype, "addToEastSection"); spyOn(StyledElements.Notebook.prototype, "createTab").and.callThrough(); view.loadWorkspace(workspace); @@ -765,7 +766,7 @@ const tab = {}; workspace.createTab.and.returnValue(Promise.resolve(tab)); - const button = view.notebook.addButton.calls.argsFor(0)[0]; + const button = view.notebook.addToEastSection.calls.argsFor(1)[0]; spyOn(button, "disable"); spyOn(button, "enable"); button.click(); @@ -787,12 +788,12 @@ const view = new ns.WorkspaceView(1); const workspace = create_workspace(); workspace.isAllowed.and.returnValue(true); - spyOn(StyledElements.Notebook.prototype, "addButton"); + spyOn(StyledElements.Notebook.prototype, "addToEastSection"); spyOn(StyledElements.Notebook.prototype, "createTab").and.callThrough(); view.loadWorkspace(workspace); workspace.createTab.and.returnValue(Promise.reject()); - const button = view.notebook.addButton.calls.argsFor(0)[0]; + const button = view.notebook.addToEastSection.calls.argsFor(1)[0]; spyOn(button, "disable"); spyOn(button, "enable"); view.notebook.createTab.calls.reset(); diff --git a/src/wirecloud/commons/static/js/StyledElements/Addon.js b/src/wirecloud/commons/static/js/StyledElements/Addon.js index 9b46923a75..5c0537dbac 100644 --- a/src/wirecloud/commons/static/js/StyledElements/Addon.js +++ b/src/wirecloud/commons/static/js/StyledElements/Addon.js @@ -60,7 +60,8 @@ const defaultOptions = { 'text': null, 'title': '', - 'class': '' + 'class': '', + 'listeners': true }; options = utils.merge({}, defaultOptions, options); @@ -81,8 +82,10 @@ /* Event handlers */ this._clickCallback = clickCallback.bind(this); - this.wrapperElement.addEventListener('mousedown', utils.stopPropagationListener, true); - this.wrapperElement.addEventListener('click', this._clickCallback, true); + if (options.listeners) { + this.wrapperElement.addEventListener('mousedown', utils.stopPropagationListener, true); + this.wrapperElement.addEventListener('click', this._clickCallback, true); + } } /** diff --git a/src/wirecloud/commons/static/js/StyledElements/Notebook.js b/src/wirecloud/commons/static/js/StyledElements/Notebook.js index 8bfff6f802..a74782d1aa 100644 --- a/src/wirecloud/commons/static/js/StyledElements/Notebook.js +++ b/src/wirecloud/commons/static/js/StyledElements/Notebook.js @@ -170,7 +170,7 @@ this.tabArea.appendChild(this.new_tab_button_tabs); this.new_tab_button_left = new this.Button({iconClass: 'fas fa-plus', 'class': 'se-notebook-new-tab', title: utils.gettext('Add Tab')}); this.new_tab_button_left.addEventListener('click', new_tab_main_listener); - this.addButton(this.new_tab_button_left); + this.addToEastSection(this.new_tab_button_left); } StyledElements.Event.prototype.addEventListener.call(this.events.newTab, listener); }.bind(this); @@ -640,24 +640,20 @@ /** * - * @name StyledElements.Notebook#addButton + * @name StyledElements.Notebook#addToEastSection * * @returns {StyledElements.Notebook} * The instance on which the member is called. */ - addButton(button, position) { - if (!(button instanceof StyledElements.Button) && !(button instanceof StyledElements.Select)) { - throw new TypeError(); - } - + addToEastSection(elem, position) { position = position || 'right'; switch (position) { case 'left': - this.tabWrapper.west.prependChild(button, this.moveLeftButton); + this.tabWrapper.west.prependChild(elem, this.moveLeftButton); break; case 'right': - this.tabWrapper.east.appendChild(button); + this.tabWrapper.east.appendChild(elem); break; } @@ -667,6 +663,25 @@ return this; } + /** + * + * @name StyledElements.Notebook#addButton + * + * @returns {StyledElements.Notebook} + * The instance on which the member is called. + * + * @deprecated Old method, use addToEastSection instead + */ + addButton(button, position) { + if (!(button instanceof StyledElements.Button) && !(button instanceof StyledElements.Select)) { + throw new TypeError(); + } + + this.addToEastSection(button, position); + + return this; + } + /** * Requests fullscreen mode. You must call this method from a user event * handler, otherwise the browser will denie this request. diff --git a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss index 264c2c126a..ec92923ff0 100644 --- a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss +++ b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss @@ -115,23 +115,16 @@ } .wc-editing-interval { - background-color: #000; - opacity: 0.8; - position: fixed; - z-index: 101110; - color: #fff; - padding: 10px; - border-radius: 7px; - right: 50px; - top: 39px; + margin: 3px 5px; } .wc-editing-interval-close { - color: #fff; + color: #333; margin-left: 10px; } .wc-editing-interval-close:hover { cursor: pointer; - color: #fff; + color: #333; + text-decoration: none; } \ No newline at end of file diff --git a/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po b/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po index 5d584896ca..97b78372ba 100644 --- a/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po +++ b/src/wirecloud/platform/locale/es/LC_MESSAGES/djangojs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: WireCloud 1.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-28 17:10+0200\n" +"POT-Creation-Date: 2024-07-02 15:35+0200\n" "PO-Revision-Date: 2019-06-04 10:40+0200\n" "Last-Translator: Álvaro Arranz García \n" "Language-Team: Español/España\n" @@ -90,7 +90,7 @@ msgstr "Error HTTP %(errorCode)s - %(errorDesc)s" #: static/js/wirecloud/core.js:744 #: static/js/wirecloud/ui/PublishResourceWindowMenu.js:104 #: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:270 -#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:423 +#: static/js/wirecloud/ui/WorkspaceTabViewDragboard.js:431 msgid "Unexpected response from server" msgstr "Respuesta inesperada del servidor" @@ -1341,7 +1341,7 @@ msgstr "" #: static/js/wirecloud/ui/MarketplaceView.js:179 #: static/js/wirecloud/ui/MyResourcesView.js:148 #: static/js/wirecloud/ui/MyResourcesView.js:166 -#: static/js/wirecloud/ui/WorkspaceView.js:177 +#: static/js/wirecloud/ui/WorkspaceView.js:181 msgid "My Resources" msgstr "Mis recursos" @@ -1442,7 +1442,7 @@ msgstr "" "botón Subir." #: static/js/wirecloud/ui/MyResourcesView.js:80 -#: static/js/wirecloud/ui/WorkspaceView.js:186 +#: static/js/wirecloud/ui/WorkspaceView.js:190 msgid "Get more components" msgstr "Obtener más componentes" @@ -1716,7 +1716,7 @@ msgstr "" #: static/js/wirecloud/ui/WiringEditor/Component.js:90 #: static/js/wirecloud/ui/WiringEditor/ComponentDraggable.js:269 #: static/js/wirecloud/ui/WiringEditor/Connection.js:330 -#: static/js/wirecloud/ui/WorkspaceTabView.js:220 +#: static/js/wirecloud/ui/WorkspaceTabView.js:238 msgid "Preferences" msgstr "Preferencias" @@ -1728,27 +1728,27 @@ msgstr "Variables persistentes" msgid "New Name" msgstr "Nuevo nombre" -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:178 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:191 msgid "Name:" msgstr "Nombre:" -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:179 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:192 msgid "Name of the screen size range." msgstr "Nombre del rango de tamaños de pantalla." -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:198 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:211 msgid "From (px):" msgstr "Desde (px):" -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:199 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:212 msgid "The left limit of the screen size range (in pixels)." msgstr "El límite izquierdo del rango de tamaños de pantalla (en píxeles)." -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:226 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:239 msgid "To (px):" msgstr "Hasta (px):" -#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:227 +#: static/js/wirecloud/ui/ScreenSizesInputInterface.js:240 msgid "" "The right limit of the screen size range (in pixels). Use -1 for no limit." msgstr "" @@ -2262,9 +2262,13 @@ msgstr "No se ha proporcionado una descripción." msgid "Empty workspace list" msgstr "Lista de entornos de trabajo vacía" -#: static/js/wirecloud/ui/WorkspaceTabView.js:358 -msgid "Currently editing for screen size %(name)s" -msgstr "Actualmente editando para los tamaños de pantalla %(name)s" +#: static/js/wirecloud/ui/WorkspaceTabView.js:373 +msgid "(Overriden) Editing for screen size %(name)s" +msgstr "(Sobrescrito) Editando para el tamaño de pantalla %(name)s" + +#: static/js/wirecloud/ui/WorkspaceTabView.js:375 +msgid "Editing for screen size %(name)s" +msgstr "Editando para el tamaño de pantalla %(name)s" #: static/js/wirecloud/ui/WorkspaceTabViewMenuItems.js:49 msgid "Rename Workspace Tab" @@ -2278,33 +2282,33 @@ msgstr "Configurar como inicial" msgid "The tab's widgets will also be removed. Would you like to continue?" msgstr "Los widgets de la pestaña serán también eliminados. ¿Desea continuar?" -#: static/js/wirecloud/ui/WorkspaceView.js:168 +#: static/js/wirecloud/ui/WorkspaceView.js:172 msgid "Wiring" msgstr "Wiring" -#: static/js/wirecloud/ui/WorkspaceView.js:372 +#: static/js/wirecloud/ui/WorkspaceView.js:388 msgid "New tab" msgstr "Nueva pestaña" -#: static/js/wirecloud/ui/WorkspaceView.js:387 -#: static/js/wirecloud/ui/WorkspaceView.js:398 +#: static/js/wirecloud/ui/WorkspaceView.js:403 +#: static/js/wirecloud/ui/WorkspaceView.js:414 msgid "Full screen" msgstr "Ver a pantalla completa" -#: static/js/wirecloud/ui/WorkspaceView.js:394 +#: static/js/wirecloud/ui/WorkspaceView.js:410 msgid "Exit full screen" msgstr "Salir de pantalla completa" -#: static/js/wirecloud/ui/WorkspaceView.js:434 +#: static/js/wirecloud/ui/WorkspaceView.js:450 msgid "Add components" msgstr "Añadir componentes" -#: static/js/wirecloud/ui/WorkspaceView.js:493 -#: static/js/wirecloud/ui/WorkspaceView.js:507 +#: static/js/wirecloud/ui/WorkspaceView.js:509 +#: static/js/wirecloud/ui/WorkspaceView.js:523 msgid "loading..." msgstr "cargando..." -#: static/js/wirecloud/ui/WorkspaceView.js:545 +#: static/js/wirecloud/ui/WorkspaceView.js:561 msgid "The requested workspace is no longer available (it was deleted)." msgstr "" "El entorno de trabajo solicitado ya no está disponible (ha sido borrado)." diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index 1bc143e82e..a96c7f54a0 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -114,9 +114,27 @@ this.prefbutton.enabled = this.workspace.editing; }; + const get_editing_interval_name = function get_editing_interval_name(width) { + const screenSizes = this.model.preferences.get('screenSizes'); + let editingIntervalName = null; + for (let i = 0; i < screenSizes.length; i++) { + if (screenSizes[i].moreOrEqual <= width && (screenSizes[i].lessOrEqual === -1 || screenSizes[i].lessOrEqual >= width)) { + editingIntervalName = screenSizes[i].name; + break; + } + } + + return editingIntervalName; + } + const on_windowresize = function on_windowresize() { if (this.dragboard.customWidth === -1) { this.dragboard.updateWidgetScreenSize(window.innerWidth); + + if (this.workspace.activeTab === this) { + this.editingIntervalName = get_editing_interval_name.call(this, window.innerWidth); + this.workspace.updateEditingInterval(this.getEditingIntervalElement()); + } } }; @@ -232,6 +250,7 @@ } this.dragboard = new ns.WorkspaceTabViewDragboard(this); + this.updateEditingIntervalName(); this.initialMessage = (new se.GUIBuilder()).parse(Wirecloud.currentTheme.templates['wirecloud/workspace/empty_tab_message'], { button: this.workspace.buildAddWidgetButton.bind(this.workspace), @@ -348,42 +367,51 @@ ); } - setEditingInterval(moreOrEqual, lessOrEqual, name) { - let avgScreenSize = Math.floor((moreOrEqual + lessOrEqual) / 2); - if (lessOrEqual === -1) { - avgScreenSize = moreOrEqual; + getEditingIntervalElement() { + let text = ""; + if (this.dragboard.customWidth !== -1) { + text = utils.interpolate(utils.gettext("(Overriden) Editing for screen size %(name)s"), {name: this.editingIntervalName}); + } else { + text = utils.interpolate(utils.gettext("Editing for screen size %(name)s"), {name: this.editingIntervalName}); } - this.dragboard.setCustomDragboardWidth(avgScreenSize); - - const text = utils.interpolate(utils.gettext("Currently editing for screen size %(name)s"), {name: name}); const div = document.createElement('div'); - div.className = 'wc-editing-interval'; const span = document.createElement('span'); span.textContent = text; div.appendChild(span); - const a = document.createElement('a'); - a.className = 'far fa-times-circle wc-editing-interval-close'; - a.href = '#'; - a.addEventListener('click', (e) => { - e.preventDefault(); - this.quitEditingInterval(); - }); - div.appendChild(a); + if (this.dragboard.customWidth !== -1) { + const a = document.createElement('a'); + a.className = 'far fa-times-circle wc-editing-interval-close'; + a.href = '#'; + a.addEventListener('click', (e) => { + e.preventDefault(); + this.quitEditingInterval(); + }); + div.appendChild(a); + } - this.intervalEditionIndicator = div; + return div; + } - this.wrapperElement.appendChild(div); + setEditingInterval(moreOrEqual, lessOrEqual, name) { + let avgScreenSize = Math.floor((moreOrEqual + lessOrEqual) / 2); + if (lessOrEqual === -1) { + avgScreenSize = moreOrEqual; + } + this.dragboard.setCustomDragboardWidth(avgScreenSize); + this.editingIntervalName = name; + this.workspace.updateEditingInterval(this.getEditingIntervalElement()); } quitEditingInterval() { this.dragboard.restoreDragboardWidth(); + this.editingIntervalName = get_editing_interval_name.call(this, window.innerWidth); + this.workspace.updateEditingInterval(this.getEditingIntervalElement()); + } - if (this.intervalEditionIndicator != null) { - this.intervalEditionIndicator.remove(); - this.intervalEditionIndicator = null; - } + updateEditingIntervalName() { + this.editingIntervalName = get_editing_interval_name.call(this, (this.dragboard.customWidth === -1) ? window.innerWidth : this.dragboard.customWidth); } /** diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js index 08708a2f85..e83baa3c1a 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceView.js @@ -46,6 +46,10 @@ if (this.addTabButton) { this.addTabButton.toggleClassName("hidden", !editing); } + + if (this.editingIntervalAddon) { + this.editingIntervalAddon.toggleClassName("hidden", !editing); + } }; const on_workspace_createoperator = function on_workspace_createoperator(workspace_model, operator) { @@ -368,12 +372,24 @@ this.notebook.removeTab(loadingTab); if (this.model.isAllowed('edit')) { + this.editingIntervalAddon = new StyledElements.Addon({ + class: 'wc-editing-interval', + listeners: false + }); + this.notebook.addToEastSection(this.editingIntervalAddon); + this.updateEditingInterval(this.activeTab.getEditingIntervalElement()); + + this.notebook.addEventListener('changed', (nt, oldTab, newTab) => { + newTab.updateEditingIntervalName(); + this.updateEditingInterval(newTab.getEditingIntervalElement()); + }); + this.addTabButton = new StyledElements.Button({ title: utils.gettext("New tab"), iconClass: "fas fa-plus", class: "wc-create-workspace-tab" }); - this.notebook.addButton(this.addTabButton); + this.notebook.addToEastSection(this.addTabButton); this.addTabButton.addEventListener('click', on_click_createtab.bind(this)); } else { this.addTabButton = null; @@ -386,7 +402,7 @@ iconClass: 'fas fa-expand', title: utils.gettext('Full screen') }); - this.notebook.addButton(this.fullscreenButton); + this.notebook.addToEastSection(this.fullscreenButton); Wirecloud.Utils.onFullscreenChange(this.notebook, () => { this.fullscreenButton.removeIconClassName(['fa-expand', 'fa-compress']); if (this.notebook.fullscreen) { @@ -412,7 +428,7 @@ this.seeOnWirecloudButton = new StyledElements.Button({ 'class': 'powered-by-wirecloud' }); - this.notebook.addButton(this.seeOnWirecloudButton); + this.notebook.addToEastSection(this.seeOnWirecloudButton); this.seeOnWirecloudButton.addEventListener('click', () => { const url = Wirecloud.URLs.WORKSPACE_VIEW.evaluate({owner: encodeURIComponent(this.model.owner), name: encodeURIComponent(this.model.name)}); window.open(url, '_blank'); @@ -421,9 +437,9 @@ this.poweredByWirecloudButton = new StyledElements.Button({ 'class': 'powered-by-wirecloud' }); - this.notebook.addButton(this.poweredByWirecloudButton); + this.notebook.addToEastSection(this.poweredByWirecloudButton); this.poweredByWirecloudButton.addEventListener('click', () => { - window.open('http://conwet.fi.upm.es/wirecloud/', '_blank'); + window.open('https://github.com/Wirecloud/wirecloud', '_blank'); }); } showHideTabBar.call(this, false); @@ -576,6 +592,16 @@ return this; } + /** + * Update the editing interval addon's content with the given element. + */ + updateEditingInterval(element) { + if (this.editingIntervalAddon) { + this.editingIntervalAddon.wrapperElement.innerHTML = ""; + this.editingIntervalAddon.wrapperElement.appendChild(element); + } + } + } ns.WorkspaceView.prototype.view_name = 'workspace'; diff --git a/src/wirecloud/platform/wiring/tests.py b/src/wirecloud/platform/wiring/tests.py index 24facc6be2..4429b245e8 100644 --- a/src/wirecloud/platform/wiring/tests.py +++ b/src/wirecloud/platform/wiring/tests.py @@ -2788,6 +2788,8 @@ def test_remove_components_using_key_delete_when_behaviour_engine_is_enabled(sel # In the case (2), the platform should remove the component selected # In the case (3), the platform should ignore the component selected + # This test is prone to failures. Rerun it if it fails + self.login(username='user_with_workspaces', next='/user_with_workspaces/mashup-with-behaviours') with self.edit_mode as edit_session: From 4c8983fc4eac3a588f4d0e5800eb67c4e5bd0209 Mon Sep 17 00:00:00 2001 From: oxixes Date: Mon, 8 Jul 2024 23:20:38 +0200 Subject: [PATCH 22/28] Remove print --- src/wirecloud/commons/tests/template.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wirecloud/commons/tests/template.py b/src/wirecloud/commons/tests/template.py index fa63509e0c..5d89e1a411 100644 --- a/src/wirecloud/commons/tests/template.py +++ b/src/wirecloud/commons/tests/template.py @@ -1583,8 +1583,6 @@ def check_minimal_mashup_data(self, testname, format): template = TemplateParser(template_contents) processed_info = template.get_resource_info() - print(json.dumps(processed_info, sort_keys=True, indent=4, ensure_ascii=False)) - self.check_full_mashup(processed_info, getattr(self, testname)) def check_full_mashup(self, processed_info, expected_result): From 9ee4e0dfab4131e5d48406befaf06426eeadd4b0 Mon Sep 17 00:00:00 2001 From: oxixes Date: Thu, 11 Jul 2024 01:37:34 +0200 Subject: [PATCH 23/28] Forgot to remove TODO --- src/wirecloud/commons/utils/template/writers/xml.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wirecloud/commons/utils/template/writers/xml.py b/src/wirecloud/commons/utils/template/writers/xml.py index beab54a650..e151d4a08b 100644 --- a/src/wirecloud/commons/utils/template/writers/xml.py +++ b/src/wirecloud/commons/utils/template/writers/xml.py @@ -78,7 +78,6 @@ def addPreferenceValues(resource, preferences): addAttribute(pref, element, 'value', type='string', default=None, required=False) addAttributes(pref, element, ('readonly', 'hidden'), default='false', type='boolean') -# TODO Adrian handle multiple screen sizes def write_mashup_tree(doc, resources, options): # Params From edeee6b650341d46626332fec0750485b60f5fed Mon Sep 17 00:00:00 2001 From: oxixes Date: Wed, 14 Aug 2024 14:32:21 +0200 Subject: [PATCH 24/28] Add updateWidgetScreenSizeWithId --- .../js/wirecloud/ui/WorkspaceTabViewDragboard.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index 5afa58c06d..3ee4d0aeba 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -232,6 +232,17 @@ this.paint(); } + updateWidgetScreenSizeWithId(id) { + const screenSize = this.tab.model.preferences.get('screenSizes').find((screenSize) => screenSize.id === id); + if (screenSize != null) { + let size = screenSize.moreOrEqual + (screenSize.lessOrEqual - screenSize.moreOrEqual) / 2; + if (screenSize.lessOrEqual === -1) { + size = screenSize.moreOrEqual; + } + this.updateWidgetScreenSize(screenSize.width); + } + } + /** * */ From 0ad8d66a2b5111855800118aef56dc0b10b6aec2 Mon Sep 17 00:00:00 2001 From: oxixes Date: Wed, 14 Aug 2024 15:01:40 +0200 Subject: [PATCH 25/28] Fix --- .../static/js/wirecloud/ui/WorkspaceTabViewDragboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index 3ee4d0aeba..bf9e5112c7 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -239,7 +239,7 @@ if (screenSize.lessOrEqual === -1) { size = screenSize.moreOrEqual; } - this.updateWidgetScreenSize(screenSize.width); + this.updateWidgetScreenSize(size); } } From 952b9c384b85f23cfff9affbd171947795e24ec6 Mon Sep 17 00:00:00 2001 From: oxixes Date: Thu, 15 Aug 2024 13:53:30 +0200 Subject: [PATCH 26/28] Add test --- .../ui/WorkspaceTabViewDragboardSpec.js | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js index 0cffd4d48e..b9086c7a22 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewDragboardSpec.js @@ -26,13 +26,13 @@ "use strict"; - const create_tab = function () { + const create_tab = function (customPreferences = null) { return { appendChild: jasmine.createSpy("appendChild"), model: { id: 3, preferences: { - get: jasmine.createSpy("get").and.returnValue({ + get: jasmine.createSpy("get").and.returnValue(customPreferences || { "type": "gridlayout", "columns": 20 }) @@ -871,6 +871,26 @@ }); + describe("updateWidgetScreenSizeWithId", () => { + + it("should update the screen size of the widget with the given id", () => { + const tab = create_tab([ + { + "id": 1, + "moreOrEqual": 0, + "lessOrEqual": 800 + } + ]); + const dragboard = new ns.WorkspaceTabViewDragboard(tab); + dragboard.updateWidgetScreenSize = jasmine.createSpy("updateWidgetScreenSize"); + + dragboard.updateWidgetScreenSizeWithId(1); + + expect(dragboard.updateWidgetScreenSize).toHaveBeenCalledWith(400); + }); + + }); + describe("update([ids, allLayoutConfigurations])", () => { let dragboard, widget1, widget2, widget3; From 8f152a2d755b5a8e8108cea801d9643dcad42fec Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 1 Oct 2024 18:46:10 +0200 Subject: [PATCH 27/28] Fix widget instance bug and some improvements --- src/js_tests/wirecloud/WidgetSpec.js | 7 ++ src/js_tests/wirecloud/ui/FreeLayoutSpec.js | 119 ++++++++++-------- .../wirecloud/ui/WorkspaceTabViewSpec.js | 6 +- .../platform/static/js/wirecloud/Widget.js | 3 +- .../platform/static/js/wirecloud/Wiring.js | 2 +- .../static/js/wirecloud/WorkspaceTab.js | 5 + .../static/js/wirecloud/ui/FreeLayout.js | 38 +++--- .../wirecloud/ui/WorkspaceTabViewDragboard.js | 2 +- 8 files changed, 107 insertions(+), 75 deletions(-) diff --git a/src/js_tests/wirecloud/WidgetSpec.js b/src/js_tests/wirecloud/WidgetSpec.js index d57dbb8140..f880db0628 100644 --- a/src/js_tests/wirecloud/WidgetSpec.js +++ b/src/js_tests/wirecloud/WidgetSpec.js @@ -2310,6 +2310,13 @@ it("should update the widget information accordingly", () => { + // Force window size to 800 + Object.defineProperty(window, 'innerWidth', { + writable: true, + configurable: true, + value: 750 + }); + const widget = new Wirecloud.Widget(WORKSPACE_TAB, EMPTY_WIDGET_META, { id: "1", layoutConfigurations: WIDGET_LAYOUT_CONFIGS diff --git a/src/js_tests/wirecloud/ui/FreeLayoutSpec.js b/src/js_tests/wirecloud/ui/FreeLayoutSpec.js index 656ea22c4e..a9bfba1e8f 100644 --- a/src/js_tests/wirecloud/ui/FreeLayoutSpec.js +++ b/src/js_tests/wirecloud/ui/FreeLayoutSpec.js @@ -827,109 +827,130 @@ it("should use first placement (bottom-right) when possible", () => { const options = { - width: 10, - height: 10, refposition: {left: 10, bottom: 10} }; - layout.searchBestPosition(options); + const layoutConfig = { + width: 10, + height: 10 + }; + + layout.searchBestPosition(options, layoutConfig, null); - expect(options.width).toBe(10); - expect(options.height).toBe(10); - expect(options.left).toBe(100000); - expect(options.top).toBe(10); + expect(layoutConfig.width).toBe(10); + expect(layoutConfig.height).toBe(10); + expect(layoutConfig.left).toBe(100000); + expect(layoutConfig.top).toBe(10); }); it("should use second placement when possible", () => { const options = { - width: 750000, - height: 20, refposition: {left: 70, right: 90, bottom: 10} }; - layout.searchBestPosition(options); + const layoutConfig = { + width: 750000, + height: 20 + }; + + layout.searchBestPosition(options, layoutConfig, null); - expect(options.width).toBe(750000); - expect(options.height).toBe(20); - expect(options.left).toBe(150000); - expect(options.top).toBe(10); + expect(layoutConfig.width).toBe(750000); + expect(layoutConfig.height).toBe(20); + expect(layoutConfig.left).toBe(150000); + expect(layoutConfig.top).toBe(10); }); it("should use last placement when possible", () => { const options = { - width: 800000, - height: 20, refposition: {left: 80, right: 90, top: 90, bottom: 99} }; - layout.searchBestPosition(options); + const layoutConfig = { + width: 800000, + height: 20 + }; - expect(options.width).toBe(800000); - expect(options.height).toBe(20); - expect(options.left).toBe(100000); - expect(options.top).toBe(70); + layout.searchBestPosition(options, layoutConfig, null); + + expect(layoutConfig.width).toBe(800000); + expect(layoutConfig.height).toBe(20); + expect(layoutConfig.left).toBe(100000); + expect(layoutConfig.top).toBe(70); }); it("should reduce widget height if there is not enough space", () => { const options = { - width: 800000, - height: 100, refposition: {left: 80, right: 90, top: 90, bottom: 99} }; - layout.searchBestPosition(options); + const layoutConfig = { + width: 800000, + height: 100 + }; + + layout.searchBestPosition(options, layoutConfig, null); - expect(options.width).toBe(800000); - expect(options.height).toBe(100); - expect(options.left).toBe(100000); - expect(options.top).toBe(0); + expect(layoutConfig.width).toBe(800000); + expect(layoutConfig.height).toBe(100); + expect(layoutConfig.left).toBe(100000); + expect(layoutConfig.top).toBe(0); }); it("should reduce widget width (rigth side) if there is not enough space", () => { const options = { - width: 950000, - height: 100, refposition: {left: 10, right: 90, top: 0, bottom: 10} }; - layout.searchBestPosition(options); + const layoutConfig = { + width: 950000, + height: 100 + }; + + layout.searchBestPosition(options, layoutConfig, null); - expect(options.width).toBe(900000); - expect(options.height).toBe(100); - expect(options.left).toBe(100000); - expect(options.top).toBe(10); + expect(layoutConfig.width).toBe(900000); + expect(layoutConfig.height).toBe(100); + expect(layoutConfig.left).toBe(100000); + expect(layoutConfig.top).toBe(10); }); it("should reduce widget width (left side) if there is not enough space", () => { const options = { - width: 950000, - height: 100, refposition: {left: 70, right: 90, top: 0, bottom: 10} }; - layout.searchBestPosition(options); + const layoutConfig = { + width: 950000, + height: 100 + }; - expect(options.width).toBe(950000); - expect(options.height).toBe(100); - expect(options.left).toBe(0); - expect(options.top).toBe(10); + layout.searchBestPosition(options, layoutConfig, null); + + expect(layoutConfig.width).toBe(950000); + expect(layoutConfig.height).toBe(100); + expect(layoutConfig.left).toBe(0); + expect(layoutConfig.top).toBe(10); }); it("should allow to use elements inside widget iframes as reference", () => { const options = { - width: 8000, - height: 20, refiframe: document.createElement('iframe'), refposition: {left: 0, right: 9, top: 60, bottom: 69} }; + const layoutConfig = { + width: 8000, + height: 20 + }; + spyOn(Wirecloud.Utils, "getRelativePosition").and.returnValue({x: 20, y: 30}); - layout.searchBestPosition(options); + layout.searchBestPosition(options, layoutConfig, null); - expect(options.width).toBe(8000); - expect(options.height).toBe(20); - expect(options.left).toBe(200000); - expect(options.top).toBe(70); + expect(layoutConfig.width).toBe(8000); + expect(layoutConfig.height).toBe(20); + expect(layoutConfig.left).toBe(200000); + expect(layoutConfig.top).toBe(70); }); }); diff --git a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js index 4e22c4712c..2104aafde6 100644 --- a/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js +++ b/src/js_tests/wirecloud/ui/WorkspaceTabViewSpec.js @@ -629,9 +629,9 @@ p.then((created_widget) => { expect(created_widget).toBe(widget); expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledTimes(3); - expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), 800); - expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), 900.5); - expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), 1001); + expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Object), 800); + expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Object), 900.5); + expect(tab.dragboard.freeLayout.searchBestPosition).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Object), 1001); done(); }); }); diff --git a/src/wirecloud/platform/static/js/wirecloud/Widget.js b/src/wirecloud/platform/static/js/wirecloud/Widget.js index 990716d1dd..1612f7074d 100644 --- a/src/wirecloud/platform/static/js/wirecloud/Widget.js +++ b/src/wirecloud/platform/static/js/wirecloud/Widget.js @@ -463,8 +463,7 @@ minimized: false, fulldragboard: false, titlevisible: true - }], - titlevisible: true + }] }, data); this.pending_events = []; diff --git a/src/wirecloud/platform/static/js/wirecloud/Wiring.js b/src/wirecloud/platform/static/js/wirecloud/Wiring.js index 6ef92e492a..b011b424b5 100644 --- a/src/wirecloud/platform/static/js/wirecloud/Wiring.js +++ b/src/wirecloud/platform/static/js/wirecloud/Wiring.js @@ -605,7 +605,7 @@ // Init operatorId counter if (priv.operators.length > 0) { - priv.operatorId = priv.operators[priv.operators.length - 1].id + 1; + priv.operatorId = parseInt(priv.operators[priv.operators.length - 1].id) + 1; } else { priv.operatorId = 1; } diff --git a/src/wirecloud/platform/static/js/wirecloud/WorkspaceTab.js b/src/wirecloud/platform/static/js/wirecloud/WorkspaceTab.js index 108890fff4..4723ddebeb 100644 --- a/src/wirecloud/platform/static/js/wirecloud/WorkspaceTab.js +++ b/src/wirecloud/platform/static/js/wirecloud/WorkspaceTab.js @@ -159,6 +159,11 @@ })); } + // Add action to all layout configurations + for (let i = 0; i < options.layoutConfigurations.length; i++) { + options.layoutConfigurations[i].action = 'update'; + } + var content = utils.merge(options, { widget: resource.uri, settings: options.preferences diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js index b201c68f28..65674669d7 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/FreeLayout.js @@ -27,7 +27,7 @@ "use strict"; - const setPosition = function setPosition(position, options, offset, screenWidth) { + const setPosition = function setPosition(position, layoutConfig, offset, screenWidth, options) { delete options.left; delete options.top; delete options.right; @@ -35,20 +35,20 @@ switch (position) { case "top-right": - options.left = offset.x + options.refposition.left - this.dragboard.leftMargin; - options.top = offset.y + options.refposition.top - this.dragboard.topMargin - options.height; + layoutConfig.left = offset.x + options.refposition.left - this.dragboard.leftMargin; + layoutConfig.top = offset.y + options.refposition.top - this.dragboard.topMargin - layoutConfig.height; break; case "top-left": - options.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(options.width, screenWidth); - options.top = offset.y + options.refposition.top - this.dragboard.topMargin - options.height; + layoutConfig.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(layoutConfig.width, screenWidth); + layoutConfig.top = offset.y + options.refposition.top - this.dragboard.topMargin - layoutConfig.height; break; case "bottom-right": - options.left = offset.x + options.refposition.left - this.dragboard.leftMargin; - options.top = offset.y + options.refposition.bottom - this.dragboard.topMargin; + layoutConfig.left = offset.x + options.refposition.left - this.dragboard.leftMargin; + layoutConfig.top = offset.y + options.refposition.bottom - this.dragboard.topMargin; break; case "bottom-left": - options.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(options.width, screenWidth); - options.top = offset.y + options.refposition.bottom - this.dragboard.topMargin; + layoutConfig.left = offset.x + options.refposition.right - this.dragboard.leftMargin - this.getWidthInPixels(layoutConfig.width, screenWidth); + layoutConfig.top = offset.y + options.refposition.bottom - this.dragboard.topMargin; break; } }; @@ -410,7 +410,7 @@ this.newPosition = null; } - searchBestPosition(options, screenWidth) { + searchBestPosition(options, layoutConfig, screenWidth) { let offset = {x: 0, y: 0}; if (options.refiframe != null) { offset = Wirecloud.Utils.getRelativePosition(options.refiframe, this.dragboard.tab.wrapperElement); @@ -421,8 +421,8 @@ const placements = ["bottom-right", "bottom-left", "top-right", "top-left"]; let i = 0; do { - setPosition.call(this, placements[i], options, offset, screenWidth); - weights.push(standsOut.call(this, options, screenWidth)); + setPosition.call(this, placements[i], layoutConfig, offset, screenWidth, options); + weights.push(standsOut.call(this, layoutConfig, screenWidth)); i += 1; } while (weights[i - 1] > 0 && i < placements.length); @@ -430,17 +430,17 @@ const best_weight = Math.min.apply(Math, weights); const index = weights.indexOf(best_weight); const placement = placements[index]; - setPosition.call(this, placement, options, offset, screenWidth); + setPosition.call(this, placement, layoutConfig, offset, screenWidth, options); - options.top = this.adaptRowOffset(options.top + "px").inPixels; - options.left = this.adaptColumnOffset(options.left + "px", screenWidth).inLU; + layoutConfig.top = this.adaptRowOffset(layoutConfig.top + "px").inPixels; + layoutConfig.left = this.adaptColumnOffset(layoutConfig.left + "px", screenWidth).inLU; - if (options.left + options.width >= this.MAX_HLU) { - options.width -= options.left + options.width - this.MAX_HLU; + if (layoutConfig.left + layoutConfig.width >= this.MAX_HLU) { + layoutConfig.width -= layoutConfig.left + layoutConfig.width - this.MAX_HLU; } } else { - options.top = this.adaptRowOffset(options.top + "px").inPixels; - options.left = this.adaptColumnOffset(options.left + "px", screenWidth).inLU; + layoutConfig.top = this.adaptRowOffset(layoutConfig.top + "px").inPixels; + layoutConfig.left = this.adaptColumnOffset(layoutConfig.left + "px", screenWidth).inLU; } } diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js index bf9e5112c7..a257eb86da 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabViewDragboard.js @@ -394,7 +394,6 @@ let requiresUpdate = false; const updatedConfig = { id: screenSize.id, - action: 'update' }; if (currentConfig.moreOrEqual !== screenSize.moreOrEqual) { @@ -408,6 +407,7 @@ } if (requiresUpdate) { + updatedConfig.action = 'update'; widgetReqData.layoutConfigurations.push(updatedConfig); } } From db6bb8c37708f3f0dbac8a270997142e2844b4c5 Mon Sep 17 00:00:00 2001 From: oxixes Date: Tue, 1 Oct 2024 18:50:31 +0200 Subject: [PATCH 28/28] Forgot this file in the commit --- .../platform/static/js/wirecloud/ui/WorkspaceTabView.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js index a96c7f54a0..c60d61c070 100644 --- a/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js +++ b/src/wirecloud/platform/static/js/wirecloud/ui/WorkspaceTabView.js @@ -285,15 +285,14 @@ }, options); layoutConfigs.forEach((layoutConfig) => { - Wirecloud.Utils.merge(layoutConfig, { - action: 'update', width: resource.default_width, anchor: 'top-left', relx: true, rely: false, relwidth: true, relheight: false, + titlevisible: true, height: resource.default_height }); @@ -302,6 +301,10 @@ avgScreenSize = layoutConfig.moreOrEqual; } + if (layoutConfig.length === 0) { + avgScreenSize = window.innerWidth; + } + if (window.innerWidth >= layoutConfig.moreOrEqual && (layoutConfig.lessOrEqual === -1 || window.innerWidth <= layoutConfig.lessOrEqual)) { avgScreenSize = window.innerWidth; } @@ -341,7 +344,7 @@ if (layoutConfig.left == null || layoutConfig.top == null) { if (options.refposition && "searchBestPosition" in layout) { - layout.searchBestPosition(layoutConfig, avgScreenSize); + layout.searchBestPosition(options, layoutConfig, avgScreenSize); } else if ("_searchFreeSpace2" in layout) { const matrix = Wirecloud.Utils.getLayoutMatrix(layout, layout.dragboard.widgets, avgScreenSize); const position = layout._searchFreeSpace2(layoutConfig.width, layoutConfig.height, matrix);