filter.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import $ from 'jquery';
  2. import { config, translations } from 'grav-config';
  3. import request from '../utils/request';
  4. import debounce from 'debounce';
  5. import { Instance as pagesTree } from './tree';
  6. import 'selectize';
  7. import '../utils/selectize-required-fix.js';
  8. import '../utils/storage';
  9. /* @formatter:off */
  10. /* eslint-disable */
  11. const options = [
  12. { flag: translations.PLUGIN_ADMIN.MODULAR, key: 'Modular', cat: 'mode' },
  13. { flag: translations.PLUGIN_ADMIN.VISIBLE, key: 'Visible', cat: 'mode' },
  14. { flag: translations.PLUGIN_ADMIN.ROUTABLE, key: 'Routable', cat: 'mode' },
  15. { flag: translations.PLUGIN_ADMIN.PUBLISHED, key: 'Published', cat: 'mode' },
  16. { flag: translations.PLUGIN_ADMIN.NON_MODULAR, key: 'NonModular', cat: 'mode' },
  17. { flag: translations.PLUGIN_ADMIN.NON_VISIBLE, key: 'NonVisible', cat: 'mode' },
  18. { flag: translations.PLUGIN_ADMIN.NON_ROUTABLE, key: 'NonRoutable', cat: 'mode' },
  19. { flag: translations.PLUGIN_ADMIN.NON_PUBLISHED, key: 'NonPublished', cat: 'mode' }
  20. ];
  21. /* @formatter:on */
  22. /* eslint-enable */
  23. export default class PagesFilter {
  24. constructor(filters, search) {
  25. this.filters = $(filters);
  26. this.search = $(search);
  27. this.options = options;
  28. this.tree = pagesTree;
  29. let storage = JSON.parse(localStorage.getItem('grav:admin:pages:filter') || '{}');
  30. if (!this.filters.length || !this.search.length) { return; }
  31. this.labels = this.filters.data('filter-labels');
  32. this.search.on('input', debounce(() => this.filter(), 250));
  33. this.filters.on('change', () => this.filter());
  34. // restore state
  35. if (storage.flags || storage.query) {
  36. this.setValues(storage);
  37. this.filter();
  38. }
  39. this._initSelectize();
  40. }
  41. filter(value) {
  42. let data = { flags: '', query: '' };
  43. if (typeof value === 'object') {
  44. Object.assign(data, value);
  45. }
  46. if (typeof value === 'string') {
  47. data.query = value;
  48. }
  49. if (typeof value === 'undefined') {
  50. data.flags = this.filters.val();
  51. data.query = this.search.val();
  52. }
  53. if (!Object.keys(data).filter((key) => data[key] !== '').length) {
  54. this.resetValues();
  55. return;
  56. }
  57. data.flags = data.flags.replace(/(\s{1,})?,(\s{1,})?/g, ',');
  58. this.setValues({ flags: data.flags, query: data.query }, 'silent');
  59. request(`${config.base_url_relative}/pages-filter.json/task${config.param_sep}filterPages`, {
  60. method: 'post',
  61. body: data
  62. }, (response) => {
  63. this.refreshDOM(response);
  64. });
  65. }
  66. refreshDOM(response) {
  67. let items = $('[data-nav-id]');
  68. if (!response) {
  69. items.removeClass('search-match').show();
  70. this.tree.restore();
  71. return;
  72. }
  73. items.removeClass('search-match').hide();
  74. response.results.forEach((page) => {
  75. let match = items.filter(`[data-nav-id="${page}"]`).addClass('search-match').show();
  76. match.parents('[data-nav-id]').addClass('search-match').show();
  77. this.tree.expand(page, 'no-store');
  78. });
  79. }
  80. setValues({ flags = '', query = ''}, silent) {
  81. let flagsArray = flags.replace(/(\s{1,})?,(\s{1,})?/g, ',').split(',');
  82. if (this.filters.val() !== flags) {
  83. let selectize = this.filters.data('selectize');
  84. this.filters[selectize ? 'setValue' : 'val'](flagsArray, silent);
  85. }
  86. if (this.search.val() !== query) { this.search.val(query); }
  87. localStorage.setItem('grav:admin:pages:filter', JSON.stringify({ flags, query }));
  88. }
  89. resetValues() {
  90. this.setValues('', 'silent');
  91. this.refreshDOM();
  92. }
  93. _initSelectize() {
  94. let extras = {
  95. type: this.filters.data('filter-types') || {},
  96. access: this.filters.data('filter-access-levels') || {}
  97. };
  98. Object.keys(extras).forEach((cat) => {
  99. Object.keys(extras[cat]).forEach((key) => {
  100. this.options.push({
  101. cat,
  102. key,
  103. flag: extras[cat][key]
  104. });
  105. });
  106. });
  107. this.filters.selectize({
  108. maxItems: null,
  109. valueField: 'key',
  110. labelField: 'flag',
  111. searchField: ['flag', 'key'],
  112. options: this.options,
  113. optgroups: this.labels,
  114. optgroupField: 'cat',
  115. optgroupLabelField: 'name',
  116. optgroupValueField: 'id',
  117. optgroupOrder: this.labels.map((item) => item.id),
  118. plugins: ['optgroup_columns', 'required-fix']
  119. });
  120. }
  121. }
  122. let Instance = new PagesFilter('input[name="page-filter"]', 'input[name="page-search"]');
  123. export { Instance };