@perspective-dev/viewer 4.2.0 → 4.4.0

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 (240) hide show
  1. package/dist/cdn/perspective-viewer.js +2 -2
  2. package/dist/cdn/perspective-viewer.js.map +4 -4
  3. package/dist/css/botanical.css +1 -0
  4. package/dist/css/dracula.css +1 -1
  5. package/dist/css/gruvbox-dark.css +1 -1
  6. package/dist/css/gruvbox.css +1 -1
  7. package/dist/css/icons.css +1 -1
  8. package/dist/css/intl/de.css +1 -1
  9. package/dist/css/intl/es.css +1 -1
  10. package/dist/css/intl/fr.css +1 -1
  11. package/dist/css/intl/ja.css +1 -1
  12. package/dist/css/intl/pt.css +1 -1
  13. package/dist/css/intl/zh.css +1 -1
  14. package/dist/css/intl.css +1 -1
  15. package/dist/css/monokai.css +1 -1
  16. package/dist/css/pro-dark.css +1 -1
  17. package/dist/css/pro.css +1 -1
  18. package/dist/css/solarized-dark.css +1 -1
  19. package/dist/css/solarized.css +1 -1
  20. package/dist/css/themes.css +1 -1
  21. package/dist/css/vaporwave.css +1 -1
  22. package/dist/esm/extensions.d.ts +32 -1
  23. package/dist/esm/perspective-viewer.d.ts +1 -0
  24. package/dist/esm/perspective-viewer.inline.js +2 -2
  25. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  26. package/dist/esm/perspective-viewer.js +2 -2
  27. package/dist/esm/perspective-viewer.js.map +4 -4
  28. package/dist/esm/ts-rs/GroupRollupMode.d.ts +1 -0
  29. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +2 -0
  30. package/dist/wasm/perspective-viewer.d.ts +57 -53
  31. package/dist/wasm/perspective-viewer.js +197 -164
  32. package/dist/wasm/perspective-viewer.wasm +0 -0
  33. package/dist/wasm/perspective-viewer.wasm.d.ts +17 -18
  34. package/package.json +9 -6
  35. package/src/{less/aggregate-selector.less → css/aggregate-selector.css} +23 -20
  36. package/src/css/column-dropdown.css +109 -0
  37. package/src/{less/column-selector.less → css/column-selector.css} +161 -159
  38. package/src/{less/column-settings-panel.less → css/column-settings-panel.css} +69 -59
  39. package/src/{less/column-style.less → css/column-style.css} +52 -66
  40. package/src/{less/column-symbol-attributes.less → css/column-symbol-attributes.css} +15 -14
  41. package/src/css/config-selector.css +441 -0
  42. package/src/{less/containers/dropdown-menu.less → css/containers/dropdown-menu.css} +20 -19
  43. package/src/{less/containers/pairs-list.less → css/containers/pairs-list.css} +13 -12
  44. package/src/{themes/variables.less → css/containers/scroll-panel.css} +25 -22
  45. package/src/{less/containers/split-panel.less → css/containers/split-panel.css} +15 -14
  46. package/src/{less/containers/tabs.less → css/containers/tabs.css} +17 -19
  47. package/src/css/dom/checkbox.css +102 -0
  48. package/src/css/dom/scrollbar.css +35 -0
  49. package/src/{less/dom/select.less → css/dom/select.css} +17 -18
  50. package/src/{less/empty-column.less → css/empty-column.css} +19 -18
  51. package/src/{less/expression-editor.less → css/expression-editor.css} +19 -18
  52. package/src/{less/filter-dropdown.less → css/filter-dropdown.css} +12 -11
  53. package/src/{less/filter-item.less → css/filter-item.css} +16 -15
  54. package/src/{less/form/code-editor.less → css/form/code-editor.css} +26 -30
  55. package/src/{less/form/debug.less → css/form/debug.css} +19 -18
  56. package/src/{less/function-dropdown.less → css/function-dropdown.css} +12 -11
  57. package/src/css/plugin-selector.css +261 -0
  58. package/src/{less/render-warning.less → css/render-warning.css} +18 -17
  59. package/src/{less/status-bar.less → css/status-bar.css} +156 -144
  60. package/src/css/type-icon.css +116 -0
  61. package/src/{less/viewer.less → css/viewer.css} +112 -146
  62. package/src/rust/components/column_dropdown.rs +229 -119
  63. package/src/rust/components/column_selector/active_column.rs +81 -62
  64. package/src/rust/components/column_selector/add_expression_button.rs +1 -0
  65. package/src/rust/components/column_selector/aggregate_selector.rs +25 -15
  66. package/src/rust/components/column_selector/config_selector.rs +374 -185
  67. package/src/rust/components/column_selector/empty_column.rs +2 -2
  68. package/src/rust/components/column_selector/expr_edit_button.rs +8 -2
  69. package/src/rust/components/column_selector/filter_column.rs +37 -26
  70. package/src/rust/components/column_selector/inactive_column.rs +41 -29
  71. package/src/rust/components/column_selector/invalid_column.rs +7 -18
  72. package/src/rust/components/column_selector/pivot_column.rs +21 -10
  73. package/src/rust/components/column_selector/sort_column.rs +23 -13
  74. package/src/rust/components/column_selector.rs +189 -100
  75. package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +1 -1
  76. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +3 -2
  77. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +3 -2
  78. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +2 -3
  79. package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +7 -1
  80. package/src/rust/components/column_settings_sidebar/style_tab.rs +153 -112
  81. package/src/rust/components/column_settings_sidebar.rs +91 -53
  82. package/src/rust/components/containers/dragdrop_list.rs +29 -7
  83. package/src/rust/components/containers/scroll_panel.rs +8 -1
  84. package/src/rust/components/containers/select.rs +3 -3
  85. package/src/rust/components/containers/sidebar_close_button.rs +1 -1
  86. package/src/rust/components/containers/split_panel.rs +3 -2
  87. package/src/rust/components/containers/tab_list.rs +1 -1
  88. package/src/rust/components/copy_dropdown.rs +7 -28
  89. package/src/rust/components/datetime_column_style/custom.rs +2 -2
  90. package/src/rust/components/datetime_column_style/simple.rs +2 -2
  91. package/src/rust/components/datetime_column_style.rs +4 -2
  92. package/src/rust/components/editable_header.rs +7 -4
  93. package/src/rust/components/empty_row.rs +1 -1
  94. package/src/rust/components/export_dropdown.rs +4 -30
  95. package/src/rust/components/expression_editor.rs +19 -10
  96. package/src/rust/components/filter_dropdown.rs +246 -102
  97. package/src/rust/components/font_loader.rs +11 -28
  98. package/src/rust/components/form/code_editor.rs +17 -2
  99. package/src/rust/components/form/color_range_selector.rs +19 -6
  100. package/src/rust/components/form/debug.rs +30 -13
  101. package/src/rust/components/function_dropdown.rs +186 -113
  102. package/src/rust/components/main_panel.rs +71 -89
  103. package/src/rust/components/mod.rs +1 -1
  104. package/src/rust/components/modal.rs +7 -1
  105. package/src/rust/components/number_column_style.rs +22 -7
  106. package/src/rust/components/plugin_selector.rs +34 -92
  107. package/src/rust/components/portal.rs +274 -0
  108. package/src/rust/components/render_warning.rs +72 -123
  109. package/src/rust/components/settings_panel.rs +115 -11
  110. package/src/rust/components/status_bar.rs +222 -98
  111. package/src/rust/components/status_bar_counter.rs +8 -20
  112. package/src/rust/components/status_indicator.rs +64 -111
  113. package/src/rust/components/string_column_style.rs +2 -2
  114. package/src/rust/components/style/style_cache.rs +5 -1
  115. package/src/rust/components/viewer.rs +391 -39
  116. package/src/rust/custom_elements/copy_dropdown.rs +102 -21
  117. package/src/rust/custom_elements/export_dropdown.rs +102 -20
  118. package/src/rust/custom_elements/mod.rs +0 -7
  119. package/src/rust/custom_elements/modal.rs +7 -103
  120. package/src/rust/custom_elements/viewer.rs +99 -35
  121. package/src/rust/custom_events.rs +23 -2
  122. package/src/rust/dragdrop.rs +149 -10
  123. package/src/{less/containers/scroll-panel.less → rust/engines.rs} +15 -13
  124. package/src/rust/js/plugin.rs +20 -1
  125. package/src/rust/lib.rs +5 -4
  126. package/src/rust/presentation/props.rs +39 -0
  127. package/src/rust/presentation/sheets.rs +3 -3
  128. package/src/rust/presentation.rs +44 -8
  129. package/src/rust/renderer/limits.rs +32 -3
  130. package/src/{less/dom/scrollbar.less → rust/renderer/props.rs} +18 -19
  131. package/src/rust/renderer/registry.rs +8 -1
  132. package/src/rust/renderer.rs +83 -9
  133. package/src/rust/session/column_defaults_update.rs +18 -0
  134. package/src/rust/session/metadata.rs +23 -2
  135. package/src/rust/session/props.rs +178 -0
  136. package/src/rust/session/replace_expression_update.rs +1 -0
  137. package/src/rust/session.rs +124 -117
  138. package/src/rust/tasks/column_locator.rs +133 -0
  139. package/src/rust/{model → tasks}/columns_iter_set.rs +14 -23
  140. package/src/rust/{model → tasks}/edit_expression.rs +34 -10
  141. package/src/rust/{model → tasks}/eject.rs +2 -2
  142. package/src/rust/{model → tasks}/get_viewer_config.rs +0 -11
  143. package/src/rust/{model → tasks}/intersection_observer.rs +22 -4
  144. package/src/{less/containers/radio-list.less → rust/tasks/is_invalid_drop.rs} +21 -14
  145. package/src/rust/tasks/mod.rs +52 -0
  146. package/src/rust/{model → tasks}/plugin_column_styles.rs +69 -46
  147. package/src/rust/{model → tasks}/resize_observer.rs +39 -6
  148. package/src/rust/{model → tasks}/send_plugin_config.rs +1 -1
  149. package/src/rust/tasks/structural.rs +53 -0
  150. package/src/rust/utils/mod.rs +4 -0
  151. package/src/rust/utils/modal_position.rs +110 -0
  152. package/src/rust/utils/ptr_eq_rc.rs +74 -0
  153. package/src/rust/utils/pubsub.rs +11 -1
  154. package/src/svg/bg-pattern.png +0 -0
  155. package/src/svg/close-icon.svg +1 -1
  156. package/src/svg/expression.svg +1 -1
  157. package/src/svg/mega-menu-icons-candlestick.svg +1 -1
  158. package/src/svg/mega-menu-icons-datagrid.svg +1 -2
  159. package/src/svg/mega-menu-icons-heatmap.svg +1 -1
  160. package/src/svg/mega-menu-icons-map-scatter.svg +1 -1
  161. package/src/svg/mega-menu-icons-ohlc.svg +1 -1
  162. package/src/svg/mega-menu-icons-sunburst.svg +1 -1
  163. package/src/svg/mega-menu-icons-treemap.svg +1 -1
  164. package/src/svg/mega-menu-icons-x-bar.svg +1 -1
  165. package/src/svg/mega-menu-icons-x-y-line.svg +1 -1
  166. package/src/svg/mega-menu-icons-x-y-scatter.svg +1 -1
  167. package/src/svg/mega-menu-icons-y-area.svg +1 -1
  168. package/src/svg/mega-menu-icons-y-bar.svg +1 -1
  169. package/src/svg/mega-menu-icons-y-line.svg +1 -1
  170. package/src/svg/mega-menu-icons-y-scatter.svg +1 -1
  171. package/src/svg/radio-hover.svg +1 -1
  172. package/src/svg/radio-off.svg +1 -1
  173. package/src/svg/radio-on.svg +1 -1
  174. package/src/themes/botanical.css +157 -0
  175. package/src/themes/defaults.css +139 -0
  176. package/src/themes/dracula.css +233 -0
  177. package/src/themes/gruvbox-dark.css +255 -0
  178. package/src/themes/gruvbox.css +134 -0
  179. package/src/themes/icons.css +124 -0
  180. package/src/themes/intl/de.css +102 -0
  181. package/src/themes/intl/es.css +102 -0
  182. package/src/themes/intl/fr.css +102 -0
  183. package/src/themes/intl/ja.css +102 -0
  184. package/src/themes/intl/pt.css +102 -0
  185. package/src/themes/intl/zh.css +102 -0
  186. package/src/themes/intl.css +102 -0
  187. package/src/themes/monokai.css +233 -0
  188. package/src/themes/pro-dark.css +158 -0
  189. package/src/themes/{themes.less → pro.css} +17 -20
  190. package/src/themes/solarized-dark.css +135 -0
  191. package/src/themes/solarized.css +95 -0
  192. package/src/themes/themes.css +22 -0
  193. package/src/themes/vaporwave.css +256 -0
  194. package/src/ts/extensions.ts +73 -2
  195. package/src/ts/perspective-viewer.ts +1 -0
  196. package/src/ts/ts-rs/GroupRollupMode.ts +3 -0
  197. package/src/ts/ts-rs/ViewerConfigUpdate.ts +2 -1
  198. package/tsconfig.json +1 -0
  199. package/dist/css/variables.css +0 -0
  200. package/src/less/column-dropdown.less +0 -95
  201. package/src/less/config-selector.less +0 -363
  202. package/src/less/dom/checkbox.less +0 -100
  203. package/src/less/plugin-selector.less +0 -183
  204. package/src/less/type-icon.less +0 -68
  205. package/src/rust/components/error_message.rs +0 -56
  206. package/src/rust/custom_elements/column_dropdown.rs +0 -123
  207. package/src/rust/custom_elements/filter_dropdown.rs +0 -179
  208. package/src/rust/custom_elements/function_dropdown.rs +0 -115
  209. package/src/rust/model/column_locator.rs +0 -82
  210. package/src/rust/model/is_invalid_drop.rs +0 -36
  211. package/src/rust/model/mod.rs +0 -100
  212. package/src/rust/model/reset_all.rs +0 -38
  213. package/src/rust/model/structural.rs +0 -244
  214. package/src/themes/dracula.less +0 -101
  215. package/src/themes/gruvbox-dark.less +0 -116
  216. package/src/themes/gruvbox.less +0 -152
  217. package/src/themes/icons.less +0 -130
  218. package/src/themes/intl/de.less +0 -102
  219. package/src/themes/intl/es.less +0 -102
  220. package/src/themes/intl/fr.less +0 -102
  221. package/src/themes/intl/ja.less +0 -102
  222. package/src/themes/intl/pt.less +0 -102
  223. package/src/themes/intl/zh.less +0 -102
  224. package/src/themes/intl.less +0 -102
  225. package/src/themes/monokai.less +0 -107
  226. package/src/themes/pro-dark.less +0 -147
  227. package/src/themes/pro.less +0 -186
  228. package/src/themes/solarized-dark.less +0 -78
  229. package/src/themes/solarized.less +0 -102
  230. package/src/themes/vaporwave.less +0 -145
  231. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline0.js +0 -0
  232. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline1.js +0 -0
  233. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline2.js +0 -0
  234. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline3.js +0 -0
  235. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline4.js +0 -0
  236. /package/src/rust/{model → tasks}/copy_export.rs +0 -0
  237. /package/src/rust/{model → tasks}/export_app.rs +0 -0
  238. /package/src/rust/{model → tasks}/export_method.rs +0 -0
  239. /package/src/rust/{model → tasks}/restore_and_render.rs +0 -0
  240. /package/src/rust/{model → tasks}/update_and_render.rs +0 -0
