@perspective-dev/viewer 4.0.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.
- package/LICENSE.md +193 -0
- package/README.md +4 -0
- package/dist/cdn/perspective-viewer.js +3 -0
- package/dist/cdn/perspective-viewer.js.map +7 -0
- package/dist/css/dracula.css +1 -0
- package/dist/css/gruvbox-dark.css +1 -0
- package/dist/css/gruvbox.css +1 -0
- package/dist/css/icons.css +1 -0
- package/dist/css/intl/de.css +1 -0
- package/dist/css/intl/es.css +1 -0
- package/dist/css/intl/fr.css +1 -0
- package/dist/css/intl/ja.css +1 -0
- package/dist/css/intl/pt.css +1 -0
- package/dist/css/intl/zh.css +1 -0
- package/dist/css/intl.css +1 -0
- package/dist/css/monokai.css +1 -0
- package/dist/css/pro-dark.css +1 -0
- package/dist/css/pro.css +1 -0
- package/dist/css/solarized-dark.css +1 -0
- package/dist/css/solarized.css +1 -0
- package/dist/css/themes.css +1 -0
- package/dist/css/vaporwave.css +1 -0
- package/dist/css/variables.css +0 -0
- package/dist/esm/bootstrap.d.ts +1 -0
- package/dist/esm/extensions.d.ts +70 -0
- package/dist/esm/perspective-viewer.d.ts +39 -0
- package/dist/esm/perspective-viewer.inline.js +3 -0
- package/dist/esm/perspective-viewer.inline.js.map +7 -0
- package/dist/esm/perspective-viewer.js +3 -0
- package/dist/esm/perspective-viewer.js.map +7 -0
- package/dist/esm/plugin.d.ts +195 -0
- package/dist/esm/ts-rs/Aggregate.d.ts +1 -0
- package/dist/esm/ts-rs/ColumnConfigValues.d.ts +31 -0
- package/dist/esm/ts-rs/CustomDatetimeFormat.d.ts +1 -0
- package/dist/esm/ts-rs/CustomDatetimeStyleConfig.d.ts +15 -0
- package/dist/esm/ts-rs/CustomNumberFormatConfig.d.ts +18 -0
- package/dist/esm/ts-rs/DatetimeColorMode.d.ts +1 -0
- package/dist/esm/ts-rs/DatetimeFormatType.d.ts +6 -0
- package/dist/esm/ts-rs/Expressions.d.ts +3 -0
- package/dist/esm/ts-rs/Filter.d.ts +2 -0
- package/dist/esm/ts-rs/FilterReducer.d.ts +1 -0
- package/dist/esm/ts-rs/FilterTerm.d.ts +2 -0
- package/dist/esm/ts-rs/FormatMode.d.ts +1 -0
- package/dist/esm/ts-rs/FormatUnit.d.ts +1 -0
- package/dist/esm/ts-rs/NumberBackgroundMode.d.ts +1 -0
- package/dist/esm/ts-rs/NumberForegroundMode.d.ts +1 -0
- package/dist/esm/ts-rs/OptionalUpdate.d.ts +1 -0
- package/dist/esm/ts-rs/PluginConfig.d.ts +2 -0
- package/dist/esm/ts-rs/RoundingMode.d.ts +1 -0
- package/dist/esm/ts-rs/RoundingPriority.d.ts +1 -0
- package/dist/esm/ts-rs/Scalar.d.ts +5 -0
- package/dist/esm/ts-rs/SignDisplay.d.ts +1 -0
- package/dist/esm/ts-rs/SimpleDatetimeFormat.d.ts +1 -0
- package/dist/esm/ts-rs/SimpleDatetimeStyleConfig.d.ts +6 -0
- package/dist/esm/ts-rs/Sort.d.ts +2 -0
- package/dist/esm/ts-rs/SortDir.d.ts +1 -0
- package/dist/esm/ts-rs/StringColorMode.d.ts +1 -0
- package/dist/esm/ts-rs/TrailingZeroDisplay.d.ts +1 -0
- package/dist/esm/ts-rs/UseGrouping.d.ts +1 -0
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +102 -0
- package/dist/esm/ts-rs/serde_json/JsonValue.d.ts +3 -0
- package/dist/wasm/perspective-viewer.d.ts +1291 -0
- package/dist/wasm/perspective-viewer.js +3883 -0
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +142 -0
- package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline0.js +1 -0
- package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline1.js +1 -0
- package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline2.js +1 -0
- package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline3.js +44 -0
- package/dist/wasm/snippets/perspective-viewer-c69283f6f62a5f14/inline4.js +1 -0
- package/package.json +55 -0
- package/src/less/aggregate-selector.less +72 -0
- package/src/less/column-dropdown.less +95 -0
- package/src/less/column-selector.less +551 -0
- package/src/less/column-settings-panel.less +255 -0
- package/src/less/column-style.less +319 -0
- package/src/less/column-symbol-attributes.less +73 -0
- package/src/less/config-selector.less +363 -0
- package/src/less/containers/dropdown-menu.less +94 -0
- package/src/less/containers/pairs-list.less +46 -0
- package/src/less/containers/radio-list.less +29 -0
- package/src/less/containers/scroll-panel.less +27 -0
- package/src/less/containers/split-panel.less +80 -0
- package/src/less/containers/tabs.less +90 -0
- package/src/less/dom/checkbox.less +100 -0
- package/src/less/dom/scrollbar.less +35 -0
- package/src/less/dom/select.less +63 -0
- package/src/less/empty-column.less +72 -0
- package/src/less/expression-editor.less +152 -0
- package/src/less/filter-dropdown.less +53 -0
- package/src/less/filter-item.less +126 -0
- package/src/less/form/code-editor.less +137 -0
- package/src/less/form/debug.less +88 -0
- package/src/less/function-dropdown.less +45 -0
- package/src/less/plugin-selector.less +173 -0
- package/src/less/render-warning.less +81 -0
- package/src/less/status-bar.less +551 -0
- package/src/less/type-icon.less +68 -0
- package/src/less/viewer.less +368 -0
- package/src/rust/components/column_dropdown.rs +162 -0
- package/src/rust/components/column_selector/active_column.rs +462 -0
- package/src/rust/components/column_selector/add_expression_button.rs +59 -0
- package/src/rust/components/column_selector/aggregate_selector.rs +186 -0
- package/src/rust/components/column_selector/config_selector.rs +674 -0
- package/src/rust/components/column_selector/empty_column.rs +134 -0
- package/src/rust/components/column_selector/expression_toolbar.rs +45 -0
- package/src/rust/components/column_selector/filter_column.rs +530 -0
- package/src/rust/components/column_selector/inactive_column.rs +221 -0
- package/src/rust/components/column_selector/invalid_column.rs +37 -0
- package/src/rust/components/column_selector/pivot_column.rs +93 -0
- package/src/rust/components/column_selector/sort_column.rs +135 -0
- package/src/rust/components/column_selector.rs +426 -0
- package/src/rust/components/column_settings_sidebar/attributes_tab.rs +34 -0
- package/src/rust/components/column_settings_sidebar/mod.rs +17 -0
- package/src/rust/components/column_settings_sidebar/save_settings.rs +68 -0
- package/src/rust/components/column_settings_sidebar/sidebar.rs +396 -0
- package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +177 -0
- package/src/rust/components/column_settings_sidebar/style_tab/stub.rs +34 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +101 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_config.rs +24 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +185 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +55 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +131 -0
- package/src/rust/components/column_settings_sidebar/style_tab.rs +231 -0
- package/src/rust/components/containers/dragdrop_list.rs +325 -0
- package/src/rust/components/containers/dropdown_menu.rs +104 -0
- package/src/rust/components/containers/kvpair.rs +47 -0
- package/src/rust/components/containers/mod.rs +28 -0
- package/src/rust/components/containers/scroll_panel.rs +311 -0
- package/src/rust/components/containers/scroll_panel_item.rs +111 -0
- package/src/rust/components/containers/select.rs +269 -0
- package/src/rust/components/containers/sidebar.rs +89 -0
- package/src/rust/components/containers/split_panel.rs +483 -0
- package/src/rust/components/containers/tab_list.rs +104 -0
- package/src/rust/components/containers/tests/mod.rs +11 -0
- package/src/rust/components/containers/tests/split_panel.rs +91 -0
- package/src/rust/components/containers/trap_door_panel.rs +50 -0
- package/src/rust/components/copy_dropdown.rs +136 -0
- package/src/rust/components/datetime_column_style/custom.rs +222 -0
- package/src/rust/components/datetime_column_style/simple.rs +122 -0
- package/src/rust/components/datetime_column_style.rs +284 -0
- package/src/rust/components/editable_header.rs +183 -0
- package/src/rust/components/empty_row.rs +169 -0
- package/src/rust/components/error_message.rs +56 -0
- package/src/rust/components/export_dropdown.rs +153 -0
- package/src/rust/components/expression_editor.rs +153 -0
- package/src/rust/components/filter_dropdown.rs +144 -0
- package/src/rust/components/font_loader.rs +254 -0
- package/src/rust/components/form/code_editor.rs +286 -0
- package/src/rust/components/form/color_range_selector.rs +115 -0
- package/src/rust/components/form/color_selector.rs +54 -0
- package/src/rust/components/form/debug.rs +253 -0
- package/src/rust/components/form/highlight.rs +50 -0
- package/src/rust/components/form/mod.rs +29 -0
- package/src/rust/components/form/number_field.rs +72 -0
- package/src/rust/components/form/number_input.rs +45 -0
- package/src/rust/components/form/number_range_field.rs +77 -0
- package/src/rust/components/form/optional_field.rs +53 -0
- package/src/rust/components/form/select_field.rs +104 -0
- package/src/rust/components/function_dropdown.rs +151 -0
- package/src/rust/components/mod.rs +45 -0
- package/src/rust/components/modal.rs +171 -0
- package/src/rust/components/number_column_style.rs +522 -0
- package/src/rust/components/plugin_selector.rs +196 -0
- package/src/rust/components/render_warning.rs +178 -0
- package/src/rust/components/status_bar.rs +315 -0
- package/src/rust/components/status_bar_counter.rs +229 -0
- package/src/rust/components/status_indicator.rs +164 -0
- package/src/rust/components/string_column_style.rs +186 -0
- package/src/rust/components/style/local_style.rs +35 -0
- package/src/rust/components/style/mod.rs +52 -0
- package/src/rust/components/style/style_cache.rs +132 -0
- package/src/rust/components/style/style_provider.rs +65 -0
- package/src/rust/components/style_controls/number_string_format/digits_section.rs +140 -0
- package/src/rust/components/style_controls/number_string_format/misc_section.rs +56 -0
- package/src/rust/components/style_controls/number_string_format/style_section.rs +69 -0
- package/src/rust/components/style_controls/number_string_format/types.rs +31 -0
- package/src/rust/components/style_controls/number_string_format.rs +259 -0
- package/src/rust/components/style_controls.rs +15 -0
- package/src/rust/components/type_icon.rs +53 -0
- package/src/rust/components/viewer.rs +668 -0
- package/src/rust/config/columns_config.rs +132 -0
- package/src/rust/config/datetime_column_style/color_mode.rs +62 -0
- package/src/rust/config/datetime_column_style/custom.rs +121 -0
- package/src/rust/config/datetime_column_style/custom_format.rs +90 -0
- package/src/rust/config/datetime_column_style/simple.rs +55 -0
- package/src/rust/config/datetime_column_style/simple_format.rs +86 -0
- package/src/rust/config/datetime_column_style.rs +104 -0
- package/src/rust/config/mod.rs +30 -0
- package/src/rust/config/number_column_style.rs +138 -0
- package/src/rust/config/number_string_format/enums.rs +298 -0
- package/src/rust/config/number_string_format.rs +269 -0
- package/src/rust/config/string_column_style.rs +140 -0
- package/src/rust/config/view_config.rs +24 -0
- package/src/rust/config/viewer_config.rs +337 -0
- package/src/rust/custom_elements/column_dropdown.rs +123 -0
- package/src/rust/custom_elements/copy_dropdown.rs +112 -0
- package/src/rust/custom_elements/debug_plugin.rs +114 -0
- package/src/rust/custom_elements/export_dropdown.rs +112 -0
- package/src/rust/custom_elements/filter_dropdown.rs +179 -0
- package/src/rust/custom_elements/function_dropdown.rs +115 -0
- package/src/rust/custom_elements/mod.rs +24 -0
- package/src/rust/custom_elements/modal.rs +395 -0
- package/src/rust/custom_elements/viewer.rs +880 -0
- package/src/rust/custom_events.rs +214 -0
- package/src/rust/dragdrop.rs +362 -0
- package/src/rust/exprtk/cursor.rs +81 -0
- package/src/rust/exprtk/mod.rs +17 -0
- package/src/rust/exprtk/tokenize/comment.rs +21 -0
- package/src/rust/exprtk/tokenize/number.rs +44 -0
- package/src/rust/exprtk/tokenize/string.rs +98 -0
- package/src/rust/exprtk/tokenize/symbol.rs +26 -0
- package/src/rust/exprtk/tokenize.rs +190 -0
- package/src/rust/js/clipboard.rs +77 -0
- package/src/rust/js/clipboard_item.rs +21 -0
- package/src/rust/js/intersection_observer.rs +32 -0
- package/src/rust/js/mimetype.rs +42 -0
- package/src/rust/js/mod.rs +29 -0
- package/src/rust/js/plugin.rs +167 -0
- package/src/rust/js/resize_observer.rs +37 -0
- package/src/rust/js/testing.rs +149 -0
- package/src/rust/lib.rs +116 -0
- package/src/rust/model/columns_iter_set.rs +340 -0
- package/src/rust/model/copy_export.rs +157 -0
- package/src/rust/model/create_col.rs +59 -0
- package/src/rust/model/edit_expression.rs +95 -0
- package/src/rust/model/export_app.rs +58 -0
- package/src/rust/model/export_method.rs +151 -0
- package/src/rust/model/get_viewer_config.rs +85 -0
- package/src/rust/model/intersection_observer.rs +81 -0
- package/src/rust/model/is_invalid_drop.rs +36 -0
- package/src/rust/model/mod.rs +93 -0
- package/src/rust/model/plugin_column_styles.rs +106 -0
- package/src/rust/model/resize_observer.rs +98 -0
- package/src/rust/model/restore_and_render.rs +113 -0
- package/src/rust/model/structural.rs +73 -0
- package/src/rust/model/update_and_render.rs +74 -0
- package/src/rust/presentation.rs +370 -0
- package/src/rust/renderer/activate.rs +49 -0
- package/src/rust/renderer/limits.rs +200 -0
- package/src/rust/renderer/plugin_store.rs +45 -0
- package/src/rust/renderer/registry.rs +135 -0
- package/src/rust/renderer/render_timer.rs +185 -0
- package/src/rust/renderer.rs +463 -0
- package/src/rust/session/column_defaults_update.rs +141 -0
- package/src/rust/session/drag_drop_update.rs +179 -0
- package/src/rust/session/metadata.rs +308 -0
- package/src/rust/session/replace_expression_update.rs +131 -0
- package/src/rust/session/view_subscription.rs +189 -0
- package/src/rust/session.rs +794 -0
- package/src/rust/utils/browser/blob.rs +49 -0
- package/src/rust/utils/browser/download.rs +26 -0
- package/src/rust/utils/browser/mod.rs +24 -0
- package/src/rust/utils/browser/request_animation_frame.rs +76 -0
- package/src/rust/utils/browser/selection.rs +79 -0
- package/src/rust/utils/browser/tests/debounce.rs +114 -0
- package/src/rust/utils/browser/tests/mod.rs +13 -0
- package/src/rust/utils/custom_element.rs +85 -0
- package/src/rust/utils/datetime.rs +49 -0
- package/src/rust/utils/debounce.rs +54 -0
- package/src/rust/utils/hooks/mod.rs +15 -0
- package/src/rust/utils/hooks/use_async_callback.rs +53 -0
- package/src/rust/utils/mod.rs +114 -0
- package/src/rust/utils/number_format.rs +48 -0
- package/src/rust/utils/pubsub.rs +222 -0
- package/src/rust/utils/scope.rs +54 -0
- package/src/rust/utils/tee.rs +88 -0
- package/src/rust/utils/tests/mod.rs +14 -0
- package/src/rust/utils/tests/pubsub.rs +95 -0
- package/src/rust/utils/tests/request_animation_frame.rs +42 -0
- package/src/rust/utils/wasm_abi.rs +61 -0
- package/src/rust/utils/weak_scope.rs +39 -0
- package/src/svg/align-scroll-icon.svg +7 -0
- package/src/svg/bg-pattern.png +0 -0
- package/src/svg/boolean-type.svg +3 -0
- package/src/svg/checkbox-checked-icon.svg +7 -0
- package/src/svg/checkbox-hover.svg +4 -0
- package/src/svg/checkbox-off.svg +4 -0
- package/src/svg/checkbox-on.svg +4 -0
- package/src/svg/checkbox-unchecked-icon.svg +3 -0
- package/src/svg/close-icon.svg +6 -0
- package/src/svg/column-settings-icon.svg +6 -0
- package/src/svg/datagrid-select-column.svg +15 -0
- package/src/svg/datagrid-select-region.svg +15 -0
- package/src/svg/datagrid-select-row.svg +13 -0
- package/src/svg/datagrid.svg +13 -0
- package/src/svg/date-type.svg +23 -0
- package/src/svg/downloading.gif +0 -0
- package/src/svg/drag-handle.svg +10 -0
- package/src/svg/drawer-bg-pattern-hidpi.png +0 -0
- package/src/svg/drawer-tab-hover.svg +8 -0
- package/src/svg/drawer-tab-invert-hover.svg +9 -0
- package/src/svg/drawer-tab-invert.svg +8 -0
- package/src/svg/drawer-tab.svg +7 -0
- package/src/svg/dropdown-selector-light.svg +3 -0
- package/src/svg/dropdown-selector.svg +3 -0
- package/src/svg/duplicate-icon.svg +4 -0
- package/src/svg/editable-icon.svg +5 -0
- package/src/svg/export-icon.svg +4 -0
- package/src/svg/expression.svg +10 -0
- package/src/svg/free-scroll-icon.svg +5 -0
- package/src/svg/inactive-mouseover.svg +4 -0
- package/src/svg/mega-menu-icons-candlestick.svg +38 -0
- package/src/svg/mega-menu-icons-datagrid.svg +38 -0
- package/src/svg/mega-menu-icons-heatmap.svg +60 -0
- package/src/svg/mega-menu-icons-map-scatter.svg +43 -0
- package/src/svg/mega-menu-icons-ohlc.svg +40 -0
- package/src/svg/mega-menu-icons-sunburst.svg +39 -0
- package/src/svg/mega-menu-icons-treemap.svg +44 -0
- package/src/svg/mega-menu-icons-x-bar.svg +36 -0
- package/src/svg/mega-menu-icons-x-y-line.svg +38 -0
- package/src/svg/mega-menu-icons-x-y-scatter.svg +72 -0
- package/src/svg/mega-menu-icons-y-area.svg +73 -0
- package/src/svg/mega-menu-icons-y-bar.svg +36 -0
- package/src/svg/mega-menu-icons-y-line.svg +36 -0
- package/src/svg/mega-menu-icons-y-scatter.svg +72 -0
- package/src/svg/number-type.svg +4 -0
- package/src/svg/radio-hover.svg +4 -0
- package/src/svg/radio-off.svg +3 -0
- package/src/svg/radio-on.svg +4 -0
- package/src/svg/read-only-icon.svg +6 -0
- package/src/svg/revert-icon.svg +4 -0
- package/src/svg/sort-abs-asc-icon.svg +3 -0
- package/src/svg/sort-abs-col-asc-icon.svg +3 -0
- package/src/svg/sort-abs-col-desc-icon.svg +3 -0
- package/src/svg/sort-abs-desc-icon.svg +3 -0
- package/src/svg/sort-asc-icon.svg +4 -0
- package/src/svg/sort-col-asc-icon.svg +4 -0
- package/src/svg/sort-col-desc-icon.svg +4 -0
- package/src/svg/sort-desc-icon.svg +4 -0
- package/src/svg/sort-none-icon.svg +3 -0
- package/src/svg/status_error.svg +70 -0
- package/src/svg/status_ok.svg +26 -0
- package/src/svg/string-type.svg +8 -0
- package/src/svg/theme-icon.svg +5 -0
- package/src/svg/updating.gif +0 -0
- package/src/themes/dracula.less +101 -0
- package/src/themes/gruvbox-dark.less +116 -0
- package/src/themes/gruvbox.less +152 -0
- package/src/themes/icons.less +130 -0
- package/src/themes/intl/de.less +102 -0
- package/src/themes/intl/es.less +102 -0
- package/src/themes/intl/fr.less +102 -0
- package/src/themes/intl/ja.less +102 -0
- package/src/themes/intl/pt.less +102 -0
- package/src/themes/intl/zh.less +102 -0
- package/src/themes/intl.less +102 -0
- package/src/themes/monokai.less +107 -0
- package/src/themes/pro-dark.less +147 -0
- package/src/themes/pro.less +186 -0
- package/src/themes/solarized-dark.less +78 -0
- package/src/themes/solarized.less +102 -0
- package/src/themes/themes.less +21 -0
- package/src/themes/vaporwave.less +145 -0
- package/src/themes/variables.less +24 -0
- package/src/ts/bootstrap.ts +26 -0
- package/src/ts/extensions.ts +124 -0
- package/src/ts/perspective-viewer.cdn.ts +19 -0
- package/src/ts/perspective-viewer.inline.ts +23 -0
- package/src/ts/perspective-viewer.ts +59 -0
- package/src/ts/plugin.ts +279 -0
- package/src/ts/ts-rs/Aggregate.ts +3 -0
- package/src/ts/ts-rs/ColumnConfigValues.ts +14 -0
- package/src/ts/ts-rs/CustomDatetimeFormat.ts +3 -0
- package/src/ts/ts-rs/CustomDatetimeStyleConfig.ts +5 -0
- package/src/ts/ts-rs/CustomNumberFormatConfig.ts +8 -0
- package/src/ts/ts-rs/DatetimeColorMode.ts +3 -0
- package/src/ts/ts-rs/DatetimeFormatType.ts +8 -0
- package/src/ts/ts-rs/Expressions.ts +3 -0
- package/src/ts/ts-rs/Filter.ts +4 -0
- package/src/ts/ts-rs/FilterReducer.ts +3 -0
- package/src/ts/ts-rs/FilterTerm.ts +4 -0
- package/src/ts/ts-rs/FormatMode.ts +3 -0
- package/src/ts/ts-rs/FormatUnit.ts +3 -0
- package/src/ts/ts-rs/NumberBackgroundMode.ts +3 -0
- package/src/ts/ts-rs/NumberForegroundMode.ts +3 -0
- package/src/ts/ts-rs/OnUpdateData.ts +8 -0
- package/src/ts/ts-rs/OptionalUpdate.ts +3 -0
- package/src/ts/ts-rs/PluginConfig.ts +4 -0
- package/src/ts/ts-rs/RoundingMode.ts +3 -0
- package/src/ts/ts-rs/RoundingPriority.ts +3 -0
- package/src/ts/ts-rs/Scalar.ts +7 -0
- package/src/ts/ts-rs/SignDisplay.ts +3 -0
- package/src/ts/ts-rs/SimpleDatetimeFormat.ts +3 -0
- package/src/ts/ts-rs/SimpleDatetimeStyleConfig.ts +4 -0
- package/src/ts/ts-rs/Sort.ts +4 -0
- package/src/ts/ts-rs/SortDir.ts +3 -0
- package/src/ts/ts-rs/StringColorMode.ts +3 -0
- package/src/ts/ts-rs/TrailingZeroDisplay.ts +3 -0
- package/src/ts/ts-rs/UseGrouping.ts +3 -0
- package/src/ts/ts-rs/ViewOnUpdateResp.ts +3 -0
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +90 -0
- package/src/ts/ts-rs/serde_json/JsonValue.ts +3 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,58 @@
|
|
|
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 itertools::Itertools;
|
|
14
|
+
|
|
15
|
+
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
16
|
+
|
|
17
|
+
fn render_plugin(tag_name: impl AsRef<str>) -> String {
|
|
18
|
+
format!(
|
|
19
|
+
"import \"https://cdn.jsdelivr.net/npm/@perspective-dev/{0}@{1}/dist/cdn/{0}.js\";\n",
|
|
20
|
+
tag_name.as_ref(),
|
|
21
|
+
VERSION
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
pub fn render(data: &str, layout: &str, plugins: &[String]) -> String {
|
|
26
|
+
let stmts = plugins.iter().map(render_plugin);
|
|
27
|
+
let imports = Itertools::intersperse(stmts, " ".to_owned()).collect::<String>();
|
|
28
|
+
|
|
29
|
+
format!("
|
|
30
|
+
<!DOCTYPE html>
|
|
31
|
+
<html lang=\"en\">
|
|
32
|
+
<head>
|
|
33
|
+
<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no\"/>
|
|
34
|
+
<link rel=\"stylesheet\" crossorigin=\"anonymous\" href=\"https://cdn.jsdelivr.net/npm/@perspective-dev/viewer@{VERSION}/dist/css/themes.css\"/>
|
|
35
|
+
<script type=\"module\">
|
|
36
|
+
import perspective from \"https://cdn.jsdelivr.net/npm/@perspective-dev/client@{VERSION}/dist/cdn/perspective.js\";
|
|
37
|
+
import \"https://cdn.jsdelivr.net/npm/@perspective-dev/viewer@{VERSION}/dist/cdn/perspective-viewer.js\";
|
|
38
|
+
{imports}
|
|
39
|
+
const worker = await perspective.worker();
|
|
40
|
+
const binary_string = window.atob(window.data.textContent);
|
|
41
|
+
const len = binary_string.length;
|
|
42
|
+
const bytes = new Uint8Array(len);
|
|
43
|
+
for (let i = 0; i < len; i++) {{
|
|
44
|
+
bytes[i] = binary_string.charCodeAt(i);
|
|
45
|
+
}}
|
|
46
|
+
window.viewer.load(worker.table(bytes.buffer));
|
|
47
|
+
window.viewer.restore(JSON.parse(window.layout.textContent));
|
|
48
|
+
</script>
|
|
49
|
+
<style>perspective-viewer{{position:absolute;top:0;left:0;right:0;bottom:0}}</style>
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<script id='data' type=\"application/octet-stream\">{data}</script>
|
|
53
|
+
<script id='layout' type=\"application/json\">{layout}</script>
|
|
54
|
+
<perspective-viewer id='viewer'></perspective-viewer>
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
|
57
|
+
")
|
|
58
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
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::rc::Rc;
|
|
14
|
+
|
|
15
|
+
use serde::Deserialize;
|
|
16
|
+
use yew::prelude::*;
|
|
17
|
+
|
|
18
|
+
use crate::js::*;
|
|
19
|
+
|
|
20
|
+
#[derive(Clone, Copy, Eq, PartialEq, Deserialize)]
|
|
21
|
+
pub enum ExportMethod {
|
|
22
|
+
#[serde(rename = "csv")]
|
|
23
|
+
Csv,
|
|
24
|
+
|
|
25
|
+
#[serde(rename = "csv-all")]
|
|
26
|
+
CsvAll,
|
|
27
|
+
|
|
28
|
+
#[serde(rename = "csv-selected")]
|
|
29
|
+
CsvSelected,
|
|
30
|
+
|
|
31
|
+
#[serde(rename = "json")]
|
|
32
|
+
Json,
|
|
33
|
+
|
|
34
|
+
#[serde(rename = "json-all")]
|
|
35
|
+
JsonAll,
|
|
36
|
+
|
|
37
|
+
#[serde(rename = "json-selected")]
|
|
38
|
+
JsonSelected,
|
|
39
|
+
|
|
40
|
+
// #[serde(rename = "columns")]
|
|
41
|
+
// JsonColumns,
|
|
42
|
+
|
|
43
|
+
// #[serde(rename = "columns-all")]
|
|
44
|
+
// JsonColumnsAll,
|
|
45
|
+
|
|
46
|
+
// #[serde(rename = "columns-selected")]
|
|
47
|
+
// JsonColumnsSelected,
|
|
48
|
+
#[serde(rename = "ndjson")]
|
|
49
|
+
Ndjson,
|
|
50
|
+
|
|
51
|
+
#[serde(rename = "ndjson-all")]
|
|
52
|
+
NdjsonAll,
|
|
53
|
+
|
|
54
|
+
#[serde(rename = "ndjson-selected")]
|
|
55
|
+
NdjsonSelected,
|
|
56
|
+
|
|
57
|
+
#[serde(rename = "html")]
|
|
58
|
+
Html,
|
|
59
|
+
|
|
60
|
+
#[serde(rename = "plugin")]
|
|
61
|
+
Plugin,
|
|
62
|
+
|
|
63
|
+
#[serde(rename = "arrow")]
|
|
64
|
+
Arrow,
|
|
65
|
+
|
|
66
|
+
#[serde(rename = "arrow-selected")]
|
|
67
|
+
ArrowSelected,
|
|
68
|
+
|
|
69
|
+
#[serde(rename = "arrow-all")]
|
|
70
|
+
ArrowAll,
|
|
71
|
+
|
|
72
|
+
#[serde(rename = "json-config")]
|
|
73
|
+
JsonConfig,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
impl ExportMethod {
|
|
77
|
+
pub const fn as_filename(&self, is_chart: bool) -> &'static str {
|
|
78
|
+
match self {
|
|
79
|
+
Self::Csv => ".csv",
|
|
80
|
+
Self::CsvAll => ".all.csv",
|
|
81
|
+
Self::Json => ".json",
|
|
82
|
+
Self::JsonAll => ".all.json",
|
|
83
|
+
Self::Html => ".html",
|
|
84
|
+
Self::Plugin => {
|
|
85
|
+
if is_chart {
|
|
86
|
+
".png"
|
|
87
|
+
} else {
|
|
88
|
+
".txt"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
Self::Arrow => ".arrow",
|
|
92
|
+
Self::ArrowAll => ".all.arrow",
|
|
93
|
+
Self::JsonConfig => ".config.json",
|
|
94
|
+
Self::CsvSelected => ".selected.csv",
|
|
95
|
+
Self::JsonSelected => ".selected.json",
|
|
96
|
+
Self::ArrowSelected => ".selected.arrow",
|
|
97
|
+
Self::Ndjson => ".ndjson",
|
|
98
|
+
Self::NdjsonAll => ".all.ndjson",
|
|
99
|
+
Self::NdjsonSelected => ".selected.ndjson",
|
|
100
|
+
// Self::JsonColumns => ".columns.json",
|
|
101
|
+
// Self::JsonColumnsAll => ".all.columns.json",
|
|
102
|
+
// Self::JsonColumnsSelected => ".selected.columns.json",
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
pub const fn mimetype(&self, is_chart: bool) -> MimeType {
|
|
107
|
+
match self {
|
|
108
|
+
Self::Plugin if is_chart => MimeType::ImagePng,
|
|
109
|
+
_ => MimeType::TextPlain,
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
pub fn to_html(&self, is_chart: bool) -> Html {
|
|
114
|
+
html! { <code>{ self.as_filename(is_chart) }</code> }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
impl ExportMethod {
|
|
119
|
+
pub fn new_file(&self, x: &str, is_chart: bool) -> ExportFile {
|
|
120
|
+
ExportFile {
|
|
121
|
+
name: Rc::new(x.to_owned()),
|
|
122
|
+
method: *self,
|
|
123
|
+
is_chart,
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#[derive(Clone, Eq, PartialEq)]
|
|
129
|
+
pub struct ExportFile {
|
|
130
|
+
pub name: Rc<String>,
|
|
131
|
+
pub method: ExportMethod,
|
|
132
|
+
pub is_chart: bool,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
impl ExportFile {
|
|
136
|
+
pub fn as_filename(&self, is_chart: bool) -> String {
|
|
137
|
+
format!("{}{}", self.name, self.method.as_filename(is_chart))
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
impl From<ExportFile> for Html {
|
|
142
|
+
fn from(x: ExportFile) -> Self {
|
|
143
|
+
let class = if x.name.is_empty() {
|
|
144
|
+
Some("invalid")
|
|
145
|
+
} else {
|
|
146
|
+
None
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
html! { <code {class}>{ x.name }{ x.method.as_filename(x.is_chart) }</code> }
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
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::ViewConfig;
|
|
14
|
+
|
|
15
|
+
use super::columns_iter_set::*;
|
|
16
|
+
use super::structural::*;
|
|
17
|
+
use crate::config::*;
|
|
18
|
+
use crate::presentation::Presentation;
|
|
19
|
+
use crate::renderer::*;
|
|
20
|
+
use crate::session::*;
|
|
21
|
+
use crate::*;
|
|
22
|
+
|
|
23
|
+
/// A `ViewerConfig` is constructed from various properties acrosss the
|
|
24
|
+
/// application state
|
|
25
|
+
///
|
|
26
|
+
/// For example, the current `Plugin`, `ViewConfig`, and `Theme`.
|
|
27
|
+
/// `GetViewerConfigModel` provides methods which should be used to get the
|
|
28
|
+
/// applications `ViewerConfig` from across these state objects.
|
|
29
|
+
pub trait GetViewerConfigModel: HasSession + HasRenderer + HasPresentation {
|
|
30
|
+
/// As these methods are asynchronous, it is commonly useful to be able to
|
|
31
|
+
/// discretely `.clone()` the state objects for dispatching to `async`.
|
|
32
|
+
///
|
|
33
|
+
/// Calling `.cloned()` yields just the state object clones of
|
|
34
|
+
/// `GetViewerConfigModel` which itself implements this trait and other
|
|
35
|
+
/// `crate::model` traits.
|
|
36
|
+
fn cloned(&self) -> GetViewerConfigModelCloned {
|
|
37
|
+
GetViewerConfigModelCloned {
|
|
38
|
+
renderer: self.renderer().clone(),
|
|
39
|
+
session: self.session().clone(),
|
|
40
|
+
presentation: self.presentation().clone(),
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// Get the current ViewerConfig
|
|
45
|
+
async fn get_viewer_config(&self) -> ApiResult<ViewerConfig> {
|
|
46
|
+
let version = config::API_VERSION.to_string();
|
|
47
|
+
let view_config = self.session().get_view_config().clone();
|
|
48
|
+
let js_plugin = self.renderer().get_active_plugin()?;
|
|
49
|
+
let settings = self.presentation().is_settings_open();
|
|
50
|
+
let plugin = js_plugin.name();
|
|
51
|
+
let plugin_config: serde_json::Value = js_plugin.save()?.into_serde_ext()?;
|
|
52
|
+
let theme = self.presentation().get_selected_theme_name().await;
|
|
53
|
+
let title = self.presentation().get_title();
|
|
54
|
+
let columns_config = self.presentation().all_columns_configs();
|
|
55
|
+
Ok(ViewerConfig {
|
|
56
|
+
version,
|
|
57
|
+
plugin,
|
|
58
|
+
title,
|
|
59
|
+
plugin_config,
|
|
60
|
+
columns_config,
|
|
61
|
+
settings,
|
|
62
|
+
view_config,
|
|
63
|
+
theme,
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
impl<T: HasRenderer + HasSession + HasPresentation> GetViewerConfigModel for T {}
|
|
69
|
+
|
|
70
|
+
#[derive(Clone)]
|
|
71
|
+
pub struct GetViewerConfigModelCloned {
|
|
72
|
+
renderer: Renderer,
|
|
73
|
+
session: Session,
|
|
74
|
+
presentation: Presentation,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
derive_model!(Renderer, Session, Presentation for GetViewerConfigModelCloned);
|
|
78
|
+
|
|
79
|
+
pub trait ColumnIteratorModel: HasSession + HasRenderer + HasDragDrop {
|
|
80
|
+
fn column_selector_iter_set<'a>(&'a self, config: &'a ViewConfig) -> ColumnsIteratorSet<'a> {
|
|
81
|
+
ColumnsIteratorSet::new(config, self.session(), self.renderer(), self.dragdrop())
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
impl<T: HasSession + HasRenderer + HasDragDrop> ColumnIteratorModel for T {}
|
|
@@ -0,0 +1,81 @@
|
|
|
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::ViewConfigUpdate;
|
|
14
|
+
use wasm_bindgen::JsCast;
|
|
15
|
+
use wasm_bindgen::prelude::*;
|
|
16
|
+
use web_sys::*;
|
|
17
|
+
|
|
18
|
+
use crate::js::*;
|
|
19
|
+
use crate::model::*;
|
|
20
|
+
use crate::renderer::*;
|
|
21
|
+
use crate::session::Session;
|
|
22
|
+
use crate::utils::*;
|
|
23
|
+
use crate::*;
|
|
24
|
+
|
|
25
|
+
pub struct IntersectionObserverHandle {
|
|
26
|
+
elem: HtmlElement,
|
|
27
|
+
observer: IntersectionObserver,
|
|
28
|
+
_callback: Closure<dyn FnMut(js_sys::Array)>,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
impl IntersectionObserverHandle {
|
|
32
|
+
pub fn new(elem: &HtmlElement, session: &Session, renderer: &Renderer) -> Self {
|
|
33
|
+
clone!(session, renderer);
|
|
34
|
+
let _callback = Closure::new(move |xs: js_sys::Array| {
|
|
35
|
+
let intersect = xs
|
|
36
|
+
.get(0)
|
|
37
|
+
.unchecked_into::<IntersectionObserverEntry>()
|
|
38
|
+
.is_intersecting();
|
|
39
|
+
|
|
40
|
+
clone!(session, renderer);
|
|
41
|
+
let state = IntersectionObserverState { session, renderer };
|
|
42
|
+
ApiFuture::spawn(state.set_pause(intersect));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
let func = _callback.as_ref().unchecked_ref::<js_sys::Function>();
|
|
46
|
+
let observer = IntersectionObserver::new(func);
|
|
47
|
+
observer.observe(elem);
|
|
48
|
+
Self {
|
|
49
|
+
elem: elem.clone(),
|
|
50
|
+
_callback,
|
|
51
|
+
observer,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
impl Drop for IntersectionObserverHandle {
|
|
57
|
+
fn drop(&mut self) {
|
|
58
|
+
self.observer.unobserve(&self.elem);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
struct IntersectionObserverState {
|
|
63
|
+
session: Session,
|
|
64
|
+
renderer: Renderer,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
impl IntersectionObserverState {
|
|
68
|
+
async fn set_pause(self, intersect: bool) -> ApiResult<()> {
|
|
69
|
+
if intersect {
|
|
70
|
+
if self.session.set_pause(false) {
|
|
71
|
+
self.update_and_render(ViewConfigUpdate::default())?.await?;
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
self.session.set_pause(true);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
Ok(())
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
derive_model!(Renderer, Session for IntersectionObserverState);
|
|
@@ -0,0 +1,36 @@
|
|
|
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 {}
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
//! Here lies Perspective's attempt to avoid a monolithic Application State
|
|
14
|
+
//! object. The major components which hold `PerspectiveViewer`-scoped state
|
|
15
|
+
//! are broken up roughly by some single resource responsibility -
|
|
16
|
+
//!
|
|
17
|
+
//! - `Session` manages the `@perspective-dev/client` engine `Table` and `View`
|
|
18
|
+
//! objects, plus caches some related metadata `Schema`.
|
|
19
|
+
//! - `Renderer` manages the JavaScript Custom Element plugin.
|
|
20
|
+
//! - .. etc.
|
|
21
|
+
//!
|
|
22
|
+
//! For complex tasks which involve overlapping state/coordination between >1 of
|
|
23
|
+
//! these Application State objects, Perspective uses a set of respective `Has*`
|
|
24
|
+
//! traits, (e.g. `HasSession`), to provide extra functions for object which
|
|
25
|
+
//! implement more than one such trait. These can be conveniently derived by
|
|
26
|
+
//! consistently naming the application state object clones when used as struct
|
|
27
|
+
//! fields, then applying the `derive_model!()` macro for the state object you
|
|
28
|
+
//! wish to expose.
|
|
29
|
+
//!
|
|
30
|
+
//! # Examples
|
|
31
|
+
//!
|
|
32
|
+
//! ```rust
|
|
33
|
+
//! struct A {
|
|
34
|
+
//! session: Session,
|
|
35
|
+
//! }
|
|
36
|
+
//!
|
|
37
|
+
//! struct B {
|
|
38
|
+
//! renderer: Renderer,
|
|
39
|
+
//! }
|
|
40
|
+
//!
|
|
41
|
+
//! struct C {
|
|
42
|
+
//! session: Session,
|
|
43
|
+
//! renderer: Renderer,
|
|
44
|
+
//! }
|
|
45
|
+
//!
|
|
46
|
+
//! derive_model!(Session for A);
|
|
47
|
+
//! derive_model!(Renderer for B);
|
|
48
|
+
//! derive_model!(Session, Renderer for C);
|
|
49
|
+
//!
|
|
50
|
+
//! trait SessionRenderModel: HasSession + HasRenderer {
|
|
51
|
+
//! fn render_session_now(&self) {
|
|
52
|
+
//! // Do some thing that requires `.session()` and `.renderer()`
|
|
53
|
+
//! }
|
|
54
|
+
//! }
|
|
55
|
+
//!
|
|
56
|
+
//! impl<T: HasSession + HasRenderer> SessionRenderModel for T {}
|
|
57
|
+
//!
|
|
58
|
+
//! fn test(session: Session, renderer: Renderer) {
|
|
59
|
+
//! // Type errors
|
|
60
|
+
//! (A { session }).render_session_now();
|
|
61
|
+
//! (B { renderer }).render_session_now();
|
|
62
|
+
//!
|
|
63
|
+
//! // The method exists only when both state object clones exist
|
|
64
|
+
//! (C { session, renderer }).render_session_now();
|
|
65
|
+
//! }
|
|
66
|
+
//! ```
|
|
67
|
+
|
|
68
|
+
mod columns_iter_set;
|
|
69
|
+
mod copy_export;
|
|
70
|
+
mod edit_expression;
|
|
71
|
+
mod export_app;
|
|
72
|
+
mod export_method;
|
|
73
|
+
mod get_viewer_config;
|
|
74
|
+
mod intersection_observer;
|
|
75
|
+
mod is_invalid_drop;
|
|
76
|
+
mod plugin_column_styles;
|
|
77
|
+
mod resize_observer;
|
|
78
|
+
mod restore_and_render;
|
|
79
|
+
mod structural;
|
|
80
|
+
mod update_and_render;
|
|
81
|
+
|
|
82
|
+
pub use self::columns_iter_set::*;
|
|
83
|
+
pub use self::copy_export::*;
|
|
84
|
+
pub use self::edit_expression::*;
|
|
85
|
+
pub use self::export_method::*;
|
|
86
|
+
pub use self::get_viewer_config::*;
|
|
87
|
+
pub use self::intersection_observer::*;
|
|
88
|
+
pub use self::is_invalid_drop::*;
|
|
89
|
+
pub use self::plugin_column_styles::*;
|
|
90
|
+
pub use self::resize_observer::*;
|
|
91
|
+
pub use self::restore_and_render::*;
|
|
92
|
+
pub use self::structural::*;
|
|
93
|
+
pub use self::update_and_render::*;
|
|
@@ -0,0 +1,106 @@
|
|
|
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 itertools::Itertools;
|
|
14
|
+
use perspective_js::utils::ApiResult;
|
|
15
|
+
|
|
16
|
+
use super::{HasRenderer, HasSession};
|
|
17
|
+
use crate::config::ColumnStyleOpts;
|
|
18
|
+
use crate::derive_model;
|
|
19
|
+
use crate::renderer::Renderer;
|
|
20
|
+
use crate::session::Session;
|
|
21
|
+
|
|
22
|
+
// TODO: This pattern of creating query objects to pass around would be
|
|
23
|
+
// redundant if we had a grab-bag of models to clone around.
|
|
24
|
+
// We could easily generate all the needed types for this in a proc_macro
|
|
25
|
+
// crate. e.g. create structs like `SessionAndRendererModel {session,
|
|
26
|
+
// renderer}` which are then called through a proc_macro like
|
|
27
|
+
// `get_model!(Session, Renderer for self)` where the function is defined as
|
|
28
|
+
// `get_model! => {($($name:ty),+ for $owner:ident)}`
|
|
29
|
+
//
|
|
30
|
+
// Or, we could just lump
|
|
31
|
+
// all the state into a single object where all these model functions are
|
|
32
|
+
// defined. Generally, we could keep the hub-and-spoke architecture "under the
|
|
33
|
+
// hood", but just not expose it to the yew framework, since it requires a lot
|
|
34
|
+
// of unecessary prop-drilling and complexity.
|
|
35
|
+
|
|
36
|
+
#[derive(Clone)]
|
|
37
|
+
pub struct PluginColumnStylesQuery {
|
|
38
|
+
session: Session,
|
|
39
|
+
renderer: Renderer,
|
|
40
|
+
}
|
|
41
|
+
derive_model!(Session, Renderer for PluginColumnStylesQuery);
|
|
42
|
+
|
|
43
|
+
pub trait PluginColumnStyles: HasSession + HasRenderer {
|
|
44
|
+
fn get_plugin_column_styles_query(&self) -> PluginColumnStylesQuery {
|
|
45
|
+
PluginColumnStylesQuery {
|
|
46
|
+
session: self.session().clone(),
|
|
47
|
+
renderer: self.renderer().clone(),
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// This function will query the plugin to see if a given column can render
|
|
52
|
+
/// column styles.
|
|
53
|
+
fn can_render_column_styles(&self, column_name: &str) -> ApiResult<bool> {
|
|
54
|
+
let plugin = self.renderer().get_active_plugin()?;
|
|
55
|
+
let names: Vec<String> = plugin
|
|
56
|
+
.config_column_names()
|
|
57
|
+
.and_then(|jsarr| serde_wasm_bindgen::from_value(jsarr.into()).ok())
|
|
58
|
+
.unwrap_or_default();
|
|
59
|
+
|
|
60
|
+
let group = self
|
|
61
|
+
.session()
|
|
62
|
+
.get_view_config()
|
|
63
|
+
.columns
|
|
64
|
+
.iter()
|
|
65
|
+
.find_position(|maybe_s| maybe_s.as_deref() == Some(column_name))
|
|
66
|
+
.and_then(|(idx, _)| names.get(idx))
|
|
67
|
+
.map(|s| s.as_str());
|
|
68
|
+
|
|
69
|
+
let view_type = self
|
|
70
|
+
.session()
|
|
71
|
+
.metadata()
|
|
72
|
+
.get_column_view_type(column_name)
|
|
73
|
+
.ok_or("Invalid column")?;
|
|
74
|
+
|
|
75
|
+
plugin.can_render_column_styles(&view_type.to_string(), group)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// Queries the plugins for the available plugin components.
|
|
79
|
+
fn get_column_style_control_options(&self, column_name: &str) -> ApiResult<ColumnStyleOpts> {
|
|
80
|
+
let plugin = self.renderer().get_active_plugin()?;
|
|
81
|
+
let names: Vec<String> = plugin
|
|
82
|
+
.config_column_names()
|
|
83
|
+
.and_then(|jsarr| serde_wasm_bindgen::from_value(jsarr.into()).ok())
|
|
84
|
+
.unwrap_or_default();
|
|
85
|
+
|
|
86
|
+
let group = self
|
|
87
|
+
.session()
|
|
88
|
+
.get_view_config()
|
|
89
|
+
.columns
|
|
90
|
+
.iter()
|
|
91
|
+
.find_position(|maybe_s| maybe_s.as_deref() == Some(column_name))
|
|
92
|
+
.and_then(|(idx, _)| names.get(idx))
|
|
93
|
+
.map(|s| s.as_str());
|
|
94
|
+
|
|
95
|
+
let view_type = self
|
|
96
|
+
.session()
|
|
97
|
+
.metadata()
|
|
98
|
+
.get_column_view_type(column_name)
|
|
99
|
+
.ok_or("Invalid column")?;
|
|
100
|
+
|
|
101
|
+
let controls = plugin.column_style_controls(&view_type.to_string(), group)?;
|
|
102
|
+
serde_wasm_bindgen::from_value(controls).map_err(|e| e.into())
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
impl<T: HasSession + HasRenderer> PluginColumnStyles for T {}
|