Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VTreeview.js 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
  6. var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // Styles
  7. // Components
  8. // Mixins
  9. // Utils
  10. require('../../../src/stylus/components/_treeview.styl');
  11. var _VTreeviewNode = require('./VTreeviewNode');
  12. var _VTreeviewNode2 = _interopRequireDefault(_VTreeviewNode);
  13. var _themeable = require('../../mixins/themeable');
  14. var _themeable2 = _interopRequireDefault(_themeable);
  15. var _registrable = require('../../mixins/registrable');
  16. var _helpers = require('../../util/helpers');
  17. var _mixins = require('../../util/mixins');
  18. var _mixins2 = _interopRequireDefault(_mixins);
  19. var _console = require('../../util/console');
  20. var _filterTreeItems = require('./util/filterTreeItems');
  21. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  22. function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  23. exports.default = (0, _mixins2.default)((0, _registrable.provide)('treeview'), _themeable2.default
  24. /* @vue/component */
  25. ).extend({
  26. name: 'v-treeview',
  27. provide: function provide() {
  28. return { treeview: this };
  29. },
  30. props: _extends({
  31. active: {
  32. type: Array,
  33. default: function _default() {
  34. return [];
  35. }
  36. },
  37. items: {
  38. type: Array,
  39. default: function _default() {
  40. return [];
  41. }
  42. },
  43. hoverable: Boolean,
  44. multipleActive: Boolean,
  45. open: {
  46. type: Array,
  47. default: function _default() {
  48. return [];
  49. }
  50. },
  51. openAll: Boolean,
  52. returnObject: {
  53. type: Boolean,
  54. default: false // TODO: Should be true in next major
  55. },
  56. value: {
  57. type: Array,
  58. default: function _default() {
  59. return [];
  60. }
  61. },
  62. search: String,
  63. filter: Function
  64. }, _VTreeviewNode.VTreeviewNodeProps),
  65. data: function data() {
  66. return {
  67. nodes: {},
  68. selectedCache: new Set(),
  69. activeCache: new Set(),
  70. openCache: new Set()
  71. };
  72. },
  73. computed: {
  74. excludedItems: function excludedItems() {
  75. var excluded = new Set();
  76. if (!this.search) return excluded;
  77. for (var i = 0; i < this.items.length; i++) {
  78. (0, _filterTreeItems.filterTreeItems)(this.filter || _filterTreeItems.filterTreeItem, this.items[i], this.search, this.itemKey, this.itemText, this.itemChildren, excluded);
  79. }
  80. return excluded;
  81. }
  82. },
  83. watch: {
  84. items: {
  85. handler: function handler() {
  86. var _this = this;
  87. var oldKeys = Object.keys(this.nodes).map(function (k) {
  88. return (0, _helpers.getObjectValueByPath)(_this.nodes[k].item, _this.itemKey);
  89. });
  90. var newKeys = this.getKeys(this.items);
  91. var diff = (0, _helpers.arrayDiff)(newKeys, oldKeys);
  92. // We only want to do stuff if items have changed
  93. if (!diff.length && newKeys.length < oldKeys.length) return;
  94. // If nodes are removed we need to clear them from this.nodes
  95. diff.forEach(function (k) {
  96. return delete _this.nodes[k];
  97. });
  98. var oldSelectedCache = [].concat(_toConsumableArray(this.selectedCache));
  99. this.selectedCache = new Set();
  100. this.activeCache = new Set();
  101. this.openCache = new Set();
  102. this.buildTree(this.items);
  103. // Only emit selected if selection has changed
  104. // as a result of items changing. This fixes a
  105. // potential double emit when selecting a node
  106. // with dynamic children
  107. if (!(0, _helpers.deepEqual)(oldSelectedCache, [].concat(_toConsumableArray(this.selectedCache)))) this.emitSelected();
  108. },
  109. deep: true
  110. },
  111. active: function active(value) {
  112. this.handleNodeCacheWatcher(value, this.activeCache, this.updateActive, this.emitActive);
  113. },
  114. value: function value(_value) {
  115. this.handleNodeCacheWatcher(_value, this.selectedCache, this.updateSelected, this.emitSelected);
  116. },
  117. open: function open(value) {
  118. this.handleNodeCacheWatcher(value, this.openCache, this.updateOpen, this.emitOpen);
  119. }
  120. },
  121. created: function created() {
  122. var _this2 = this;
  123. this.buildTree(this.items);
  124. this.value.forEach(function (key) {
  125. return _this2.updateSelected(key, true);
  126. });
  127. this.emitSelected();
  128. this.active.forEach(function (key) {
  129. return _this2.updateActive(key, true);
  130. });
  131. this.emitActive();
  132. },
  133. mounted: function mounted() {
  134. var _this3 = this;
  135. // Save the developer from themselves
  136. if (this.$slots.prepend || this.$slots.append) {
  137. (0, _console.consoleWarn)('The prepend and append slots require a slot-scope attribute', this);
  138. }
  139. if (this.openAll) {
  140. this.updateAll(true);
  141. } else {
  142. this.open.forEach(function (key) {
  143. return _this3.updateOpen(key, true);
  144. });
  145. this.emitOpen();
  146. }
  147. },
  148. methods: {
  149. /** @public */
  150. updateAll: function updateAll(value) {
  151. var _this4 = this;
  152. Object.keys(this.nodes).forEach(function (key) {
  153. return _this4.updateOpen((0, _helpers.getObjectValueByPath)(_this4.nodes[key].item, _this4.itemKey), value);
  154. });
  155. this.emitOpen();
  156. },
  157. getKeys: function getKeys(items) {
  158. var keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  159. for (var i = 0; i < items.length; i++) {
  160. var key = (0, _helpers.getObjectValueByPath)(items[i], this.itemKey);
  161. keys.push(key);
  162. var children = (0, _helpers.getObjectValueByPath)(items[i], this.itemChildren);
  163. if (children) {
  164. keys.push.apply(keys, _toConsumableArray(this.getKeys(children)));
  165. }
  166. }
  167. return keys;
  168. },
  169. buildTree: function buildTree(items) {
  170. var _this5 = this;
  171. var parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  172. for (var i = 0; i < items.length; i++) {
  173. var item = items[i];
  174. var key = (0, _helpers.getObjectValueByPath)(item, this.itemKey);
  175. var children = (0, _helpers.getObjectValueByPath)(item, this.itemChildren, []);
  176. var oldNode = this.nodes.hasOwnProperty(key) ? this.nodes[key] : {
  177. isSelected: false, isIndeterminate: false, isActive: false, isOpen: false, vnode: null
  178. };
  179. var node = {
  180. vnode: oldNode.vnode,
  181. parent: parent,
  182. children: children.map(function (c) {
  183. return (0, _helpers.getObjectValueByPath)(c, _this5.itemKey);
  184. }),
  185. item: item
  186. };
  187. this.buildTree(children, key);
  188. // This fixed bug with dynamic children resetting selected parent state
  189. if (!this.nodes.hasOwnProperty(key) && parent !== null && this.nodes.hasOwnProperty(parent)) {
  190. node.isSelected = this.nodes[parent].isSelected;
  191. node.isIndeterminate = this.nodes[parent].isIndeterminate;
  192. } else {
  193. node.isSelected = oldNode.isSelected;
  194. node.isIndeterminate = oldNode.isIndeterminate;
  195. }
  196. node.isActive = oldNode.isActive;
  197. node.isOpen = oldNode.isOpen;
  198. this.nodes[key] = !children.length ? node : this.calculateState(node, this.nodes);
  199. // Don't forget to rebuild cache
  200. if (this.nodes[key].isSelected) this.selectedCache.add(key);
  201. if (this.nodes[key].isActive) this.activeCache.add(key);
  202. if (this.nodes[key].isOpen) this.openCache.add(key);
  203. this.updateVnodeState(key);
  204. }
  205. },
  206. calculateState: function calculateState(node, state) {
  207. var counts = node.children.reduce(function (counts, child) {
  208. counts[0] += +Boolean(state[child].isSelected);
  209. counts[1] += +Boolean(state[child].isIndeterminate);
  210. return counts;
  211. }, [0, 0]);
  212. node.isSelected = !!node.children.length && counts[0] === node.children.length;
  213. node.isIndeterminate = !node.isSelected && (counts[0] > 0 || counts[1] > 0);
  214. return node;
  215. },
  216. emitOpen: function emitOpen() {
  217. this.emitNodeCache('update:open', this.openCache);
  218. },
  219. emitSelected: function emitSelected() {
  220. this.emitNodeCache('input', this.selectedCache);
  221. },
  222. emitActive: function emitActive() {
  223. this.emitNodeCache('update:active', this.activeCache);
  224. },
  225. emitNodeCache: function emitNodeCache(event, cache) {
  226. var _this6 = this;
  227. this.$emit(event, this.returnObject ? [].concat(_toConsumableArray(cache)).map(function (key) {
  228. return _this6.nodes[key].item;
  229. }) : [].concat(_toConsumableArray(cache)));
  230. },
  231. handleNodeCacheWatcher: function handleNodeCacheWatcher(value, cache, updateFn, emitFn) {
  232. var _this7 = this;
  233. value = this.returnObject ? value.map(function (v) {
  234. return (0, _helpers.getObjectValueByPath)(v, _this7.itemKey);
  235. }) : value;
  236. var old = [].concat(_toConsumableArray(cache));
  237. if ((0, _helpers.deepEqual)(old, value)) return;
  238. old.forEach(function (key) {
  239. return updateFn(key, false);
  240. });
  241. value.forEach(function (key) {
  242. return updateFn(key, true);
  243. });
  244. emitFn();
  245. },
  246. getDescendants: function getDescendants(key) {
  247. var _descendants;
  248. var descendants = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  249. var children = this.nodes[key].children;
  250. (_descendants = descendants).push.apply(_descendants, _toConsumableArray(children));
  251. for (var i = 0; i < children.length; i++) {
  252. descendants = this.getDescendants(children[i], descendants);
  253. }
  254. return descendants;
  255. },
  256. getParents: function getParents(key) {
  257. var parent = this.nodes[key].parent;
  258. var parents = [];
  259. while (parent !== null) {
  260. parents.push(parent);
  261. parent = this.nodes[parent].parent;
  262. }
  263. return parents;
  264. },
  265. register: function register(node) {
  266. var key = (0, _helpers.getObjectValueByPath)(node.item, this.itemKey);
  267. this.nodes[key].vnode = node;
  268. this.updateVnodeState(key);
  269. },
  270. unregister: function unregister(node) {
  271. var key = (0, _helpers.getObjectValueByPath)(node.item, this.itemKey);
  272. if (this.nodes[key]) this.nodes[key].vnode = null;
  273. },
  274. updateActive: function updateActive(key, isActive) {
  275. var _this8 = this;
  276. if (!this.nodes.hasOwnProperty(key)) return;
  277. if (!this.multipleActive) {
  278. this.activeCache.forEach(function (active) {
  279. _this8.nodes[active].isActive = false;
  280. _this8.updateVnodeState(active);
  281. _this8.activeCache.delete(active);
  282. });
  283. }
  284. var node = this.nodes[key];
  285. if (!node) return;
  286. if (isActive) this.activeCache.add(key);else this.activeCache.delete(key);
  287. node.isActive = isActive;
  288. this.updateVnodeState(key);
  289. },
  290. updateSelected: function updateSelected(key, isSelected) {
  291. var _this9 = this;
  292. if (!this.nodes.hasOwnProperty(key)) return;
  293. var changed = new Map();
  294. var descendants = [key].concat(_toConsumableArray(this.getDescendants(key)));
  295. descendants.forEach(function (descendant) {
  296. _this9.nodes[descendant].isSelected = isSelected;
  297. _this9.nodes[descendant].isIndeterminate = false;
  298. changed.set(descendant, isSelected);
  299. });
  300. var parents = this.getParents(key);
  301. parents.forEach(function (parent) {
  302. _this9.nodes[parent] = _this9.calculateState(_this9.nodes[parent], _this9.nodes);
  303. changed.set(parent, _this9.nodes[parent].isSelected);
  304. });
  305. var all = [key].concat(_toConsumableArray(descendants), _toConsumableArray(parents));
  306. all.forEach(this.updateVnodeState);
  307. var _iteratorNormalCompletion = true;
  308. var _didIteratorError = false;
  309. var _iteratorError = undefined;
  310. try {
  311. for (var _iterator = changed.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
  312. var _ref = _step.value;
  313. var _ref2 = _slicedToArray(_ref, 2);
  314. var _key = _ref2[0];
  315. var value = _ref2[1];
  316. value === true ? this.selectedCache.add(_key) : this.selectedCache.delete(_key);
  317. }
  318. } catch (err) {
  319. _didIteratorError = true;
  320. _iteratorError = err;
  321. } finally {
  322. try {
  323. if (!_iteratorNormalCompletion && _iterator.return) {
  324. _iterator.return();
  325. }
  326. } finally {
  327. if (_didIteratorError) {
  328. throw _iteratorError;
  329. }
  330. }
  331. }
  332. },
  333. updateOpen: function updateOpen(key, isOpen) {
  334. var _this10 = this;
  335. if (!this.nodes.hasOwnProperty(key)) return;
  336. var node = this.nodes[key];
  337. var children = (0, _helpers.getObjectValueByPath)(node.item, this.itemChildren);
  338. if (children && !children.length && node.vnode && !node.vnode.hasLoaded) {
  339. node.vnode.checkChildren().then(function () {
  340. return _this10.updateOpen(key, isOpen);
  341. });
  342. } else if (children && children.length) {
  343. node.isOpen = isOpen;
  344. node.isOpen ? this.openCache.add(key) : this.openCache.delete(key);
  345. this.updateVnodeState(key);
  346. }
  347. },
  348. updateVnodeState: function updateVnodeState(key) {
  349. var node = this.nodes[key];
  350. if (node && node.vnode) {
  351. node.vnode.isSelected = node.isSelected;
  352. node.vnode.isIndeterminate = node.isIndeterminate;
  353. node.vnode.isActive = node.isActive;
  354. node.vnode.isOpen = node.isOpen;
  355. }
  356. },
  357. isExcluded: function isExcluded(key) {
  358. return !!this.search && this.excludedItems.has(key);
  359. }
  360. },
  361. render: function render(h) {
  362. var children = this.items.length ? this.items.map(_VTreeviewNode2.default.options.methods.genChild.bind(this))
  363. /* istanbul ignore next */
  364. : this.$slots.default; // TODO: remove type annotation with TS 3.2
  365. return h('div', {
  366. staticClass: 'v-treeview',
  367. class: _extends({
  368. 'v-treeview--hoverable': this.hoverable
  369. }, this.themeClasses)
  370. }, children);
  371. }
  372. });
  373. //# sourceMappingURL=VTreeview.js.map