module.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import {
  2. FieldOverrideContext,
  3. FieldType,
  4. getFieldDisplayName,
  5. PanelPlugin,
  6. ReducerID,
  7. standardEditorsRegistry,
  8. } from '@grafana/data';
  9. import { TableFieldOptions } from '@grafana/schema';
  10. import { TableCellDisplayMode } from '@grafana/ui';
  11. import { PaginationEditor } from './PaginationEditor';
  12. import { TablePanel } from './TablePanel';
  13. import { tableMigrationHandler, tablePanelChangedHandler } from './migrations';
  14. import { PanelOptions, defaultPanelOptions, defaultPanelFieldConfig } from './models.gen';
  15. import { TableSuggestionsSupplier } from './suggestions';
  16. const footerCategory = 'Table footer';
  17. export const plugin = new PanelPlugin<PanelOptions, TableFieldOptions>(TablePanel)
  18. .setPanelChangeHandler(tablePanelChangedHandler)
  19. .setMigrationHandler(tableMigrationHandler)
  20. .setNoPadding()
  21. .useFieldConfig({
  22. useCustomConfig: (builder) => {
  23. builder
  24. .addNumberInput({
  25. path: 'minWidth',
  26. name: 'Minimum column width',
  27. description: 'The minimum width for column auto resizing',
  28. settings: {
  29. placeholder: '150',
  30. min: 50,
  31. max: 500,
  32. },
  33. shouldApply: () => true,
  34. defaultValue: defaultPanelFieldConfig.minWidth,
  35. })
  36. .addNumberInput({
  37. path: 'width',
  38. name: 'Column width',
  39. settings: {
  40. placeholder: 'auto',
  41. min: 20,
  42. max: 300,
  43. },
  44. shouldApply: () => true,
  45. defaultValue: defaultPanelFieldConfig.width,
  46. })
  47. .addRadio({
  48. path: 'align',
  49. name: 'Column alignment',
  50. settings: {
  51. options: [
  52. { label: 'auto', value: 'auto' },
  53. { label: 'left', value: 'left' },
  54. { label: 'center', value: 'center' },
  55. { label: 'right', value: 'right' },
  56. ],
  57. },
  58. defaultValue: defaultPanelFieldConfig.align,
  59. })
  60. .addSelect({
  61. path: 'displayMode',
  62. name: 'Cell display mode',
  63. description: 'Color text, background, show as gauge, etc',
  64. settings: {
  65. options: [
  66. { value: TableCellDisplayMode.Auto, label: 'Auto' },
  67. { value: TableCellDisplayMode.ColorText, label: 'Color text' },
  68. { value: TableCellDisplayMode.ColorBackground, label: 'Color background (gradient)' },
  69. { value: TableCellDisplayMode.ColorBackgroundSolid, label: 'Color background (solid)' },
  70. { value: TableCellDisplayMode.GradientGauge, label: 'Gradient gauge' },
  71. { value: TableCellDisplayMode.LcdGauge, label: 'LCD gauge' },
  72. { value: TableCellDisplayMode.BasicGauge, label: 'Basic gauge' },
  73. { value: TableCellDisplayMode.JSONView, label: 'JSON View' },
  74. { value: TableCellDisplayMode.Image, label: 'Image' },
  75. ],
  76. },
  77. defaultValue: defaultPanelFieldConfig.displayMode,
  78. })
  79. .addBooleanSwitch({
  80. path: 'inspect',
  81. name: 'Cell value inspect',
  82. description: 'Enable cell value inspection in a modal window',
  83. defaultValue: false,
  84. showIf: (cfg) => {
  85. return (
  86. cfg.displayMode === TableCellDisplayMode.Auto ||
  87. cfg.displayMode === TableCellDisplayMode.JSONView ||
  88. cfg.displayMode === TableCellDisplayMode.ColorText ||
  89. cfg.displayMode === TableCellDisplayMode.ColorBackground ||
  90. cfg.displayMode === TableCellDisplayMode.ColorBackgroundSolid
  91. );
  92. },
  93. })
  94. .addBooleanSwitch({
  95. path: 'filterable',
  96. name: 'Column filter',
  97. description: 'Enables/disables field filters in table',
  98. defaultValue: defaultPanelFieldConfig.filterable,
  99. })
  100. .addBooleanSwitch({
  101. path: 'hidden',
  102. name: 'Hide in table',
  103. defaultValue: undefined,
  104. hideFromDefaults: true,
  105. });
  106. },
  107. })
  108. .setPanelOptions((builder) => {
  109. builder
  110. .addBooleanSwitch({
  111. path: 'showHeader',
  112. name: 'Show table header',
  113. defaultValue: defaultPanelOptions.showHeader,
  114. })
  115. .addBooleanSwitch({
  116. path: 'footer.show',
  117. category: [footerCategory],
  118. name: 'Show table footer',
  119. defaultValue: defaultPanelOptions.footer?.show,
  120. })
  121. .addCustomEditor({
  122. id: 'footer.reducer',
  123. category: [footerCategory],
  124. path: 'footer.reducer',
  125. name: 'Calculation',
  126. description: 'Choose a reducer function / calculation',
  127. editor: standardEditorsRegistry.get('stats-picker').editor as any,
  128. defaultValue: [ReducerID.sum],
  129. showIf: (cfg) => cfg.footer?.show,
  130. })
  131. .addMultiSelect({
  132. path: 'footer.fields',
  133. category: [footerCategory],
  134. name: 'Fields',
  135. description: 'Select the fields that should be calculated',
  136. settings: {
  137. allowCustomValue: false,
  138. options: [],
  139. placeholder: 'All Numeric Fields',
  140. getOptions: async (context: FieldOverrideContext) => {
  141. const options = [];
  142. if (context && context.data && context.data.length > 0) {
  143. const frame = context.data[0];
  144. for (const field of frame.fields) {
  145. if (field.type === FieldType.number) {
  146. const name = getFieldDisplayName(field, frame, context.data);
  147. const value = field.name;
  148. options.push({ value, label: name } as any);
  149. }
  150. }
  151. }
  152. return options;
  153. },
  154. },
  155. defaultValue: '',
  156. showIf: (cfg) => cfg.footer?.show,
  157. })
  158. .addCustomEditor({
  159. id: 'footer.enablePagination',
  160. path: 'footer.enablePagination',
  161. name: 'Enable pagination',
  162. editor: PaginationEditor,
  163. });
  164. })
  165. .setSuggestionsSupplier(new TableSuggestionsSupplier());