tree.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import $ from 'jquery';
  2. import '../utils/storage';
  3. const sessionKey = 'grav:admin:pages';
  4. if (!sessionStorage.getItem(sessionKey)) {
  5. sessionStorage.setItem(sessionKey, '{}');
  6. }
  7. export default class PagesTree {
  8. constructor(elements) {
  9. this.elements = $(elements);
  10. this.session = JSON.parse(sessionStorage.getItem(sessionKey) || '{}');
  11. if (!this.elements.length) { return; }
  12. this.restore();
  13. this.elements.find('.page-icon').on('click', (event) => this.toggle(event.target));
  14. $('[data-page-toggleall]').on('click', (event) => {
  15. let element = $(event.target).closest('[data-page-toggleall]');
  16. let action = element.data('page-toggleall');
  17. this[action]();
  18. });
  19. }
  20. toggle(elements, dontStore = false) {
  21. if (typeof elements === 'string') {
  22. elements = $(`[data-nav-id="${elements}"]`).find('[data-toggle="children"]');
  23. }
  24. elements = $(elements || this.elements);
  25. elements.each((index, element) => {
  26. element = $(element);
  27. let state = this.getState(element.closest('[data-toggle="children"]'));
  28. this[state.isOpen ? 'collapse' : 'expand'](state.id, dontStore);
  29. });
  30. }
  31. collapse(elements, dontStore = false) {
  32. if (typeof elements === 'string') {
  33. elements = $(`[data-nav-id="${elements}"]`).find('[data-toggle="children"]');
  34. }
  35. elements = $(elements || this.elements);
  36. elements.each((index, element) => {
  37. element = $(element);
  38. let state = this.getState(element);
  39. if (state.isOpen) {
  40. state.children.hide();
  41. state.icon.removeClass('children-open').addClass('children-closed');
  42. if (!dontStore) { delete this.session[state.id]; }
  43. }
  44. });
  45. if (!dontStore) { this.save(); }
  46. }
  47. expand(elements, dontStore = false) {
  48. if (typeof elements === 'string') {
  49. let element = $(`[data-nav-id="${elements}"]`);
  50. let parents = element.parents('[data-nav-id]');
  51. // loop back through parents, we don't want to expand an hidden child
  52. if (parents.length) {
  53. parents = parents.find('[data-toggle="children"]:first');
  54. parents = parents.add(element.find('[data-toggle="children"]:first'));
  55. return this.expand(parents, dontStore);
  56. }
  57. elements = element.find('[data-toggle="children"]:first');
  58. }
  59. elements = $(elements || this.elements);
  60. elements.each((index, element) => {
  61. element = $(element);
  62. let state = this.getState(element);
  63. if (!state.isOpen) {
  64. state.children.show();
  65. state.icon.removeClass('children-closed').addClass('children-open');
  66. if (!dontStore) { this.session[state.id] = 1; }
  67. }
  68. });
  69. if (!dontStore) { this.save(); }
  70. }
  71. restore() {
  72. this.collapse(null, true);
  73. Object.keys(this.session).forEach((key) => {
  74. this.expand(key, 'no-store');
  75. });
  76. }
  77. save() {
  78. return sessionStorage.setItem(sessionKey, JSON.stringify(this.session));
  79. }
  80. getState(element) {
  81. element = $(element);
  82. return {
  83. id: element.closest('[data-nav-id]').data('nav-id'),
  84. children: element.closest('li.page-item').find('ul:first'),
  85. icon: element.find('.page-icon'),
  86. get isOpen() { return this.icon.hasClass('children-open'); }
  87. };
  88. }
  89. }
  90. let Instance = new PagesTree('[data-toggle="children"]');
  91. export { Instance };