tree.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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(query, elements = undefined) {
  9. this.query = query;
  10. this.elements = $(elements !== undefined ? elements : this.query);
  11. this.session = JSON.parse(sessionStorage.getItem(sessionKey) || '{}');
  12. if (!this.elements.length) { return; }
  13. this.restore();
  14. this.elements.find('.page-icon').on('click', (event) => this.toggle(event.target));
  15. this.elements.data('tree_init', 1);
  16. $('[data-page-toggleall]').on('click', (event) => {
  17. let element = $(event.target).closest('[data-page-toggleall]');
  18. let action = element.data('page-toggleall');
  19. this[action]();
  20. });
  21. }
  22. reload() {
  23. const elements = $(this.query).filter((index, element) => !$(element).data('tree_init'));
  24. if (!elements.length) { return; }
  25. this.constructor(this.query, elements);
  26. }
  27. toggle(elements, dontStore = false) {
  28. if (typeof elements === 'string') {
  29. elements = $(`[data-nav-id="${elements}"]`).find('[data-toggle="children"]');
  30. }
  31. elements = $(elements || this.elements);
  32. elements.each((index, element) => {
  33. element = $(element);
  34. let state = this.getState(element.closest('[data-toggle="children"]'));
  35. this[state.isOpen ? 'collapse' : 'expand'](state.id, dontStore);
  36. });
  37. }
  38. collapse(elements, dontStore = false) {
  39. if (typeof elements === 'string') {
  40. elements = $(`[data-nav-id="${elements}"]`).find('[data-toggle="children"]');
  41. }
  42. elements = $(elements || this.elements);
  43. elements.each((index, element) => {
  44. element = $(element);
  45. let state = this.getState(element);
  46. if (state.isOpen) {
  47. state.children.hide();
  48. state.icon.removeClass('children-open').addClass('children-closed');
  49. if (!dontStore) { delete this.session[state.id]; }
  50. }
  51. });
  52. const scroller = elements.closest('.mediapicker-scroll');
  53. if (scroller.length && scroller.data('scrollbar')) {
  54. scroller.data('scrollbar').update();
  55. }
  56. if (!dontStore) { this.save(); }
  57. }
  58. expand(elements, dontStore = false) {
  59. if (typeof elements === 'string') {
  60. let element = $(`[data-nav-id="${elements}"]`);
  61. let parents = element.parents('[data-nav-id]');
  62. // loop back through parents, we don't want to expand an hidden child
  63. if (parents.length) {
  64. parents = parents.find('[data-toggle="children"]:first');
  65. parents = parents.add(element.find('[data-toggle="children"]:first'));
  66. return this.expand(parents, dontStore);
  67. }
  68. elements = element.find('[data-toggle="children"]:first');
  69. }
  70. elements = $(elements || this.elements);
  71. elements.each((index, element) => {
  72. element = $(element);
  73. let state = this.getState(element);
  74. if (!state.isOpen) {
  75. state.children.show();
  76. state.icon.removeClass('children-closed').addClass('children-open');
  77. if (!dontStore) { this.session[state.id] = 1; }
  78. }
  79. });
  80. const scroller = elements.closest('.mediapicker-scroll');
  81. if (scroller.length && scroller.data('scrollbar')) {
  82. scroller.data('scrollbar').update();
  83. }
  84. if (!dontStore) { this.save(); }
  85. }
  86. restore() {
  87. this.collapse(null, true);
  88. Object.keys(this.session).forEach((key) => {
  89. this.expand(key, 'no-store');
  90. });
  91. }
  92. save() {
  93. return sessionStorage.setItem(sessionKey, JSON.stringify(this.session));
  94. }
  95. getState(element) {
  96. element = $(element);
  97. return {
  98. id: element.closest('[data-nav-id]').data('nav-id'),
  99. children: element.closest('li.page-item').find('ul:first'),
  100. icon: element.find('.page-icon'),
  101. get isOpen() { return this.icon.hasClass('children-open'); }
  102. };
  103. }
  104. }
  105. let Instance = new PagesTree('[data-toggle="children"]');
  106. export { Instance };