* save modal UI and Redirect and save to library Co-authored-by: Poff Poffenberger <poffdeluxe@gmail.com> # Conflicts: # .github/CODEOWNERS
This commit is contained in:
parent
8b22bd10b3
commit
52e0a43e21
374
.github/CODEOWNERS
vendored
Normal file
374
.github/CODEOWNERS
vendored
Normal file
|
@ -0,0 +1,374 @@
|
|||
# GitHub CODEOWNERS definition
|
||||
# Identify which groups will be pinged by changes to different parts of the codebase.
|
||||
# For more info, see https://help.github.com/articles/about-codeowners/
|
||||
|
||||
# The #CC# prefix delineates Code Coverage,
|
||||
# used for the 'team' designator within Kibana Stats
|
||||
|
||||
# App
|
||||
/x-pack/plugins/discover_enhanced/ @elastic/kibana-app
|
||||
/x-pack/plugins/lens/ @elastic/kibana-app
|
||||
/x-pack/plugins/graph/ @elastic/kibana-app
|
||||
/src/plugins/advanced_settings/ @elastic/kibana-app
|
||||
/src/plugins/charts/ @elastic/kibana-app
|
||||
/src/plugins/discover/ @elastic/kibana-app
|
||||
/src/plugins/management/ @elastic/kibana-app
|
||||
/src/plugins/kibana_legacy/ @elastic/kibana-app
|
||||
/src/plugins/timelion/ @elastic/kibana-app
|
||||
/src/plugins/vis_default_editor/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_metric/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_table/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_tagcloud/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_timelion/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_timeseries/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_vega/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_vislib/ @elastic/kibana-app
|
||||
/src/plugins/vis_type_xy/ @elastic/kibana-app
|
||||
/src/plugins/visualize/ @elastic/kibana-app
|
||||
/src/plugins/visualizations/ @elastic/kibana-app
|
||||
/packages/kbn-tinymath/ @elastic/kibana-app
|
||||
|
||||
# Application Services
|
||||
/examples/bfetch_explorer/ @elastic/kibana-app-services
|
||||
/examples/dashboard_embeddable_examples/ @elastic/kibana-app-services
|
||||
/examples/demo_search/ @elastic/kibana-app-services
|
||||
/examples/developer_examples/ @elastic/kibana-app-services
|
||||
/examples/embeddable_examples/ @elastic/kibana-app-services
|
||||
/examples/embeddable_explorer/ @elastic/kibana-app-services
|
||||
/examples/state_containers_examples/ @elastic/kibana-app-services
|
||||
/examples/ui_action_examples/ @elastic/kibana-app-services
|
||||
/examples/ui_actions_explorer/ @elastic/kibana-app-services
|
||||
/examples/url_generators_examples/ @elastic/kibana-app-services
|
||||
/examples/url_generators_explorer/ @elastic/kibana-app-services
|
||||
/packages/elastic-datemath/ @elastic/kibana-app-services
|
||||
/packages/kbn-interpreter/ @elastic/kibana-app-services
|
||||
/src/plugins/bfetch/ @elastic/kibana-app-services
|
||||
/src/plugins/data/ @elastic/kibana-app-services
|
||||
/src/plugins/embeddable/ @elastic/kibana-app-services
|
||||
/src/plugins/expressions/ @elastic/kibana-app-services
|
||||
/src/plugins/inspector/ @elastic/kibana-app-services
|
||||
/src/plugins/kibana_react/ @elastic/kibana-app-services
|
||||
/src/plugins/kibana_react/public/code_editor @elastic/kibana-presentation
|
||||
/src/plugins/kibana_utils/ @elastic/kibana-app-services
|
||||
/src/plugins/navigation/ @elastic/kibana-app-services
|
||||
/src/plugins/share/ @elastic/kibana-app-services
|
||||
/src/plugins/ui_actions/ @elastic/kibana-app-services
|
||||
/x-pack/examples/ui_actions_enhanced_examples/ @elastic/kibana-app-services
|
||||
/x-pack/plugins/data_enhanced/ @elastic/kibana-app-services
|
||||
/x-pack/plugins/embeddable_enhanced/ @elastic/kibana-app-services
|
||||
/x-pack/plugins/ui_actions_enhanced/ @elastic/kibana-app-services
|
||||
/x-pack/plugins/runtime_fields @elastic/kibana-app-services
|
||||
#CC# /src/plugins/bfetch/ @elastic/kibana-app-services
|
||||
#CC# /src/plugins/index_pattern_management/ @elastic/kibana-app-services
|
||||
#CC# /src/plugins/inspector/ @elastic/kibana-app-services
|
||||
#CC# /src/plugins/share/ @elastic/kibana-app-services
|
||||
#CC# /x-pack/plugins/drilldowns/ @elastic/kibana-app-services
|
||||
#CC# /packages/kbn-interpreter/ @elastic/kibana-app-services
|
||||
|
||||
# APM
|
||||
/x-pack/plugins/apm/ @elastic/apm-ui
|
||||
/x-pack/test/functional/apps/apm/ @elastic/apm-ui
|
||||
/x-pack/test/apm_api_integration/ @elastic/apm-ui
|
||||
/src/plugins/apm_oss/ @elastic/apm-ui
|
||||
/src/apm.js @elastic/kibana-core @vigneshshanmugam
|
||||
/packages/kbn-apm-config-loader/ @elastic/kibana-core @vigneshshanmugam
|
||||
#CC# /src/plugins/apm_oss/ @elastic/apm-ui
|
||||
#CC# /x-pack/plugins/observability/ @elastic/apm-ui
|
||||
|
||||
# Uptime
|
||||
/x-pack/plugins/uptime @elastic/uptime
|
||||
/x-pack/test/functional_with_es_ssl/apps/uptime @elastic/uptime
|
||||
/x-pack/test/functional/apps/uptime @elastic/uptime
|
||||
/x-pack/test/api_integration/apis/uptime @elastic/uptime
|
||||
|
||||
# Client Side Monitoring / Uptime (lives in APM directories but owned by Uptime)
|
||||
/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm @elastic/uptime
|
||||
/x-pack/plugins/apm/e2e/cypress/integration/csm_dashboard.feature @elastic/uptime
|
||||
/x-pack/plugins/apm/public/application/csmApp.tsx @elastic/uptime
|
||||
/x-pack/plugins/apm/public/components/app/RumDashboard @elastic/uptime
|
||||
/x-pack/plugins/apm/server/lib/rum_client @elastic/uptime
|
||||
/x-pack/plugins/apm/server/routes/rum_client.ts @elastic/uptime
|
||||
/x-pack/plugins/apm/server/projections/rum_page_load_transactions.ts @elastic/uptime
|
||||
/x-pack/test/apm_api_integration/tests/csm/ @elastic/uptime
|
||||
|
||||
# Beats
|
||||
/x-pack/plugins/beats_management/ @elastic/beats
|
||||
#CC# /x-pack/plugins/beats_management/ @elastic/beats
|
||||
|
||||
# Presentation
|
||||
/src/plugins/dashboard/ @elastic/kibana-presentation
|
||||
/src/plugins/input_control_vis/ @elastic/kibana-presentation
|
||||
/src/plugins/vis_type_markdown/ @elastic/kibana-presentation
|
||||
/src/plugins/presentation_util/ @elastic/kibana-presentation
|
||||
/test/functional/apps/dashboard/ @elastic/kibana-presentation
|
||||
/x-pack/plugins/canvas/ @elastic/kibana-presentation
|
||||
/x-pack/plugins/dashboard_enhanced/ @elastic/kibana-presentation
|
||||
/x-pack/test/functional/apps/canvas/ @elastic/kibana-presentation
|
||||
#CC# /src/plugins/kibana_react/public/code_editor/ @elastic/kibana-presentation
|
||||
#CC# /x-pack/legacy/plugins/canvas/ @elastic/kibana-presentation
|
||||
#CC# /x-pack/plugins/dashboard_mode @elastic/kibana-presentation
|
||||
|
||||
|
||||
# Observability UIs
|
||||
/x-pack/plugins/infra/ @elastic/logs-metrics-ui
|
||||
/x-pack/plugins/fleet/ @elastic/fleet
|
||||
/x-pack/plugins/observability/ @elastic/observability-ui
|
||||
/x-pack/plugins/monitoring/ @elastic/stack-monitoring-ui
|
||||
|
||||
# Machine Learning
|
||||
/x-pack/plugins/ml/ @elastic/ml-ui
|
||||
/x-pack/test/functional/apps/ml/ @elastic/ml-ui
|
||||
/x-pack/test/functional/services/ml/ @elastic/ml-ui
|
||||
/x-pack/test/accessibility/apps/ml.ts @elastic/ml-ui
|
||||
# ML team owns and maintains the transform plugin despite it living in the Elasticsearch management section.
|
||||
/x-pack/plugins/transform/ @elastic/ml-ui
|
||||
/x-pack/test/functional/apps/transform/ @elastic/ml-ui
|
||||
/x-pack/test/functional/services/transform/ @elastic/ml-ui
|
||||
/x-pack/test/accessibility/apps/transform.ts @elastic/ml-ui
|
||||
/x-pack/test/api_integration_basic/apis/ml/ @elastic/ml-ui
|
||||
/x-pack/test/functional_basic/apps/ml/ @elastic/ml-ui
|
||||
|
||||
/x-pack/test/api_integration_basic/apis/transform/ @elastic/ml-ui
|
||||
/x-pack/test/functional_basic/apps/transform/ @elastic/ml-ui
|
||||
|
||||
# Maps
|
||||
#CC# /x-pack/plugins/maps/ @elastic/kibana-gis
|
||||
/x-pack/test/api_integration/apis/maps/ @elastic/kibana-gis
|
||||
/x-pack/test/functional/apps/maps/ @elastic/kibana-gis
|
||||
/x-pack/test/functional/es_archives/maps/ @elastic/kibana-gis
|
||||
/x-pack/test/visual_regression/tests/maps/index.js @elastic/kibana-gis
|
||||
#CC# /src/plugins/maps_legacy/ @elastic/kibana-gis
|
||||
#CC# /x-pack/plugins/file_upload @elastic/kibana-gis
|
||||
#CC# /x-pack/plugins/maps_legacy_licensing @elastic/kibana-gis
|
||||
/src/plugins/tile_map/ @elastic/kibana-gis
|
||||
/src/plugins/region_map/ @elastic/kibana-gis
|
||||
|
||||
# Operations
|
||||
/src/dev/ @elastic/kibana-operations
|
||||
/src/setup_node_env/ @elastic/kibana-operations
|
||||
/packages/*eslint*/ @elastic/kibana-operations
|
||||
/packages/*babel*/ @elastic/kibana-operations
|
||||
/packages/kbn-dev-utils*/ @elastic/kibana-operations
|
||||
/packages/kbn-es/ @elastic/kibana-operations
|
||||
/packages/kbn-optimizer/ @elastic/kibana-operations
|
||||
/packages/kbn-pm/ @elastic/kibana-operations
|
||||
/packages/kbn-test/ @elastic/kibana-operations
|
||||
/packages/kbn-ui-shared-deps/ @elastic/kibana-operations
|
||||
/packages/kbn-es-archiver/ @elastic/kibana-operations
|
||||
/packages/kbn-utils/ @elastic/kibana-operations
|
||||
/src/cli/keystore/ @elastic/kibana-operations
|
||||
/src/legacy/server/warnings/ @elastic/kibana-operations
|
||||
/.ci/es-snapshots/ @elastic/kibana-operations
|
||||
/.github/workflows/ @elastic/kibana-operations
|
||||
/vars/ @elastic/kibana-operations
|
||||
/.bazelignore @elastic/kibana-operations
|
||||
/.bazeliskversion @elastic/kibana-operations
|
||||
/.bazelrc @elastic/kibana-operations
|
||||
/.bazelrc.common @elastic/kibana-operations
|
||||
/.bazelversion @elastic/kibana-operations
|
||||
/WORKSPACE.bazel @elastic/kibana-operations
|
||||
#CC# /packages/kbn-expect/ @elastic/kibana-operations
|
||||
|
||||
# Quality Assurance
|
||||
/src/dev/code_coverage @elastic/kibana-qa
|
||||
/vars/*Coverage.groovy @elastic/kibana-qa
|
||||
/test/functional/services/common @elastic/kibana-qa
|
||||
/test/functional/services/lib @elastic/kibana-qa
|
||||
/test/functional/services/remote @elastic/kibana-qa
|
||||
|
||||
# Core
|
||||
/src/core/ @elastic/kibana-core
|
||||
/src/plugins/saved_objects_tagging_oss @elastic/kibana-core
|
||||
/config/kibana.yml @elastic/kibana-core
|
||||
/x-pack/plugins/features/ @elastic/kibana-core
|
||||
/x-pack/plugins/licensing/ @elastic/kibana-core
|
||||
/x-pack/plugins/global_search/ @elastic/kibana-core
|
||||
/x-pack/plugins/cloud/ @elastic/kibana-core
|
||||
/x-pack/plugins/saved_objects_tagging/ @elastic/kibana-core
|
||||
/x-pack/test/saved_objects_field_count/ @elastic/kibana-core
|
||||
/x-pack/test/saved_object_tagging/ @elastic/kibana-core
|
||||
/packages/kbn-config-schema/ @elastic/kibana-core
|
||||
/packages/kbn-std/ @elastic/kibana-core
|
||||
/packages/kbn-config/ @elastic/kibana-core
|
||||
/packages/kbn-logging/ @elastic/kibana-core
|
||||
/packages/kbn-legacy-logging/ @elastic/kibana-core
|
||||
/src/legacy/server/config/ @elastic/kibana-core
|
||||
/src/legacy/server/http/ @elastic/kibana-core
|
||||
/src/legacy/server/logging/ @elastic/kibana-core
|
||||
/src/plugins/status_page/ @elastic/kibana-core
|
||||
/src/plugins/saved_objects_management/ @elastic/kibana-core
|
||||
/src/dev/run_check_published_api_changes.ts @elastic/kibana-core
|
||||
/src/plugins/home/public @elastic/kibana-core
|
||||
/src/plugins/home/server/*.ts @elastic/kibana-core
|
||||
/src/plugins/home/server/services/ @elastic/kibana-core
|
||||
/src/plugins/kibana_overview/ @elastic/kibana-core
|
||||
/x-pack/plugins/global_search_bar/ @elastic/kibana-core
|
||||
#CC# /src/core/server/csp/ @elastic/kibana-core
|
||||
#CC# /src/legacy/server/config/ @elastic/kibana-core
|
||||
#CC# /src/legacy/server/http/ @elastic/kibana-core
|
||||
#CC# /src/legacy/ui/public/documentation_links @elastic/kibana-core
|
||||
#CC# /src/plugins/legacy_export/ @elastic/kibana-core
|
||||
#CC# /src/plugins/xpack_legacy/ @elastic/kibana-core
|
||||
#CC# /src/plugins/saved_objects/ @elastic/kibana-core
|
||||
#CC# /src/plugins/status_page/ @elastic/kibana-core
|
||||
#CC# /x-pack/plugins/cloud/ @elastic/kibana-core
|
||||
#CC# /x-pack/plugins/features/ @elastic/kibana-core
|
||||
#CC# /x-pack/plugins/global_search/ @elastic/kibana-core
|
||||
#CC# /src/plugins/newsfeed @elastic/kibana-core
|
||||
#CC# /src/plugins/home/public @elastic/kibana-core
|
||||
#CC# /src/plugins/home/server/services/ @elastic/kibana-core
|
||||
#CC# /src/plugins/home/ @elastic/kibana-core
|
||||
#CC# /x-pack/plugins/global_search_providers/ @elastic/kibana-core
|
||||
|
||||
# Kibana Telemetry
|
||||
/packages/kbn-analytics/ @elastic/kibana-core
|
||||
/packages/kbn-telemetry-tools/ @elastic/kibana-core
|
||||
/src/plugins/kibana_usage_collection/ @elastic/kibana-core
|
||||
/src/plugins/newsfeed/ @elastic/kibana-core
|
||||
/src/plugins/telemetry/ @elastic/kibana-core
|
||||
/src/plugins/telemetry_collection_manager/ @elastic/kibana-core
|
||||
/src/plugins/telemetry_management_section/ @elastic/kibana-core
|
||||
/src/plugins/usage_collection/ @elastic/kibana-core
|
||||
/x-pack/plugins/telemetry_collection_xpack/ @elastic/kibana-core
|
||||
/.telemetryrc.json @elastic/kibana-core
|
||||
/x-pack/.telemetryrc.json @elastic/kibana-core
|
||||
/src/plugins/telemetry/schema/ @elastic/kibana-core @elastic/kibana-telemetry
|
||||
/x-pack/plugins/telemetry_collection_xpack/schema/ @elastic/kibana-core @elastic/kibana-telemetry
|
||||
|
||||
# Kibana Localization
|
||||
/src/dev/i18n/ @elastic/kibana-localization @elastic/kibana-core
|
||||
/src/core/public/i18n/ @elastic/kibana-localization @elastic/kibana-core
|
||||
/packages/kbn-i18n/ @elastic/kibana-localization @elastic/kibana-core
|
||||
#CC# /x-pack/plugins/translations/ @elastic/kibana-localization @elastic/kibana-core
|
||||
|
||||
# Security
|
||||
/src/core/server/csp/ @elastic/kibana-security @elastic/kibana-core
|
||||
/src/plugins/security_oss/ @elastic/kibana-security
|
||||
/src/plugins/spaces_oss/ @elastic/kibana-security
|
||||
/test/security_functional/ @elastic/kibana-security
|
||||
/x-pack/plugins/spaces/ @elastic/kibana-security
|
||||
/x-pack/plugins/encrypted_saved_objects/ @elastic/kibana-security
|
||||
/x-pack/plugins/security/ @elastic/kibana-security
|
||||
/x-pack/test/api_integration/apis/security/ @elastic/kibana-security
|
||||
/x-pack/test/ui_capabilities/ @elastic/kibana-security
|
||||
/x-pack/test/encrypted_saved_objects_api_integration/ @elastic/kibana-security
|
||||
/x-pack/test/functional/apps/security/ @elastic/kibana-security
|
||||
/x-pack/test/security_api_integration/ @elastic/kibana-security
|
||||
/x-pack/test/security_functional/ @elastic/kibana-security
|
||||
/x-pack/test/spaces_api_integration/ @elastic/kibana-security
|
||||
/x-pack/test/saved_object_api_integration/ @elastic/kibana-security
|
||||
#CC# /x-pack/plugins/security/ @elastic/kibana-security
|
||||
|
||||
# Kibana Alerting Services
|
||||
/x-pack/plugins/alerting/ @elastic/kibana-alerting-services
|
||||
/x-pack/plugins/actions/ @elastic/kibana-alerting-services
|
||||
/x-pack/plugins/event_log/ @elastic/kibana-alerting-services
|
||||
/x-pack/plugins/task_manager/ @elastic/kibana-alerting-services
|
||||
/x-pack/test/alerting_api_integration/ @elastic/kibana-alerting-services
|
||||
/x-pack/test/plugin_api_integration/test_suites/task_manager/ @elastic/kibana-alerting-services
|
||||
/x-pack/plugins/triggers_actions_ui/ @elastic/kibana-alerting-services
|
||||
/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/ @elastic/kibana-alerting-services
|
||||
/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/ @elastic/kibana-alerting-services
|
||||
/docs/user/alerting/ @elastic/kibana-alerting-services
|
||||
/docs/management/alerting/ @elastic/kibana-alerting-services
|
||||
#CC# /x-pack/plugins/stack_alerts @elastic/kibana-alerting-services
|
||||
|
||||
# Enterprise Search
|
||||
# Shared
|
||||
/x-pack/plugins/enterprise_search/* @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/common/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/public/* @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/public/applications/* @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/public/applications/enterprise_search/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/public/applications/shared/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/public/applications/__mocks__/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/* @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/lib/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/__mocks__/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/collectors/lib/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/routes/enterprise_search/ @elastic/enterprise-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/ @elastic/enterprise-search-frontend
|
||||
/x-pack/test/functional_enterprise_search/ @elastic/enterprise-search-frontend
|
||||
# App Search
|
||||
/x-pack/plugins/enterprise_search/public/applications/app_search/ @elastic/app-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/routes/app_search/ @elastic/app-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/collectors/app_search/ @elastic/app-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/saved_objects/app_search/ @elastic/app-search-frontend
|
||||
# Workplace Search
|
||||
/x-pack/plugins/enterprise_search/public/applications/workplace_search/ @elastic/workplace-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/routes/workplace_search/ @elastic/workplace-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/collectors/workplace_search/ @elastic/workplace-search-frontend
|
||||
/x-pack/plugins/enterprise_search/server/saved_objects/workplace_search/ @elastic/workplace-search-frontend
|
||||
|
||||
# Elasticsearch UI
|
||||
/src/plugins/dev_tools/ @elastic/es-ui
|
||||
/src/plugins/console/ @elastic/es-ui
|
||||
/src/plugins/es_ui_shared/ @elastic/es-ui
|
||||
/x-pack/plugins/cross_cluster_replication/ @elastic/es-ui
|
||||
/x-pack/plugins/index_lifecycle_management/ @elastic/es-ui
|
||||
/x-pack/plugins/console_extensions/ @elastic/es-ui
|
||||
/x-pack/plugins/grokdebugger/ @elastic/es-ui
|
||||
/x-pack/plugins/index_management/ @elastic/es-ui
|
||||
/x-pack/plugins/license_management/ @elastic/es-ui
|
||||
/x-pack/plugins/painless_lab/ @elastic/es-ui
|
||||
/x-pack/plugins/remote_clusters/ @elastic/es-ui
|
||||
/x-pack/plugins/rollup/ @elastic/es-ui
|
||||
/x-pack/plugins/searchprofiler/ @elastic/es-ui
|
||||
/x-pack/plugins/snapshot_restore/ @elastic/es-ui
|
||||
/x-pack/plugins/upgrade_assistant/ @elastic/es-ui
|
||||
/x-pack/plugins/watcher/ @elastic/es-ui
|
||||
/x-pack/plugins/ingest_pipelines/ @elastic/es-ui
|
||||
/packages/kbn-ace/ @elastic/es-ui
|
||||
/packages/kbn-monaco/ @elastic/es-ui
|
||||
#CC# /x-pack/plugins/console_extensions/ @elastic/es-ui
|
||||
#CC# /x-pack/plugins/cross_cluster_replication/ @elastic/es-ui
|
||||
|
||||
# Security Solution
|
||||
/x-pack/test/endpoint_api_integration_no_ingest/ @elastic/security-solution
|
||||
/x-pack/test/security_solution_endpoint/ @elastic/security-solution
|
||||
/x-pack/test/functional/es_archives/endpoint/ @elastic/security-solution
|
||||
/x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/security-solution
|
||||
/x-pack/test/plugin_functional/test_suites/resolver/ @elastic/security-solution
|
||||
/x-pack/plugins/security_solution/ @elastic/security-solution
|
||||
/x-pack/test/detection_engine_api_integration @elastic/security-solution
|
||||
/x-pack/test/lists_api_integration @elastic/security-solution
|
||||
/x-pack/test/api_integration/apis/security_solution @elastic/security-solution
|
||||
#CC# /x-pack/plugins/security_solution/ @elastic/security-solution
|
||||
|
||||
# Security Solution sub teams
|
||||
/x-pack/plugins/case @elastic/security-threat-hunting
|
||||
/x-pack/test/case_api_integration @elastic/security-threat-hunting
|
||||
/x-pack/plugins/lists @elastic/security-detections-response
|
||||
|
||||
# Security Intelligence And Analytics
|
||||
/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules @elastic/security-intelligence-analytics
|
||||
|
||||
# Security Asset Management
|
||||
/x-pack/plugins/osquery @elastic/security-asset-management
|
||||
|
||||
# Design (at the bottom for specificity of SASS files)
|
||||
**/*.scss @elastic/kibana-design
|
||||
#CC# /packages/kbn-ui-framework/ @elastic/kibana-design
|
||||
|
||||
# Observability design
|
||||
/x-pack/plugins/apm/**/*.scss @elastic/observability-design
|
||||
/x-pack/plugins/infra/**/*.scss @elastic/observability-design
|
||||
/x-pack/plugins/fleet/**/*.scss @elastic/observability-design
|
||||
/x-pack/plugins/observability/**/*.scss @elastic/observability-design
|
||||
/x-pack/plugins/monitoring/**/*.scss @elastic/observability-design
|
||||
|
||||
# Ent. Search design
|
||||
/x-pack/plugins/enterprise_search/**/*.scss @elastic/ent-search-design
|
||||
|
||||
# Security design
|
||||
/x-pack/plugins/endpoint/**/*.scss @elastic/security-design
|
||||
/x-pack/plugins/security_solution/**/*.scss @elastic/security-design
|
||||
|
||||
# Logstash
|
||||
#CC# /x-pack/plugins/logstash/ @elastic/logstash
|
||||
|
||||
# Reporting
|
||||
#CC# /x-pack/plugins/reporting/ @elastic/kibana-reporting-services
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ export interface SaveModalDashboardProps {
|
|||
documentInfo: SaveModalDocumentInfo;
|
||||
objectType: string;
|
||||
onClose: () => void;
|
||||
onSave: (props: OnSaveProps & { dashboardId: string | null }) => void;
|
||||
onSave: (props: OnSaveProps & { dashboardId: string | null; addToLibrary: boolean }) => void;
|
||||
tagOptions?: React.ReactNode | ((state: SaveModalState) => React.ReactNode);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,9 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
const [dashboardOption, setDashboardOption] = useState<'new' | 'existing' | null>(
|
||||
documentId || disableDashboardOptions ? null : 'existing'
|
||||
);
|
||||
const [isAddToLibrarySelected, setAddToLibrary] = useState<boolean>(
|
||||
!initialCopyOnSave || disableDashboardOptions
|
||||
);
|
||||
const [selectedDashboard, setSelectedDashboard] = useState<{ id: string; name: string } | null>(
|
||||
null
|
||||
);
|
||||
|
@ -62,12 +65,13 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
onChange={(option) => {
|
||||
setDashboardOption(option);
|
||||
}}
|
||||
{...{ copyOnSave, documentId, dashboardOption }}
|
||||
{...{ copyOnSave, documentId, dashboardOption, setAddToLibrary, isAddToLibrarySelected }}
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
|
||||
const onCopyOnSaveChange = (newCopyOnSave: boolean) => {
|
||||
setAddToLibrary(true);
|
||||
setDashboardOption(null);
|
||||
setCopyOnSave(newCopyOnSave);
|
||||
};
|
||||
|
@ -85,7 +89,7 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
}
|
||||
}
|
||||
|
||||
props.onSave({ ...onSaveProps, dashboardId });
|
||||
props.onSave({ ...onSaveProps, dashboardId, addToLibrary: isAddToLibrarySelected });
|
||||
};
|
||||
|
||||
const saveLibraryLabel =
|
||||
|
@ -113,7 +117,7 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
onSave={onModalSave}
|
||||
title={documentInfo.title}
|
||||
showCopyOnSave={documentId ? true : false}
|
||||
options={dashboardOption === null ? tagOptions : undefined} // Show tags when not adding to dashboard
|
||||
options={isAddToLibrarySelected ? tagOptions : undefined} // Show tags when not adding to dashboard
|
||||
description={documentInfo.description}
|
||||
showDescription={true}
|
||||
{...{
|
||||
|
|
|
@ -44,6 +44,7 @@ export function Example({
|
|||
hasDocumentId: boolean;
|
||||
} & StorybookParams) {
|
||||
const [dashboardOption, setDashboardOption] = useState<'new' | 'existing' | null>('existing');
|
||||
const [isAddToLibrarySelected, setAddToLibrary] = useState(false);
|
||||
|
||||
return (
|
||||
<SaveModalDashboardSelector
|
||||
|
@ -52,6 +53,8 @@ export function Example({
|
|||
dashboardOption={dashboardOption}
|
||||
copyOnSave={copyOnSave}
|
||||
documentId={hasDocumentId ? 'abc' : undefined}
|
||||
isAddToLibrarySelected={isAddToLibrarySelected}
|
||||
setAddToLibrary={setAddToLibrary}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
EuiIconTip,
|
||||
EuiPanel,
|
||||
EuiSpacer,
|
||||
EuiCheckbox,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { DashboardPicker, DashboardPickerProps } from './dashboard_picker';
|
||||
|
@ -29,24 +30,105 @@ export interface SaveModalDashboardSelectorProps {
|
|||
copyOnSave: boolean;
|
||||
documentId?: string;
|
||||
onSelectDashboard: DashboardPickerProps['onChange'];
|
||||
|
||||
setAddToLibrary: (selected: boolean) => void;
|
||||
isAddToLibrarySelected: boolean;
|
||||
dashboardOption: 'new' | 'existing' | null;
|
||||
onChange: (dashboardOption: 'new' | 'existing' | null) => void;
|
||||
}
|
||||
|
||||
export function SaveModalDashboardSelector(props: SaveModalDashboardSelectorProps) {
|
||||
const { documentId, onSelectDashboard, dashboardOption, onChange, copyOnSave } = props;
|
||||
const {
|
||||
documentId,
|
||||
onSelectDashboard,
|
||||
setAddToLibrary,
|
||||
isAddToLibrarySelected,
|
||||
dashboardOption,
|
||||
onChange,
|
||||
copyOnSave,
|
||||
} = props;
|
||||
const isDisabled = !copyOnSave && !!documentId;
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFormRow
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="presentationUtil.saveModalDashboard.addToDashboardLabel"
|
||||
defaultMessage="Add to dashboard"
|
||||
/>
|
||||
}
|
||||
hasChildLabel={false}
|
||||
>
|
||||
<>
|
||||
<EuiPanel color="subdued" hasShadow={false} data-test-subj="add-to-dashboard-options">
|
||||
<div>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'existing'}
|
||||
id="existing-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.existingDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'Existing',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('existing')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<div className="savAddDashboard__searchDashboards">
|
||||
<DashboardPicker
|
||||
isDisabled={dashboardOption !== 'existing'}
|
||||
onChange={onSelectDashboard}
|
||||
/>
|
||||
</div>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'new'}
|
||||
id="new-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.newDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'New',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('new')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === null}
|
||||
id="add-to-library-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.noDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'None',
|
||||
}
|
||||
)}
|
||||
onChange={() => {
|
||||
setAddToLibrary(true);
|
||||
onChange(null);
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
</EuiPanel>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<FormattedMessage
|
||||
id="presentationUtil.saveModalDashboard.addToDashboardLabel"
|
||||
defaultMessage="Add to dashboard"
|
||||
<EuiFlexItem grow={false} data-test-subj="add-to-library-checkbox">
|
||||
<EuiCheckbox
|
||||
id="add-to-library-checkbox"
|
||||
label={i18n.translate('presentationUtil.saveModalDashboard.libraryOptionLabel', {
|
||||
defaultMessage: 'Add to library',
|
||||
})}
|
||||
checked={isAddToLibrarySelected}
|
||||
disabled={dashboardOption === null || isDisabled}
|
||||
onChange={(event) => setAddToLibrary(event.target.checked)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -55,67 +137,13 @@ export function SaveModalDashboardSelector(props: SaveModalDashboardSelectorProp
|
|||
content={
|
||||
<FormattedMessage
|
||||
id="presentationUtil.saveModalDashboard.dashboardInfoTooltip"
|
||||
defaultMessage="Items added to a dashboard will not appear in the library and must be edited from the dashboard."
|
||||
defaultMessage="items added to the Visualize Library are available to all dashboards. Edits to a library item appear everywhere it is used."
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
hasChildLabel={false}
|
||||
>
|
||||
<EuiPanel color="subdued" hasShadow={false} data-test-subj="add-to-dashboard-options">
|
||||
<div>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'existing'}
|
||||
id="existing-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.existingDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'Existing',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('existing')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<div className="savAddDashboard__searchDashboards">
|
||||
<DashboardPicker
|
||||
isDisabled={dashboardOption !== 'existing'}
|
||||
onChange={onSelectDashboard}
|
||||
/>
|
||||
</div>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'new'}
|
||||
id="new-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.newDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'New',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('new')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === null}
|
||||
id="add-to-library-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate('presentationUtil.saveModalDashboard.libraryOptionLabel', {
|
||||
defaultMessage: 'No dashboard, but add to library',
|
||||
})}
|
||||
onChange={() => onChange(null)}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
</EuiPanel>
|
||||
</>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -93,7 +93,7 @@ export const getTopNavConfig = (
|
|||
/**
|
||||
* Called when the user clicks "Save" button.
|
||||
*/
|
||||
async function doSave(saveOptions: SavedObjectSaveOpts) {
|
||||
async function doSave(saveOptions: SavedObjectSaveOpts & { dashboardId?: string }) {
|
||||
const newlyCreated = !Boolean(savedVis.id) || savedVis.copyOnSave;
|
||||
// vis.title was not bound and it's needed to reflect title into visState
|
||||
stateContainer.transitions.setVis({
|
||||
|
@ -118,7 +118,7 @@ export const getTopNavConfig = (
|
|||
'data-test-subj': 'saveVisualizationSuccess',
|
||||
});
|
||||
|
||||
if (originatingApp && saveOptions.returnToOrigin) {
|
||||
if ((originatingApp && saveOptions.returnToOrigin) || saveOptions.dashboardId) {
|
||||
if (!embeddableId) {
|
||||
const appPath = `${VisualizeConstants.EDIT_PATH}/${encodeURIComponent(id)}`;
|
||||
|
||||
|
@ -127,16 +127,26 @@ export const getTopNavConfig = (
|
|||
setActiveUrl(appPath);
|
||||
}
|
||||
|
||||
const app = originatingApp || 'dashboards';
|
||||
|
||||
let path;
|
||||
if (saveOptions.dashboardId) {
|
||||
path =
|
||||
saveOptions.dashboardId === 'new' ? '#/create' : `#/view/${saveOptions.dashboardId}`;
|
||||
}
|
||||
|
||||
if (newlyCreated && stateTransfer) {
|
||||
stateTransfer.navigateToWithEmbeddablePackage(originatingApp, {
|
||||
stateTransfer.navigateToWithEmbeddablePackage(app, {
|
||||
state: {
|
||||
type: VISUALIZE_EMBEDDABLE_TYPE,
|
||||
input: { savedObjectId: id },
|
||||
embeddableId,
|
||||
},
|
||||
path,
|
||||
});
|
||||
} else {
|
||||
application.navigateToApp(originatingApp);
|
||||
// TODO: need the same thing here?
|
||||
application.navigateToApp(app, { path });
|
||||
}
|
||||
} else {
|
||||
if (setOriginatingApp && originatingApp && newlyCreated) {
|
||||
|
@ -321,7 +331,11 @@ export const getTopNavConfig = (
|
|||
newDescription,
|
||||
returnToOrigin,
|
||||
dashboardId,
|
||||
}: OnSaveProps & { returnToOrigin?: boolean } & { dashboardId?: string | null }) => {
|
||||
addToLibrary,
|
||||
}: OnSaveProps & { returnToOrigin?: boolean } & {
|
||||
dashboardId?: string | null;
|
||||
addToLibrary?: boolean;
|
||||
}) => {
|
||||
const currentTitle = savedVis.title;
|
||||
savedVis.title = newTitle;
|
||||
embeddableHandler.updateInput({ title: newTitle });
|
||||
|
@ -337,9 +351,12 @@ export const getTopNavConfig = (
|
|||
isTitleDuplicateConfirmed,
|
||||
onTitleDuplicate,
|
||||
returnToOrigin,
|
||||
dashboardId: !!dashboardId ? dashboardId : undefined,
|
||||
};
|
||||
|
||||
if (dashboardId) {
|
||||
// If we're adding to a dashboard and not saving to library,
|
||||
// we'll want to use a by-value operation
|
||||
if (dashboardId && !addToLibrary) {
|
||||
const appPath = `${VisualizeConstants.LANDING_PAGE_PATH}`;
|
||||
|
||||
// Manually insert a new url so the back button will open the saved visualization.
|
||||
|
@ -369,6 +386,8 @@ export const getTopNavConfig = (
|
|||
return { id: true };
|
||||
}
|
||||
|
||||
// We're adding the viz to a library so we need to save it and then
|
||||
// add to a dashboard if necessary
|
||||
const response = await doSave(saveOptions);
|
||||
// If the save wasn't successful, put the original values back.
|
||||
if (!response.id || response.error) {
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
]);
|
||||
|
||||
describe('Add to Dashboard', function describeIndexTests() {
|
||||
it('adding a new metric to a new dashboard', async function () {
|
||||
it('adding a new metric to a new dashboard by value', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
|
@ -36,6 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
@ -43,10 +44,39 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists('My New Vis 1');
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a existing metric to a new dashboard', async function () {
|
||||
it('adding a new metric to a new dashboard by reference', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My Saved New Vis 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My Saved New Vis 1'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a existing metric to a new dashboard by value', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
|
@ -57,6 +87,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
@ -68,6 +99,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1 Copy', {
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
@ -75,10 +107,85 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Vis 1 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a new metric to an existing dashboard', async function () {
|
||||
it('adding a existing metric to a new dashboard by reference', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('Another New Vis 1', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// All the options should be disabled
|
||||
await PageObjects.timeToVisualize.ensureDashboardOptionsAreDisabled();
|
||||
|
||||
// Save a new copy of this viz to a new dashboard
|
||||
await PageObjects.timeToVisualize.saveFromModal('Another New Vis 1 Copy', {
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Another New Vis 1 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a new metric to an existing dashboard by value', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations(['Visualization AreaChart']);
|
||||
await PageObjects.dashboard.saveDashboard('My Excellent Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Excellent Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Excellent Dashboard',
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists('My New Vis 2');
|
||||
expect(isLinked).to.be(false);
|
||||
});
|
||||
|
||||
it('adding a new metric to an existing dashboard by reference', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
@ -94,18 +201,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
|
||||
await PageObjects.timeToVisualize.saveFromModal('My Saved New Vis 2', {
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Wonderful Dashboard',
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My Saved New Vis 2'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
});
|
||||
|
||||
it('adding a existing metric to an existing dashboard', async function () {
|
||||
it('adding a existing metric to an existing dashboard by value', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
@ -124,6 +237,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
@ -136,12 +250,64 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Very Cool Dashboard',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Vis 2 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
});
|
||||
|
||||
it('adding a existing metric to an existing dashboard by reference', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations(['Visualization AreaChart']);
|
||||
await PageObjects.dashboard.saveDashboard('My Very Neat Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Very Neat Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('Neat Saved Vis 2', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// All the options should be disabled
|
||||
await PageObjects.timeToVisualize.ensureDashboardOptionsAreDisabled();
|
||||
|
||||
// Save a new copy of this viz to an existing dashboard
|
||||
await PageObjects.timeToVisualize.saveFromModal('Neat Saved Vis 2 Copy', {
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Very Neat Dashboard',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Neat Saved Vis 2 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { FtrProviderContext } from '../ftr_provider_context';
|
|||
|
||||
interface SaveModalArgs {
|
||||
addToDashboard?: 'new' | 'existing' | null;
|
||||
saveToLibrary?: boolean;
|
||||
dashboardId?: string;
|
||||
saveAsNew?: boolean;
|
||||
redirectToOrigin?: boolean;
|
||||
|
@ -35,7 +36,9 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
const dashboardSelector = await testSubjects.find('add-to-dashboard-options');
|
||||
await dashboardSelector.findByCssSelector(`input[id="new-dashboard-option"]:disabled`);
|
||||
await dashboardSelector.findByCssSelector(`input[id="existing-dashboard-option"]:disabled`);
|
||||
await dashboardSelector.findByCssSelector(`input[id="add-to-library-option"]:disabled`);
|
||||
|
||||
const librarySelector = await testSubjects.find('add-to-library-checkbox');
|
||||
await librarySelector.findByCssSelector(`input[id="add-to-library-checkbox"]:disabled`);
|
||||
}
|
||||
|
||||
public async resetNewDashboard() {
|
||||
|
@ -46,7 +49,13 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
|
||||
public async setSaveModalValues(
|
||||
vizName: string,
|
||||
{ saveAsNew, redirectToOrigin, addToDashboard, dashboardId }: SaveModalArgs = {}
|
||||
{
|
||||
saveAsNew,
|
||||
redirectToOrigin,
|
||||
addToDashboard,
|
||||
dashboardId,
|
||||
saveToLibrary,
|
||||
}: SaveModalArgs = {}
|
||||
) {
|
||||
await testSubjects.setValue('savedObjectTitle', vizName);
|
||||
|
||||
|
@ -57,13 +66,6 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
await testSubjects.setEuiSwitch('saveAsNewCheckbox', state);
|
||||
}
|
||||
|
||||
const hasRedirectToOrigin = await testSubjects.exists('returnToOriginModeSwitch');
|
||||
if (hasRedirectToOrigin && redirectToOrigin !== undefined) {
|
||||
const state = redirectToOrigin ? 'check' : 'uncheck';
|
||||
log.debug('redirect to origin checkbox exists. Setting its state to', state);
|
||||
await testSubjects.setEuiSwitch('returnToOriginModeSwitch', state);
|
||||
}
|
||||
|
||||
const hasDashboardSelector = await testSubjects.exists('add-to-dashboard-options');
|
||||
if (hasDashboardSelector && addToDashboard !== undefined) {
|
||||
let option: DashboardPickerOption = 'add-to-library-option';
|
||||
|
@ -80,6 +82,40 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
await find.clickByButtonText(dashboardId);
|
||||
}
|
||||
}
|
||||
|
||||
const hasSaveToLibrary = await testSubjects.exists('add-to-library-checkbox');
|
||||
if (hasSaveToLibrary && saveToLibrary !== undefined) {
|
||||
const libraryCheckbox = await find.byCssSelector('#add-to-library-checkbox');
|
||||
const isChecked = await libraryCheckbox.isSelected();
|
||||
const needsClick = isChecked !== saveToLibrary;
|
||||
const state = saveToLibrary ? 'check' : 'uncheck';
|
||||
|
||||
log.debug('save to library checkbox exists. Setting its state to', state);
|
||||
if (needsClick) {
|
||||
const selector = await testSubjects.find('add-to-library-checkbox');
|
||||
const label = await selector.findByCssSelector(`label[for="add-to-library-checkbox"]`);
|
||||
await label.click();
|
||||
}
|
||||
}
|
||||
|
||||
const hasRedirectToOrigin = await testSubjects.exists('returnToOriginModeSwitch');
|
||||
if (hasRedirectToOrigin && redirectToOrigin !== undefined) {
|
||||
const state = redirectToOrigin ? 'check' : 'uncheck';
|
||||
log.debug('redirect to origin checkbox exists. Setting its state to', state);
|
||||
await testSubjects.setEuiSwitch('returnToOriginModeSwitch', state);
|
||||
}
|
||||
}
|
||||
|
||||
public async libraryNotificationExists(panelTitle: string) {
|
||||
log.debug('searching for library modal on panel:', panelTitle);
|
||||
const panel = await testSubjects.find(
|
||||
`embeddablePanelHeading-${panelTitle.replace(/ /g, '')}`
|
||||
);
|
||||
const libraryActionExists = await testSubjects.descendantExists(
|
||||
'embeddablePanelNotification-ACTION_LIBRARY_NOTIFICATION',
|
||||
panel
|
||||
);
|
||||
return libraryActionExists;
|
||||
}
|
||||
|
||||
public async saveFromModal(
|
||||
|
|
|
@ -86,7 +86,7 @@ export const SaveModal = (props: Props) => {
|
|||
savedObjectsTagging={savedObjectsTagging}
|
||||
initialTags={tagsIds}
|
||||
onSave={(saveProps) => {
|
||||
const saveToLibrary = saveProps.dashboardId === null;
|
||||
const saveToLibrary = Boolean(saveProps.addToLibrary);
|
||||
onSave(saveProps, { saveToLibrary });
|
||||
}}
|
||||
onClose={onClose}
|
||||
|
|
|
@ -16,6 +16,7 @@ import { SavedObjectTaggingPluginStart } from '../../../saved_objects_tagging/pu
|
|||
export type DashboardSaveProps = OnSaveProps & {
|
||||
returnToOrigin: boolean;
|
||||
dashboardId?: string | null;
|
||||
addToLibrary?: boolean;
|
||||
newTags?: string[];
|
||||
};
|
||||
|
||||
|
|
|
@ -145,7 +145,11 @@ export function getTopNavConfig({
|
|||
|
||||
const saveModalProps = {
|
||||
onSave: async (
|
||||
props: OnSaveProps & { returnToOrigin?: boolean; dashboardId?: string | null }
|
||||
props: OnSaveProps & {
|
||||
returnToOrigin?: boolean;
|
||||
dashboardId?: string | null;
|
||||
addToLibrary?: boolean;
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
await checkForDuplicateTitle(
|
||||
|
@ -172,7 +176,7 @@ export function getTopNavConfig({
|
|||
await savedMap.save({
|
||||
...props,
|
||||
newTags: selectedTags,
|
||||
saveByReference: !props.dashboardId,
|
||||
saveByReference: Boolean(props.addToLibrary),
|
||||
});
|
||||
// showSaveModal wrapper requires onSave to return an object with an id to close the modal after successful save
|
||||
return { id: 'id' };
|
||||
|
|
|
@ -23,28 +23,57 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const testSubjects = getService('testSubjects');
|
||||
const security = getService('security');
|
||||
|
||||
const createNewLens = async () => {
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
|
||||
operation: 'avg',
|
||||
field: 'bytes',
|
||||
});
|
||||
|
||||
await PageObjects.lens.switchToVisualization('lnsMetric');
|
||||
|
||||
await PageObjects.lens.waitForVisualization();
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
};
|
||||
|
||||
const createAndSaveDashboard = async (dashboardName: string) => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.clickOpenAddPanel();
|
||||
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
|
||||
await find.clickByButtonText('lnsXYvis');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard(dashboardName);
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1);
|
||||
};
|
||||
|
||||
const loadExistingLens = async () => {
|
||||
await PageObjects.visualize.gotoVisualizationLandingPage();
|
||||
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
};
|
||||
|
||||
describe('lens add-to-dashboards tests', () => {
|
||||
it('should allow new lens vizs be added to a new dashboard', async () => {
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
|
||||
operation: 'avg',
|
||||
field: 'bytes',
|
||||
});
|
||||
|
||||
await PageObjects.lens.switchToVisualization('lnsMetric');
|
||||
|
||||
await PageObjects.lens.waitForVisualization();
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
|
||||
await PageObjects.lens.save('New Lens from Modal', false, false, 'new');
|
||||
it('should allow new lens to be added by value to a new dashboard', async () => {
|
||||
await createNewLens();
|
||||
await PageObjects.lens.save('New Lens from Modal', false, false, false, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New Lens from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
@ -52,18 +81,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing lens vizs be added to a new dashboard', async () => {
|
||||
await PageObjects.visualize.gotoVisualizationLandingPage();
|
||||
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
|
||||
await PageObjects.lens.save('Artistpreviouslyknownaslens Copy', true, false, 'new');
|
||||
it('should allow existing lens be added by value to a new dashboard', async () => {
|
||||
await loadExistingLens();
|
||||
await PageObjects.lens.save('Artistpreviouslyknownaslens Copy', true, false, false, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
@ -71,38 +99,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new lens vizs be added to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.clickOpenAddPanel();
|
||||
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
|
||||
await find.clickByButtonText('lnsXYvis');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Very Cool Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Very Cool Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
|
||||
operation: 'avg',
|
||||
field: 'bytes',
|
||||
});
|
||||
|
||||
await PageObjects.lens.switchToVisualization('lnsMetric');
|
||||
|
||||
await PageObjects.lens.waitForVisualization();
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
it('should allow new lens be added by value to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Very Cool Dashboard');
|
||||
await createNewLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'New Lens from Modal',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'existing',
|
||||
'My Very Cool Dashboard'
|
||||
);
|
||||
|
@ -110,34 +115,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New Lens from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
});
|
||||
|
||||
it('should allow existing lens vizs be added to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.clickOpenAddPanel();
|
||||
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
|
||||
await find.clickByButtonText('lnsXYvis');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Wonderful Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Wonderful Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.gotoVisualizationLandingPage();
|
||||
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
it('should allow existing lens be added by value to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Wonderful Dashboard');
|
||||
await loadExistingLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'Artistpreviouslyknownaslens Copy',
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
'existing',
|
||||
'My Wonderful Dashboard'
|
||||
);
|
||||
|
@ -145,6 +140,96 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
});
|
||||
|
||||
it('should allow new lens to be added by reference to a new dashboard', async () => {
|
||||
await createNewLens();
|
||||
await PageObjects.lens.save('New by ref Lens from Modal', false, false, true, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New by ref Lens from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing lens be added by reference to a new dashboard', async () => {
|
||||
await loadExistingLens();
|
||||
await PageObjects.lens.save('Artistpreviouslyknownaslens by ref', true, false, true, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens by ref'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new lens be added by reference to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Very Cool Dashboard 2');
|
||||
await createNewLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'New Lens by ref from Modal',
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
'existing',
|
||||
'My Very Cool Dashboard 2'
|
||||
);
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New Lens by ref from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
});
|
||||
|
||||
it('should allow existing lens be added by reference to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Wonderful Dashboard 2');
|
||||
await loadExistingLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'Artistpreviouslyknownaslens by ref 2',
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
'existing',
|
||||
'My Wonderful Dashboard 2'
|
||||
);
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens by ref 2'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
|
|
@ -39,27 +39,33 @@ export default function ({ getPageObjects, getService }) {
|
|||
await security.testUser.restoreDefaults();
|
||||
});
|
||||
|
||||
it('should allow new map be added to a new dashboard', async () => {
|
||||
it('should allow new map be added by value to a new dashboard', async () => {
|
||||
await PageObjects.maps.openNewMap();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('map 1', { addToDashboard: 'new' });
|
||||
await PageObjects.timeToVisualize.saveFromModal('map 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists('map 1');
|
||||
expect(isInLibrary).to.be(false);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing maps be added to a new dashboard', async () => {
|
||||
it('should allow existing maps be added by value to a new dashboard', async () => {
|
||||
await PageObjects.maps.loadSavedMap('document example');
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy', {
|
||||
saveToLibrary: false,
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
});
|
||||
|
@ -69,10 +75,14 @@ export default function ({ getPageObjects, getService }) {
|
|||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy'
|
||||
);
|
||||
expect(isInLibrary).to.be(false);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new map be added to an existing dashboard', async () => {
|
||||
it('should allow new map be added by value to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
|
@ -86,6 +96,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Map 2', {
|
||||
saveToLibrary: false,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Very Cool Dashboard',
|
||||
});
|
||||
|
@ -94,9 +105,14 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Map 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(false);
|
||||
});
|
||||
|
||||
it('should allow existing maps be added to an existing dashboard', async () => {
|
||||
it('should allow existing maps be added by value to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
|
@ -108,6 +124,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy 2', {
|
||||
saveToLibrary: false,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Wonderful Dashboard',
|
||||
saveAsNew: true,
|
||||
|
@ -117,6 +134,113 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(false);
|
||||
});
|
||||
|
||||
it('should allow new map be added by reference to a new dashboard', async () => {
|
||||
await PageObjects.maps.openNewMap();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('map 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists('map 1');
|
||||
expect(isInLibrary).to.be(true);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing maps be added by reference to a new dashboard', async () => {
|
||||
await PageObjects.maps.loadSavedMap('document example');
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy', {
|
||||
saveToLibrary: true,
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy'
|
||||
);
|
||||
expect(isInLibrary).to.be(true);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new map be added by reference to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Super Cool Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Super Cool Dashboard', 1);
|
||||
|
||||
await PageObjects.maps.openNewMap();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Map 2', {
|
||||
saveToLibrary: true,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Super Cool Dashboard',
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Map 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(true);
|
||||
});
|
||||
|
||||
it('should allow existing maps be added by reference to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Amazing Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Amazing Dashboard', 1);
|
||||
|
||||
await PageObjects.maps.loadSavedMap('document example');
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy 2', {
|
||||
saveToLibrary: true,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Amazing Dashboard',
|
||||
saveAsNew: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -376,6 +376,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
|
|||
title: string,
|
||||
saveAsNew?: boolean,
|
||||
redirectToOrigin?: boolean,
|
||||
saveToLibrary?: boolean,
|
||||
addToDashboard?: 'new' | 'existing' | null,
|
||||
dashboardId?: string
|
||||
) {
|
||||
|
@ -387,6 +388,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
|
|||
redirectToOrigin,
|
||||
addToDashboard: addToDashboard ? addToDashboard : null,
|
||||
dashboardId,
|
||||
saveToLibrary,
|
||||
});
|
||||
|
||||
await testSubjects.click('confirmSaveSavedObjectButton');
|
||||
|
|
Loading…
Reference in a new issue