search_srv.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import _ from 'lodash';
  2. import coreModule from 'app/core/core_module';
  3. import impressionSrv from 'app/core/services/impression_srv';
  4. import store from 'app/core/store';
  5. import { contextSrv } from 'app/core/services/context_srv';
  6. export class SearchSrv {
  7. recentIsOpen: boolean;
  8. starredIsOpen: boolean;
  9. /** @ngInject */
  10. constructor(private backendSrv, private $q) {
  11. this.recentIsOpen = store.getBool('search.sections.recent', true);
  12. this.starredIsOpen = store.getBool('search.sections.starred', true);
  13. }
  14. private getRecentDashboards(sections) {
  15. return this.queryForRecentDashboards().then(result => {
  16. if (result.length > 0) {
  17. sections['recent'] = {
  18. title: 'Recent',
  19. icon: 'fa fa-clock-o',
  20. score: -1,
  21. removable: true,
  22. expanded: this.recentIsOpen,
  23. toggle: this.toggleRecent.bind(this),
  24. items: result,
  25. };
  26. }
  27. });
  28. }
  29. private queryForRecentDashboards() {
  30. var dashIds = _.take(impressionSrv.getDashboardOpened(), 5);
  31. if (dashIds.length === 0) {
  32. return Promise.resolve([]);
  33. }
  34. return this.backendSrv.search({ dashboardIds: dashIds }).then(result => {
  35. return dashIds
  36. .map(orderId => {
  37. return _.find(result, { id: orderId });
  38. })
  39. .filter(hit => hit && !hit.isStarred);
  40. });
  41. }
  42. private toggleRecent(section) {
  43. this.recentIsOpen = section.expanded = !section.expanded;
  44. store.set('search.sections.recent', this.recentIsOpen);
  45. if (!section.expanded || section.items.length) {
  46. return Promise.resolve(section);
  47. }
  48. return this.queryForRecentDashboards().then(result => {
  49. section.items = result;
  50. return Promise.resolve(section);
  51. });
  52. }
  53. private toggleStarred(section) {
  54. this.starredIsOpen = section.expanded = !section.expanded;
  55. store.set('search.sections.starred', this.starredIsOpen);
  56. return Promise.resolve(section);
  57. }
  58. private getStarred(sections) {
  59. if (!contextSrv.isSignedIn) {
  60. return Promise.resolve();
  61. }
  62. return this.backendSrv.search({ starred: true, limit: 5 }).then(result => {
  63. if (result.length > 0) {
  64. sections['starred'] = {
  65. title: 'Starred',
  66. icon: 'fa fa-star-o',
  67. score: -2,
  68. expanded: this.starredIsOpen,
  69. toggle: this.toggleStarred.bind(this),
  70. items: result,
  71. };
  72. }
  73. });
  74. }
  75. search(options) {
  76. let sections: any = {};
  77. let promises = [];
  78. let query = _.clone(options);
  79. let hasFilters =
  80. options.query ||
  81. (options.tag && options.tag.length > 0) ||
  82. options.starred ||
  83. (options.folderIds && options.folderIds.length > 0);
  84. if (!options.skipRecent && !hasFilters) {
  85. promises.push(this.getRecentDashboards(sections));
  86. }
  87. if (!options.skipStarred && !hasFilters) {
  88. promises.push(this.getStarred(sections));
  89. }
  90. query.folderIds = query.folderIds || [];
  91. if (!hasFilters) {
  92. query.folderIds = [0];
  93. }
  94. promises.push(
  95. this.backendSrv.search(query).then(results => {
  96. return this.handleSearchResult(sections, results);
  97. })
  98. );
  99. return this.$q.all(promises).then(() => {
  100. return _.sortBy(_.values(sections), 'score');
  101. });
  102. }
  103. private handleSearchResult(sections, results) {
  104. if (results.length === 0) {
  105. return sections;
  106. }
  107. // create folder index
  108. for (let hit of results) {
  109. if (hit.type === 'dash-folder') {
  110. sections[hit.id] = {
  111. id: hit.id,
  112. uid: hit.uid,
  113. title: hit.title,
  114. expanded: false,
  115. items: [],
  116. toggle: this.toggleFolder.bind(this),
  117. url: hit.url,
  118. icon: 'fa fa-folder',
  119. score: _.keys(sections).length,
  120. };
  121. }
  122. }
  123. for (let hit of results) {
  124. if (hit.type === 'dash-folder') {
  125. continue;
  126. }
  127. let section = sections[hit.folderId || 0];
  128. if (!section) {
  129. if (hit.folderId) {
  130. section = {
  131. id: hit.folderId,
  132. uid: hit.folderUid,
  133. title: hit.folderTitle,
  134. url: hit.folderUrl,
  135. items: [],
  136. icon: 'fa fa-folder-open',
  137. toggle: this.toggleFolder.bind(this),
  138. score: _.keys(sections).length,
  139. };
  140. } else {
  141. section = {
  142. id: 0,
  143. title: 'General',
  144. items: [],
  145. icon: 'fa fa-folder-open',
  146. toggle: this.toggleFolder.bind(this),
  147. score: _.keys(sections).length,
  148. };
  149. }
  150. // add section
  151. sections[hit.folderId || 0] = section;
  152. }
  153. section.expanded = true;
  154. section.items.push(hit);
  155. }
  156. }
  157. private toggleFolder(section) {
  158. section.expanded = !section.expanded;
  159. section.icon = section.expanded ? 'fa fa-folder-open' : 'fa fa-folder';
  160. if (section.items.length) {
  161. return Promise.resolve(section);
  162. }
  163. let query = {
  164. folderIds: [section.id],
  165. };
  166. return this.backendSrv.search(query).then(results => {
  167. section.items = results;
  168. return Promise.resolve(section);
  169. });
  170. }
  171. getDashboardTags() {
  172. return this.backendSrv.get('/api/dashboards/tags');
  173. }
  174. }
  175. coreModule.service('searchSrv', SearchSrv);