@@ -1,68 +0,0 @@
1
- // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
- // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
- // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
- // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
- // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
- // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
- // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
- // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
- // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
- // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
- // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
-
13
- :host #selected-columns .type-icon,
14
- :host #sub-columns .type-icon {
15
- position: absolute;
16
- left: 15px;
17
- }
18
-
19
- :host .type-icon {
20
- height: 13px;
21
- width: 13px;
22
- background-repeat: no-repeat;
23
- background-color: var(--icon--color);
24
- content: "";
25
- display: inline-block;
26
- -webkit-mask-size: cover;
27
- mask-size: cover;
28
- flex-shrink: 0;
29
-
30
- &.none {
31
- content: none;
32
- }
33
-
34
- &.integer {
35
- -webkit-mask-image: var(--column-type-integer--mask-image);
36
- mask-image: var(--column-type-integer--mask-image);
37
- }
38
-
39
- &.float {
40
- -webkit-mask-image: var(--column-type-float--mask-image);
41
- mask-image: var(--column-type-float--mask-image);
42
- }
43
-
44
- &.string {
45
- -webkit-mask-image: var(--column-type-string--mask-image);
46
- mask-image: var(--column-type-string--mask-image);
47
- }
48
-
49
- &.boolean {
50
- -webkit-mask-image: var(--column-type-boolean--mask-image);
51
- mask-image: var(--column-type-boolean--mask-image);
52
- }
53
-
54
- &.date {
55
- -webkit-mask-image: var(--column-type-date--mask-image);
56
- mask-image: var(--column-type-date--mask-image);
57
- }
58
-
59
- &.datetime {
60
- -webkit-mask-image: var(--column-type-datetime--mask-image);
61
- mask-image: var(--column-type-datetime--mask-image);
62
- }
63
-
64
- &.expression {
65
- -webkit-mask-image: var(--add-expression-icon--mask-image);
66
- mask-image: var(--add-expression-icon--mask-image);
67
- }
68
- }
@@ -1,56 +0,0 @@
1
- // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
- // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
- // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
- // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
- // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
- // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
- // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
- // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
- // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
- // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
- // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
-
13
- use perspective_client::clone;
14
- use yew::prelude::*;
15
- use yew::{Properties, function_component, html};
16
-
17
- use crate::components::style::LocalStyle;
18
- use crate::css;
19
- use crate::session::Session;
20
- use crate::utils::AddListener;
21
-
22
- #[derive(PartialEq, Properties)]
23
- pub struct ErrorMessageProps {
24
- pub session: Session,
25
- }
26
-
27
- #[function_component(ErrorMessage)]
28
- pub fn error_message(p: &ErrorMessageProps) -> yew::Html {
29
- let error = use_state(|| p.session.get_error());
30
- use_effect_with(
31
- (error.setter(), p.session.clone()),
32
- |(set_error, session)| {
33
- let sub = session.table_errored.add_listener({
34
- clone!(set_error);
35
- move |y| set_error.set(Some(y))
36
- });
37
-
38
- || drop(sub)
39
- },
40
- );
41
-
42
- html! {
43
- <>
44
- <LocalStyle href={css!("render-warning")} />
45
- <div
46
- class="plugin_information plugin_information--warning"
47
- id="plugin_information--size"
48
- >
49
- <span class="plugin_information__icon" />
50
- <span class="plugin_information__text" id="plugin_information_count">
51
- if let Some(msg) = error.as_ref() { { msg } }
52
- </span>
53
- </div>
54
- </>
55
- }
56
- }
@@ -1,123 +0,0 @@
1
- // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
- // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
- // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
- // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
- // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
- // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
- // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
- // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
- // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
- // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
- // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
-
13
- use std::collections::HashSet;
14
-
15
- use perspective_client::clone;
16
- use perspective_client::config::Expression;
17
- use perspective_js::json;
18
- use perspective_js::utils::global;
19
- use wasm_bindgen::JsCast;
20
- use wasm_bindgen::prelude::*;
21
- use web_sys::*;
22
- use yew::html::ImplicitClone;
23
- use yew::{Callback, props};
24
-
25
- use crate::components::column_dropdown::*;
26
- use crate::components::column_selector::InPlaceColumn;
27
- use crate::custom_elements::modal::*;
28
- use crate::session::Session;
29
- use crate::*;
30
-
31
- #[wasm_bindgen]
32
- #[derive(Clone)]
33
- pub struct ColumnDropDownElement {
34
- modal: ModalElement<ColumnDropDown>,
35
- session: Session,
36
- }
37
-
38
- impl ImplicitClone for ColumnDropDownElement {}
39
-
40
- impl ColumnDropDownElement {
41
- pub fn new(session: Session) -> Self {
42
- let dropdown = global::document()
43
- .create_element("perspective-dropdown")
44
- .unwrap()
45
- .unchecked_into::<HtmlElement>();
46
-
47
- let props = props!(ColumnDropDownProps {});
48
- let modal = ModalElement::new(dropdown, props, false, None);
49
- Self { modal, session }
50
- }
51
-
52
- pub fn autocomplete(
53
- &self,
54
- target: HtmlInputElement,
55
- exclude: HashSet<String>,
56
- callback: Callback<InPlaceColumn>,
57
- ) -> Option<()> {
58
- let input = target.value();
59
- let metadata = self.session.metadata();
60
- let mut values: Vec<InPlaceColumn> = vec![];
61
- let small_input = input.to_lowercase();
62
- for col in metadata.get_table_columns()? {
63
- if !exclude.contains(col) && col.to_lowercase().contains(&small_input) {
64
- values.push(InPlaceColumn::Column(col.to_owned()));
65
- }
66
- }
67
-
68
- for col in self.session.metadata().get_expression_columns() {
69
- if !exclude.contains(col) && col.to_lowercase().contains(&small_input) {
70
- values.push(InPlaceColumn::Column(col.to_owned()));
71
- }
72
- }
73
-
74
- clone!(self.modal, self.session);
75
- ApiFuture::spawn(async move {
76
- if !exclude.contains(&input) {
77
- let is_expr = session.validate_expr(&input).await?.is_none();
78
-
79
- if is_expr {
80
- values.push(InPlaceColumn::Expression(Expression::new(
81
- None,
82
- input.into(),
83
- )));
84
- }
85
- }
86
-
87
- let classes = modal.custom_element.class_list();
88
- let no_results = json!(["no-results"]);
89
- if values.is_empty() {
90
- classes.add(&no_results).unwrap();
91
- } else {
92
- classes.remove(&no_results).unwrap();
93
- }
94
-
95
- modal.send_message_batch(vec![
96
- ColumnDropDownMsg::SetCallback(callback),
97
- ColumnDropDownMsg::SetValues(values, target.get_bounding_client_rect().width()),
98
- ]);
99
-
100
- modal.open(target.unchecked_into(), None).await
101
- });
102
-
103
- Some(())
104
- }
105
-
106
- pub fn item_select(&self) {
107
- self.modal.send_message(ColumnDropDownMsg::ItemSelect);
108
- }
109
-
110
- pub fn item_down(&self) {
111
- self.modal.send_message(ColumnDropDownMsg::ItemDown);
112
- }
113
-
114
- pub fn item_up(&self) {
115
- self.modal.send_message(ColumnDropDownMsg::ItemUp);
116
- }
117
-
118
- pub fn hide(&self) -> ApiResult<()> {
119
- self.modal.hide()
120
- }
121
-
122
- pub fn connected_callback(&self) {}
123
- }
@@ -1,179 +0,0 @@
1
- // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
- // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
- // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
- // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
- // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
- // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
- // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
- // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
- // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
- // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
- // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
-
13
- use std::cell::RefCell;
14
- use std::collections::HashSet;
15
- use std::rc::Rc;
16
-
17
- use perspective_client::clone;
18
- use perspective_js::utils::global;
19
- use wasm_bindgen::JsCast;
20
- use wasm_bindgen::prelude::*;
21
- use web_sys::*;
22
- use yew::html::ImplicitClone;
23
- use yew::*;
24
-
25
- use crate::components::filter_dropdown::*;
26
- use crate::custom_elements::modal::*;
27
- use crate::session::Session;
28
- use crate::*;
29
-
30
- #[wasm_bindgen]
31
- #[derive(Clone)]
32
- pub struct FilterDropDownElement {
33
- modal: ModalElement<FilterDropDown>,
34
- session: Session,
35
- column: Rc<RefCell<Option<(usize, String)>>>,
36
- values: Rc<RefCell<Option<Vec<String>>>>,
37
- target: Rc<RefCell<Option<HtmlElement>>>,
38
- }
39
-
40
- impl PartialEq for FilterDropDownElement {
41
- fn eq(&self, other: &Self) -> bool {
42
- self.column == other.column && self.values == other.values && self.target == other.target
43
- }
44
- }
45
-
46
- impl ImplicitClone for FilterDropDownElement {}
47
-
48
- impl FilterDropDownElement {
49
- pub fn new(session: Session) -> Self {
50
- let dropdown = global::document()
51
- .create_element("perspective-dropdown")
52
- .unwrap()
53
- .unchecked_into::<HtmlElement>();
54
-
55
- let column: Rc<RefCell<Option<(usize, String)>>> = Rc::new(RefCell::new(None));
56
- let props = props!(FilterDropDownProps {});
57
- let modal = ModalElement::new(dropdown, props, false, None);
58
- let values = Rc::new(RefCell::new(None));
59
- Self {
60
- modal,
61
- session,
62
- column,
63
- values,
64
- target: Default::default(),
65
- }
66
- }
67
-
68
- pub fn reautocomplete(&self) {
69
- ApiFuture::spawn(
70
- self.modal
71
- .clone()
72
- .open(self.target.borrow().clone().unwrap(), None),
73
- );
74
- }
75
-
76
- pub fn autocomplete(
77
- &self,
78
- column: (usize, String),
79
- input: String,
80
- exclude: HashSet<String>,
81
- target: HtmlElement,
82
- callback: Callback<String>,
83
- ) {
84
- let current_column = self.column.borrow().clone();
85
- match current_column {
86
- Some(filter_col) if filter_col == column => {
87
- let values = filter_values(&input, &self.values, &exclude);
88
- if values.len() == 1 && values[0] == input {
89
- self.hide().unwrap();
90
- } else {
91
- self.modal.send_message_batch(vec![
92
- FilterDropDownMsg::SetCallback(callback),
93
- FilterDropDownMsg::SetValues(values),
94
- ]);
95
-
96
- if let Some(x) = self.target.borrow().clone()
97
- && !self.modal.is_open()
98
- {
99
- ApiFuture::spawn(self.modal.clone().open(x, None))
100
- }
101
- }
102
- },
103
- _ => {
104
- ApiFuture::spawn({
105
- clone!(
106
- self.modal,
107
- self.session,
108
- self.values,
109
- old_column = self.column,
110
- old_target = self.target
111
- );
112
- async move {
113
- let all_values = session.get_column_values(column.1.clone()).await?;
114
- *values.borrow_mut() = Some(all_values);
115
- let filter_values = filter_values(&input, &values, &exclude);
116
- if filter_values.len() == 1 && filter_values[0] == input {
117
- *old_column.borrow_mut() = Some(column);
118
- *old_target.borrow_mut() = Some(target.clone());
119
- let filter_values = self::filter_values("", &values, &exclude);
120
- modal.send_message_batch(vec![
121
- FilterDropDownMsg::SetCallback(callback),
122
- FilterDropDownMsg::SetValues(filter_values),
123
- ]);
124
-
125
- modal.hide()
126
- } else {
127
- *old_column.borrow_mut() = Some(column);
128
- *old_target.borrow_mut() = Some(target.clone());
129
- modal.send_message_batch(vec![
130
- FilterDropDownMsg::SetCallback(callback),
131
- FilterDropDownMsg::SetValues(filter_values),
132
- ]);
133
-
134
- modal.open(target, None).await
135
- }
136
- }
137
- });
138
- },
139
- }
140
- }
141
-
142
- pub fn item_select(&self) {
143
- self.modal.send_message(FilterDropDownMsg::ItemSelect);
144
- }
145
-
146
- pub fn item_down(&self) {
147
- self.modal.send_message(FilterDropDownMsg::ItemDown);
148
- }
149
-
150
- pub fn item_up(&self) {
151
- self.modal.send_message(FilterDropDownMsg::ItemUp);
152
- }
153
-
154
- pub fn hide(&self) -> ApiResult<()> {
155
- let result = self.modal.hide();
156
- drop(self.column.borrow_mut().take());
157
- result
158
- }
159
-
160
- pub fn connected_callback(&self) {}
161
- }
162
-
163
- fn filter_values(
164
- input: &str,
165
- values: &Rc<RefCell<Option<Vec<String>>>>,
166
- exclude: &HashSet<String>,
167
- ) -> Vec<String> {
168
- let input = input.to_lowercase();
169
- if let Some(values) = &*values.borrow() {
170
- values
171
- .iter()
172
- .filter(|x| x.to_lowercase().contains(&input) && !exclude.contains(x.as_str()))
173
- .take(10)
174
- .cloned()
175
- .collect::<Vec<String>>()
176
- } else {
177
- vec![]
178
- }
179
- }
@@ -1,115 +0,0 @@
1
- // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
- // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
- // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
- // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
- // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
- // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
- // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
- // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
- // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
- // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
- // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
-
13
- use std::cell::RefCell;
14
- use std::rc::Rc;
15
-
16
- use perspective_client::config::{COMPLETIONS, CompletionItemSuggestion};
17
- use perspective_js::utils::global;
18
- use wasm_bindgen::JsCast;
19
- use wasm_bindgen::prelude::*;
20
- use web_sys::*;
21
- use yew::html::ImplicitClone;
22
- use yew::*;
23
-
24
- use crate::components::function_dropdown::*;
25
- use crate::custom_elements::modal::*;
26
- use crate::*;
27
-
28
- #[wasm_bindgen]
29
- #[derive(Clone)]
30
- pub struct FunctionDropDownElement {
31
- modal: ModalElement<FunctionDropDown>,
32
- target: Rc<RefCell<Option<HtmlElement>>>,
33
- }
34
-
35
- impl PartialEq for FunctionDropDownElement {
36
- fn eq(&self, _other: &Self) -> bool {
37
- true
38
- }
39
- }
40
-
41
- impl ImplicitClone for FunctionDropDownElement {}
42
-
43
- impl FunctionDropDownElement {
44
- pub fn reautocomplete(&self) {
45
- ApiFuture::spawn(
46
- self.modal
47
- .clone()
48
- .open(self.target.borrow().clone().unwrap(), None),
49
- );
50
- }
51
-
52
- pub fn autocomplete(
53
- &self,
54
- input: String,
55
- target: HtmlElement,
56
- callback: Callback<CompletionItemSuggestion>,
57
- ) -> ApiResult<()> {
58
- let values = filter_values(&input);
59
- if values.is_empty() {
60
- self.modal.hide()?;
61
- } else {
62
- self.modal.send_message_batch(vec![
63
- FunctionDropDownMsg::SetCallback(callback),
64
- FunctionDropDownMsg::SetValues(values),
65
- ]);
66
-
67
- ApiFuture::spawn(self.modal.clone().open(target, None));
68
- }
69
-
70
- Ok(())
71
- }
72
-
73
- pub fn item_select(&self) {
74
- self.modal.send_message(FunctionDropDownMsg::ItemSelect);
75
- }
76
-
77
- pub fn item_down(&self) {
78
- self.modal.send_message(FunctionDropDownMsg::ItemDown);
79
- }
80
-
81
- pub fn item_up(&self) {
82
- self.modal.send_message(FunctionDropDownMsg::ItemUp);
83
- }
84
-
85
- pub fn hide(&self) -> ApiResult<()> {
86
- self.modal.hide()
87
- }
88
-
89
- pub fn connected_callback(&self) {}
90
- }
91
-
92
- impl Default for FunctionDropDownElement {
93
- fn default() -> Self {
94
- let dropdown = global::document()
95
- .create_element("perspective-dropdown")
96
- .unwrap()
97
- .unchecked_into::<HtmlElement>();
98
-
99
- let props = props!(FunctionDropDownProps {});
100
- let modal = ModalElement::new(dropdown, props, false, None);
101
- Self {
102
- modal,
103
- target: Default::default(),
104
- }
105
- }
106
- }
107
-
108
- fn filter_values(input: &str) -> Vec<CompletionItemSuggestion> {
109
- let input = input.to_lowercase();
110
- COMPLETIONS
111
- .iter()
112
- .filter(|x| x.label.to_lowercase().starts_with(&input))
113
- .cloned()
114
- .collect::<Vec<_>>()
115
- }
@@ -1,82 +0,0 @@
1
- // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
- // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
- // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
- // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
- // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
- // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
- // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
- // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
- // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
- // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
- // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
-
13
- use perspective_client::config::ColumnType;
14
-
15
- use super::HasSession;
16
- use crate::model::{HasPresentation, HasRenderer, PluginColumnStyles};
17
- use crate::presentation::ColumnLocator;
18
-
19
- pub trait ColumnLocatorExt: HasSession {
20
- fn locator_name_or_default(&self, locator: &ColumnLocator) -> String {
21
- match locator {
22
- ColumnLocator::Table(s) | ColumnLocator::Expression(s) => s.clone(),
23
- ColumnLocator::NewExpression => self.session().metadata().make_new_column_name(None),
24
- }
25
- }
26
-
27
- fn is_locator_active(&self, locator: &ColumnLocator) -> bool {
28
- locator
29
- .name()
30
- .map(|name| self.session().is_column_active(name))
31
- .unwrap_or_default()
32
- }
33
-
34
- fn locator_view_type(&self, locator: &ColumnLocator) -> Option<ColumnType> {
35
- let name = locator.name().cloned().unwrap_or_default();
36
- self.session()
37
- .metadata()
38
- .get_column_view_type(name.as_str())
39
- }
40
-
41
- /// This function will return a [`ColumnLocator`] for agiven column name, or
42
- /// [`None`] if no such column already exists. If you want to
43
- /// create a new expression column, use ColumnLocator::Expr(None)
44
- fn get_column_locator(&self, name: Option<String>) -> Option<ColumnLocator> {
45
- name.and_then(|name| {
46
- if self.session().metadata().is_column_expression(&name) {
47
- Some(ColumnLocator::Expression(name))
48
- } else {
49
- self.session().metadata().get_table_columns().and_then(|x| {
50
- x.iter()
51
- .find_map(|n| (n == &name).then_some(ColumnLocator::Table(name.clone())))
52
- })
53
- }
54
- })
55
- }
56
- }
57
-
58
- impl<T: HasSession> ColumnLocatorExt for T {}
59
-
60
- pub trait ColumnLocatorCurrentExt:
61
- HasPresentation + HasRenderer + HasSession + PluginColumnStyles
62
- {
63
- /// Gets a [`ColumnLocator`] for the current UI's column settings state,
64
- /// or [`None`] if it is not currently active.
65
- fn get_current_column_locator(&self) -> Option<ColumnLocator> {
66
- self.presentation()
67
- .get_open_column_settings()
68
- .locator
69
- .filter(|locator| match locator {
70
- ColumnLocator::Table(name) => {
71
- self.session().is_locator_active(locator)
72
- && self.can_render_column_styles(name).unwrap_or_default()
73
- },
74
- _ => true,
75
- })
76
- }
77
- }
78
-
79
- impl<T: HasPresentation + HasRenderer + HasSession + PluginColumnStyles> ColumnLocatorCurrentExt
80
- for T
81
- {
82
- }
@@ -1,36 +0,0 @@
1
- // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
- // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
- // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
- // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
- // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
- // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
- // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
- // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
- // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
- // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
- // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
-
13
- use super::{HasRenderer, HasSession};
14
-
15
- pub trait IsInvalidDrop: HasRenderer + HasSession {
16
- fn is_invalid_columns_column(&self, from_column: &String, to_index: usize) -> bool {
17
- let config = self.session().get_view_config();
18
- let from_index = config
19
- .columns
20
- .iter()
21
- .position(|x| x.as_ref() == Some(from_column));
22
-
23
- let min_cols = self.renderer().metadata().min;
24
- let is_to_empty = !config
25
- .columns
26
- .get(to_index)
27
- .map(|x| x.is_some())
28
- .unwrap_or_default();
29
- min_cols
30
- .and_then(|x| from_index.map(|from_index| from_index < x))
31
- .unwrap_or_default()
32
- && is_to_empty
33
- }
34
- }
35
-
36
- impl<T: HasRenderer + HasSession> IsInvalidDrop for T {}