From 7e9c479f7de77702622631cff2628a9c8dcbc627 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 19 Nov 2020 08:27:35 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-6-stable-ee --- .../access_tokens/components/expires_at_field.vue | 26 +- app/assets/javascripts/access_tokens/index.js | 31 +- .../admin/dev_ops_report/devops_adoption.js | 2 + .../dev_ops_report/devops_score_empty_state.js | 27 + .../alert_management/components/alert_details.vue | 9 +- .../components/alert_mapping_builder.vue | 221 +++++++ .../components/alert_settings_form_help_block.vue | 32 + .../components/alerts_integrations_list.vue | 133 ++++- .../components/alerts_settings_form.vue | 522 ---------------- .../components/alerts_settings_form_new.vue | 661 +++++++++++++++++++++ .../components/alerts_settings_form_old.vue | 494 +++++++++++++++ .../components/alerts_settings_wrapper.vue | 331 +++++++++++ .../components/mocks/gitlabFields.json | 112 ++++ .../components/mocks/parsedMapping.json | 121 ++++ .../javascripts/alerts_settings/constants.js | 32 +- app/assets/javascripts/alerts_settings/graphql.js | 44 ++ .../fragments/integration_item.fragment.graphql | 9 + .../create_http_integration.mutation.graphql | 10 + .../create_prometheus_integration.mutation.graphql | 12 + .../destroy_http_integration.mutation.graphql | 10 + .../mutations/reset_http_token.mutation.graphql | 10 + .../reset_prometheus_token.mutation.graphql | 10 + .../update_current_intergration.mutation.graphql | 19 + .../update_http_integration.mutation.graphql | 10 + .../update_prometheus_integration.mutation.graphql | 10 + .../queries/get_current_integration.query.graphql | 3 + .../graphql/queries/get_integrations.query.graphql | 11 + app/assets/javascripts/alerts_settings/index.js | 39 +- .../javascripts/alerts_settings/services/index.js | 5 +- .../alerts_settings/utils/cache_updates.js | 84 +++ .../alerts_settings/utils/error_messages.js | 21 + .../instance_statistics/components/app.vue | 24 +- .../components/charts_config.js | 87 +++ .../components/instance_statistics_count_chart.vue | 206 +++++++ .../components/pipelines_chart.vue | 215 ------- .../components/projects_and_groups_chart.vue | 224 +++++++ .../graphql/queries/groups.query.graphql | 13 + .../graphql/queries/instance_count.query.graphql | 13 + .../graphql/queries/pipeline_stats.query.graphql | 76 --- .../graphql/queries/projects.query.graphql | 13 + .../analytics/instance_statistics/utils.js | 45 +- .../components/activity_chart.vue | 13 +- .../analytics/shared/components/metric_card.vue | 2 +- app/assets/javascripts/api.js | 59 +- app/assets/javascripts/awards_handler.js | 37 +- app/assets/javascripts/badges/components/badge.vue | 14 +- .../components/inline_draft_comment_row.vue | 32 - .../components/parallel_draft_comment_row.vue | 49 -- .../batch_comments/mixins/resolved_status.js | 6 + .../javascripts/behaviors/copy_to_clipboard.js | 30 + .../javascripts/behaviors/details_behavior.js | 28 - app/assets/javascripts/behaviors/index.js | 1 - .../behaviors/markdown/gfm_auto_complete.js | 1 + .../behaviors/markdown/render_mermaid.js | 2 +- app/assets/javascripts/behaviors/quick_submit.js | 16 +- .../behaviors/shortcuts/shortcuts_issuable.js | 17 + .../javascripts/behaviors/toggler_behavior.js | 18 +- .../blob/components/blob_edit_content.vue | 2 +- .../blob/components/blob_edit_header.vue | 1 + .../javascripts/blob/components/blob_header.vue | 2 +- .../components/blob_header_default_actions.vue | 6 +- .../blob/components/blob_header_filepath.vue | 2 +- .../blob/pipeline_tour_success_modal.vue | 14 +- app/assets/javascripts/blob_edit/blob_bundle.js | 58 +- .../boards/components/board_assignee_dropdown.vue | 178 ++++++ .../boards/components/board_card_layout.vue | 5 +- .../javascripts/boards/components/board_column.vue | 49 +- .../boards/components/board_column_new.vue | 94 +++ .../components/board_configuration_options.vue | 2 +- .../boards/components/board_content.vue | 8 +- .../javascripts/boards/components/board_form.vue | 4 +- .../javascripts/boards/components/board_list.vue | 15 +- .../boards/components/board_list_header.vue | 50 +- .../boards/components/board_list_header_new.vue | 358 +++++++++++ .../boards/components/board_list_new.vue | 2 +- .../boards/components/board_new_issue.vue | 34 +- .../boards/components/board_new_issue_new.vue | 129 ++++ .../boards/components/board_promotion_state.js | 1 + .../boards/components/board_settings_sidebar.vue | 18 +- .../boards/components/boards_selector.vue | 2 +- .../boards/components/issue_card_inner.vue | 35 +- .../boards/components/modal/empty_state.vue | 21 +- .../boards/components/new_list_dropdown.js | 3 +- .../boards/components/project_select.vue | 12 +- .../components/sidebar/board_sidebar_due_date.vue | 111 ++++ .../sidebar/board_sidebar_labels_select.vue | 14 +- .../sidebar/board_sidebar_subscription.vue | 71 +++ app/assets/javascripts/boards/constants.js | 4 + .../issue_set_subscription.mutation.graphql | 8 + app/assets/javascripts/boards/index.js | 12 +- .../boards/mixins/sortable_default_options.js | 5 - .../boards/queries/board_labels.query.graphql | 23 + .../queries/board_list_destroy.mutation.graphql | 5 + .../boards/queries/issue_create.mutation.graphql | 10 + .../queries/issue_set_due_date.mutation.graphql | 8 + .../boards/queries/users_search.query.graphql | 11 + app/assets/javascripts/boards/stores/actions.js | 193 +++++- .../javascripts/boards/stores/boards_store.js | 7 +- app/assets/javascripts/boards/stores/getters.js | 11 +- .../javascripts/boards/stores/mutation_types.js | 9 +- app/assets/javascripts/boards/stores/mutations.js | 41 +- app/assets/javascripts/boards/toggle_focus.js | 5 +- .../javascripts/ci_lint/components/ci_lint.vue | 14 +- .../ci_lint/components/ci_lint_results.vue | 37 +- .../javascripts/ci_lint/graphql/resolvers.js | 34 ++ app/assets/javascripts/ci_lint/index.js | 37 +- .../ci_variable_list/ajax_variable_list.js | 128 ---- .../components/ci_environments_dropdown.vue | 4 +- .../components/ci_variable_modal.vue | 8 +- .../clusters/components/application_row.vue | 2 +- .../clusters/components/applications.vue | 15 +- .../clusters_list/components/clusters.vue | 10 +- app/assets/javascripts/compare_autocomplete.js | 3 +- .../components/eks_cluster_configuration_form.vue | 61 +- .../components/service_credentials_form.vue | 40 +- .../create_cluster/eks_cluster/constants.js | 2 + .../eks_cluster/services/aws_services_facade.js | 21 +- .../create_cluster/eks_cluster/store/actions.js | 16 +- .../create_cluster/eks_cluster/store/index.js | 5 - .../components/gke_project_id_dropdown.vue | 11 +- .../javascripts/create_merge_request_dropdown.js | 6 - app/assets/javascripts/dependency_proxy.js | 5 + .../javascripts/deploy_keys/components/key.vue | 19 +- .../components/design_destroyer.vue | 2 +- .../components/design_notes/design_discussion.vue | 6 +- .../components/design_notes/design_note.vue | 4 +- .../components/design_notes/design_reply_form.vue | 2 +- .../components/design_overlay.vue | 4 +- .../design_management/components/design_scaler.vue | 23 +- .../components/design_sidebar.vue | 2 +- .../components/toolbar/design_navigation.vue | 7 +- .../design_management/components/toolbar/index.vue | 16 +- .../design_management/components/upload/button.vue | 5 +- .../components/upload/design_dropzone.vue | 147 ----- .../javascripts/design_management/constants.js | 3 - .../fragments/note_permissions.fragment.graphql | 1 + .../reposition_image_diff_note.mutation.graphql | 10 + .../update_image_diff_note.mutation.graphql | 10 - .../queries/design_permissions.query.graphql | 10 - .../graphql/queries/get_design.query.graphql | 7 +- .../graphql/queries/get_design_list.query.graphql | 23 - .../design_management/mixins/all_designs.js | 18 +- .../design_management/mixins/all_versions.js | 2 +- .../design_management/pages/design/index.vue | 41 +- .../javascripts/design_management/pages/index.vue | 91 ++- .../javascripts/design_management/router/index.js | 17 - .../design_management/utils/cache_update.js | 14 +- .../utils/design_management_utils.js | 6 +- app/assets/javascripts/diffs/components/app.vue | 25 +- .../diffs/components/collapsed_files_warning.vue | 8 +- .../diffs/components/compare_versions.vue | 11 +- .../diffs/components/diff_comment_cell.vue | 69 +++ .../javascripts/diffs/components/diff_content.vue | 35 +- .../diffs/components/diff_expansion_cell.vue | 55 +- .../javascripts/diffs/components/diff_file.vue | 209 +++++-- .../diffs/components/diff_file_header.vue | 26 +- .../javascripts/diffs/components/diff_file_row.vue | 1 + .../diffs/components/diff_line_note_form.vue | 28 +- .../javascripts/diffs/components/diff_row.vue | 271 +++++++++ .../javascripts/diffs/components/diff_row_utils.js | 73 +++ .../javascripts/diffs/components/diff_view.vue | 151 +++++ .../diffs/components/inline_diff_comment_row.vue | 82 --- .../diffs/components/inline_diff_expansion_row.vue | 51 -- .../diffs/components/inline_diff_table_row.vue | 61 +- .../diffs/components/inline_diff_view.vue | 70 ++- .../diffs/components/parallel_diff_comment_row.vue | 175 ------ .../components/parallel_diff_expansion_row.vue | 56 -- .../diffs/components/parallel_diff_table_row.vue | 63 +- .../diffs/components/parallel_diff_view.vue | 89 ++- app/assets/javascripts/diffs/constants.js | 12 + app/assets/javascripts/diffs/diff_file.js | 24 +- app/assets/javascripts/diffs/event_hub.js | 3 + app/assets/javascripts/diffs/i18n.js | 13 + app/assets/javascripts/diffs/store/actions.js | 57 +- app/assets/javascripts/diffs/store/getters.js | 21 +- .../javascripts/diffs/store/mutation_types.js | 1 - app/assets/javascripts/diffs/store/mutations.js | 52 +- app/assets/javascripts/diffs/store/utils.js | 8 +- app/assets/javascripts/diffs/utils/performance.js | 80 +++ app/assets/javascripts/dropzone_input.js | 3 +- app/assets/javascripts/editor/editor_lite.js | 3 +- .../environments/components/container.vue | 2 +- .../components/delete_environment_modal.vue | 42 +- .../environments/components/environment_delete.vue | 23 +- .../environments/components/environment_stop.vue | 6 +- .../environments/components/environments_app.vue | 2 +- .../components/stop_environment_modal.vue | 48 +- .../error_tracking/components/error_details.vue | 34 +- .../components/error_tracking_list.vue | 57 +- .../components/project_dropdown.vue | 16 +- .../components/configure_feature_flags_modal.vue | 50 +- .../feature_flags/components/edit_feature_flag.vue | 2 +- .../feature_flags/components/feature_flags.vue | 4 +- .../javascripts/feature_flags/components/form.vue | 22 +- .../components/strategies/flexible_rollout.vue | 4 +- .../components/strategies/gitlab_user_list.vue | 73 ++- .../components/strategies/percent_rollout.vue | 4 +- app/assets/javascripts/feature_flags/edit.js | 2 +- app/assets/javascripts/feature_flags/new.js | 2 +- .../javascripts/feature_flags/store/edit/index.js | 4 + .../store/gitlab_user_list/actions.js | 17 + .../store/gitlab_user_list/getters.js | 11 + .../feature_flags/store/gitlab_user_list/index.js | 12 + .../store/gitlab_user_list/mutation_types.js | 5 + .../store/gitlab_user_list/mutations.js | 19 + .../feature_flags/store/gitlab_user_list/state.js | 9 + .../feature_flags/store/gitlab_user_list/status.js | 6 + .../javascripts/feature_flags/store/helpers.js | 4 +- .../javascripts/feature_flags/store/new/index.js | 4 + .../add_extra_tokens_for_merge_requests.js | 83 ++- .../filtered_search/dropdown_ajax_filter.js | 10 +- .../filtered_search/dropdown_operator.js | 5 +- .../javascripts/filtered_search/dropdown_user.js | 2 +- .../filtered_search/filtered_search_dropdown.js | 6 +- .../filtered_search_dropdown_manager.js | 16 +- .../filtered_search/filtered_search_manager.js | 14 +- app/assets/javascripts/frequent_items/index.js | 82 ++- app/assets/javascripts/gfm_auto_complete.js | 51 +- app/assets/javascripts/graphql_shared/utils.js | 8 +- app/assets/javascripts/groups/components/app.vue | 58 +- .../javascripts/groups/components/group_item.vue | 8 +- .../javascripts/groups/components/item_actions.vue | 40 +- app/assets/javascripts/groups/constants.js | 6 +- app/assets/javascripts/groups/index.js | 7 + app/assets/javascripts/groups/members/index.js | 3 +- app/assets/javascripts/groups/new_group_child.js | 65 -- app/assets/javascripts/header.js | 24 +- .../javascripts/helpers/startup_css_helper.js | 14 +- .../ide/components/commit_sidebar/form.vue | 26 +- .../ide/components/commit_sidebar/list.vue | 12 +- .../components/commit_sidebar/list_collapsed.vue | 103 ---- .../ide/components/commit_sidebar/list_item.vue | 7 +- .../javascripts/ide/components/file_row_extra.vue | 7 +- app/assets/javascripts/ide/components/ide.vue | 74 ++- .../javascripts/ide/components/ide_side_bar.vue | 10 +- .../javascripts/ide/components/ide_status_list.vue | 7 +- app/assets/javascripts/ide/components/ide_tree.vue | 2 +- .../javascripts/ide/components/ide_tree_list.vue | 11 +- .../javascripts/ide/components/jobs/detail.vue | 9 +- .../javascripts/ide/components/jobs/item.vue | 6 +- .../javascripts/ide/components/mr_file_icon.vue | 7 +- .../ide/components/new_dropdown/button.vue | 7 +- .../ide/components/panes/collapsible_sidebar.vue | 4 - .../javascripts/ide/components/pipelines/list.vue | 36 +- .../ide/components/repo_commit_section.vue | 5 - .../javascripts/ide/components/repo_editor.vue | 45 +- .../ide/components/repo_file_status_icon.vue | 7 +- app/assets/javascripts/ide/components/repo_tab.vue | 4 +- .../ide/components/terminal/empty_state.vue | 22 +- app/assets/javascripts/ide/stores/actions.js | 4 +- app/assets/javascripts/ide/stores/actions/file.js | 24 +- app/assets/javascripts/ide/stores/index.js | 11 +- .../ide/stores/modules/commit/getters.js | 2 + .../ide/stores/modules/editor/actions.js | 19 + .../ide/stores/modules/editor/getters.js | 13 + .../javascripts/ide/stores/modules/editor/index.js | 12 + .../ide/stores/modules/editor/mutation_types.js | 3 + .../ide/stores/modules/editor/mutations.js | 25 + .../javascripts/ide/stores/modules/editor/setup.js | 19 + .../javascripts/ide/stores/modules/editor/state.js | 8 + .../javascripts/ide/stores/modules/editor/utils.js | 11 + .../javascripts/ide/stores/mutation_types.js | 3 - .../javascripts/ide/stores/mutations/file.js | 16 - app/assets/javascripts/ide/stores/utils.js | 6 +- app/assets/javascripts/ide/utils.js | 2 +- .../javascripts/import_projects/store/actions.js | 21 +- app/assets/javascripts/importer_status.js | 4 +- .../incidents/components/incidents_list.vue | 24 +- .../edit/components/confirmation_modal.vue | 6 +- .../edit/components/integration_form.vue | 41 +- .../edit/components/jira_trigger_fields.vue | 7 +- .../edit/components/reset_confirmation_modal.vue | 61 ++ app/assets/javascripts/integrations/edit/index.js | 2 + .../javascripts/integrations/edit/store/actions.js | 2 + .../javascripts/integrations/edit/store/getters.js | 2 +- .../integrations/edit/store/mutation_types.js | 1 + .../integrations/edit/store/mutations.js | 3 + .../javascripts/integrations/edit/store/state.js | 1 + .../components/invite_members_modal.vue | 85 +-- .../components/members_token_select.vue | 120 ++++ app/assets/javascripts/invite_members/constants.js | 1 + .../invite_members/init_invite_members_modal.js | 1 - .../components/issuable_bulk_edit_sidebar.vue | 35 ++ .../issuable_list/components/issuable_item.vue | 124 +++- .../components/issuable_list_root.vue | 153 ++++- .../issuable_list/components/issuable_tabs.vue | 5 +- app/assets/javascripts/issuable_list/constants.js | 51 ++ .../components/issuable_sidebar_root.vue | 1 + app/assets/javascripts/issue.js | 8 +- .../javascripts/issue_show/components/app.vue | 34 +- .../issue_show/components/header_actions.vue | 281 +++++++++ app/assets/javascripts/issue_show/constants.js | 11 +- app/assets/javascripts/issue_show/issue.js | 58 +- .../queries/promote_to_epic.mutation.graphql | 8 + .../queries/update_issue.mutation.graphql | 5 + .../issues_list/components/issuable.vue | 6 +- app/assets/javascripts/issues_list/index.js | 5 +- app/assets/javascripts/jira_connect/.eslintrc.yml | 5 + .../javascripts/jira_connect/components/app.vue | 7 + app/assets/javascripts/jira_connect/index.js | 15 + .../job_retry_forward_deployment_modal.vue | 66 ++ .../jobs/components/job_sidebar_retry_button.vue | 45 ++ .../javascripts/jobs/components/jobs_container.vue | 2 +- .../javascripts/jobs/components/log/line.vue | 51 +- app/assets/javascripts/jobs/components/sidebar.vue | 174 ++---- .../components/sidebar_job_details_container.vue | 102 ++++ .../jobs/components/stages_dropdown.vue | 29 +- app/assets/javascripts/jobs/constants.js | 24 + app/assets/javascripts/jobs/index.js | 32 +- app/assets/javascripts/jobs/store/getters.js | 5 +- app/assets/javascripts/jobs/utils.js | 4 + app/assets/javascripts/lib/ace.js | 4 - .../javascripts/lib/ace/ace_config_paths.js.erb | 34 -- app/assets/javascripts/lib/graphql.js | 3 +- app/assets/javascripts/lib/utils/ace_utils.js | 6 - .../lib/utils/apollo_startup_js_link.js | 106 ++++ app/assets/javascripts/lib/utils/common_utils.js | 21 +- app/assets/javascripts/lib/utils/constants.js | 1 - app/assets/javascripts/lib/utils/css_utils.js | 2 + .../javascripts/lib/utils/datetime_utility.js | 4 - app/assets/javascripts/lib/utils/dom_utils.js | 22 + app/assets/javascripts/lib/utils/http_status.js | 1 + app/assets/javascripts/lib/utils/number_utils.js | 14 +- app/assets/javascripts/lib/utils/text_utility.js | 12 + app/assets/javascripts/main.js | 11 +- .../merge_conflicts/components/diff_file_editor.js | 38 +- .../milestones/components/milestone_combobox.vue | 250 ++++++++ .../components/milestone_results_section.vue | 93 +++ .../milestones/project_milestone_combobox.vue | 249 -------- .../javascripts/milestones/stores/actions.js | 61 +- .../javascripts/milestones/stores/getters.js | 4 + .../milestones/stores/mutation_types.js | 8 +- .../javascripts/milestones/stores/mutations.js | 30 +- app/assets/javascripts/milestones/stores/state.js | 8 +- .../monitoring/components/charts/column.vue | 10 +- .../components/charts/stacked_column.vue | 21 +- .../monitoring/components/charts/time_series.vue | 8 +- .../monitoring/components/dashboard.vue | 2 +- .../monitoring/components/dashboard_panel.vue | 2 +- .../components/dashboard_panel_builder.vue | 4 +- .../monitoring/components/embeds/embed_group.vue | 2 +- .../components/variables/dropdown_field.vue | 17 +- .../javascripts/notebook/cells/output/html.vue | 2 +- .../javascripts/notes/components/comment_form.vue | 9 +- .../notes/components/diff_with_note.vue | 6 +- .../notes/components/discussion_actions.vue | 2 +- .../notes/components/discussion_filter.vue | 5 +- .../notes/components/discussion_filter_note.vue | 42 +- .../notes/components/discussion_notes.vue | 2 + .../javascripts/notes/components/note_actions.vue | 118 ++-- .../notes/components/note_actions/reply_button.vue | 2 +- .../notes/components/note_attachment.vue | 7 +- .../javascripts/notes/components/note_form.vue | 8 +- .../javascripts/notes/components/note_header.vue | 28 +- .../javascripts/notes/components/noteable_note.vue | 13 +- .../notes/components/toggle_replies_widget.vue | 12 +- app/assets/javascripts/notes/mixins/resolvable.js | 13 +- app/assets/javascripts/notes/stores/actions.js | 2 +- app/assets/javascripts/notes/stores/mutations.js | 38 +- app/assets/javascripts/notifications_form.js | 19 +- .../packages/details/components/package_title.vue | 35 +- app/assets/javascripts/pages/admin/admin.js | 16 +- .../admin/application_settings/general/index.js | 20 +- .../pages/admin/dev_ops_report/index.js | 30 +- .../jobs/index/components/stop_jobs_modal.vue | 23 +- .../javascripts/pages/admin/jobs/index/index.js | 11 +- .../javascripts/pages/admin/runners/index.js | 13 +- app/assets/javascripts/pages/admin/users/index.js | 4 +- .../javascripts/pages/groups/boards/index.js | 8 +- .../pages/groups/clusters/destroy/index.js | 4 +- .../pages/groups/clusters/edit/index.js | 4 +- .../javascripts/pages/groups/clusters/index.js | 6 +- .../pages/groups/clusters/index/index.js | 8 +- .../javascripts/pages/groups/clusters/new/index.js | 4 +- .../pages/groups/clusters/show/index.js | 6 +- .../pages/groups/dependency_proxies/index.js | 13 + .../javascripts/pages/groups/details/index.js | 4 +- .../pages/groups/group_members/index.js | 61 +- .../javascripts/pages/groups/labels/edit/index.js | 3 +- .../javascripts/pages/groups/labels/index/index.js | 2 +- .../javascripts/pages/groups/labels/new/index.js | 3 +- .../pages/groups/merge_requests/index.js | 18 +- .../pages/groups/milestones/edit/index.js | 2 +- .../pages/groups/milestones/new/index.js | 2 +- app/assets/javascripts/pages/groups/new/index.js | 16 +- .../pages/groups/packages/index/index.js | 8 +- .../pages/groups/settings/ci_cd/show/index.js | 38 +- .../pages/groups/shared/group_details.js | 5 - .../pages/profiles/preferences/show/index.js | 3 + .../projects/alert_management/details/index.js | 4 +- .../pages/projects/alert_management/index/index.js | 4 +- .../javascripts/pages/projects/blob/show/index.js | 3 +- .../pages/projects/ci/lints/ci_lint_editor.js | 32 - .../pages/projects/ci/lints/new/index.js | 17 - .../pages/projects/ci/lints/show/index.js | 18 +- .../projects/ci/pipeline_editor/show/index.js | 3 + .../pages/projects/commit/show/index.js | 2 +- .../pages/projects/error_tracking/details/index.js | 4 +- .../pages/projects/error_tracking/index/index.js | 4 +- .../pages/projects/graphs/charts/index.js | 14 +- .../projects/graphs/components/code_coverage.vue | 4 +- .../pages/projects/incidents/index/index.js | 4 +- .../pages/projects/incidents/show/index.js | 12 +- .../integrations/jira/issues/index/index.js | 5 - .../javascripts/pages/projects/issues/show.js | 5 +- .../labels/components/promote_label_modal.vue | 24 +- .../pages/projects/labels/index/index.js | 102 ++-- .../pages/projects/metrics_dashboard/index.js | 2 +- .../projects/pipeline_schedules/index/index.js | 34 +- .../components/pipeline_schedules_callout.vue | 23 +- .../pages/projects/pipelines/show/index.js | 6 +- app/assets/javascripts/pages/projects/project.js | 31 +- .../pages/projects/settings/ci_cd/show/index.js | 59 +- .../projects/settings/integrations/show/index.js | 6 +- .../projects/settings/operations/show/index.js | 18 +- .../permissions/components/settings_panel.vue | 25 + .../permissions/mixins/settings_pannel_mixin.js | 1 + .../javascripts/pages/projects/show/index.js | 5 + .../pages/projects/terraform/index/index.js | 3 + .../search/show/highlight_blob_search_result.js | 15 - app/assets/javascripts/pages/search/show/index.js | 4 +- app/assets/javascripts/pages/search/show/search.js | 36 +- .../pages/shared/mount_runner_instructions.js | 32 + .../shared/wikis/components/delete_wiki_modal.vue | 49 +- app/assets/javascripts/pages/shared/wikis/wikis.js | 7 + .../javascripts/pages/users/activity_calendar.js | 11 +- app/assets/javascripts/pages/users/index.js | 5 - app/assets/javascripts/pages/users/user_tabs.js | 17 +- app/assets/javascripts/performance/constants.js | 45 ++ app/assets/javascripts/performance/utils.js | 10 + .../performance/vue_performance_plugin.js | 53 ++ .../performance_bar/components/detailed_metric.vue | 64 +- .../performance_bar/performance_bar_log.js | 2 +- app/assets/javascripts/performance_constants.js | 31 - app/assets/javascripts/performance_utils.js | 10 - app/assets/javascripts/persistent_user_callouts.js | 1 + .../pipeline_editor/components/text_editor.vue | 26 + .../graphql/queries/blob_content.graphql | 5 + .../pipeline_editor/graphql/resolvers.js | 16 + .../pipeline_editor/graphql/typedefs.graphql | 7 + app/assets/javascripts/pipeline_editor/index.js | 34 ++ .../pipeline_editor/pipeline_editor_app.vue | 108 ++++ .../pipeline_new/components/pipeline_new_form.vue | 11 +- .../javascripts/pipelines/components/dag/dag.vue | 21 +- .../pipelines/components/graph/constants.js | 3 + .../pipelines/components/graph/graph_component.vue | 73 +-- .../pipelines/components/graph/job_item.vue | 11 +- .../pipelines/components/graph/linked_pipeline.vue | 27 +- .../components/graph/linked_pipelines_column.vue | 15 +- .../pipelines/components/header_component.vue | 72 ++- .../components/pipeline_graph/job_pill.vue | 2 +- .../components/pipeline_graph/pipeline_graph.vue | 28 +- .../components/pipeline_graph/stage_pill.vue | 2 +- .../components/pipelines_list/pipelines.vue | 9 +- .../pipelines_list/pipelines_actions.vue | 2 +- .../pipelines_list/pipelines_artifacts.vue | 2 +- .../pipelines/components/pipelines_list/stage.vue | 2 +- .../components/pipelines_list/time_ago.vue | 1 - .../components/test_reports/test_case_details.vue | 67 +++ .../components/test_reports/test_reports.vue | 6 +- .../components/test_reports/test_suite_table.vue | 39 +- .../mutations/cancel_pipeline.mutation.graphql | 5 + .../mutations/delete_pipeline.mutation.graphql | 5 + .../mutations/retry_pipeline.mutation.graphql | 5 + .../mixins/graph_pipeline_bundle_mixin.js | 6 +- .../pipelines/mixins/stage_column_mixin.js | 4 +- .../pipelines/pipeline_details_bundle.js | 58 +- .../javascripts/pipelines/pipeline_details_dag.js | 18 +- .../pipelines/pipeline_details_graph.js | 7 + .../pipelines/pipeline_details_header.js | 6 +- .../javascripts/popovers/components/popovers.vue | 92 +++ app/assets/javascripts/popovers/index.js | 51 ++ .../profile/account/components/update_username.vue | 44 +- .../preferences/components/integration_view.vue | 81 +++ .../preferences/components/profile_preferences.vue | 56 ++ .../preferences/profile_preferences_bundle.js | 23 + .../javascripts/projects/commit_box/info/index.js | 3 + .../commit_box/info/init_details_button.js | 11 + .../projects/components/project_delete_button.vue | 2 +- .../projects/pipelines/charts/components/app.vue | 11 +- .../charts/components/statistics_list.vue | 54 +- .../javascripts/projects/pipelines/charts/index.js | 2 + .../components/service_desk_root.vue | 33 +- .../components/service_desk_setting.vue | 25 +- .../projects/settings_service_desk/index.js | 4 +- .../services/service_desk_service.js | 4 - .../prometheus_metrics/prometheus_metrics.js | 17 +- .../explorer/components/details_page/tags_list.vue | 8 +- .../components/details_page/tags_list_row.vue | 6 +- .../explorer/components/list_page/cli_commands.vue | 13 +- .../components/list_page/image_list_row.vue | 13 +- .../explorer/components/registry_breadcrumb.vue | 4 +- .../registry/explorer/constants/details.js | 4 + .../registry/explorer/pages/details.vue | 30 +- app/assets/javascripts/registry/explorer/router.js | 3 +- .../registry/explorer/stores/actions.js | 43 +- .../registry/explorer/stores/mutation_types.js | 1 + .../registry/explorer/stores/mutations.js | 4 + .../javascripts/registry/explorer/stores/state.js | 1 + app/assets/javascripts/registry/explorer/utils.js | 17 +- .../registry/settings/components/settings_form.vue | 3 +- .../javascripts/registry/shared/constants.js | 2 +- .../related_issues/components/issue_token.vue | 11 +- .../components/related_issues_block.vue | 4 +- .../components/related_issues_list.vue | 12 +- .../releases/components/app_edit_new.vue | 7 +- .../javascripts/releases/components/app_index.vue | 26 +- .../releases/components/issuable_stats.vue | 97 +++ .../releases/components/release_block.vue | 7 +- .../components/release_block_milestone_info.vue | 150 +++-- .../releases/components/releases_sort.vue | 62 ++ .../releases/components/tag_field_existing.vue | 20 +- app/assets/javascripts/releases/constants.js | 18 + .../releases/queries/all_releases.query.graphql | 11 +- .../releases/queries/release.fragment.graphql | 8 +- .../releases/stores/modules/detail/state.js | 6 +- .../releases/stores/modules/list/actions.js | 11 +- .../releases/stores/modules/list/mutation_types.js | 1 + .../releases/stores/modules/list/mutations.js | 4 + .../releases/stores/modules/list/state.js | 6 + app/assets/javascripts/releases/util.js | 4 +- .../components/codequality_issue_body.vue | 44 +- .../reports/codequality_report/constants.js | 17 + .../grouped_codequality_reports_app.vue | 1 + .../reports/codequality_report/store/getters.js | 3 +- .../components/grouped_test_reports_app.vue | 45 +- .../reports/components/report_section.vue | 5 +- .../reports/components/test_issue_body.vue | 24 +- app/assets/javascripts/reports/store/mutations.js | 8 + app/assets/javascripts/reports/store/utils.js | 42 ++ .../repository/components/breadcrumbs.vue | 2 +- .../repository/components/last_commit.vue | 4 +- .../repository/components/preview/index.vue | 2 +- .../repository/components/tree_action_link.vue | 2 +- .../repository/components/tree_content.vue | 2 +- app/assets/javascripts/repository/index.js | 28 +- .../javascripts/repository/mixins/preload.js | 2 +- .../repository/queries/files.query.graphql | 60 -- .../repository/queries/permissions.query.graphql | 9 - .../dropdown_filter/components/dropdown_filter.vue | 100 ---- .../constants/confidential_filter_data.js | 36 -- .../dropdown_filter/constants/state_filter_data.js | 42 -- .../javascripts/search/dropdown_filter/index.js | 38 -- .../group_filter/components/group_filter.vue | 124 ++++ .../javascripts/search/group_filter/constants.js | 10 + .../javascripts/search/group_filter/index.js | 28 + .../search/highlight_blob_search_result.js | 15 + app/assets/javascripts/search/index.js | 13 +- .../javascripts/search/sidebar/components/app.vue | 41 ++ .../sidebar/components/confidentiality_filter.vue | 26 + .../search/sidebar/components/radio_filter.vue | 68 +++ .../search/sidebar/components/status_filter.vue | 26 + .../sidebar/constants/confidential_filter_data.js | 36 ++ .../search/sidebar/constants/state_filter_data.js | 42 ++ app/assets/javascripts/search/sidebar/index.js | 19 + app/assets/javascripts/search/store/actions.js | 29 + app/assets/javascripts/search/store/index.js | 4 + .../javascripts/search/store/mutation_types.js | 5 + app/assets/javascripts/search/store/mutations.js | 18 + app/assets/javascripts/search/store/state.js | 2 + .../javascripts/serverless/components/area.vue | 4 +- .../components/user_availability_status.vue | 26 + .../set_status_modal/set_status_modal_wrapper.vue | 63 +- app/assets/javascripts/set_status_modal/utils.js | 9 + app/assets/javascripts/shared/milestones/form.js | 1 + .../components/assignees/assignee_avatar.vue | 4 +- .../components/assignees/assignee_avatar_link.vue | 6 +- .../components/assignees/assignee_title.vue | 3 +- .../components/assignees/issuable_assignees.vue | 1 - .../assignees/uncollapsed_assignee_list.vue | 10 +- .../sidebar/components/labels/sidebar_labels.vue | 100 +++- .../components/subscriptions/subscriptions.vue | 12 +- .../components/time_tracking/collapsed_state.vue | 7 +- .../components/time_tracking/comparison_pane.vue | 9 +- .../time_tracking/estimate_only_pane.vue | 5 +- .../components/time_tracking/help_state.vue | 2 +- .../components/time_tracking/no_tracking_pane.vue | 4 +- .../time_tracking/sidebar_time_tracking.vue | 1 - .../components/time_tracking/spent_only_pane.vue | 4 +- .../components/time_tracking/time_tracker.vue | 30 +- app/assets/javascripts/sidebar/mount_sidebar.js | 5 + .../update_merge_request_labels.mutation.graphql | 15 + app/assets/javascripts/sidebar/utils.js | 1 + app/assets/javascripts/single_file_diff.js | 7 +- .../javascripts/snippets/components/edit.vue | 51 +- .../javascripts/snippets/components/show.vue | 4 +- .../snippets/components/snippet_blob_view.vue | 13 +- .../snippets/components/snippet_header.vue | 22 +- .../components/snippet_visibility_edit.vue | 27 +- app/assets/javascripts/snippets/constants.js | 2 +- app/assets/javascripts/snippets/index.js | 11 +- app/assets/javascripts/snippets/mixins/snippets.js | 12 +- .../queries/projectPermissions.query.graphql | 7 - .../queries/snippet.blob.content.query.graphql | 14 - .../snippets/queries/snippet.query.graphql | 15 - .../queries/snippet_visibility.query.graphql | 5 - .../snippets/queries/userPermissions.query.graphql | 7 - app/assets/javascripts/snippets/utils/blob.js | 4 +- .../static_site_editor/components/edit_area.vue | 50 +- .../components/edit_meta_controls.vue | 100 ++-- .../components/edit_meta_modal.vue | 45 +- .../javascripts/static_site_editor/constants.js | 3 +- .../static_site_editor/graphql/index.js | 4 + .../graphql/queries/app_data.query.graphql | 7 + .../static_site_editor/graphql/typedefs.graphql | 9 + .../static_site_editor/image_repository.js | 4 +- app/assets/javascripts/static_site_editor/index.js | 9 +- .../javascripts/static_site_editor/pages/home.vue | 10 + .../static_site_editor/services/front_matterify.js | 2 + .../services/parse_source_file.js | 18 +- .../services/renderers/render_image.js | 89 +++ .../terraform/components/empty_state.vue | 44 ++ .../terraform/components/states_table.vue | 101 ++++ .../terraform/components/terraform_list.vue | 134 +++++ app/assets/javascripts/terraform/constants.js | 1 + .../graphql/fragments/state.fragment.graphql | 17 + .../fragments/state_version.fragment.graphql | 9 + .../graphql/queries/get_states.query.graphql | 18 + app/assets/javascripts/terraform/index.js | 31 + .../javascripts/tooltips/components/tooltips.vue | 1 + app/assets/javascripts/tooltips/index.js | 6 + app/assets/javascripts/tracking.js | 1 + app/assets/javascripts/users_select/index.js | 7 +- .../components/extensions/base.vue | 157 +++++ .../components/extensions/container.js | 27 + .../components/extensions/index.js | 30 + .../components/mr_widget_author.vue | 16 +- .../components/mr_widget_header.vue | 13 - .../components/states/commit_message_dropdown.vue | 14 +- .../states/mr_widget_auto_merge_enabled.vue | 6 +- .../components/states/ready_to_merge.vue | 86 ++- .../components/states/work_in_progress.vue | 15 +- .../vue_merge_request_widget/extensions/issues.js | 66 ++ .../extensions/issues.query.graphql | 13 + .../extensions/issues_collapsed.query.graphql | 7 + .../javascripts/vue_merge_request_widget/index.js | 11 +- .../vue_merge_request_widget/mr_widget_options.vue | 6 +- .../vue_shared/components/actions_button.vue | 1 - .../vue_shared/components/alert_details_table.vue | 11 +- .../vue_shared/components/awards_list.vue | 11 +- .../vue_shared/components/blob_viewers/mixins.js | 2 +- .../components/blob_viewers/simple_viewer.vue | 3 +- .../javascripts/vue_shared/components/ci_icon.vue | 3 - .../vue_shared/components/confirm_modal.vue | 8 +- .../components/dropdown/dropdown_button.vue | 11 +- .../javascripts/vue_shared/components/file_row.vue | 15 +- .../vue_shared/components/file_row_header.vue | 14 +- .../filtered_search_bar_root.vue | 24 + .../filtered_search_bar/tokens/milestone_token.vue | 2 +- .../vue_shared/components/gl_mentions.vue | 36 +- .../javascripts/vue_shared/components/gl_modal.vue | 6 - .../components/integrations_help_text.vue | 35 ++ .../vue_shared/components/local_storage_sync.vue | 10 + .../vue_shared/components/markdown/field.vue | 9 +- .../components/markdown/suggestion_diff_header.vue | 4 + .../vue_shared/components/markdown/toolbar.vue | 44 +- .../members/action_buttons/user_action_buttons.vue | 11 +- .../vue_shared/components/members/constants.js | 1 + .../members/table/expiration_datepicker.vue | 99 +++ .../components/members/table/members_table.vue | 56 +- .../members/table/members_table_cell.vue | 13 +- .../components/members/table/role_dropdown.vue | 27 +- .../vue_shared/components/members/utils.js | 29 + .../vue_shared/components/modal_copy_button.vue | 33 +- .../paginated_table_with_search_and_tabs.vue | 2 +- .../vue_shared/components/registry/title_area.vue | 9 +- .../modals/add_image/add_image_modal.vue | 25 +- .../rich_content_editor/rich_content_editor.vue | 4 +- .../services/build_html_to_markdown_renderer.js | 4 + .../rich_content_editor/services/editor_service.js | 23 +- .../queries/get_runner_platforms.query.graphql | 20 + .../graphql/queries/get_runner_setup.query.graphql | 16 + .../runner_instructions/runner_instructions.vue | 220 +++++++ .../components/sidebar/issuable_move_dropdown.vue | 211 +++++++ .../labels_select/dropdown_value_collapsed.vue | 10 +- .../dropdown_contents_labels_view.vue | 11 +- .../sidebar/labels_select_vue/store/actions.js | 2 +- .../components/sidebar/multiselect_dropdown.vue | 29 + .../queries/getIssueParticipants.query.graphql | 13 + .../queries/updateAssignees.mutation.graphql | 17 + .../vue_shared/components/stacked_progress_bar.vue | 4 +- .../components/upload_dropzone/constants.js | 9 + .../components/upload_dropzone/upload_dropzone.vue | 172 ++++++ .../vue_shared/components/upload_dropzone/utils.js | 4 + .../components/user_popover/user_popover.vue | 9 + .../vue_shared/components/web_ide_link.vue | 2 +- .../vue_shared/directives/validation.js | 132 ++++ .../vue_shared/mixins/related_issuable_mixin.js | 4 - .../vue_shared/security_reports/constants.js | 3 + .../security_reports/security_reports_app.vue | 26 +- .../security_reports/store/modules/sast/actions.js | 24 + .../security_reports/store/modules/sast/index.js | 10 + .../store/modules/sast/mutation_types.js | 4 + .../store/modules/sast/mutations.js | 31 + .../security_reports/store/modules/sast/state.js | 16 + .../store/modules/secret_detection/actions.js | 24 + .../store/modules/secret_detection/index.js | 10 + .../modules/secret_detection/mutation_types.js | 4 + .../store/modules/secret_detection/mutations.js | 30 + .../store/modules/secret_detection/state.js | 16 + .../vue_shared/security_reports/store/utils.js | 75 +++ .../vuex_shared/modules/members/actions.js | 19 + .../vuex_shared/modules/members/index.js | 4 +- .../vuex_shared/modules/members/mutation_types.js | 3 + .../vuex_shared/modules/members/mutations.js | 15 + .../vuex_shared/modules/members/state.js | 2 + .../javascripts/whats_new/components/app.vue | 80 ++- app/assets/javascripts/whats_new/store/actions.js | 33 +- .../javascripts/whats_new/store/mutation_types.js | 5 +- .../javascripts/whats_new/store/mutations.js | 13 +- app/assets/javascripts/whats_new/store/state.js | 7 +- .../whats_new/utils/get_drawer_body_height.js | 6 + app/assets/stylesheets/_page_specific_files.scss | 5 - app/assets/stylesheets/behaviors.scss | 25 - app/assets/stylesheets/bootstrap_migration.scss | 14 +- .../components/design_management/design.scss | 42 -- .../stylesheets/components/severity/icons.scss | 27 + .../upload_dropzone/upload_dropzone.scss | 37 ++ app/assets/stylesheets/components/whats_new.scss | 13 + app/assets/stylesheets/fontawesome_custom.scss | 76 +-- .../stylesheets/framework/broadcast_messages.scss | 8 - app/assets/stylesheets/framework/calendar.scss | 14 +- app/assets/stylesheets/framework/common.scss | 1 - app/assets/stylesheets/framework/diffs.scss | 96 ++- app/assets/stylesheets/framework/dropdowns.scss | 3 +- app/assets/stylesheets/framework/editor-lite.scss | 18 + app/assets/stylesheets/framework/files.scss | 37 +- app/assets/stylesheets/framework/flash.scss | 8 +- app/assets/stylesheets/framework/mixins.scss | 32 + app/assets/stylesheets/framework/modal.scss | 12 +- .../framework/secondary_navigation_elements.scss | 68 +-- app/assets/stylesheets/framework/spinner.scss | 14 +- app/assets/stylesheets/framework/typography.scss | 6 +- app/assets/stylesheets/highlight/common.scss | 10 + app/assets/stylesheets/highlight/themes/dark.scss | 17 +- .../stylesheets/highlight/themes/monokai.scss | 17 +- app/assets/stylesheets/highlight/themes/none.scss | 14 +- .../highlight/themes/solarized-dark.scss | 17 +- .../highlight/themes/solarized-light.scss | 17 +- app/assets/stylesheets/highlight/white_base.scss | 14 +- app/assets/stylesheets/lazy_bundles/select2.scss | 654 ++++++++++++++++++++ .../lazy_bundles/select2_overrides.scss | 359 +++++++++++ app/assets/stylesheets/mailer.scss | 17 + .../page_bundles/_ide_theme_overrides.scss | 6 +- .../page_bundles/alert_management_details.scss | 46 ++ .../page_bundles/alert_management_settings.scss | 24 + app/assets/stylesheets/page_bundles/boards.scss | 89 --- app/assets/stylesheets/page_bundles/build.scss | 294 +++++++++ app/assets/stylesheets/page_bundles/ci_status.scss | 79 +++ .../experimental_separate_sign_up.scss | 96 --- app/assets/stylesheets/page_bundles/ide.scss | 14 +- .../stylesheets/page_bundles/ide_themes/_dark.scss | 8 + .../page_bundles/ide_themes/_monokai.scss | 66 ++ .../page_bundles/ide_themes/_solarized-dark.scss | 8 + .../page_bundles/ide_themes/_solarized-light.scss | 57 ++ .../stylesheets/page_bundles/jira_connect.scss | 4 +- .../stylesheets/page_bundles/merge_requests.scss | 12 +- app/assets/stylesheets/page_bundles/pipeline.scss | 4 + .../page_bundles/pipeline_schedules.scss | 68 +++ app/assets/stylesheets/page_bundles/pipelines.scss | 4 + app/assets/stylesheets/page_bundles/reports.scss | 6 +- app/assets/stylesheets/page_bundles/signup.scss | 75 +++ app/assets/stylesheets/page_bundles/todos.scss | 1 - app/assets/stylesheets/pages/admin.scss | 8 + .../pages/alert_management/details.scss | 42 -- .../pages/alert_management/severity-icons.scss | 27 - app/assets/stylesheets/pages/builds.scss | 349 ----------- app/assets/stylesheets/pages/commits.scss | 21 +- app/assets/stylesheets/pages/editor.scss | 18 +- app/assets/stylesheets/pages/groups.scss | 8 +- .../pages/incident_management_list.scss | 27 +- app/assets/stylesheets/pages/issuable.scss | 45 +- app/assets/stylesheets/pages/issues.scss | 12 +- app/assets/stylesheets/pages/labels.scss | 147 +---- app/assets/stylesheets/pages/members.scss | 7 +- app/assets/stylesheets/pages/merge_requests.scss | 17 +- app/assets/stylesheets/pages/note_form.scss | 49 +- app/assets/stylesheets/pages/notes.scss | 36 +- .../stylesheets/pages/pipeline_schedules.scss | 70 --- app/assets/stylesheets/pages/pipelines.scss | 61 +- app/assets/stylesheets/pages/projects.scss | 181 ------ app/assets/stylesheets/pages/search.scss | 3 +- app/assets/stylesheets/pages/status.scss | 77 --- app/assets/stylesheets/pages/tree.scss | 2 +- app/assets/stylesheets/pages/users.scss | 37 -- app/assets/stylesheets/performance_bar.scss | 2 +- app/assets/stylesheets/print.scss | 2 +- app/assets/stylesheets/themes/_dark.scss | 18 + app/assets/stylesheets/utilities.scss | 7 + 789 files changed, 17549 insertions(+), 7577 deletions(-) create mode 100644 app/assets/javascripts/admin/dev_ops_report/devops_adoption.js create mode 100644 app/assets/javascripts/admin/dev_ops_report/devops_score_empty_state.js create mode 100644 app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue create mode 100644 app/assets/javascripts/alerts_settings/components/alert_settings_form_help_block.vue delete mode 100644 app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue create mode 100644 app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue create mode 100644 app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue create mode 100644 app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue create mode 100644 app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json create mode 100644 app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json create mode 100644 app/assets/javascripts/alerts_settings/graphql.js create mode 100644 app/assets/javascripts/alerts_settings/graphql/fragments/integration_item.fragment.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/create_prometheus_integration.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/destroy_http_integration.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/update_current_intergration.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/queries/get_current_integration.query.graphql create mode 100644 app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql create mode 100644 app/assets/javascripts/alerts_settings/utils/cache_updates.js create mode 100644 app/assets/javascripts/alerts_settings/utils/error_messages.js create mode 100644 app/assets/javascripts/analytics/instance_statistics/components/charts_config.js create mode 100644 app/assets/javascripts/analytics/instance_statistics/components/instance_statistics_count_chart.vue delete mode 100644 app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue create mode 100644 app/assets/javascripts/analytics/instance_statistics/components/projects_and_groups_chart.vue create mode 100644 app/assets/javascripts/analytics/instance_statistics/graphql/queries/groups.query.graphql create mode 100644 app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_count.query.graphql delete mode 100644 app/assets/javascripts/analytics/instance_statistics/graphql/queries/pipeline_stats.query.graphql create mode 100644 app/assets/javascripts/analytics/instance_statistics/graphql/queries/projects.query.graphql delete mode 100644 app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue delete mode 100644 app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue delete mode 100644 app/assets/javascripts/behaviors/details_behavior.js create mode 100644 app/assets/javascripts/boards/components/board_assignee_dropdown.vue create mode 100644 app/assets/javascripts/boards/components/board_column_new.vue create mode 100644 app/assets/javascripts/boards/components/board_list_header_new.vue create mode 100644 app/assets/javascripts/boards/components/board_new_issue_new.vue create mode 100644 app/assets/javascripts/boards/components/board_promotion_state.js create mode 100644 app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue create mode 100644 app/assets/javascripts/boards/components/sidebar/board_sidebar_subscription.vue create mode 100644 app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql create mode 100644 app/assets/javascripts/boards/queries/board_labels.query.graphql create mode 100644 app/assets/javascripts/boards/queries/board_list_destroy.mutation.graphql create mode 100644 app/assets/javascripts/boards/queries/issue_create.mutation.graphql create mode 100644 app/assets/javascripts/boards/queries/issue_set_due_date.mutation.graphql create mode 100644 app/assets/javascripts/boards/queries/users_search.query.graphql create mode 100644 app/assets/javascripts/ci_lint/graphql/resolvers.js delete mode 100644 app/assets/javascripts/ci_variable_list/ajax_variable_list.js create mode 100644 app/assets/javascripts/dependency_proxy.js delete mode 100644 app/assets/javascripts/design_management/components/upload/design_dropzone.vue create mode 100644 app/assets/javascripts/design_management/graphql/mutations/reposition_image_diff_note.mutation.graphql delete mode 100644 app/assets/javascripts/design_management/graphql/mutations/update_image_diff_note.mutation.graphql delete mode 100644 app/assets/javascripts/design_management/graphql/queries/design_permissions.query.graphql delete mode 100644 app/assets/javascripts/design_management/graphql/queries/get_design_list.query.graphql create mode 100644 app/assets/javascripts/diffs/components/diff_comment_cell.vue create mode 100644 app/assets/javascripts/diffs/components/diff_row.vue create mode 100644 app/assets/javascripts/diffs/components/diff_view.vue delete mode 100644 app/assets/javascripts/diffs/components/inline_diff_comment_row.vue delete mode 100644 app/assets/javascripts/diffs/components/inline_diff_expansion_row.vue delete mode 100644 app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue delete mode 100644 app/assets/javascripts/diffs/components/parallel_diff_expansion_row.vue create mode 100644 app/assets/javascripts/diffs/event_hub.js create mode 100644 app/assets/javascripts/diffs/utils/performance.js create mode 100644 app/assets/javascripts/feature_flags/store/gitlab_user_list/actions.js create mode 100644 app/assets/javascripts/feature_flags/store/gitlab_user_list/getters.js create mode 100644 app/assets/javascripts/feature_flags/store/gitlab_user_list/index.js create mode 100644 app/assets/javascripts/feature_flags/store/gitlab_user_list/mutation_types.js create mode 100644 app/assets/javascripts/feature_flags/store/gitlab_user_list/mutations.js create mode 100644 app/assets/javascripts/feature_flags/store/gitlab_user_list/state.js create mode 100644 app/assets/javascripts/feature_flags/store/gitlab_user_list/status.js delete mode 100644 app/assets/javascripts/groups/new_group_child.js delete mode 100644 app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue create mode 100644 app/assets/javascripts/ide/stores/modules/editor/actions.js create mode 100644 app/assets/javascripts/ide/stores/modules/editor/getters.js create mode 100644 app/assets/javascripts/ide/stores/modules/editor/index.js create mode 100644 app/assets/javascripts/ide/stores/modules/editor/mutation_types.js create mode 100644 app/assets/javascripts/ide/stores/modules/editor/mutations.js create mode 100644 app/assets/javascripts/ide/stores/modules/editor/setup.js create mode 100644 app/assets/javascripts/ide/stores/modules/editor/state.js create mode 100644 app/assets/javascripts/ide/stores/modules/editor/utils.js create mode 100644 app/assets/javascripts/integrations/edit/components/reset_confirmation_modal.vue create mode 100644 app/assets/javascripts/invite_members/components/members_token_select.vue create mode 100644 app/assets/javascripts/invite_members/constants.js create mode 100644 app/assets/javascripts/issuable_list/components/issuable_bulk_edit_sidebar.vue create mode 100644 app/assets/javascripts/issuable_list/constants.js create mode 100644 app/assets/javascripts/issue_show/components/header_actions.vue create mode 100644 app/assets/javascripts/issue_show/queries/promote_to_epic.mutation.graphql create mode 100644 app/assets/javascripts/issue_show/queries/update_issue.mutation.graphql create mode 100644 app/assets/javascripts/jira_connect/.eslintrc.yml create mode 100644 app/assets/javascripts/jira_connect/components/app.vue create mode 100644 app/assets/javascripts/jira_connect/index.js create mode 100644 app/assets/javascripts/jobs/components/job_retry_forward_deployment_modal.vue create mode 100644 app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue create mode 100644 app/assets/javascripts/jobs/components/sidebar_job_details_container.vue create mode 100644 app/assets/javascripts/jobs/constants.js create mode 100644 app/assets/javascripts/jobs/utils.js delete mode 100644 app/assets/javascripts/lib/ace.js delete mode 100644 app/assets/javascripts/lib/ace/ace_config_paths.js.erb delete mode 100644 app/assets/javascripts/lib/utils/ace_utils.js create mode 100644 app/assets/javascripts/lib/utils/apollo_startup_js_link.js create mode 100644 app/assets/javascripts/milestones/components/milestone_combobox.vue create mode 100644 app/assets/javascripts/milestones/components/milestone_results_section.vue delete mode 100644 app/assets/javascripts/milestones/project_milestone_combobox.vue create mode 100644 app/assets/javascripts/pages/groups/dependency_proxies/index.js create mode 100644 app/assets/javascripts/pages/profiles/preferences/show/index.js delete mode 100644 app/assets/javascripts/pages/projects/ci/lints/ci_lint_editor.js delete mode 100644 app/assets/javascripts/pages/projects/ci/lints/new/index.js create mode 100644 app/assets/javascripts/pages/projects/ci/pipeline_editor/show/index.js delete mode 100644 app/assets/javascripts/pages/projects/integrations/jira/issues/index/index.js create mode 100644 app/assets/javascripts/pages/projects/terraform/index/index.js delete mode 100644 app/assets/javascripts/pages/search/show/highlight_blob_search_result.js create mode 100644 app/assets/javascripts/pages/shared/mount_runner_instructions.js create mode 100644 app/assets/javascripts/performance/constants.js create mode 100644 app/assets/javascripts/performance/utils.js create mode 100644 app/assets/javascripts/performance/vue_performance_plugin.js delete mode 100644 app/assets/javascripts/performance_constants.js delete mode 100644 app/assets/javascripts/performance_utils.js create mode 100644 app/assets/javascripts/pipeline_editor/components/text_editor.vue create mode 100644 app/assets/javascripts/pipeline_editor/graphql/queries/blob_content.graphql create mode 100644 app/assets/javascripts/pipeline_editor/graphql/resolvers.js create mode 100644 app/assets/javascripts/pipeline_editor/graphql/typedefs.graphql create mode 100644 app/assets/javascripts/pipeline_editor/index.js create mode 100644 app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue create mode 100644 app/assets/javascripts/pipelines/components/graph/constants.js create mode 100644 app/assets/javascripts/pipelines/components/test_reports/test_case_details.vue create mode 100644 app/assets/javascripts/pipelines/graphql/mutations/cancel_pipeline.mutation.graphql create mode 100644 app/assets/javascripts/pipelines/graphql/mutations/delete_pipeline.mutation.graphql create mode 100644 app/assets/javascripts/pipelines/graphql/mutations/retry_pipeline.mutation.graphql create mode 100644 app/assets/javascripts/pipelines/pipeline_details_graph.js create mode 100644 app/assets/javascripts/popovers/components/popovers.vue create mode 100644 app/assets/javascripts/popovers/index.js create mode 100644 app/assets/javascripts/profile/preferences/components/integration_view.vue create mode 100644 app/assets/javascripts/profile/preferences/components/profile_preferences.vue create mode 100644 app/assets/javascripts/profile/preferences/profile_preferences_bundle.js create mode 100644 app/assets/javascripts/projects/commit_box/info/init_details_button.js create mode 100644 app/assets/javascripts/releases/components/issuable_stats.vue create mode 100644 app/assets/javascripts/releases/components/releases_sort.vue create mode 100644 app/assets/javascripts/reports/codequality_report/constants.js delete mode 100644 app/assets/javascripts/repository/queries/files.query.graphql delete mode 100644 app/assets/javascripts/repository/queries/permissions.query.graphql delete mode 100644 app/assets/javascripts/search/dropdown_filter/components/dropdown_filter.vue delete mode 100644 app/assets/javascripts/search/dropdown_filter/constants/confidential_filter_data.js delete mode 100644 app/assets/javascripts/search/dropdown_filter/constants/state_filter_data.js delete mode 100644 app/assets/javascripts/search/dropdown_filter/index.js create mode 100644 app/assets/javascripts/search/group_filter/components/group_filter.vue create mode 100644 app/assets/javascripts/search/group_filter/constants.js create mode 100644 app/assets/javascripts/search/group_filter/index.js create mode 100644 app/assets/javascripts/search/highlight_blob_search_result.js create mode 100644 app/assets/javascripts/search/sidebar/components/app.vue create mode 100644 app/assets/javascripts/search/sidebar/components/confidentiality_filter.vue create mode 100644 app/assets/javascripts/search/sidebar/components/radio_filter.vue create mode 100644 app/assets/javascripts/search/sidebar/components/status_filter.vue create mode 100644 app/assets/javascripts/search/sidebar/constants/confidential_filter_data.js create mode 100644 app/assets/javascripts/search/sidebar/constants/state_filter_data.js create mode 100644 app/assets/javascripts/search/sidebar/index.js create mode 100644 app/assets/javascripts/search/store/actions.js create mode 100644 app/assets/javascripts/search/store/mutation_types.js create mode 100644 app/assets/javascripts/search/store/mutations.js create mode 100644 app/assets/javascripts/set_status_modal/components/user_availability_status.vue create mode 100644 app/assets/javascripts/set_status_modal/utils.js create mode 100644 app/assets/javascripts/sidebar/queries/update_merge_request_labels.mutation.graphql create mode 100644 app/assets/javascripts/sidebar/utils.js delete mode 100644 app/assets/javascripts/snippets/queries/projectPermissions.query.graphql delete mode 100644 app/assets/javascripts/snippets/queries/snippet.blob.content.query.graphql delete mode 100644 app/assets/javascripts/snippets/queries/snippet.query.graphql delete mode 100644 app/assets/javascripts/snippets/queries/snippet_visibility.query.graphql delete mode 100644 app/assets/javascripts/snippets/queries/userPermissions.query.graphql create mode 100644 app/assets/javascripts/static_site_editor/services/renderers/render_image.js create mode 100644 app/assets/javascripts/terraform/components/empty_state.vue create mode 100644 app/assets/javascripts/terraform/components/states_table.vue create mode 100644 app/assets/javascripts/terraform/components/terraform_list.vue create mode 100644 app/assets/javascripts/terraform/constants.js create mode 100644 app/assets/javascripts/terraform/graphql/fragments/state.fragment.graphql create mode 100644 app/assets/javascripts/terraform/graphql/fragments/state_version.fragment.graphql create mode 100644 app/assets/javascripts/terraform/graphql/queries/get_states.query.graphql create mode 100644 app/assets/javascripts/terraform/index.js create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js create mode 100644 app/assets/javascripts/vue_merge_request_widget/extensions/issues.js create mode 100644 app/assets/javascripts/vue_merge_request_widget/extensions/issues.query.graphql create mode 100644 app/assets/javascripts/vue_merge_request_widget/extensions/issues_collapsed.query.graphql delete mode 100644 app/assets/javascripts/vue_shared/components/gl_modal.vue create mode 100644 app/assets/javascripts/vue_shared/components/integrations_help_text.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/table/expiration_datepicker.vue create mode 100644 app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_platforms.query.graphql create mode 100644 app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_setup.query.graphql create mode 100644 app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions.vue create mode 100644 app/assets/javascripts/vue_shared/components/sidebar/issuable_move_dropdown.vue create mode 100644 app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue create mode 100644 app/assets/javascripts/vue_shared/components/sidebar/queries/getIssueParticipants.query.graphql create mode 100644 app/assets/javascripts/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql create mode 100644 app/assets/javascripts/vue_shared/components/upload_dropzone/constants.js create mode 100644 app/assets/javascripts/vue_shared/components/upload_dropzone/upload_dropzone.vue create mode 100644 app/assets/javascripts/vue_shared/components/upload_dropzone/utils.js create mode 100644 app/assets/javascripts/vue_shared/directives/validation.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/constants.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/sast/actions.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/sast/index.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/sast/mutation_types.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/sast/mutations.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/sast/state.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/actions.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/index.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutation_types.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/mutations.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/state.js create mode 100644 app/assets/javascripts/vue_shared/security_reports/store/utils.js create mode 100644 app/assets/javascripts/whats_new/utils/get_drawer_body_height.js create mode 100644 app/assets/stylesheets/components/severity/icons.scss create mode 100644 app/assets/stylesheets/components/upload_dropzone/upload_dropzone.scss create mode 100644 app/assets/stylesheets/lazy_bundles/select2.scss create mode 100644 app/assets/stylesheets/lazy_bundles/select2_overrides.scss create mode 100644 app/assets/stylesheets/page_bundles/alert_management_details.scss create mode 100644 app/assets/stylesheets/page_bundles/alert_management_settings.scss create mode 100644 app/assets/stylesheets/page_bundles/build.scss create mode 100644 app/assets/stylesheets/page_bundles/ci_status.scss delete mode 100644 app/assets/stylesheets/page_bundles/experimental_separate_sign_up.scss create mode 100644 app/assets/stylesheets/page_bundles/ide_themes/_monokai.scss create mode 100644 app/assets/stylesheets/page_bundles/ide_themes/_solarized-light.scss create mode 100644 app/assets/stylesheets/page_bundles/pipeline_schedules.scss create mode 100644 app/assets/stylesheets/page_bundles/signup.scss delete mode 100644 app/assets/stylesheets/pages/alert_management/details.scss delete mode 100644 app/assets/stylesheets/pages/alert_management/severity-icons.scss delete mode 100644 app/assets/stylesheets/pages/builds.scss delete mode 100644 app/assets/stylesheets/pages/pipeline_schedules.scss delete mode 100644 app/assets/stylesheets/pages/status.scss (limited to 'app/assets') diff --git a/app/assets/javascripts/access_tokens/components/expires_at_field.vue b/app/assets/javascripts/access_tokens/components/expires_at_field.vue index d0932ad80e1..1fec186f2fa 100644 --- a/app/assets/javascripts/access_tokens/components/expires_at_field.vue +++ b/app/assets/javascripts/access_tokens/components/expires_at_field.vue @@ -1,14 +1,32 @@ diff --git a/app/assets/javascripts/access_tokens/index.js b/app/assets/javascripts/access_tokens/index.js index 9bdb2940956..319144193f1 100644 --- a/app/assets/javascripts/access_tokens/index.js +++ b/app/assets/javascripts/access_tokens/index.js @@ -1,11 +1,34 @@ import Vue from 'vue'; import ExpiresAtField from './components/expires_at_field.vue'; +const getInputAttrs = el => { + const input = el.querySelector('input'); + + return { + id: input.id, + name: input.name, + placeholder: input.placeholder, + }; +}; + const initExpiresAtField = () => { - // eslint-disable-next-line no-new - new Vue({ - el: document.querySelector('.js-access-tokens-expires-at'), - components: { ExpiresAtField }, + const el = document.querySelector('.js-access-tokens-expires-at'); + + if (!el) { + return null; + } + + const inputAttrs = getInputAttrs(el); + + return new Vue({ + el, + render(h) { + return h(ExpiresAtField, { + props: { + inputAttrs, + }, + }); + }, }); }; diff --git a/app/assets/javascripts/admin/dev_ops_report/devops_adoption.js b/app/assets/javascripts/admin/dev_ops_report/devops_adoption.js new file mode 100644 index 00000000000..ae73033079d --- /dev/null +++ b/app/assets/javascripts/admin/dev_ops_report/devops_adoption.js @@ -0,0 +1,2 @@ +// EE-specific feature. Find the implementation in the `ee/`-folder +export default () => {}; diff --git a/app/assets/javascripts/admin/dev_ops_report/devops_score_empty_state.js b/app/assets/javascripts/admin/dev_ops_report/devops_score_empty_state.js new file mode 100644 index 00000000000..0cb8d9be0e4 --- /dev/null +++ b/app/assets/javascripts/admin/dev_ops_report/devops_score_empty_state.js @@ -0,0 +1,27 @@ +import Vue from 'vue'; +import UserCallout from '~/user_callout'; +import UsagePingDisabled from './components/usage_ping_disabled.vue'; + +export default () => { + // eslint-disable-next-line no-new + new UserCallout(); + + const emptyStateContainer = document.getElementById('js-devops-empty-state'); + + if (!emptyStateContainer) return false; + + const { emptyStateSvgPath, enableUsagePingLink, docsLink, isAdmin } = emptyStateContainer.dataset; + + return new Vue({ + el: emptyStateContainer, + provide: { + isAdmin: Boolean(isAdmin), + svgPath: emptyStateSvgPath, + primaryButtonPath: enableUsagePingLink, + docsLink, + }, + render(h) { + return h(UsagePingDisabled); + }, + }); +}; diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue index f7a5d31b835..1f3fdd5eef2 100644 --- a/app/assets/javascripts/alert_management/components/alert_details.vue +++ b/app/assets/javascripts/alert_management/components/alert_details.vue @@ -30,7 +30,6 @@ import AlertSidebar from './alert_sidebar.vue'; import AlertMetrics from './alert_metrics.vue'; import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue'; import AlertSummaryRow from './alert_summary_row.vue'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; const containerEl = document.querySelector('.page-with-contextual-sidebar'); @@ -77,7 +76,6 @@ export default { SystemNote, AlertMetrics, }, - mixins: [glFeatureFlagsMixin()], inject: { projectPath: { default: '', @@ -150,13 +148,10 @@ export default { }, }, environmentName() { - return this.shouldDisplayEnvironment && this.alert?.environment?.name; + return this.alert?.environment?.name; }, environmentPath() { - return this.shouldDisplayEnvironment && this.alert?.environment?.path; - }, - shouldDisplayEnvironment() { - return this.glFeatures.exposeEnvironmentPathInAlertDetails; + return this.alert?.environment?.path; }, }, mounted() { diff --git a/app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue b/app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue new file mode 100644 index 00000000000..f6474efcc1f --- /dev/null +++ b/app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue @@ -0,0 +1,221 @@ + + + diff --git a/app/assets/javascripts/alerts_settings/components/alert_settings_form_help_block.vue b/app/assets/javascripts/alerts_settings/components/alert_settings_form_help_block.vue new file mode 100644 index 00000000000..35b7fe84c5f --- /dev/null +++ b/app/assets/javascripts/alerts_settings/components/alert_settings_form_help_block.vue @@ -0,0 +1,32 @@ + + + diff --git a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue index 217442e6131..12c0409629f 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue @@ -1,8 +1,24 @@ @@ -75,15 +138,16 @@ export default {
{{ $options.i18n.title }}
- diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue deleted file mode 100644 index f885afae378..00000000000 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue +++ /dev/null @@ -1,522 +0,0 @@ - - - diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue new file mode 100644 index 00000000000..3656fc4d7ec --- /dev/null +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue @@ -0,0 +1,661 @@ + + + diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue new file mode 100644 index 00000000000..0246315bdc5 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue @@ -0,0 +1,494 @@ + + + diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue new file mode 100644 index 00000000000..1ffc2f80148 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue @@ -0,0 +1,331 @@ + + + diff --git a/app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json b/app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json new file mode 100644 index 00000000000..ac559a30eda --- /dev/null +++ b/app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json @@ -0,0 +1,112 @@ +[ + { + "name": "title", + "label": "Title", + "type": [ + "String" + ], + "compatibleTypes": [ + "String", + "Number", + "DateTime" + ], + "numberOfFallbacks": 1 + }, + { + "name": "description", + "label": "Description", + "type": [ + "String" + ], + "compatibleTypes": [ + "String", + "Number", + "DateTime" + ] + }, + { + "name": "startTime", + "label": "Start time", + "type": [ + "DateTime" + ], + "compatibleTypes": [ + "Number", + "DateTime" + ] + }, + { + "name": "service", + "label": "Service", + "type": [ + "String" + ], + "compatibleTypes": [ + "String", + "Number", + "DateTime" + ] + }, + { + "name": "monitoringTool", + "label": "Monitoring tool", + "type": [ + "String" + ], + "compatibleTypes": [ + "String", + "Number", + "DateTime" + ] + }, + { + "name": "hosts", + "label": "Hosts", + "type": [ + "String", + "Array" + ], + "compatibleTypes": [ + "String", + "Array", + "Number", + "DateTime" + ] + }, + { + "name": "severity", + "label": "Severity", + "type": [ + "String" + ], + "compatibleTypes": [ + "String", + "Number", + "DateTime" + ] + }, + { + "name": "fingerprint", + "label": "Fingerprint", + "type": [ + "String" + ], + "compatibleTypes": [ + "String", + "Number", + "DateTime" + ] + }, + { + "name": "environment", + "label": "Environment", + "type": [ + "String" + ], + "compatibleTypes": [ + "String", + "Number", + "DateTime" + ] + } +] diff --git a/app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json b/app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json new file mode 100644 index 00000000000..5326678155d --- /dev/null +++ b/app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json @@ -0,0 +1,121 @@ +{ + "samplePayload": { + "body": "{\n \"dashboardId\":1,\n \"evalMatches\":[\n {\n \"value\":1,\n \"metric\":\"Count\",\n \"tags\":{}\n }\n ],\n \"imageUrl\":\"https://grafana.com/static/assets/img/blog/mixed_styles.png\",\n \"message\":\"Notification Message\",\n \"orgId\":1,\n \"panelId\":2,\n \"ruleId\":1,\n \"ruleName\":\"Panel Title alert\",\n \"ruleUrl\":\"http://localhost:3000/d/hZ7BuVbWz/test-dashboard?fullscreen\\u0026edit\\u0026tab=alert\\u0026panelId=2\\u0026orgId=1\",\n \"state\":\"alerting\",\n \"tags\":{\n \"tag name\":\"tag value\"\n },\n \"title\":\"[Alerting] Panel Title alert\"\n}\n", + "payloadAlerFields": { + "nodes": [ + { + "name": "dashboardId", + "label": "Dashboard Id", + "type": [ + "Number" + ] + }, + { + "name": "evalMatches", + "label": "Eval Matches", + "type": [ + "Array" + ] + }, + { + "name": "createdAt", + "label": "Created At", + "type": [ + "DateTime" + ] + }, + { + "name": "imageUrl", + "label": "Image Url", + "type": [ + "String" + ] + }, + { + "name": "message", + "label": "Message", + "type": [ + "String" + ] + }, + { + "name": "orgId", + "label": "Org Id", + "type": [ + "Number" + ] + }, + { + "name": "panelId", + "label": "Panel Id", + "type": [ + "String" + ] + }, + { + "name": "ruleId", + "label": "Rule Id", + "type": [ + "Number" + ] + }, + { + "name": "ruleName", + "label": "Rule Name", + "type": [ + "String" + ] + }, + { + "name": "ruleUrl", + "label": "Rule Url", + "type": [ + "String" + ] + }, + { + "name": "state", + "label": "State", + "type": [ + "String" + ] + }, + { + "name": "title", + "label": "Title", + "type": [ + "String" + ] + }, + { + "name": "tags", + "label": "Tags", + "type": [ + "Object" + ] + } + ] + } + }, + "storedMapping": { + "nodes": [ + { + "alertFieldName": "title", + "payloadAlertPaths": "title", + "fallbackAlertPaths": "ruleUrl" + }, + { + "alertFieldName": "description", + "payloadAlertPaths": "message" + }, + { + "alertFieldName": "hosts", + "payloadAlertPaths": "evalMatches" + }, + { + "alertFieldName": "startTime", + "payloadAlertPaths": "createdAt" + } + ] + } +} diff --git a/app/assets/javascripts/alerts_settings/constants.js b/app/assets/javascripts/alerts_settings/constants.js index 4220dbde0c7..e30dc2ad553 100644 --- a/app/assets/javascripts/alerts_settings/constants.js +++ b/app/assets/javascripts/alerts_settings/constants.js @@ -1,5 +1,6 @@ import { s__ } from '~/locale'; +// TODO: Remove this as part of the form old removal export const i18n = { usageSection: s__( 'AlertSettings|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page.', @@ -17,11 +18,10 @@ export const i18n = { changesSaved: s__('AlertSettings|Your integration was successfully updated.'), prometheusInfo: s__('AlertSettings|Add URL and auth key to your Prometheus config file'), integrationsInfo: s__( - 'AlertSettings|Learn more about our improvements for %{linkStart}integrations%{linkEnd}', + 'AlertSettings|Learn more about our our upcoming %{linkStart}integrations%{linkEnd}', ), resetKey: s__('AlertSettings|Reset key'), copyToClipboard: s__('AlertSettings|Copy'), - integrationsLabel: s__('AlertSettings|Add new integrations'), apiBaseUrlLabel: s__('AlertSettings|API URL'), authKeyLabel: s__('AlertSettings|Authorization key'), urlLabel: s__('AlertSettings|Webhook URL'), @@ -40,12 +40,26 @@ export const i18n = { integration: s__('AlertSettings|Integration'), }; -export const serviceOptions = [ - { value: 'generic', text: s__('AlertSettings|HTTP Endpoint') }, - { value: 'prometheus', text: s__('AlertSettings|External Prometheus') }, - { value: 'opsgenie', text: s__('AlertSettings|Opsgenie') }, +// TODO: Delete as part of old form removal in 13.6 +export const integrationTypes = [ + { value: 'HTTP', text: s__('AlertSettings|HTTP Endpoint') }, + { value: 'PROMETHEUS', text: s__('AlertSettings|External Prometheus') }, + { value: 'OPSGENIE', text: s__('AlertSettings|Opsgenie') }, ]; +export const integrationTypesNew = [ + { value: '', text: s__('AlertSettings|Select integration type') }, + ...integrationTypes, +]; + +export const typeSet = { + http: 'HTTP', + prometheus: 'PROMETHEUS', + opsgenie: 'OPSGENIE', +}; + +export const integrationToDeleteDefault = { id: null, name: '' }; + export const JSON_VALIDATE_DELAY = 250; export const targetPrometheusUrlPlaceholder = 'http://prometheus.example.com/'; @@ -56,9 +70,9 @@ export const sectionHash = 'js-alert-management-settings'; /* eslint-disable @gitlab/require-i18n-strings */ /** - * Tracks snowplow event when user views alerts intergration list + * Tracks snowplow event when user views alerts integration list */ -export const trackAlertIntergrationsViewsOptions = { - category: 'Alert Intergrations', +export const trackAlertIntegrationsViewsOptions = { + category: 'Alert Integrations', action: 'view_alert_integrations_list', }; diff --git a/app/assets/javascripts/alerts_settings/graphql.js b/app/assets/javascripts/alerts_settings/graphql.js new file mode 100644 index 00000000000..02c2def87fa --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql.js @@ -0,0 +1,44 @@ +import Vue from 'vue'; +import produce from 'immer'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import getCurrentIntegrationQuery from './graphql/queries/get_current_integration.query.graphql'; + +Vue.use(VueApollo); + +const resolvers = { + Mutation: { + updateCurrentIntegration: ( + _, + { id = null, name, active, token, type, url, apiUrl }, + { cache }, + ) => { + const sourceData = cache.readQuery({ query: getCurrentIntegrationQuery }); + const data = produce(sourceData, draftData => { + if (id === null) { + // eslint-disable-next-line no-param-reassign + draftData.currentIntegration = null; + } else { + // eslint-disable-next-line no-param-reassign + draftData.currentIntegration = { + id, + name, + active, + token, + type, + url, + apiUrl, + }; + } + }); + cache.writeQuery({ query: getCurrentIntegrationQuery, data }); + }, + }, +}; + +export default new VueApollo({ + defaultClient: createDefaultClient(resolvers, { + cacheConfig: {}, + assumeImmutableResults: true, + }), +}); diff --git a/app/assets/javascripts/alerts_settings/graphql/fragments/integration_item.fragment.graphql b/app/assets/javascripts/alerts_settings/graphql/fragments/integration_item.fragment.graphql new file mode 100644 index 00000000000..6d9307959df --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/fragments/integration_item.fragment.graphql @@ -0,0 +1,9 @@ +fragment IntegrationItem on AlertManagementIntegration { + id + type + active + name + url + token + apiUrl +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql new file mode 100644 index 00000000000..d1dacbad40a --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation createHttpIntegration($projectPath: ID!, $name: String!, $active: Boolean!) { + httpIntegrationCreate(input: { projectPath: $projectPath, name: $name, active: $active }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/create_prometheus_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/create_prometheus_integration.mutation.graphql new file mode 100644 index 00000000000..bb22795ddd5 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/create_prometheus_integration.mutation.graphql @@ -0,0 +1,12 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation createPrometheusIntegration($projectPath: ID!, $apiUrl: String!, $active: Boolean!) { + prometheusIntegrationCreate( + input: { projectPath: $projectPath, apiUrl: $apiUrl, active: $active } + ) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/destroy_http_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/destroy_http_integration.mutation.graphql new file mode 100644 index 00000000000..0a49c140e6a --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/destroy_http_integration.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation destroyHttpIntegration($id: ID!) { + httpIntegrationDestroy(input: { id: $id }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql new file mode 100644 index 00000000000..178d1e13047 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation resetHttpIntegrationToken($id: ID!) { + httpIntegrationResetToken(input: { id: $id }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql new file mode 100644 index 00000000000..8f34521b9fd --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation resetPrometheusIntegrationToken($id: ID!) { + prometheusIntegrationResetToken(input: { id: $id }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/update_current_intergration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/update_current_intergration.mutation.graphql new file mode 100644 index 00000000000..3505241309e --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/update_current_intergration.mutation.graphql @@ -0,0 +1,19 @@ +mutation updateCurrentIntegration( + $id: String + $name: String + $active: Boolean + $token: String + $type: String + $url: String + $apiUrl: String +) { + updateCurrentIntegration( + id: $id + name: $name + active: $active + token: $token + type: $type + url: $url + apiUrl: $apiUrl + ) @client +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql new file mode 100644 index 00000000000..bb5b334deeb --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation updateHttpIntegration($id: ID!, $name: String!, $active: Boolean!) { + httpIntegrationUpdate(input: { id: $id, name: $name, active: $active }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql new file mode 100644 index 00000000000..62761730bd2 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation updatePrometheusIntegration($id: ID!, $apiUrl: String!, $active: Boolean!) { + prometheusIntegrationUpdate(input: { id: $id, apiUrl: $apiUrl, active: $active }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/queries/get_current_integration.query.graphql b/app/assets/javascripts/alerts_settings/graphql/queries/get_current_integration.query.graphql new file mode 100644 index 00000000000..4f22849a618 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/queries/get_current_integration.query.graphql @@ -0,0 +1,3 @@ +query currentIntegration { + currentIntegration @client +} diff --git a/app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql b/app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql new file mode 100644 index 00000000000..228dd5fb176 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql @@ -0,0 +1,11 @@ +#import "../fragments/integration_item.fragment.graphql" + +query getIntegrations($projectPath: ID!) { + project(fullPath: $projectPath) { + alertManagementIntegrations { + nodes { + ...IntegrationItem + } + } + } +} diff --git a/app/assets/javascripts/alerts_settings/index.js b/app/assets/javascripts/alerts_settings/index.js index 8d1d342d229..41b19a675c5 100644 --- a/app/assets/javascripts/alerts_settings/index.js +++ b/app/assets/javascripts/alerts_settings/index.js @@ -1,6 +1,15 @@ import Vue from 'vue'; +import { GlToast } from '@gitlab/ui'; import { parseBoolean } from '~/lib/utils/common_utils'; -import AlertSettingsForm from './components/alerts_settings_form.vue'; +import AlertSettingsWrapper from './components/alerts_settings_wrapper.vue'; +import apolloProvider from './graphql'; + +apolloProvider.clients.defaultClient.cache.writeData({ + data: { + currentIntegration: null, + }, +}); +Vue.use(GlToast); export default el => { if (!el) { @@ -24,20 +33,17 @@ export default el => { opsgenieMvcFormPath, opsgenieMvcEnabled, opsgenieMvcTargetUrl, + projectPath, + multiIntegrations, } = el.dataset; - const genericActivated = parseBoolean(activatedStr); - const prometheusIsActivated = parseBoolean(prometheusActivated); - const opsgenieMvcActivated = parseBoolean(opsgenieMvcEnabled); - const opsgenieMvcIsAvailable = parseBoolean(opsgenieMvcAvailable); - return new Vue({ el, provide: { prometheus: { - activated: prometheusIsActivated, - prometheusUrl, - authorizationKey: prometheusAuthorizationKey, + active: parseBoolean(prometheusActivated), + url: prometheusUrl, + token: prometheusAuthorizationKey, prometheusFormPath, prometheusResetKeyPath, prometheusApiUrl, @@ -45,23 +51,26 @@ export default el => { generic: { alertsSetupUrl, alertsUsageUrl, - activated: genericActivated, + active: parseBoolean(activatedStr), formPath, - authorizationKey, + token: authorizationKey, url, }, opsgenie: { formPath: opsgenieMvcFormPath, - activated: opsgenieMvcActivated, + active: parseBoolean(opsgenieMvcEnabled), opsgenieMvcTargetUrl, - opsgenieMvcIsAvailable, + opsgenieMvcIsAvailable: parseBoolean(opsgenieMvcAvailable), }, + projectPath, + multiIntegrations: parseBoolean(multiIntegrations), }, + apolloProvider, components: { - AlertSettingsForm, + AlertSettingsWrapper, }, render(createElement) { - return createElement('alert-settings-form'); + return createElement('alert-settings-wrapper'); }, }); }; diff --git a/app/assets/javascripts/alerts_settings/services/index.js b/app/assets/javascripts/alerts_settings/services/index.js index c49992d4f57..1835d6b46aa 100644 --- a/app/assets/javascripts/alerts_settings/services/index.js +++ b/app/assets/javascripts/alerts_settings/services/index.js @@ -2,6 +2,7 @@ import axios from '~/lib/utils/axios_utils'; export default { + // TODO: All this code save updateTestAlert will be deleted as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/255501 updateGenericKey({ endpoint, params }) { return axios.put(endpoint, params); }, @@ -25,11 +26,11 @@ export default { }, }); }, - updateTestAlert({ endpoint, data, authKey }) { + updateTestAlert({ endpoint, data, token }) { return axios.post(endpoint, data, { headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${authKey}`, + Authorization: `Bearer ${token}`, }, }); }, diff --git a/app/assets/javascripts/alerts_settings/utils/cache_updates.js b/app/assets/javascripts/alerts_settings/utils/cache_updates.js new file mode 100644 index 00000000000..18054b29fe9 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/utils/cache_updates.js @@ -0,0 +1,84 @@ +import produce from 'immer'; +import createFlash from '~/flash'; + +import { DELETE_INTEGRATION_ERROR, ADD_INTEGRATION_ERROR } from './error_messages'; + +const deleteIntegrationFromStore = (store, query, { httpIntegrationDestroy }, variables) => { + const integration = httpIntegrationDestroy?.integration; + if (!integration) { + return; + } + + const sourceData = store.readQuery({ + query, + variables, + }); + + const data = produce(sourceData, draftData => { + // eslint-disable-next-line no-param-reassign + draftData.project.alertManagementIntegrations.nodes = draftData.project.alertManagementIntegrations.nodes.filter( + ({ id }) => id !== integration.id, + ); + }); + + store.writeQuery({ + query, + variables, + data, + }); +}; + +const addIntegrationToStore = ( + store, + query, + { httpIntegrationCreate, prometheusIntegrationCreate }, + variables, +) => { + const integration = + httpIntegrationCreate?.integration || prometheusIntegrationCreate?.integration; + if (!integration) { + return; + } + + const sourceData = store.readQuery({ + query, + variables, + }); + + const data = produce(sourceData, draftData => { + // eslint-disable-next-line no-param-reassign + draftData.project.alertManagementIntegrations.nodes = [ + integration, + ...draftData.project.alertManagementIntegrations.nodes, + ]; + }); + + store.writeQuery({ + query, + variables, + data, + }); +}; + +const onError = (data, message) => { + createFlash({ message }); + throw new Error(data.errors); +}; + +export const hasErrors = ({ errors = [] }) => errors?.length; + +export const updateStoreAfterIntegrationDelete = (store, query, data, variables) => { + if (hasErrors(data)) { + onError(data, DELETE_INTEGRATION_ERROR); + } else { + deleteIntegrationFromStore(store, query, data, variables); + } +}; + +export const updateStoreAfterIntegrationAdd = (store, query, data, variables) => { + if (hasErrors(data)) { + onError(data, ADD_INTEGRATION_ERROR); + } else { + addIntegrationToStore(store, query, data, variables); + } +}; diff --git a/app/assets/javascripts/alerts_settings/utils/error_messages.js b/app/assets/javascripts/alerts_settings/utils/error_messages.js new file mode 100644 index 00000000000..979d1ca3ccc --- /dev/null +++ b/app/assets/javascripts/alerts_settings/utils/error_messages.js @@ -0,0 +1,21 @@ +import { s__ } from '~/locale'; + +export const DELETE_INTEGRATION_ERROR = s__( + 'AlertsIntegrations|The integration could not be deleted. Please try again.', +); + +export const ADD_INTEGRATION_ERROR = s__( + 'AlertsIntegrations|The integration could not be added. Please try again.', +); + +export const UPDATE_INTEGRATION_ERROR = s__( + 'AlertsIntegrations|The current integration could not be updated. Please try again.', +); + +export const RESET_INTEGRATION_TOKEN_ERROR = s__( + 'AlertsIntegrations|The integration token could not be reset. Please try again.', +); + +export const INTEGRATION_PAYLOAD_TEST_ERROR = s__( + 'AlertsIntegrations|Integration payload is invalid. You can still save your changes.', +); diff --git a/app/assets/javascripts/analytics/instance_statistics/components/app.vue b/app/assets/javascripts/analytics/instance_statistics/components/app.vue index 7aa5c98aa0b..8df4d2e2524 100644 --- a/app/assets/javascripts/analytics/instance_statistics/components/app.vue +++ b/app/assets/javascripts/analytics/instance_statistics/components/app.vue @@ -1,19 +1,23 @@ @@ -25,6 +29,20 @@ export default { :end-date="$options.TODAY" :total-data-points="$options.TOTAL_DAYS_TO_SHOW" /> - + +
diff --git a/app/assets/javascripts/analytics/instance_statistics/components/charts_config.js b/app/assets/javascripts/analytics/instance_statistics/components/charts_config.js new file mode 100644 index 00000000000..6fba3c56cfe --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/components/charts_config.js @@ -0,0 +1,87 @@ +import { s__, __, sprintf } from '~/locale'; +import query from '../graphql/queries/instance_count.query.graphql'; + +const noDataMessage = s__('InstanceStatistics|No data available.'); + +export default [ + { + loadChartError: sprintf( + s__( + 'InstanceStatistics|Could not load the pipelines chart. Please refresh the page to try again.', + ), + ), + noDataMessage, + chartTitle: s__('InstanceStatistics|Pipelines'), + yAxisTitle: s__('InstanceStatistics|Items'), + xAxisTitle: s__('InstanceStatistics|Month'), + queries: [ + { + query, + title: s__('InstanceStatistics|Pipelines total'), + identifier: 'PIPELINES', + loadError: sprintf( + s__('InstanceStatistics|There was an error fetching the total pipelines'), + ), + }, + { + query, + title: s__('InstanceStatistics|Pipelines succeeded'), + identifier: 'PIPELINES_SUCCEEDED', + loadError: sprintf( + s__('InstanceStatistics|There was an error fetching the successful pipelines'), + ), + }, + { + query, + title: s__('InstanceStatistics|Pipelines failed'), + identifier: 'PIPELINES_FAILED', + loadError: sprintf( + s__('InstanceStatistics|There was an error fetching the failed pipelines'), + ), + }, + { + query, + title: s__('InstanceStatistics|Pipelines canceled'), + identifier: 'PIPELINES_CANCELED', + loadError: sprintf( + s__('InstanceStatistics|There was an error fetching the cancelled pipelines'), + ), + }, + { + query, + title: s__('InstanceStatistics|Pipelines skipped'), + identifier: 'PIPELINES_SKIPPED', + loadError: sprintf( + s__('InstanceStatistics|There was an error fetching the skipped pipelines'), + ), + }, + ], + }, + { + loadChartError: sprintf( + s__( + 'InstanceStatistics|Could not load the issues and merge requests chart. Please refresh the page to try again.', + ), + ), + noDataMessage, + chartTitle: s__('InstanceStatistics|Issues & Merge Requests'), + yAxisTitle: s__('InstanceStatistics|Items'), + xAxisTitle: s__('InstanceStatistics|Month'), + queries: [ + { + query, + title: __('Issues'), + identifier: 'ISSUES', + loadError: sprintf(s__('InstanceStatistics|There was an error fetching the issues')), + }, + { + query, + title: __('Merge requests'), + identifier: 'MERGE_REQUESTS', + loadError: sprintf( + s__('InstanceStatistics|There was an error fetching the merge requests'), + ), + }, + ], + }, +]; diff --git a/app/assets/javascripts/analytics/instance_statistics/components/instance_statistics_count_chart.vue b/app/assets/javascripts/analytics/instance_statistics/components/instance_statistics_count_chart.vue new file mode 100644 index 00000000000..a9bd1bb2f41 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/components/instance_statistics_count_chart.vue @@ -0,0 +1,206 @@ + + diff --git a/app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue b/app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue deleted file mode 100644 index b16d960402b..00000000000 --- a/app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue +++ /dev/null @@ -1,215 +0,0 @@ - - diff --git a/app/assets/javascripts/analytics/instance_statistics/components/projects_and_groups_chart.vue b/app/assets/javascripts/analytics/instance_statistics/components/projects_and_groups_chart.vue new file mode 100644 index 00000000000..e8e35c22fe1 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/components/projects_and_groups_chart.vue @@ -0,0 +1,224 @@ + + diff --git a/app/assets/javascripts/analytics/instance_statistics/graphql/queries/groups.query.graphql b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/groups.query.graphql new file mode 100644 index 00000000000..ec56d91ffaa --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/groups.query.graphql @@ -0,0 +1,13 @@ +#import "~/graphql_shared/fragments/pageInfo.fragment.graphql" +#import "../fragments/count.fragment.graphql" + +query getGroupsCount($first: Int, $after: String) { + groups: instanceStatisticsMeasurements(identifier: GROUPS, first: $first, after: $after) { + nodes { + ...Count + } + pageInfo { + ...PageInfo + } + } +} diff --git a/app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_count.query.graphql b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_count.query.graphql new file mode 100644 index 00000000000..dd22a16cd51 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_count.query.graphql @@ -0,0 +1,13 @@ +#import "~/graphql_shared/fragments/pageInfo.fragment.graphql" +#import "../fragments/count.fragment.graphql" + +query getCount($identifier: MeasurementIdentifier!, $first: Int, $after: String) { + instanceStatisticsMeasurements(identifier: $identifier, first: $first, after: $after) { + nodes { + ...Count + } + pageInfo { + ...PageInfo + } + } +} diff --git a/app/assets/javascripts/analytics/instance_statistics/graphql/queries/pipeline_stats.query.graphql b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/pipeline_stats.query.graphql deleted file mode 100644 index 3bf40403f91..00000000000 --- a/app/assets/javascripts/analytics/instance_statistics/graphql/queries/pipeline_stats.query.graphql +++ /dev/null @@ -1,76 +0,0 @@ -#import "~/graphql_shared/fragments/pageInfo.fragment.graphql" -#import "./count.fragment.graphql" - -query pipelineStats( - $firstTotal: Int - $firstSucceeded: Int - $firstFailed: Int - $firstCanceled: Int - $firstSkipped: Int - $endCursorTotal: String - $endCursorSucceeded: String - $endCursorFailed: String - $endCursorCanceled: String - $endCursorSkipped: String -) { - pipelinesTotal: instanceStatisticsMeasurements( - identifier: PIPELINES - first: $firstTotal - after: $endCursorTotal - ) { - nodes { - ...Count - } - pageInfo { - ...PageInfo - } - } - pipelinesSucceeded: instanceStatisticsMeasurements( - identifier: PIPELINES_SUCCEEDED - first: $firstSucceeded - after: $endCursorSucceeded - ) { - nodes { - ...Count - } - pageInfo { - ...PageInfo - } - } - pipelinesFailed: instanceStatisticsMeasurements( - identifier: PIPELINES_FAILED - first: $firstFailed - after: $endCursorFailed - ) { - nodes { - ...Count - } - pageInfo { - ...PageInfo - } - } - pipelinesCanceled: instanceStatisticsMeasurements( - identifier: PIPELINES_CANCELED - first: $firstCanceled - after: $endCursorCanceled - ) { - nodes { - ...Count - } - pageInfo { - ...PageInfo - } - } - pipelinesSkipped: instanceStatisticsMeasurements( - identifier: PIPELINES_SKIPPED - first: $firstSkipped - after: $endCursorSkipped - ) { - nodes { - ...Count - } - pageInfo { - ...PageInfo - } - } -} diff --git a/app/assets/javascripts/analytics/instance_statistics/graphql/queries/projects.query.graphql b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/projects.query.graphql new file mode 100644 index 00000000000..0845b703435 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/projects.query.graphql @@ -0,0 +1,13 @@ +#import "~/graphql_shared/fragments/pageInfo.fragment.graphql" +#import "../fragments/count.fragment.graphql" + +query getProjectsCount($first: Int, $after: String) { + projects: instanceStatisticsMeasurements(identifier: PROJECTS, first: $first, after: $after) { + nodes { + ...Count + } + pageInfo { + ...PageInfo + } + } +} diff --git a/app/assets/javascripts/analytics/instance_statistics/utils.js b/app/assets/javascripts/analytics/instance_statistics/utils.js index 907482c0c72..e1fa5d155a2 100644 --- a/app/assets/javascripts/analytics/instance_statistics/utils.js +++ b/app/assets/javascripts/analytics/instance_statistics/utils.js @@ -1,5 +1,5 @@ import { masks } from 'dateformat'; -import { mapKeys, mapValues, pick, sortBy } from 'lodash'; +import { get } from 'lodash'; import { formatDate } from '~/lib/utils/datetime_utility'; const { isoDate } = masks; @@ -41,29 +41,28 @@ export function getAverageByMonth(items = [], options = {}) { } /** - * Extracts values given a data set and a set of keys - * @example - * const data = { fooBar: { baz: 'quis' }, ignored: 'ignored' }; - * extractValues(data, ['fooBar'], 'foo', 'baz') => { bazBar: 'quis' } - * @param {Object} data set to extract values from - * @param {Array} dataKeys keys describing where to look for values in the data set - * @param {String} replaceKey name key to be replaced in the data set - * @param {String} nestedKey key nested in the data set to be extracted, - * this is also used to rename the newly created data set - * @return {Object} the newly created data set with the extracted values + * Takes an array of instance counts and returns the last item in the list + * @param {Array} arr array of instance counts in the form { count: Number, recordedAt: date String } + * @return {String} the 'recordedAt' value of the earliest item */ -export function extractValues(data, dataKeys = [], replaceKey, nestedKey) { - return mapKeys(pick(mapValues(data, nestedKey), dataKeys), (value, key) => - key.replace(replaceKey, nestedKey), - ); -} +export const getEarliestDate = (arr = []) => { + const len = arr.length; + return get(arr, `[${len - 1}].recordedAt`, null); +}; /** - * Creates a new array of items sorted by the date string of each item - * @param {Array} items [description] - * @param {String} items[0] date string - * @return {Array} the new sorted array. + * Takes an array of queries and produces an object with the query identifier as key + * and a supplied defaultValue as its value + * @param {Array} queries array of chart query configs, + * see ./analytics/instance_statistics/components/charts_config.js + * @param {any} defaultValue value to set each identifier to + * @return {Object} key value pair of the form { queryIdentifier: defaultValue } */ -export function sortByDate(items = []) { - return sortBy(items, ({ recordedAt }) => new Date(recordedAt).getTime()); -} +export const generateDataKeys = (queries, defaultValue) => + queries.reduce( + (acc, { identifier }) => ({ + ...acc, + [identifier]: defaultValue, + }), + {}, + ); diff --git a/app/assets/javascripts/analytics/product_analytics/components/activity_chart.vue b/app/assets/javascripts/analytics/product_analytics/components/activity_chart.vue index a475ff8fd25..2be9ebda87a 100644 --- a/app/assets/javascripts/analytics/product_analytics/components/activity_chart.vue +++ b/app/assets/javascripts/analytics/product_analytics/components/activity_chart.vue @@ -17,10 +17,13 @@ export default { }, }, computed: { - seriesData() { - return { - full: this.formattedData.keys.map((val, idx) => [val, this.formattedData.values[idx]]), - }; + barSeriesData() { + return [ + { + name: 'full', + data: this.formattedData.keys.map((val, idx) => [val, this.formattedData.values[idx]]), + }, + ]; }, }, }; @@ -30,7 +33,7 @@ export default {