1 (function (GCN) { 2 3 'use strict'; 4 5 /** 6 * Maps contracts that were fetched via the Rest API into a flat hash map. 7 * 8 * @param {object<string, object>} categories 9 * @return {object<string, object>} 10 */ 11 function mapConstructs(categories) { 12 var groupName; 13 var group; 14 var constructName; 15 var construct; 16 var map = {}; 17 18 for (groupName in categories) { 19 if (categories.hasOwnProperty(groupName)) { 20 group = categories[groupName].constructs; 21 22 for (constructName in group) { 23 if (group.hasOwnProperty(constructName)) { 24 construct = group[constructName]; 25 map[constructName] = construct; 26 } 27 } 28 } 29 } 30 31 return map; 32 } 33 34 /** 35 * Node object. 36 * 37 * @name NodeAPI 38 * @class 39 * @augments Chainback 40 */ 41 var NodeAPI = GCN.defineChainback({ 42 /** @lends NodeAPI */ 43 44 __chainbacktype__: 'NodeAPI', 45 _extends: GCN.ContentObjectAPI, 46 _type: 'folder', 47 48 _data: { 49 folderId: null 50 }, 51 52 /** 53 * @protected 54 * @type {object<string, number} Constructs for this node are cached 55 * here so that we only need to fetch 56 * this once. 57 */ 58 _constructs: null, 59 60 /** 61 * Retrieves a list of constructs and constructs categories that are 62 * assigned to this node and passes it as the only argument into the 63 * the `success()' callback. 64 * 65 * @param {function(Array.<object>)=} success Callback to receive an 66 * array of constructs. 67 * @param {function(GCNError):boolean=} error Custom error handler. 68 * @return Returns the constructs / categories 69 * @throws INVALID_ARGUMENTS 70 */ 71 constructs: function (success, error) { 72 if (!success) { 73 GCN.error('INVALID_ARGUMENTS', 'the `constructs()\' method ' + 74 'requires at least a success callback to be given'); 75 } 76 77 if (this._constructs) { 78 success(this._constructs); 79 } else { 80 var that = this; 81 82 this._continueWith(function (child) { 83 that._data.id = child._data.nodeId; 84 85 that.constructCategories(function (categories) { 86 that._constructs = mapConstructs(categories); 87 success(that._constructs); 88 }, error); 89 }, error); 90 } 91 }, 92 93 /** 94 * Removes this node object. 95 * 96 * @param {function()=} success Callback. 97 * @param {function(GCNError):boolean=} error Custom error handler. 98 * @param {function} success callback 99 */ 100 remove: function (success, error) { 101 102 }, 103 104 /** 105 * @FIXME: Is it really possible to save changes to a node? If not, 106 * then we should not surface this method. 107 */ 108 save: function () {}, 109 110 /** 111 * Retreives the top-level folders of this node's root folder. 112 * 113 * @param {function(FolderAPI)=} success 114 * @param {function(GCNError):boolean=} error Custom error handler. 115 */ 116 '!folders': function (success, error) { 117 return this.folder(null, error).folders(success, error); 118 }, 119 120 /** 121 * Helper method that will load the constructs of this node. 122 * 123 * @private 124 * @this {NodeAPI} 125 * @param {function(Array.<object>)} success callback 126 * @param {function(GCNError):boolean=} error callback 127 */ 128 constructCategories: function (success, error) { 129 this._authAjax({ 130 url : GCN.settings.BACKEND_PATH + '/rest/construct/load.json', 131 type : 'GET', 132 error : function (xhr, status, msg) { 133 GCN.handleHttpError(xhr, msg, error); 134 }, 135 success: function (response) { 136 if (GCN.getResponseCode(response) === 'OK') { 137 success(response.constructCategories); 138 } else { 139 GCN.handleResponseError(response, error); 140 } 141 } 142 }); 143 } 144 145 }); 146 147 GCN.node = GCN.exposeAPI(NodeAPI); 148 GCN.NodeAPI = NodeAPI; 149 150 }(GCN)); 151