navModel.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import { DataSourceSettings, PluginType, PluginInclude, NavModel, NavModelItem } from '@grafana/data';
  2. import { featureEnabled } from '@grafana/runtime';
  3. import { ProBadge } from 'app/core/components/Upgrade/ProBadge';
  4. import config from 'app/core/config';
  5. import { contextSrv } from 'app/core/core';
  6. import { AccessControlAction } from 'app/types';
  7. import { highlightTrial } from '../../admin/utils';
  8. import { GenericDataSourcePlugin } from '../settings/PluginSettings';
  9. const loadingDSType = 'Loading';
  10. export function buildNavModel(dataSource: DataSourceSettings, plugin: GenericDataSourcePlugin): NavModelItem {
  11. const pluginMeta = plugin.meta;
  12. const highlightsEnabled = config.featureToggles.featureHighlights;
  13. const navModel: NavModelItem = {
  14. img: pluginMeta.info.logos.large,
  15. id: 'datasource-' + dataSource.uid,
  16. subTitle: `Type: ${pluginMeta.name}`,
  17. url: '',
  18. text: dataSource.name,
  19. breadcrumbs: [{ title: 'Data Sources', url: 'datasources' }],
  20. children: [
  21. {
  22. active: false,
  23. icon: 'sliders-v-alt',
  24. id: `datasource-settings-${dataSource.uid}`,
  25. text: 'Settings',
  26. url: `datasources/edit/${dataSource.uid}/`,
  27. },
  28. ],
  29. };
  30. if (plugin.configPages) {
  31. for (const page of plugin.configPages) {
  32. navModel.children!.push({
  33. active: false,
  34. text: page.title,
  35. icon: page.icon,
  36. url: `datasources/edit/${dataSource.uid}/?page=${page.id}`,
  37. id: `datasource-page-${page.id}`,
  38. });
  39. }
  40. }
  41. if (pluginMeta.includes && hasDashboards(pluginMeta.includes) && contextSrv.hasRole('Admin')) {
  42. navModel.children!.push({
  43. active: false,
  44. icon: 'apps',
  45. id: `datasource-dashboards-${dataSource.uid}`,
  46. text: 'Dashboards',
  47. url: `datasources/edit/${dataSource.uid}/dashboards`,
  48. });
  49. }
  50. const isLoadingNav = dataSource.type === loadingDSType;
  51. const permissionsExperimentId = 'feature-highlights-data-source-permissions-badge';
  52. const dsPermissions: NavModelItem = {
  53. active: false,
  54. icon: 'lock',
  55. id: `datasource-permissions-${dataSource.uid}`,
  56. text: 'Permissions',
  57. url: `datasources/edit/${dataSource.uid}/permissions`,
  58. };
  59. if (highlightTrial() && !isLoadingNav) {
  60. dsPermissions.tabSuffix = () => ProBadge({ experimentId: permissionsExperimentId, eventVariant: 'trial' });
  61. }
  62. if (featureEnabled('dspermissions')) {
  63. if (contextSrv.hasPermission(AccessControlAction.DataSourcesPermissionsRead)) {
  64. navModel.children!.push(dsPermissions);
  65. }
  66. } else if (highlightsEnabled && !isLoadingNav) {
  67. navModel.children!.push({
  68. ...dsPermissions,
  69. url: dsPermissions.url + '/upgrade',
  70. tabSuffix: () => ProBadge({ experimentId: permissionsExperimentId }),
  71. });
  72. }
  73. const analyticsExperimentId = 'feature-highlights-data-source-insights-badge';
  74. const analytics: NavModelItem = {
  75. active: false,
  76. icon: 'info-circle',
  77. id: `datasource-insights-${dataSource.uid}`,
  78. text: 'Insights',
  79. url: `datasources/edit/${dataSource.uid}/insights`,
  80. };
  81. if (highlightTrial() && !isLoadingNav) {
  82. analytics.tabSuffix = () => ProBadge({ experimentId: analyticsExperimentId, eventVariant: 'trial' });
  83. }
  84. if (featureEnabled('analytics')) {
  85. navModel.children!.push(analytics);
  86. } else if (highlightsEnabled && !isLoadingNav) {
  87. navModel.children!.push({
  88. ...analytics,
  89. url: analytics.url + '/upgrade',
  90. tabSuffix: () => ProBadge({ experimentId: analyticsExperimentId }),
  91. });
  92. }
  93. const cachingExperimentId = 'feature-highlights-query-caching-badge';
  94. const caching: NavModelItem = {
  95. active: false,
  96. icon: 'database',
  97. id: `datasource-cache-${dataSource.uid}`,
  98. text: 'Cache',
  99. url: `datasources/edit/${dataSource.uid}/cache`,
  100. hideFromTabs: !pluginMeta.isBackend || !config.caching.enabled,
  101. };
  102. if (highlightTrial() && !isLoadingNav) {
  103. caching.tabSuffix = () => ProBadge({ experimentId: cachingExperimentId, eventVariant: 'trial' });
  104. }
  105. if (featureEnabled('caching')) {
  106. navModel.children!.push(caching);
  107. } else if (highlightsEnabled && !isLoadingNav) {
  108. navModel.children!.push({
  109. ...caching,
  110. url: caching.url + '/upgrade',
  111. tabSuffix: () => ProBadge({ experimentId: cachingExperimentId }),
  112. });
  113. }
  114. return navModel;
  115. }
  116. export function getDataSourceNav(main: NavModelItem, pageName: string): NavModel {
  117. let node: NavModelItem = { text: '' };
  118. // find active page
  119. for (const child of main.children!) {
  120. if (child.id!.indexOf(pageName) > 0) {
  121. child.active = true;
  122. node = child;
  123. break;
  124. }
  125. }
  126. return {
  127. main: main,
  128. node: node!,
  129. };
  130. }
  131. export function getDataSourceLoadingNav(pageName: string): NavModel {
  132. const main = buildNavModel(
  133. {
  134. access: '',
  135. basicAuth: false,
  136. basicAuthUser: '',
  137. withCredentials: false,
  138. database: '',
  139. id: 1,
  140. uid: 'x',
  141. isDefault: false,
  142. jsonData: { authType: 'credentials', defaultRegion: 'eu-west-2' },
  143. name: 'Loading',
  144. orgId: 1,
  145. readOnly: false,
  146. type: loadingDSType,
  147. typeName: loadingDSType,
  148. typeLogoUrl: 'public/img/icn-datasource.svg',
  149. url: '',
  150. user: '',
  151. secureJsonFields: {},
  152. },
  153. {
  154. meta: {
  155. id: '1',
  156. type: PluginType.datasource,
  157. name: '',
  158. info: {
  159. author: {
  160. name: '',
  161. url: '',
  162. },
  163. description: '',
  164. links: [{ name: '', url: '' }],
  165. logos: {
  166. large: '',
  167. small: '',
  168. },
  169. screenshots: [],
  170. updated: '',
  171. version: '',
  172. },
  173. includes: [],
  174. module: '',
  175. baseUrl: '',
  176. },
  177. } as any
  178. );
  179. return getDataSourceNav(main, pageName);
  180. }
  181. function hasDashboards(includes: PluginInclude[]): boolean {
  182. return (
  183. includes.find((include) => {
  184. return include.type === 'dashboard';
  185. }) !== undefined
  186. );
  187. }