/** @module store/TreeNode */
import { ajax } from '../util';
import { types, flow, getRoot } from "mobx-state-tree";
import $ from 'jquery';
import { uuid } from 'react-aiot';
/**
* The store holding general data for folders. The properties are read-only.
*
* @see React AIOT TreeNode documentation for properties and defaults
* @class TreeNode
*/
const TreeNode = types.model('RMLTreeNode', {
id: types.identifier(types.union(types.string, types.number)),
hash: '',
className: types.optional(types.frozen),
icon: types.optional(types.frozen),
iconActive: types.optional(types.frozen),
childNodes: types.optional(types.array(types.late(() => TreeNode))),
title: types.frozen,
count: 0,
attr: types.optional(types.frozen),
isTreeLinkDisabled: false,
selected: false,
$busy: false,
$busyOrder: false,
$droppable: true,
$visible: true,
$rename: false,
$create: types.optional(types.frozen),
contentCustomOrder: 0,
lastOrderBy: '',
orderAutomatically: false,
//searchSelected: false,
//expandedState: true,
//displayChildren: true,
//selectedIds: [],
//onRenameClose: undefined,
//onAddClose: undefined,
//onSelect: undefined,
//onNodePressF2: undefined,
//onExpand: undefined,
//onUlRef: undefined
properties: types.optional(types.frozen),
isQueried: true
}).actions(self => ({
afterAttach() {
getRoot(self)._afterAttachTreeNode(self);
},
beforeDestroy() {
getRoot(self)._beforeDestroyTreeNode(self);
},
/**
* Update this node attributes.
*
* @param {function} callback The callback with one argument (node draft)
* @param {boolean} [setHash] If true the hash node is changed so a rerender is forced
* @memberof module:store/TreeNode~TreeNode
* @instance
*/
setter(callback, setHash = false) {
callback(self);
setHash && (self.hash = uuid());
},
/**
* Rename folder.
*
* @param {string} inputValue The new name
* @returns {object} Server response
* @throws Error
* @memberof module:store/TreeNode~TreeNode
* @instance
* @async
*/
setName: flow(function*(inputValue) {
self.setter(node => { node.$busy = true });
try {
let result;
const { id, name, cnt, children, ...rest } = result = yield ajax('folders/' + self.id, {
method: 'PUT',
data: {
name: inputValue
}
});
self.setter(node => {
node.title = name;
node.properties = $.merge(node.properties, rest);
node.$busy = false;
});
return result;
} catch(e) {
self.setter(node => { node.$busy = false }, self.id);
throw e;
}
}),
/**
* Apply an order to the folder.
*
* @param {string} id The sortable id
* @param {boolean} [automatically=false] If true the order is applied automatically if new files are added to the folder
* @memberof module:store/TreeNode~TreeNode
* @instance
* @async
*/
applyOrder: flow(function*(id, automatically = false) {
self.setter(node => { node.$busyOrder = true });
try {
const result = yield ajax('folders/content/sortables', {
method: 'POST',
data: {
id,
applyTo: self.id,
automatically
}
});
result && id !== 'reindex' && id !== 'last' && (self.contentCustomOrder = 1, self.lastOrderBy = id);
result && automatically && (self.orderAutomatically = true);
id === 'original' && result && (self.contentCustomOrder = 0,
self.orderAutomatically = false);
id === 'deactivate' && result && (self.orderAutomatically = false);
}catch(e) {
throw e;
}finally{
self.setter(node => { node.$busyOrder = false });
}
}),
/**
* Permanently delete folder.
*
* @returns {string|int} The parent id
* @throws Error
* @memberof module:store/TreeNode~TreeNode
* @instance
* @async
*/
trash: flow(function*() {
self.setter(node => { node.$busy = true });
try {
yield ajax('folders/' + self.id, {
method: 'DELETE'
});
self.setter(node => { node.$visible = false });
}catch(e) {
throw e;
}finally{
self.setter(node => { node.$busy = false });
}
})
}));
export default TreeNode;