diff options
Diffstat (limited to 'apps/files/js')
-rw-r--r-- | apps/files/js/app.js | 14 | ||||
-rw-r--r-- | apps/files/js/merged-index.json | 1 | ||||
-rw-r--r-- | apps/files/js/newfilemenu.js | 6 | ||||
-rw-r--r-- | apps/files/js/systemtagsplugin.js | 128 | ||||
-rw-r--r-- | apps/files/js/templates.js | 10 | ||||
-rw-r--r-- | apps/files/js/templates/newfilemenu.handlebars | 2 | ||||
-rw-r--r-- | apps/files/js/templates/newfilemenu_filename_form.handlebars | 2 |
7 files changed, 151 insertions, 12 deletions
diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 1252bd5796c..ba80e028bd7 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -108,12 +108,14 @@ iconClass: 'icon-delete', order: 99, }, - { - name: 'tags', - displayName: t('files', 'Tags'), - iconClass: 'icon-tag', - order: 100, - }, + ...( + OCA?.SystemTags === undefined ? [] : ([{ + name: 'tags', + displayName: t('files', 'Tags'), + iconClass: 'icon-tag', + order: 100, + }]) + ), ], sorting: { mode: $('#defaultFileSorting').val() === 'basename' diff --git a/apps/files/js/merged-index.json b/apps/files/js/merged-index.json index 01a46958d8b..2b7d6ec7d6d 100644 --- a/apps/files/js/merged-index.json +++ b/apps/files/js/merged-index.json @@ -27,5 +27,6 @@ "sidebarpreviewmanager.js", "sidebarpreviewtext.js", "tagsplugin.js", + "systemtagsplugin.js", "templates.js" ] diff --git a/apps/files/js/newfilemenu.js b/apps/files/js/newfilemenu.js index a101eccef29..ce23b4a9c58 100644 --- a/apps/files/js/newfilemenu.js +++ b/apps/files/js/newfilemenu.js @@ -51,6 +51,7 @@ templateName: t('files', 'New folder'), iconClass: 'icon-folder', fileType: 'folder', + actionLabel: t('files', 'Create new folder'), actionHandler: function(name) { self.fileList.createDirectory(name); } @@ -112,10 +113,12 @@ var newName = $target.attr('data-templatename'); var fileType = $target.attr('data-filetype'); + var actionLabel = $target.attr('data-action-label'); var $form = $(OCA.Files.Templates['newfilemenu_filename_form']({ fileName: newName, cid: this.cid, - fileType: fileType + fileType: fileType, + actionLabel, })); //this.trigger('actionPerformed', action); @@ -207,6 +210,7 @@ iconClass: actionSpec.iconClass, fileType: actionSpec.fileType, useInput: actionSpec.useInput, + actionLabel: actionSpec.actionLabel, actionHandler: actionSpec.actionHandler, checkFilename: actionSpec.checkFilename, shouldShow: actionSpec.shouldShow, diff --git a/apps/files/js/systemtagsplugin.js b/apps/files/js/systemtagsplugin.js new file mode 100644 index 00000000000..f92e6879a3f --- /dev/null +++ b/apps/files/js/systemtagsplugin.js @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com> + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global Handlebars */ + +(function (OCA) { + + _.extend(OC.Files.Client, { + PROPERTY_SYSTEM_TAGS: '{' + OC.Files.Client.NS_NEXTCLOUD + '}system-tags', + }); + + OCA.Files = OCA.Files || {}; + + /** + * Extends the file actions and file list to add system tags inline + * + * @namespace OCA.Files.SystemTagsPlugin + */ + OCA.Files.SystemTagsPlugin = { + name: 'SystemTags', + + allowedLists: [ + 'files', + 'favorites', + 'shares.self', + 'shares.others', + 'shares.link' + ], + + _buildTagSpan: function(tag, isMore = false) { + var $tag = $('<li class="system-tags__tag"></li>'); + $tag.text(tag).addClass(isMore ? 'system-tags__tag--more' : ''); + return $tag; + }, + + _buildTagsUI: function(tags) { + $systemTags = $('<ul class="system-tags"></ul>'); + if (tags.length === 1) { + $systemTags.attr('aria-label', t('files', 'This file has the tag {tag}', { tag: tags[0] })); + } else if (tags.length > 1) { + var firstTags = tags.slice(0, -1).join(', '); + var lastTag = tags[tags.length - 1]; + $systemTags.attr('aria-label', t('files', 'This file has the tags {firstTags} and {lastTag}', { firstTags, lastTag })); + } + + if (tags.length > 0) { + $systemTags.append(this._buildTagSpan(tags[0])); + } + + // More tags than the one we're showing + if (tags.length > 1) { + $moreTag = this._buildTagSpan('+' + (tags.length - 1), true) + $moreTag.attr('title', tags.slice(1).join(', ')); + $systemTags.append($moreTag); + } + + return $systemTags; + }, + + _extendFileList: function(fileList) { + var self = this; + + // extend row prototype + var oldCreateRow = fileList._createRow; + fileList._createRow = function(fileData) { + var $tr = oldCreateRow.apply(this, arguments); + var systemTags = fileData.systemTags || []; + + // Update tr data list + $tr.attr('data-systemTags', systemTags.join('|')); + + // No tags, no need to do anything + if (systemTags.length === 0) { + return $tr; + } + + // Build tags ui and inject + $systemTags = self._buildTagsUI.apply(self, [systemTags]) + $systemTags.insertAfter($tr.find('td.filename .nametext')); + return $tr; + }; + + var oldElementToFile = fileList.elementToFile; + fileList.elementToFile = function ($el) { + var fileInfo = oldElementToFile.apply(this, arguments); + var systemTags = $el.attr('data-systemTags'); + fileInfo.systemTags = systemTags?.split?.('|') || []; + return fileInfo; + }; + + var oldGetWebdavProperties = fileList._getWebdavProperties; + fileList._getWebdavProperties = function () { + var props = oldGetWebdavProperties.apply(this, arguments); + props.push(OC.Files.Client.PROPERTY_SYSTEM_TAGS); + return props; + }; + + fileList.filesClient.addFileInfoParser(function (response) { + var data = {}; + var props = response.propStat[0].properties; + var systemTags = props[OC.Files.Client.PROPERTY_SYSTEM_TAGS] || []; + if (systemTags && systemTags.length) { + data.systemTags = systemTags + .filter(xmlvalue => xmlvalue.namespaceURI === OC.Files.Client.NS_NEXTCLOUD && xmlvalue.nodeName.split(':')[1] === 'system-tag') + .map(xmlvalue => xmlvalue.textContent || xmlvalue.text); + } + return data; + }); + }, + + attach: function(fileList) { + if (this.allowedLists.indexOf(fileList.id) < 0) { + return; + } + this._extendFileList(fileList); + }, + }; +}) +(OCA); + +OC.Plugins.register('OCA.Files.FileList', OCA.Files.SystemTagsPlugin); diff --git a/apps/files/js/templates.js b/apps/files/js/templates.js index d9d333648ce..315f697728e 100644 --- a/apps/files/js/templates.js +++ b/apps/files/js/templates.js @@ -344,10 +344,12 @@ templates['newfilemenu'] = template({"1":function(container,depth0,helpers,parti + alias4(((helper = (helper = lookupProperty(helpers,"fileType") || (depth0 != null ? lookupProperty(depth0,"fileType") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileType","hash":{},"data":data,"loc":{"start":{"line":7,"column":84},"end":{"line":7,"column":96}}}) : helper))) + "\" data-action=\"" + alias4(((helper = (helper = lookupProperty(helpers,"id") || (depth0 != null ? lookupProperty(depth0,"id") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"id","hash":{},"data":data,"loc":{"start":{"line":7,"column":111},"end":{"line":7,"column":117}}}) : helper))) + + "\" data-action-label=\"" + + alias4(((helper = (helper = lookupProperty(helpers,"actionLabel") || (depth0 != null ? lookupProperty(depth0,"actionLabel") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"actionLabel","hash":{},"data":data,"loc":{"start":{"line":7,"column":138},"end":{"line":7,"column":153}}}) : helper))) + "\"><span class=\"icon " - + alias4(((helper = (helper = lookupProperty(helpers,"iconClass") || (depth0 != null ? lookupProperty(depth0,"iconClass") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"iconClass","hash":{},"data":data,"loc":{"start":{"line":7,"column":137},"end":{"line":7,"column":150}}}) : helper))) + + alias4(((helper = (helper = lookupProperty(helpers,"iconClass") || (depth0 != null ? lookupProperty(depth0,"iconClass") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"iconClass","hash":{},"data":data,"loc":{"start":{"line":7,"column":173},"end":{"line":7,"column":186}}}) : helper))) + " svg\"></span><span class=\"displayname\">" - + alias4(((helper = (helper = lookupProperty(helpers,"displayName") || (depth0 != null ? lookupProperty(depth0,"displayName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"displayName","hash":{},"data":data,"loc":{"start":{"line":7,"column":189},"end":{"line":7,"column":204}}}) : helper))) + + alias4(((helper = (helper = lookupProperty(helpers,"displayName") || (depth0 != null ? lookupProperty(depth0,"displayName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"displayName","hash":{},"data":data,"loc":{"start":{"line":7,"column":225},"end":{"line":7,"column":240}}}) : helper))) + "</span></a>\n </li>\n"; },"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) { @@ -379,7 +381,9 @@ templates['newfilemenu_filename_form'] = template({"compiler":[8,">= 4.3.0"],"ma + alias4(((helper = (helper = lookupProperty(helpers,"fileType") || (depth0 != null ? lookupProperty(depth0,"fileType") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileType","hash":{},"data":data,"loc":{"start":{"line":2,"column":26},"end":{"line":2,"column":38}}}) : helper))) + "\" type=\"text\" value=\"" + alias4(((helper = (helper = lookupProperty(helpers,"fileName") || (depth0 != null ? lookupProperty(depth0,"fileName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileName","hash":{},"data":data,"loc":{"start":{"line":2,"column":59},"end":{"line":2,"column":71}}}) : helper))) - + "\" autocomplete=\"off\" autocapitalize=\"off\">\n <input type=\"submit\" value=\" \" class=\"icon-confirm\" />\n</form>\n"; + + "\" autocomplete=\"off\" autocapitalize=\"off\">\n <input type=\"submit\" value=\" \" class=\"icon-confirm\" aria-label=\"" + + alias4(((helper = (helper = lookupProperty(helpers,"actionLabel") || (depth0 != null ? lookupProperty(depth0,"actionLabel") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"actionLabel","hash":{},"data":data,"loc":{"start":{"line":3,"column":65},"end":{"line":3,"column":80}}}) : helper))) + + "\" />\n</form>\n"; },"useData":true}); templates['operationprogressbar'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { var helper, lookupProperty = container.lookupProperty || function(parent, propertyName) { diff --git a/apps/files/js/templates/newfilemenu.handlebars b/apps/files/js/templates/newfilemenu.handlebars index 0d9ad9682ca..756595212d9 100644 --- a/apps/files/js/templates/newfilemenu.handlebars +++ b/apps/files/js/templates/newfilemenu.handlebars @@ -4,7 +4,7 @@ </li> {{#each items}} <li> - <a href="#" class="menuitem" data-templatename="{{templateName}}" data-filetype="{{fileType}}" data-action="{{id}}"><span class="icon {{iconClass}} svg"></span><span class="displayname">{{displayName}}</span></a> + <a href="#" class="menuitem" data-templatename="{{templateName}}" data-filetype="{{fileType}}" data-action="{{id}}" data-action-label="{{actionLabel}}"><span class="icon {{iconClass}} svg"></span><span class="displayname">{{displayName}}</span></a> </li> {{/each}} </ul> diff --git a/apps/files/js/templates/newfilemenu_filename_form.handlebars b/apps/files/js/templates/newfilemenu_filename_form.handlebars index 5fc37ecf781..2d5af97ee76 100644 --- a/apps/files/js/templates/newfilemenu_filename_form.handlebars +++ b/apps/files/js/templates/newfilemenu_filename_form.handlebars @@ -1,4 +1,4 @@ <form class="filenameform"> <input id="{{cid}}-input-{{fileType}}" type="text" value="{{fileName}}" autocomplete="off" autocapitalize="off"> - <input type="submit" value=" " class="icon-confirm" /> + <input type="submit" value=" " class="icon-confirm" aria-label="{{actionLabel}}" /> </form> |