@perses-dev/plugin-system 0.0.0-snapshot-time-range-height-80d08fc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/LICENSE +201 -0
  2. package/dist/cjs/components/CalculationSelector/CalculationSelector.js +52 -0
  3. package/dist/cjs/components/CalculationSelector/CalculationSelector.test.js +65 -0
  4. package/dist/cjs/components/CalculationSelector/index.js +28 -0
  5. package/dist/cjs/components/DatasourceSelect.js +76 -0
  6. package/dist/cjs/components/OptionsEditorTabs/OptionsEditorTabs.js +102 -0
  7. package/dist/cjs/components/OptionsEditorTabs/OptionsEditorTabs.test.js +167 -0
  8. package/dist/cjs/components/OptionsEditorTabs/TabPanel.js +37 -0
  9. package/dist/cjs/components/OptionsEditorTabs/index.js +28 -0
  10. package/dist/cjs/components/PluginEditor/PluginEditor.js +67 -0
  11. package/dist/cjs/components/PluginEditor/PluginEditor.test.js +150 -0
  12. package/dist/cjs/components/PluginEditor/index.js +29 -0
  13. package/dist/cjs/components/PluginEditor/plugin-editor-api.js +101 -0
  14. package/dist/cjs/components/PluginKindSelect.js +41 -0
  15. package/dist/cjs/components/PluginKindSelect.test.js +86 -0
  16. package/dist/cjs/components/PluginRegistry/PluginRegistry.js +85 -0
  17. package/dist/cjs/components/PluginRegistry/PluginRegistry.test.js +144 -0
  18. package/dist/cjs/components/PluginRegistry/index.js +28 -0
  19. package/dist/cjs/components/PluginRegistry/plugin-indexes.js +78 -0
  20. package/dist/cjs/components/PluginSpecEditor.js +43 -0
  21. package/dist/cjs/components/PluginSpecEditor.test.js +70 -0
  22. package/dist/cjs/components/TimeSeriesQueryEditor.js +42 -0
  23. package/dist/cjs/components/index.js +35 -0
  24. package/dist/cjs/index.js +31 -0
  25. package/dist/cjs/model/calculations.js +77 -0
  26. package/dist/cjs/model/datasource.js +16 -0
  27. package/dist/cjs/model/index.js +35 -0
  28. package/dist/cjs/model/panels.js +16 -0
  29. package/dist/cjs/model/plugin-base.js +22 -0
  30. package/dist/cjs/model/plugin-loading.js +38 -0
  31. package/dist/cjs/model/plugins.js +16 -0
  32. package/dist/cjs/model/time-series-queries.js +16 -0
  33. package/dist/cjs/model/variables.js +16 -0
  34. package/dist/cjs/runtime/TimeRangeProvider/TimeRangeProvider.js +118 -0
  35. package/dist/cjs/runtime/TimeRangeProvider/index.js +29 -0
  36. package/dist/cjs/runtime/TimeRangeProvider/query-params.js +161 -0
  37. package/dist/cjs/runtime/datasources.js +44 -0
  38. package/dist/cjs/runtime/index.js +32 -0
  39. package/dist/cjs/runtime/plugin-registry.js +75 -0
  40. package/dist/cjs/runtime/template-variables.js +57 -0
  41. package/dist/cjs/runtime/time-series-queries.js +140 -0
  42. package/dist/cjs/test/index.js +28 -0
  43. package/dist/cjs/test/render.js +52 -0
  44. package/dist/cjs/test/setup-tests.js +20 -0
  45. package/dist/cjs/test/test-plugins/bert/index.js +77 -0
  46. package/dist/cjs/test/test-plugins/ernie/index.js +58 -0
  47. package/dist/cjs/test/test-plugins/index.js +77 -0
  48. package/dist/cjs/test-utils/index.js +28 -0
  49. package/dist/cjs/test-utils/mock-plugin-registry.js +68 -0
  50. package/dist/components/CalculationSelector/CalculationSelector.d.ts +8 -0
  51. package/dist/components/CalculationSelector/CalculationSelector.d.ts.map +1 -0
  52. package/dist/components/CalculationSelector/CalculationSelector.js +46 -0
  53. package/dist/components/CalculationSelector/CalculationSelector.js.map +1 -0
  54. package/dist/components/CalculationSelector/CalculationSelector.test.d.ts +2 -0
  55. package/dist/components/CalculationSelector/CalculationSelector.test.d.ts.map +1 -0
  56. package/dist/components/CalculationSelector/CalculationSelector.test.js +58 -0
  57. package/dist/components/CalculationSelector/CalculationSelector.test.js.map +1 -0
  58. package/dist/components/CalculationSelector/index.d.ts +2 -0
  59. package/dist/components/CalculationSelector/index.d.ts.map +1 -0
  60. package/dist/components/CalculationSelector/index.js +15 -0
  61. package/dist/components/CalculationSelector/index.js.map +1 -0
  62. package/dist/components/DatasourceSelect.d.ts +16 -0
  63. package/dist/components/DatasourceSelect.d.ts.map +1 -0
  64. package/dist/components/DatasourceSelect.js +73 -0
  65. package/dist/components/DatasourceSelect.js.map +1 -0
  66. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.d.ts +34 -0
  67. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.d.ts.map +1 -0
  68. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.js +96 -0
  69. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.js.map +1 -0
  70. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.test.d.ts +2 -0
  71. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.test.d.ts.map +1 -0
  72. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.test.js +160 -0
  73. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.test.js.map +1 -0
  74. package/dist/components/OptionsEditorTabs/TabPanel.d.ts +9 -0
  75. package/dist/components/OptionsEditorTabs/TabPanel.d.ts.map +1 -0
  76. package/dist/components/OptionsEditorTabs/TabPanel.js +31 -0
  77. package/dist/components/OptionsEditorTabs/TabPanel.js.map +1 -0
  78. package/dist/components/OptionsEditorTabs/index.d.ts +2 -0
  79. package/dist/components/OptionsEditorTabs/index.d.ts.map +1 -0
  80. package/dist/components/OptionsEditorTabs/index.js +15 -0
  81. package/dist/components/OptionsEditorTabs/index.js.map +1 -0
  82. package/dist/components/PluginEditor/PluginEditor.d.ts +12 -0
  83. package/dist/components/PluginEditor/PluginEditor.d.ts.map +1 -0
  84. package/dist/components/PluginEditor/PluginEditor.js +68 -0
  85. package/dist/components/PluginEditor/PluginEditor.js.map +1 -0
  86. package/dist/components/PluginEditor/PluginEditor.test.d.ts +2 -0
  87. package/dist/components/PluginEditor/PluginEditor.test.d.ts.map +1 -0
  88. package/dist/components/PluginEditor/PluginEditor.test.js +143 -0
  89. package/dist/components/PluginEditor/PluginEditor.test.js.map +1 -0
  90. package/dist/components/PluginEditor/index.d.ts +3 -0
  91. package/dist/components/PluginEditor/index.d.ts.map +1 -0
  92. package/dist/components/PluginEditor/index.js +16 -0
  93. package/dist/components/PluginEditor/index.js.map +1 -0
  94. package/dist/components/PluginEditor/plugin-editor-api.d.ts +30 -0
  95. package/dist/components/PluginEditor/plugin-editor-api.d.ts.map +1 -0
  96. package/dist/components/PluginEditor/plugin-editor-api.js +100 -0
  97. package/dist/components/PluginEditor/plugin-editor-api.js.map +1 -0
  98. package/dist/components/PluginKindSelect.d.ts +12 -0
  99. package/dist/components/PluginKindSelect.d.ts.map +1 -0
  100. package/dist/components/PluginKindSelect.js +38 -0
  101. package/dist/components/PluginKindSelect.js.map +1 -0
  102. package/dist/components/PluginKindSelect.test.d.ts +2 -0
  103. package/dist/components/PluginKindSelect.test.d.ts.map +1 -0
  104. package/dist/components/PluginKindSelect.test.js +79 -0
  105. package/dist/components/PluginKindSelect.test.js.map +1 -0
  106. package/dist/components/PluginRegistry/PluginRegistry.d.ts +13 -0
  107. package/dist/components/PluginRegistry/PluginRegistry.d.ts.map +1 -0
  108. package/dist/components/PluginRegistry/PluginRegistry.js +82 -0
  109. package/dist/components/PluginRegistry/PluginRegistry.js.map +1 -0
  110. package/dist/components/PluginRegistry/PluginRegistry.test.d.ts +2 -0
  111. package/dist/components/PluginRegistry/PluginRegistry.test.d.ts.map +1 -0
  112. package/dist/components/PluginRegistry/PluginRegistry.test.js +137 -0
  113. package/dist/components/PluginRegistry/PluginRegistry.test.js.map +1 -0
  114. package/dist/components/PluginRegistry/index.d.ts +2 -0
  115. package/dist/components/PluginRegistry/index.d.ts.map +1 -0
  116. package/dist/components/PluginRegistry/index.js +15 -0
  117. package/dist/components/PluginRegistry/index.js.map +1 -0
  118. package/dist/components/PluginRegistry/plugin-indexes.d.ts +14 -0
  119. package/dist/components/PluginRegistry/plugin-indexes.d.ts.map +1 -0
  120. package/dist/components/PluginRegistry/plugin-indexes.js +70 -0
  121. package/dist/components/PluginRegistry/plugin-indexes.js.map +1 -0
  122. package/dist/components/PluginSpecEditor.d.ts +9 -0
  123. package/dist/components/PluginSpecEditor.d.ts.map +1 -0
  124. package/dist/components/PluginSpecEditor.js +37 -0
  125. package/dist/components/PluginSpecEditor.js.map +1 -0
  126. package/dist/components/PluginSpecEditor.test.d.ts +2 -0
  127. package/dist/components/PluginSpecEditor.test.d.ts.map +1 -0
  128. package/dist/components/PluginSpecEditor.test.js +63 -0
  129. package/dist/components/PluginSpecEditor.test.js.map +1 -0
  130. package/dist/components/TimeSeriesQueryEditor.d.ts +14 -0
  131. package/dist/components/TimeSeriesQueryEditor.d.ts.map +1 -0
  132. package/dist/components/TimeSeriesQueryEditor.js +38 -0
  133. package/dist/components/TimeSeriesQueryEditor.js.map +1 -0
  134. package/dist/components/index.d.ts +9 -0
  135. package/dist/components/index.d.ts.map +1 -0
  136. package/dist/components/index.js +22 -0
  137. package/dist/components/index.js.map +1 -0
  138. package/dist/index.d.ts +5 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +18 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/model/calculations.d.ts +21 -0
  143. package/dist/model/calculations.d.ts.map +1 -0
  144. package/dist/model/calculations.js +64 -0
  145. package/dist/model/calculations.js.map +1 -0
  146. package/dist/model/datasource.d.ts +12 -0
  147. package/dist/model/datasource.d.ts.map +1 -0
  148. package/dist/model/datasource.js +15 -0
  149. package/dist/model/datasource.js.map +1 -0
  150. package/dist/model/index.d.ts +9 -0
  151. package/dist/model/index.d.ts.map +1 -0
  152. package/dist/model/index.js +22 -0
  153. package/dist/model/index.js.map +1 -0
  154. package/dist/model/panels.d.ts +20 -0
  155. package/dist/model/panels.d.ts.map +1 -0
  156. package/dist/model/panels.js +15 -0
  157. package/dist/model/panels.js.map +1 -0
  158. package/dist/model/plugin-base.d.ts +22 -0
  159. package/dist/model/plugin-base.d.ts.map +1 -0
  160. package/dist/model/plugin-base.js +15 -0
  161. package/dist/model/plugin-base.js.map +1 -0
  162. package/dist/model/plugin-loading.d.ts +22 -0
  163. package/dist/model/plugin-loading.d.ts.map +1 -0
  164. package/dist/model/plugin-loading.js +35 -0
  165. package/dist/model/plugin-loading.js.map +1 -0
  166. package/dist/model/plugins.d.ts +54 -0
  167. package/dist/model/plugins.d.ts.map +1 -0
  168. package/dist/model/plugins.js +15 -0
  169. package/dist/model/plugins.js.map +1 -0
  170. package/dist/model/time-series-queries.d.ts +42 -0
  171. package/dist/model/time-series-queries.d.ts.map +1 -0
  172. package/dist/model/time-series-queries.js +15 -0
  173. package/dist/model/time-series-queries.js.map +1 -0
  174. package/dist/model/variables.d.ts +35 -0
  175. package/dist/model/variables.d.ts.map +1 -0
  176. package/dist/model/variables.js +15 -0
  177. package/dist/model/variables.js.map +1 -0
  178. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.d.ts +25 -0
  179. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.d.ts.map +1 -0
  180. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js +69 -0
  181. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js.map +1 -0
  182. package/dist/runtime/TimeRangeProvider/index.d.ts +3 -0
  183. package/dist/runtime/TimeRangeProvider/index.d.ts.map +1 -0
  184. package/dist/runtime/TimeRangeProvider/index.js +16 -0
  185. package/dist/runtime/TimeRangeProvider/index.js.map +1 -0
  186. package/dist/runtime/TimeRangeProvider/query-params.d.ts +25 -0
  187. package/dist/runtime/TimeRangeProvider/query-params.d.ts.map +1 -0
  188. package/dist/runtime/TimeRangeProvider/query-params.js +153 -0
  189. package/dist/runtime/TimeRangeProvider/query-params.js.map +1 -0
  190. package/dist/runtime/datasources.d.ts +25 -0
  191. package/dist/runtime/datasources.d.ts.map +1 -0
  192. package/dist/runtime/datasources.js +34 -0
  193. package/dist/runtime/datasources.js.map +1 -0
  194. package/dist/runtime/index.d.ts +6 -0
  195. package/dist/runtime/index.d.ts.map +1 -0
  196. package/dist/runtime/index.js +19 -0
  197. package/dist/runtime/index.js.map +1 -0
  198. package/dist/runtime/plugin-registry.d.ts +32 -0
  199. package/dist/runtime/plugin-registry.d.ts.map +1 -0
  200. package/dist/runtime/plugin-registry.js +69 -0
  201. package/dist/runtime/plugin-registry.js.map +1 -0
  202. package/dist/runtime/template-variables.d.ts +17 -0
  203. package/dist/runtime/template-variables.d.ts.map +1 -0
  204. package/dist/runtime/template-variables.js +44 -0
  205. package/dist/runtime/template-variables.js.map +1 -0
  206. package/dist/runtime/time-series-queries.d.ts +13 -0
  207. package/dist/runtime/time-series-queries.d.ts.map +1 -0
  208. package/dist/runtime/time-series-queries.js +132 -0
  209. package/dist/runtime/time-series-queries.js.map +1 -0
  210. package/dist/test/index.d.ts +2 -0
  211. package/dist/test/index.d.ts.map +1 -0
  212. package/dist/test/index.js +15 -0
  213. package/dist/test/index.js.map +1 -0
  214. package/dist/test/render.d.ts +13 -0
  215. package/dist/test/render.d.ts.map +1 -0
  216. package/dist/test/render.js +49 -0
  217. package/dist/test/render.js.map +1 -0
  218. package/dist/test/setup-tests.d.ts +2 -0
  219. package/dist/test/setup-tests.d.ts.map +1 -0
  220. package/dist/test/setup-tests.js +18 -0
  221. package/dist/test/setup-tests.js.map +1 -0
  222. package/dist/test/test-plugins/bert/index.d.ts +8 -0
  223. package/dist/test/test-plugins/bert/index.d.ts.map +1 -0
  224. package/dist/test/test-plugins/bert/index.js +66 -0
  225. package/dist/test/test-plugins/bert/index.js.map +1 -0
  226. package/dist/test/test-plugins/ernie/index.d.ts +5 -0
  227. package/dist/test/test-plugins/ernie/index.d.ts.map +1 -0
  228. package/dist/test/test-plugins/ernie/index.js +53 -0
  229. package/dist/test/test-plugins/ernie/index.js.map +1 -0
  230. package/dist/test/test-plugins/index.d.ts +6 -0
  231. package/dist/test/test-plugins/index.d.ts.map +1 -0
  232. package/dist/test/test-plugins/index.js +29 -0
  233. package/dist/test/test-plugins/index.js.map +1 -0
  234. package/dist/test-utils/index.d.ts +2 -0
  235. package/dist/test-utils/index.d.ts.map +1 -0
  236. package/dist/test-utils/index.js +15 -0
  237. package/dist/test-utils/index.js.map +1 -0
  238. package/dist/test-utils/mock-plugin-registry.d.ts +20 -0
  239. package/dist/test-utils/mock-plugin-registry.d.ts.map +1 -0
  240. package/dist/test-utils/mock-plugin-registry.js +62 -0
  241. package/dist/test-utils/mock-plugin-registry.js.map +1 -0
  242. package/package.json +45 -0
