diff --git a/services/static-webserver/client/source/class/osparc/data/Resources.js b/services/static-webserver/client/source/class/osparc/data/Resources.js
index 1332df084a9..830aff303fc 100644
--- a/services/static-webserver/client/source/class/osparc/data/Resources.js
+++ b/services/static-webserver/client/source/class/osparc/data/Resources.js
@@ -1237,7 +1237,23 @@ qx.Class.define("osparc.data.Resources", {
delete: {
method: "DELETE",
url: statics.API + "/tags/{tagId}"
- }
+ },
+ getAccessRights: {
+ method: "GET",
+ url: statics.API + "/tags/{tagId}/groups"
+ },
+ putAccessRights: {
+ method: "PUT",
+ url: statics.API + "/tags/{tagId}/groups/{groupId}"
+ },
+ postAccessRights: {
+ method: "POST",
+ url: statics.API + "/tags/{tagId}/groups/{groupId}"
+ },
+ deleteAccessRights: {
+ method: "DELETE",
+ url: statics.API + "/tags/{tagId}/groups/{groupId}"
+ },
}
}
};
diff --git a/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/GeneralPage.js b/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/GeneralPage.js
index dffafeabc72..1c218487d31 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/GeneralPage.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/GeneralPage.js
@@ -147,6 +147,7 @@ qx.Class.define("osparc.desktop.preferences.pages.GeneralPage", {
allowGrowX: false,
enabled: true
});
+ const preferences = osparc.Preferences.getInstance();
preferences.bind("lowDiskSpaceThreshold", diskUsageSpinner, "value");
diskUsageSpinner.addListener("changeValue", e => osparc.Preferences.patchPreferenceField("lowDiskSpaceThreshold", diskUsageSpinner, e.getData()));
diff --git a/services/static-webserver/client/source/class/osparc/file/FilePicker.js b/services/static-webserver/client/source/class/osparc/file/FilePicker.js
index 67d67c8455a..0a04558952d 100644
--- a/services/static-webserver/client/source/class/osparc/file/FilePicker.js
+++ b/services/static-webserver/client/source/class/osparc/file/FilePicker.js
@@ -545,7 +545,8 @@ qx.Class.define("osparc.file.FilePicker", {
flex: 1
});
treeFolderLayout.add(treeLayout, 0);
- const folderViewer = new osparc.file.FolderViewer();
+ const allowMultiselection = false;
+ const folderViewer = new osparc.file.FolderViewer(allowMultiselection);
treeFolderLayout.add(folderViewer, 1);
filesTree.addListener("selectionChanged", () => {
diff --git a/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js b/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js
index 45fe07c10ce..5e7a4a02236 100644
--- a/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js
+++ b/services/static-webserver/client/source/class/osparc/file/FileTreeItem.js
@@ -45,6 +45,11 @@ qx.Class.define("osparc.file.FileTreeItem", {
construct: function() {
this.base(arguments);
+ this.set({
+ indent: 12, // defaults to 19,
+ decorator: "rounded",
+ });
+
// create a date format like "Oct. 19, 2018 11:31 AM"
this._dateFormat = new qx.util.format.DateFormat(
qx.locale.Date.getDateFormat("medium") + " " +
diff --git a/services/static-webserver/client/source/class/osparc/file/FolderContent.js b/services/static-webserver/client/source/class/osparc/file/FolderContent.js
new file mode 100644
index 00000000000..7424f89ed45
--- /dev/null
+++ b/services/static-webserver/client/source/class/osparc/file/FolderContent.js
@@ -0,0 +1,283 @@
+/* ************************************************************************
+
+ osparc - the simcore frontend
+
+ https://osparc.io
+
+ Copyright:
+ 2024 IT'IS Foundation, https://itis.swiss
+
+ License:
+ MIT: https://opensource.org/licenses/MIT
+
+ Authors:
+ * Odei Maiz (odeimaiz)
+
+************************************************************************ */
+
+qx.Class.define("osparc.file.FolderContent", {
+ extend: qx.ui.container.Stack,
+
+ construct: function() {
+ this.base(arguments);
+
+ this.getChildControl("icons-layout");
+ this.getChildControl("table");
+ },
+
+ properties: {
+ folder: {
+ check: "qx.core.Object",
+ init: null,
+ nullable: true,
+ event: "changeFolder",
+ apply: "__applyFolder"
+ },
+
+ mode: {
+ check: ["list", "icons"],
+ init: "icons",
+ nullable: false,
+ event: "changeMode",
+ apply: "__reloadFolderContent"
+ },
+
+ multiSelect: {
+ check: "Boolean",
+ init: false,
+ nullable: false,
+ event: "changeMultiSelect",
+ apply: "__reloadFolderContent"
+ },
+ },
+
+ events: {
+ "selectionChanged": "qx.event.type.Data", // tap
+ "multiSelectionChanged": "qx.event.type.Data", // tap
+ "itemSelected": "qx.event.type.Data", // dbltap
+ "requestDatasetFiles": "qx.event.type.Data",
+ },
+
+ statics: {
+ getItemButton: function() {
+ const item = new qx.ui.form.ToggleButton().set({
+ iconPosition: "top",
+ width: 100,
+ height: 80,
+ padding: 2
+ });
+ item.getChildControl("label").set({
+ font: "text-12",
+ rich: true,
+ textAlign: "center",
+ maxWidth: 100,
+ maxHeight: 33 // two lines
+ });
+ osparc.utils.Utils.setIdToWidget(item, "FolderViewerItem");
+ return item;
+ },
+
+ T_POS: {
+ TYPE: 0,
+ NAME: 1,
+ DATE: 2,
+ SIZE: 3,
+ ID: 4
+ }
+ },
+
+ members: {
+ _createChildControlImpl: function(id) {
+ let control;
+ switch (id) {
+ case "table": {
+ const tableModel = new qx.ui.table.model.Simple();
+ tableModel.setColumns([
+ "",
+ this.tr("Name"),
+ this.tr("Date Modified"),
+ this.tr("Size"),
+ this.tr("Id")
+ ]);
+ control = new osparc.ui.table.Table(tableModel, {
+ // tableColumnModel: obj => new qx.ui.table.columnmodel.Resize(obj),
+ initiallyHiddenColumns: [this.self().T_POS.ID]
+ });
+ control.getTableColumnModel().setDataCellRenderer(this.self().T_POS.TYPE, new qx.ui.table.cellrenderer.Image());
+ control.setColumnWidth(this.self().T_POS.TYPE, 30);
+ control.setColumnWidth(this.self().T_POS.NAME, 360);
+ control.setColumnWidth(this.self().T_POS.DATE, 170);
+ control.setColumnWidth(this.self().T_POS.SIZE, 70);
+ this.bind("mode", control, "visibility", {
+ converter: mode => mode === "list" ? "visible" : "excluded"
+ });
+ const scroll = new qx.ui.container.Scroll();
+ scroll.add(control);
+ this.add(scroll);
+ break;
+ }
+ case "icons-layout": {
+ control = new qx.ui.container.Composite(new qx.ui.layout.Flow(5, 5));
+ osparc.utils.Utils.setIdToWidget(control, "FolderViewerIconsContent");
+ this.bind("mode", control, "visibility", {
+ converter: mode => mode === "icons" ? "visible" : "excluded"
+ });
+ const scroll = new qx.ui.container.Scroll();
+ scroll.add(control);
+ this.add(scroll);
+ break;
+ }
+ }
+ return control || this.base(arguments, id);
+ },
+
+ __convertEntries: function(content) {
+ const datas = [];
+ content.forEach(entry => {
+ const data = {
+ icon: entry.getIcon ? entry.getIcon() : this.__getIcon(entry),
+ label: entry.getLabel(),
+ lastModified: entry.getLastModified ? osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())) : "",
+ size: entry.getSize ? osparc.utils.Utils.bytesToSize(entry.getSize()) : "",
+ itemId: entry.getItemId ? entry.getItemId() : null,
+ entry: entry,
+ };
+ datas.push(data);
+ });
+ const items = [];
+ if (this.getMode() === "list") {
+ datas.forEach(data => {
+ const row = [];
+ row.push(data["icon"]);
+ row.push(data["label"]);
+ row.push(data["lastModified"]);
+ row.push(data["size"]);
+ if (data["itemId"]) {
+ row.push(data["itemId"]);
+ }
+ row.entry = data["entry"];
+ items.push(row);
+ });
+ } else if (this.getMode() === "icons") {
+ datas.forEach(data => {
+ let toolTip = data["label"];
+ if (data["size"]) {
+ toolTip += "
" + data["size"];
+ }
+ if (data["lastModified"]) {
+ toolTip += "
" + data["lastModified"];
+ }
+ const item = this.self().getItemButton().set({
+ label: data["label"],
+ icon: data["icon"],
+ toolTipText: toolTip
+ });
+ const icon = item.getChildControl("icon", true);
+ if (icon.getSource() === "@FontAwesome5Solid/circle-notch/12") {
+ icon.setPadding(0);
+ icon.setMarginRight(4);
+ icon.getContentElement().addClass("rotate");
+ }
+ if (data["itemId"]) {
+ item.itemId = data["itemId"];
+ }
+ this.__attachListenersToItems(item, data["entry"]);
+ items.push(item);
+ });
+ }
+ return items;
+ },
+
+ __getIcon: function(entry) {
+ return osparc.file.FilesTree.isDir(entry) ? "@MaterialIcons/folder" : "@MaterialIcons/insert_drive_file";
+ },
+
+ __getEntries: function() {
+ if (this.getFolder()) {
+ const children = this.getFolder().getChildren().toArray();
+ return this.__convertEntries(children);
+ }
+ return [];
+ },
+
+ __applyFolder: function(folder) {
+ if (folder) {
+ if (folder.getLoaded && !folder.getLoaded()) {
+ this.fireDataEvent("requestDatasetFiles", {
+ locationId: folder.getLocation(),
+ datasetId: folder.getPath()
+ });
+ }
+
+ folder.getChildren().addListener("change", () => {
+ this.__reloadFolderContent();
+ }, this);
+ }
+
+ this.__reloadFolderContent();
+ },
+
+ __reloadFolderContent: function() {
+ const entries = this.__getEntries();
+ if (this.getMode() === "list") {
+ const table = this.getChildControl("table");
+ table.setData(entries);
+ this.__attachListenersTotable(table);
+ } else if (this.getMode() === "icons") {
+ const iconsLayout = this.getChildControl("icons-layout");
+ iconsLayout.removeAll();
+ const iconsGroup = new qx.ui.form.RadioGroup().set({
+ allowEmptySelection: true
+ });
+ entries.forEach(entry => {
+ if (!this.isMultiSelect()) {
+ iconsGroup.add(entry);
+ }
+ iconsLayout.add(entry);
+ });
+ }
+ this.setSelection([this.getSelectables()[this.getMode() === "icons" ? 0 : 1]]);
+ },
+
+ __itemTapped: function(item) {
+ if (this.isMultiSelect()) {
+ this.fireDataEvent("multiSelectionChanged", item);
+ } else {
+ this.fireDataEvent("selectionChanged", item);
+ }
+ },
+
+ __itemDblTapped: function(item) {
+ this.fireDataEvent("itemSelected", item);
+ if (osparc.file.FilesTree.isDir(item)) {
+ this.setFolder(item);
+ }
+ },
+
+ __attachListenersToItems: function(btn, entry) {
+ btn.addListener("tap", () => {
+ this.__itemTapped(entry);
+ }, this);
+ btn.addListener("dbltap", () => {
+ this.__itemDblTapped(entry);
+ }, this);
+ },
+
+ __attachListenersTotable: function(table) {
+ table.addListener("cellTap", e => {
+ const selectedRow = e.getRow();
+ const rowData = table.getTableModel().getRowData(selectedRow);
+ if ("entry" in rowData) {
+ this.__itemTapped(rowData.entry);
+ }
+ }, this);
+ table.addListener("cellDbltap", e => {
+ const selectedRow = e.getRow();
+ const rowData = table.getTableModel().getRowData(selectedRow);
+ if ("entry" in rowData) {
+ this.__itemDblTapped(rowData.entry);
+ }
+ }, this);
+ }
+ }
+});
diff --git a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js
index 26fb4433bf3..218c3a90a49 100644
--- a/services/static-webserver/client/source/class/osparc/file/FolderViewer.js
+++ b/services/static-webserver/client/source/class/osparc/file/FolderViewer.js
@@ -22,7 +22,7 @@
qx.Class.define("osparc.file.FolderViewer", {
extend: qx.ui.core.Widget,
- construct: function() {
+ construct: function(allowMultiselection = true) {
this.base(arguments);
this._setLayout(new qx.ui.layout.VBox(10));
@@ -32,10 +32,13 @@ qx.Class.define("osparc.file.FolderViewer", {
const folderUpBtn = this.getChildControl("folder-up");
folderUpBtn.addListener("execute", () => this.fireDataEvent("folderUp", this.getFolder()), this);
this.getChildControl("folder-path");
- this.getChildControl("view-options-icons");
- this.getChildControl("view-options-list");
- this.getChildControl("icons-layout");
- this.getChildControl("table");
+ let multiSelectButton = null;
+ if (allowMultiselection) {
+ multiSelectButton = this.getChildControl("multi-select-button");
+ }
+ const iconsButton = this.getChildControl("view-options-icons");
+ const listButton = this.getChildControl("view-options-list");
+ const folderContent = this.getChildControl("folder-content");
this.bind("folder", this.getChildControl("folder-up"), "enabled", {
converter: folder => Boolean(folder && folder.getPathLabel && folder.getPathLabel().length > 1)
@@ -44,6 +47,18 @@ qx.Class.define("osparc.file.FolderViewer", {
this.bind("folder", this.getChildControl("folder-path"), "value", {
converter: folder => folder ? folder.getPathLabel().join(" / ") : this.tr("Select folder")
});
+
+ this.bind("folder", folderContent, "folder");
+
+ if (allowMultiselection) {
+ multiSelectButton.addListener("changeValue", e => folderContent.setMultiSelect(e.getData()));
+ }
+ iconsButton.addListener("execute", () => folderContent.setMode("icons"));
+ listButton.addListener("execute", () => folderContent.setMode("list"));
+
+ folderContent.addListener("selectionChanged", e => this.fireDataEvent("selectionChanged", e.getData()));
+ folderContent.addListener("itemSelected", e => this.fireDataEvent("itemSelected", e.getData()));
+ folderContent.addListener("requestDatasetFiles", e => this.fireDataEvent("requestDatasetFiles", e.getData()));
},
properties: {
@@ -52,16 +67,7 @@ qx.Class.define("osparc.file.FolderViewer", {
init: null,
nullable: true,
event: "changeFolder",
- apply: "__applyFolder"
},
-
- mode: {
- check: ["list", "icons"],
- init: "icons",
- nullable: false,
- event: "changeMode",
- apply: "__reloadFolderContent"
- }
},
events: {
@@ -71,33 +77,6 @@ qx.Class.define("osparc.file.FolderViewer", {
"requestDatasetFiles": "qx.event.type.Data"
},
- statics: {
- getItemButton: function() {
- const item = new qx.ui.form.ToggleButton().set({
- iconPosition: "top",
- width: 100,
- height: 80,
- padding: 3
- });
- item.getChildControl("label").set({
- rich: true,
- textAlign: "center",
- maxWidth: 100,
- maxHeight: 31
- });
- osparc.utils.Utils.setIdToWidget(item, "FolderViewerItem");
- return item;
- },
-
- T_POS: {
- TYPE: 0,
- NAME: 1,
- DATE: 2,
- SIZE: 3,
- ID: 4
- }
- },
-
members: {
_createChildControlImpl: function(id) {
let control;
@@ -128,6 +107,14 @@ qx.Class.define("osparc.file.FolderViewer", {
});
break;
}
+ case "multi-select-button":
+ control = new qx.ui.form.ToggleButton(this.tr("Multiselect")).set({
+ value: false,
+ marginRight: 10,
+ });
+ const header = this.getChildControl("header");
+ header.addAt(control, 2);
+ break;
case "view-options-rgroup":
control = new qx.ui.form.RadioGroup();
break;
@@ -135,203 +122,27 @@ qx.Class.define("osparc.file.FolderViewer", {
control = new qx.ui.form.ToggleButton(null, "@MaterialIcons/apps/18");
const group = this.getChildControl("view-options-rgroup");
group.add(control);
- control.addListener("execute", () => {
- this.setMode("icons");
- });
const header = this.getChildControl("header");
- header.addAt(control, 2);
+ header.addAt(control, 3);
break;
}
case "view-options-list": {
control = new qx.ui.form.ToggleButton(null, "@MaterialIcons/reorder/18");
const group = this.getChildControl("view-options-rgroup");
group.add(control);
- control.addListener("execute", () => {
- this.setMode("list");
- });
const header = this.getChildControl("header");
- header.addAt(control, 3);
+ header.addAt(control, 4);
break;
}
- case "content-stack": {
- control = new qx.ui.container.Stack();
+ case "folder-content": {
+ control = new osparc.file.FolderContent();
this._add(control, {
flex: 1
});
break;
}
- case "table": {
- const tableModel = new qx.ui.table.model.Simple();
- tableModel.setColumns([
- "",
- this.tr("Name"),
- this.tr("Date Modified"),
- this.tr("Size"),
- this.tr("Id")
- ]);
- control = new osparc.ui.table.Table(tableModel, {
- // tableColumnModel: obj => new qx.ui.table.columnmodel.Resize(obj),
- initiallyHiddenColumns: [this.self().T_POS.ID]
- });
- control.getTableColumnModel().setDataCellRenderer(this.self().T_POS.TYPE, new qx.ui.table.cellrenderer.Image());
- control.setColumnWidth(this.self().T_POS.TYPE, 30);
- control.setColumnWidth(this.self().T_POS.NAME, 360);
- control.setColumnWidth(this.self().T_POS.DATE, 170);
- control.setColumnWidth(this.self().T_POS.SIZE, 70);
- this.bind("mode", control, "visibility", {
- converter: mode => mode === "list" ? "visible" : "excluded"
- });
- const scroll = new qx.ui.container.Scroll();
- scroll.add(control);
- this.getChildControl("content-stack").add(scroll);
- break;
- }
- case "icons-layout": {
- control = new qx.ui.container.Composite(new qx.ui.layout.Flow(5, 5));
- osparc.utils.Utils.setIdToWidget(control, "FolderViewerIconsContent");
- this.bind("mode", control, "visibility", {
- converter: mode => mode === "icons" ? "visible" : "excluded"
- });
- const scroll = new qx.ui.container.Scroll();
- scroll.add(control);
- this.getChildControl("content-stack").add(scroll);
- break;
- }
}
return control || this.base(arguments, id);
},
-
- __convertEntries: function(content) {
- const items = [];
- if (this.getMode() === "list") {
- content.forEach(entry => {
- const row = [];
- row.push(entry.getIcon ? entry.getIcon() : this.__getIcon(entry));
- row.push(entry.getLabel());
- row.push(entry.getLastModified ? osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified())) : "");
- row.push(entry.getSize ? osparc.utils.Utils.bytesToSize(entry.getSize()) : "");
- if (entry.getItemId) {
- row.push(entry.getItemId());
- }
- row.entry = entry;
- items.push(row);
- });
- } else if (this.getMode() === "icons") {
- content.forEach(entry => {
- let tt = entry.getLabel();
- if (entry.getSize) {
- tt += "
" + osparc.utils.Utils.bytesToSize(entry.getSize());
- }
- if (entry.getLastModified) {
- tt += "
" + osparc.utils.Utils.formatDateAndTime(new Date(entry.getLastModified()));
- }
- const item = this.self().getItemButton().set({
- label: entry.getLabel(),
- icon: entry.getIcon ? entry.getIcon() : this.__getIcon(entry),
- toolTipText: tt
- });
- const icon = item.getChildControl("icon", true);
- if (icon.getSource() === "@FontAwesome5Solid/circle-notch/12") {
- icon.setPadding(0);
- icon.setMarginRight(4);
- icon.getContentElement().addClass("rotate");
- }
-
- if (entry.getItemId) {
- item.itemId = entry.getItemId();
- this.__attachListenersToItems(item, entry);
- }
- items.push(item);
- });
- }
- return items;
- },
-
- __getIcon: function(entry) {
- return osparc.file.FilesTree.isDir(entry) ? "@MaterialIcons/folder" : "@MaterialIcons/insert_drive_file";
- },
-
- __getEntries: function() {
- if (this.getFolder()) {
- const children = this.getFolder().getChildren().toArray();
- return this.__convertEntries(children);
- }
- return [];
- },
-
- __applyFolder: function(folder) {
- if (folder) {
- if (folder.getLoaded && !folder.getLoaded()) {
- this.fireDataEvent("requestDatasetFiles", {
- locationId: folder.getLocation(),
- datasetId: folder.getPath()
- });
- }
-
- folder.getChildren().addListener("change", () => {
- this.__reloadFolderContent();
- }, this);
- }
-
- this.__reloadFolderContent();
- },
-
- __reloadFolderContent: function() {
- const entries = this.__getEntries();
- if (this.getMode() === "list") {
- const table = this.getChildControl("table");
- table.setData(entries);
- this.__attachListenersTotable(table);
- } else if (this.getMode() === "icons") {
- const iconsLayout = this.getChildControl("icons-layout");
- iconsLayout.removeAll();
- const iconsGroup = new qx.ui.form.RadioGroup().set({
- allowEmptySelection: true
- });
- entries.forEach(entry => {
- iconsGroup.add(entry);
- iconsLayout.add(entry);
- });
- }
- const stack = this.getChildControl("content-stack");
- stack.setSelection([stack.getSelectables()[this.getMode() === "icons" ? 0 : 1]]);
- },
-
- __itemTapped: function(item) {
- this.fireDataEvent("selectionChanged", item);
- },
-
- __itemDblTapped: function(item) {
- this.fireDataEvent("itemSelected", item);
- if (osparc.file.FilesTree.isDir(item)) {
- this.setFolder(item);
- }
- },
-
- __attachListenersToItems: function(btn, entry) {
- btn.addListener("tap", () => {
- this.__itemTapped(entry);
- }, this);
- btn.addListener("dbltap", () => {
- this.__itemDblTapped(entry);
- }, this);
- },
-
- __attachListenersTotable: function(table) {
- table.addListener("cellTap", e => {
- const selectedRow = e.getRow();
- const rowData = table.getTableModel().getRowData(selectedRow);
- if ("entry" in rowData) {
- this.__itemTapped(rowData.entry);
- }
- }, this);
- table.addListener("cellDbltap", e => {
- const selectedRow = e.getRow();
- const rowData = table.getTableModel().getRowData(selectedRow);
- if ("entry" in rowData) {
- this.__itemDblTapped(rowData.entry);
- }
- }, this);
- }
}
});
diff --git a/services/static-webserver/client/source/class/osparc/store/Tags.js b/services/static-webserver/client/source/class/osparc/store/Tags.js
index c07e9d8d8ae..748300f0cb9 100644
--- a/services/static-webserver/client/source/class/osparc/store/Tags.js
+++ b/services/static-webserver/client/source/class/osparc/store/Tags.js
@@ -45,6 +45,7 @@ qx.Class.define("osparc.store.Tags", {
tagsData.forEach(tagData => {
const tag = this.__addToCache(tagData);
tags.push(tag);
+ this.fetchAccessRights(tag);
});
return tags;
});
@@ -54,6 +55,10 @@ qx.Class.define("osparc.store.Tags", {
return this.tagsCached;
},
+ getTag: function(tagId = null) {
+ return this.tagsCached.find(f => f.getTagId() === tagId);
+ },
+
postTag: function(newTagData) {
const params = {
data: newTagData
@@ -97,8 +102,15 @@ qx.Class.define("osparc.store.Tags", {
.catch(console.error);
},
- getTag: function(tagId = null) {
- return this.tagsCached.find(f => f.getTagId() === tagId);
+ fetchAccessRights: function(tag) {
+ const params = {
+ url: {
+ "tagId": tag.getTagId()
+ }
+ };
+ osparc.data.Resources.fetch("tags", "getAccessRights", params)
+ .then(accessRights => tag.setAccessRights(accessRights))
+ .catch(err => console.error(err));
},
__addToCache: function(tagData) {