@@ -0,0 +1,167 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ const _jsxRuntime = require("react/jsx-runtime");
18
+ const _react = require("@testing-library/react");
19
+ const _userEvent = /*#__PURE__*/ _interopRequireDefault(require("@testing-library/user-event"));
20
+ const _optionsEditorTabs = require("./OptionsEditorTabs");
21
+ function _interopRequireDefault(obj) {
22
+ return obj && obj.__esModule ? obj : {
23
+ default: obj
24
+ };
25
+ }
26
+ describe('OptionsEditorTabs', ()=>{
27
+ const renderTabs = (otherTabs)=>{
28
+ (0, _react.render)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_optionsEditorTabs.OptionsEditorTabs, {
29
+ tabs: {
30
+ query: {
31
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
32
+ children: "Edit query configuration"
33
+ })
34
+ },
35
+ settings: {
36
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
37
+ children: "Edit settings configuration"
38
+ })
39
+ },
40
+ json: {
41
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
42
+ children: "JSON editor"
43
+ })
44
+ },
45
+ other: otherTabs
46
+ }
47
+ }));
48
+ };
49
+ const renderCustomTabs = ()=>{
50
+ renderTabs([
51
+ {
52
+ id: 'tableCols',
53
+ label: 'Table columns',
54
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
55
+ children: "custom table column"
56
+ })
57
+ },
58
+ {
59
+ id: 'tableOpts',
60
+ label: 'Table options',
61
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
62
+ children: "custom table options"
63
+ })
64
+ }
65
+ ]);
66
+ };
67
+ it('renders all specified tabs in a tab list', ()=>{
68
+ renderTabs();
69
+ const tabList = _react.screen.getByRole('tablist');
70
+ const tabs = (0, _react.getAllByRole)(tabList, 'tab');
71
+ expect(tabs).toHaveLength(3);
72
+ expect(tabs[0]).toHaveTextContent('Query');
73
+ expect(tabs[1]).toHaveTextContent('Settings');
74
+ expect(tabs[2]).toHaveTextContent('JSON');
75
+ });
76
+ it('defaults to selecting the first tab', ()=>{
77
+ renderTabs();
78
+ const activeTab = _react.screen.getByRole('tab', {
79
+ selected: true
80
+ });
81
+ expect(activeTab).toHaveTextContent('Query');
82
+ const activeTabPanel = _react.screen.getByRole('tabpanel');
83
+ expect(activeTabPanel).toHaveTextContent('query configuration');
84
+ });
85
+ it('switches selected tab on click', ()=>{
86
+ renderTabs();
87
+ const jsonTab = _react.screen.getByRole('tab', {
88
+ name: 'JSON'
89
+ });
90
+ _userEvent.default.click(jsonTab);
91
+ const activeTab = _react.screen.getByRole('tab', {
92
+ selected: true
93
+ });
94
+ expect(activeTab).toBe(jsonTab);
95
+ const activeTabPanel = _react.screen.getByRole('tabpanel');
96
+ expect(activeTabPanel).toHaveTextContent('JSON editor');
97
+ });
98
+ it('switches selected tab on keyboard interactions', ()=>{
99
+ renderTabs();
100
+ const vizTab = _react.screen.getByRole('tab', {
101
+ name: 'Settings'
102
+ });
103
+ _userEvent.default.tab();
104
+ _userEvent.default.keyboard('{arrowright}{space}');
105
+ const activeTab = _react.screen.getByRole('tab', {
106
+ selected: true
107
+ });
108
+ expect(activeTab).toBe(vizTab);
109
+ const activeTabPanel = _react.screen.getByRole('tabpanel');
110
+ expect(activeTabPanel).toHaveTextContent('settings configuration');
111
+ });
112
+ it('renders custom tabs between visual tabs and json editor', ()=>{
113
+ renderCustomTabs();
114
+ const tabList = _react.screen.getByRole('tablist');
115
+ const tabs = (0, _react.getAllByRole)(tabList, 'tab');
116
+ expect(tabs).toHaveLength(5);
117
+ expect(tabs[0]).toHaveTextContent('Query');
118
+ expect(tabs[1]).toHaveTextContent('Settings');
119
+ expect(tabs[2]).toHaveTextContent('Table column');
120
+ expect(tabs[3]).toHaveTextContent('Table options');
121
+ expect(tabs[4]).toHaveTextContent('JSON');
122
+ });
123
+ it('shows the correct content when selecting a custom tab', ()=>{
124
+ renderCustomTabs();
125
+ const tableColTab = _react.screen.getByRole('tab', {
126
+ name: 'Table columns'
127
+ });
128
+ _userEvent.default.click(tableColTab);
129
+ const activeTab = _react.screen.getByRole('tab', {
130
+ selected: true
131
+ });
132
+ expect(activeTab).toBe(tableColTab);
133
+ const activeTabPanel = _react.screen.getByRole('tabpanel');
134
+ expect(activeTabPanel).toHaveTextContent('custom table column');
135
+ });
136
+ it('only renders common tabs that are specified', ()=>{
137
+ (0, _react.render)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_optionsEditorTabs.OptionsEditorTabs, {
138
+ tabs: {
139
+ settings: {
140
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
141
+ children: "settings are alone"
142
+ })
143
+ },
144
+ json: {
145
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
146
+ children: "JSON is at the end"
147
+ })
148
+ },
149
+ other: [
150
+ {
151
+ id: 'custom',
152
+ label: 'Another tab',
153
+ content: /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
154
+ children: "another tab content"
155
+ })
156
+ }
157
+ ]
158
+ }
159
+ }));
160
+ const tabList = _react.screen.getByRole('tablist');
161
+ const tabs = (0, _react.getAllByRole)(tabList, 'tab');
162
+ expect(tabs).toHaveLength(3);
163
+ expect(tabs[0]).toHaveTextContent('Settings');
164
+ expect(tabs[1]).toHaveTextContent('Another tab');
165
+ expect(tabs[2]).toHaveTextContent('JSON');
166
+ });
167
+ });
@@ -0,0 +1,37 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "TabPanel", {
18
+ enumerable: true,
19
+ get: ()=>TabPanel
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _material = require("@mui/material");
23
+ function TabPanel(props) {
24
+ const { children , value , index , ...other } = props;
25
+ const isActive = value === index;
26
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
27
+ role: "tabpanel",
28
+ hidden: !isActive,
29
+ id: `options-editor-tabpanel-${index}`,
30
+ "aria-labelledby": `options-editor-tab-${index}`,
31
+ ...other,
32
+ children: isActive && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Box, {
33
+ mt: 2,
34
+ children: children
35
+ })
36
+ });
37
+ }
@@ -0,0 +1,28 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ _exportStar(require("./OptionsEditorTabs"), exports);
18
+ function _exportStar(from, to) {
19
+ Object.keys(from).forEach(function(k) {
20
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) Object.defineProperty(to, k, {
21
+ enumerable: true,
22
+ get: function() {
23
+ return from[k];
24
+ }
25
+ });
26
+ });
27
+ return from;
28
+ }
@@ -0,0 +1,67 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "PluginEditor", {
18
+ enumerable: true,
19
+ get: ()=>PluginEditor
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _material = require("@mui/material");
23
+ const _pluginKindSelect = require("../PluginKindSelect");
24
+ const _pluginSpecEditor = require("../PluginSpecEditor");
25
+ const _pluginEditorApi = require("./plugin-editor-api");
26
+ function PluginEditor(props) {
27
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
+ const { value , pluginType , pluginKindLabel , onChange: _ , ...others } = props;
29
+ const { pendingKind , isLoading , error , onKindChange , onSpecChange } = (0, _pluginEditorApi.usePluginEditor)(props);
30
+ var ref;
31
+ return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
32
+ ...others,
33
+ children: [
34
+ /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.FormControl, {
35
+ margin: "dense",
36
+ fullWidth: false,
37
+ disabled: isLoading,
38
+ error: error !== null,
39
+ sx: {
40
+ mb: 1
41
+ },
42
+ children: [
43
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.InputLabel, {
44
+ id: "plugin-kind-label",
45
+ children: pluginKindLabel
46
+ }),
47
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginKindSelect.PluginKindSelect, {
48
+ labelId: "plugin-kind-label",
49
+ label: pluginKindLabel,
50
+ pluginType: pluginType,
51
+ value: pendingKind !== '' ? pendingKind : value.kind,
52
+ onChange: onKindChange
53
+ }),
54
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.FormHelperText, {
55
+ children: (ref = error === null || error === void 0 ? void 0 : error.message) !== null && ref !== void 0 ? ref : ''
56
+ })
57
+ ]
58
+ }),
59
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginSpecEditor.PluginSpecEditor, {
60
+ pluginType: pluginType,
61
+ pluginKind: value.kind,
62
+ value: value.spec,
63
+ onChange: onSpecChange
64
+ })
65
+ ]
66
+ });
67
+ }
@@ -0,0 +1,150 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ const _jsxRuntime = require("react/jsx-runtime");
18
+ const _userEvent = /*#__PURE__*/ _interopRequireDefault(require("@testing-library/user-event"));
19
+ const _react = require("@testing-library/react");
20
+ const _react1 = require("react");
21
+ const _test = require("../../test");
22
+ const _pluginEditor = require("./PluginEditor");
23
+ function _interopRequireDefault(obj) {
24
+ return obj && obj.__esModule ? obj : {
25
+ default: obj
26
+ };
27
+ }
28
+ describe('PluginEditor', ()=>{
29
+ const renderComponent = ({ pluginType ='Panel' , defaultPluginKinds , value } = {})=>{
30
+ const testValue = value || {
31
+ kind: 'BertPanel1',
32
+ spec: {
33
+ option1: 'Option1Value'
34
+ }
35
+ };
36
+ // A test helper component that includes the state that's controlled from outside
37
+ let onChange = jest.fn();
38
+ function TestHelperForm() {
39
+ const [value, setValue] = (0, _react1.useState)(testValue);
40
+ onChange = jest.fn((v)=>setValue(v));
41
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginEditor.PluginEditor, {
42
+ pluginType: pluginType,
43
+ pluginKindLabel: "Panel Type",
44
+ value: value,
45
+ onChange: onChange
46
+ });
47
+ }
48
+ (0, _test.renderWithContext)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(TestHelperForm, {}), undefined, {
49
+ defaultPluginKinds
50
+ });
51
+ return {
52
+ onChange
53
+ };
54
+ };
55
+ // Opens the PluginKindSelect and waits for loading to finish (i.e. options to appear)
56
+ const openPluginKind = async ()=>{
57
+ const select = _react.screen.getByRole('button', {
58
+ name: 'Panel Type'
59
+ });
60
+ _userEvent.default.click(select);
61
+ const options = await _react.screen.findAllByRole('option');
62
+ return options;
63
+ };
64
+ it('shows plugin kind and spec editor', async ()=>{
65
+ renderComponent();
66
+ const pluginKind = _react.screen.getByRole('button', {
67
+ name: 'Panel Type'
68
+ });
69
+ await (0, _react.waitFor)(()=>expect(pluginKind).toHaveTextContent('Bert Panel 1'));
70
+ const specEditor = await _react.screen.findByLabelText('BertPanel1 editor');
71
+ expect(specEditor).toHaveValue('Option1Value');
72
+ });
73
+ it('initializes kind and spec together', async ()=>{
74
+ const { onChange } = renderComponent();
75
+ // Switch to a new plugin kind
76
+ await openPluginKind();
77
+ const newPluginKind = _react.screen.getByRole('option', {
78
+ name: 'Bert Panel 2'
79
+ });
80
+ _userEvent.default.click(newPluginKind);
81
+ // Wait for the editor of the other plugin
82
+ const newEditor = await _react.screen.findByLabelText('BertPanel2 editor');
83
+ expect(newEditor).toBeInTheDocument();
84
+ expect(newEditor).toHaveValue('');
85
+ // Make sure onChange was only called once (i.e. initializes both kind and spec at the same time
86
+ expect(onChange).toHaveBeenCalledTimes(1);
87
+ expect(onChange).toHaveBeenCalledWith({
88
+ kind: 'BertPanel2',
89
+ spec: {
90
+ option2: ''
91
+ }
92
+ });
93
+ });
94
+ it('remembers previous spec values', async ()=>{
95
+ renderComponent();
96
+ // Use the current editor to make a change to the spec value
97
+ let editor = await _react.screen.findByLabelText('BertPanel1 editor');
98
+ _userEvent.default.clear(editor);
99
+ _userEvent.default.type(editor, 'MyNewValue');
100
+ // Switch to a new plugin kind
101
+ await openPluginKind();
102
+ const newPluginKind = _react.screen.getByRole('option', {
103
+ name: 'Bert Panel 2'
104
+ });
105
+ _userEvent.default.click(newPluginKind);
106
+ // Wait for the other editor to appear, then switch back
107
+ const newEditor = await _react.screen.findByLabelText('BertPanel2 editor');
108
+ expect(newEditor).toHaveValue('');
109
+ await openPluginKind();
110
+ const oldPluginKind = _react.screen.getByRole('option', {
111
+ name: 'Bert Panel 1'
112
+ });
113
+ _userEvent.default.click(oldPluginKind);
114
+ // Make sure the editor from the first plugin appears and has our modified value from before the switch
115
+ editor = await _react.screen.findByLabelText('BertPanel1 editor');
116
+ expect(editor).toHaveValue('MyNewValue');
117
+ });
118
+ describe('when defaultPluginKinds specified in plugin registry', ()=>{
119
+ it('uses default kind when one is not provided', async ()=>{
120
+ renderComponent({
121
+ pluginType: 'Panel',
122
+ defaultPluginKinds: {
123
+ Panel: 'BertPanel2'
124
+ },
125
+ value: {
126
+ kind: '',
127
+ spec: {}
128
+ }
129
+ });
130
+ // Wait for default panel kind to load.
131
+ const pluginKind = _react.screen.getByRole('button', {
132
+ name: 'Panel Type'
133
+ });
134
+ await (0, _react.waitFor)(()=>expect(pluginKind).toHaveTextContent('Bert Panel 2'));
135
+ });
136
+ it('does not use default when kind is provided', async ()=>{
137
+ renderComponent({
138
+ pluginType: 'Panel',
139
+ defaultPluginKinds: {
140
+ Panel: 'BertPanel2'
141
+ }
142
+ });
143
+ // Wait for specified panel kind to load.
144
+ const pluginKind = _react.screen.getByRole('button', {
145
+ name: 'Panel Type'
146
+ });
147
+ await (0, _react.waitFor)(()=>expect(pluginKind).toHaveTextContent('Bert Panel 1'));
148
+ });
149
+ });
150
+ });
@@ -0,0 +1,29 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ _exportStar(require("./PluginEditor"), exports);
18
+ _exportStar(require("./plugin-editor-api"), exports);
19
+ function _exportStar(from, to) {
20
+ Object.keys(from).forEach(function(k) {
21
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) Object.defineProperty(to, k, {
22
+ enumerable: true,
23
+ get: function() {
24
+ return from[k];
25
+ }
26
+ });
27
+ });
28
+ return from;
29
+ }
@@ -0,0 +1,101 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "usePluginEditor", {
18
+ enumerable: true,
19
+ get: ()=>usePluginEditor
20
+ });
21
+ const _core = require("@perses-dev/core");
22
+ const _react = require("react");
23
+ const _immer = require("immer");
24
+ const _runtime = require("../../runtime");
25
+ function usePluginEditor(props) {
26
+ const { pluginType , value } = props;
27
+ // Keep a stable reference so we don't run the effect below when we don't need to
28
+ const onChange = (0, _core.useEvent)(props.onChange);
29
+ // The previous spec state for PluginType and kind and a helper function for remembering current values
30
+ const prevSpecState = (0, _react.useRef)({
31
+ [pluginType]: {
32
+ [value.kind]: value.spec
33
+ }
34
+ });
35
+ const rememberCurrentSpecState = (0, _core.useEvent)(()=>{
36
+ let byPluginType = prevSpecState.current[pluginType];
37
+ if (byPluginType === undefined) {
38
+ byPluginType = {};
39
+ prevSpecState.current[pluginType] = byPluginType;
40
+ }
41
+ byPluginType[value.kind] = value.spec;
42
+ });
43
+ const { defaultPluginKinds } = (0, _runtime.usePluginRegistry)();
44
+ const defaultPluginKind = defaultPluginKinds === null || defaultPluginKinds === void 0 ? void 0 : defaultPluginKinds[pluginType];
45
+ const initPendingKind = !value.kind && defaultPluginKind ? defaultPluginKind : '';
46
+ // When kind changes and we haven't loaded that plugin before, we will need to enter a "pending" state so that we
47
+ // can generate proper initial spec values that match the new plugin kind
48
+ const [pendingKind, setPendingKind] = (0, _react.useState)(initPendingKind);
49
+ const { data: plugin , isFetching , error } = (0, _runtime.usePlugin)(pluginType, pendingKind);
50
+ (0, _react.useEffect)(()=>{
51
+ // Nothing to do if no new plugin kind is pending
52
+ if (pendingKind === '') return;
53
+ // Can't get spec value until we have a plugin
54
+ if (plugin === undefined) return;
55
+ // Fire an onChange to change to the pending kind with initial values from the plugin
56
+ rememberCurrentSpecState();
57
+ onChange({
58
+ kind: pendingKind,
59
+ spec: plugin.createInitialOptions()
60
+ });
61
+ setPendingKind('');
62
+ }, [
63
+ pendingKind,
64
+ plugin,
65
+ rememberCurrentSpecState,
66
+ onChange
67
+ ]);
68
+ /**
69
+ * When the user tries to change the plugin kind, make sure we have the correct spec for that plugin kind before we
70
+ * make the switch.
71
+ */ const onKindChange = (e)=>{
72
+ var ref;
73
+ const nextKind = e.target.value;
74
+ // If we already have state for this plugin type/kind from a previous selection, just use it
75
+ const previousState = (ref = prevSpecState.current[pluginType]) === null || ref === void 0 ? void 0 : ref[nextKind];
76
+ if (previousState !== undefined) {
77
+ rememberCurrentSpecState();
78
+ onChange({
79
+ kind: nextKind,
80
+ spec: previousState
81
+ });
82
+ return;
83
+ }
84
+ // Otherwise, kick off the async loading process
85
+ setPendingKind(nextKind);
86
+ };
87
+ /**
88
+ * Spec changes are independent and always just set the spec state.
89
+ */ const onSpecChange = (next)=>{
90
+ onChange((0, _immer.produce)(value, (draft)=>{
91
+ draft.spec = next;
92
+ }));
93
+ };
94
+ return {
95
+ pendingKind,
96
+ isLoading: isFetching,
97
+ error,
98
+ onKindChange,
99
+ onSpecChange
100
+ };
101
+ }
@@ -0,0 +1,41 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "PluginKindSelect", {
18
+ enumerable: true,
19
+ get: ()=>PluginKindSelect
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _material = require("@mui/material");
23
+ const _runtime = require("../runtime");
24
+ function PluginKindSelect(props) {
25
+ const { pluginType , value: propValue , ...others } = props;
26
+ const { data , isLoading } = (0, _runtime.useListPluginMetadata)(pluginType);
27
+ // Pass an empty value while options are still loading so MUI doesn't complain about us using an "out of range" value
28
+ const value = propValue !== '' && isLoading ? '' : propValue;
29
+ // TODO: Does this need a loading indicator of some kind?
30
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Select, {
31
+ sx: {
32
+ minWidth: 120
33
+ },
34
+ ...others,
35
+ value: value,
36
+ children: data === null || data === void 0 ? void 0 : data.map((metadata)=>/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.MenuItem, {
37
+ value: metadata.kind,
38
+ children: metadata.display.name
39
+ }, metadata.kind))
40
+ });
41
+ }