From be834a25982746ffd85252ff502df42bb88cb9d5 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 5 Oct 2020 13:54:15 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-5-stable-ee --- .../cohorts/components/usage_ping_disabled.vue | 6 +- .../components/usage_ping_disabled.vue | 8 +- app/assets/javascripts/alert_handler.js | 22 +- .../alert_management/components/alert_details.vue | 120 ++-- .../components/alert_management_table.vue | 4 +- .../alert_management/components/alert_sidebar.vue | 1 - .../alert_management/components/alert_status.vue | 30 +- .../components/alert_summary_row.vue | 18 + .../components/sidebar/sidebar_assignee.vue | 8 +- .../components/sidebar/sidebar_assignees.vue | 64 +- .../components/system_notes/system_note.vue | 27 +- .../components/alerts_service_form.vue | 8 +- .../components/alerts_settings_form.vue | 14 +- .../instance_statistics/components/app.vue | 14 + .../components/instance_counts.vue | 64 ++ .../instance_statistics_count.query.graphql | 32 + .../analytics/instance_statistics/index.js | 24 + .../analytics/shared/components/metric_card.vue | 80 +++ app/assets/javascripts/api.js | 58 ++ app/assets/javascripts/awards_handler.js | 2 +- .../javascripts/badges/components/badge_form.vue | 4 +- .../badges/components/badge_list_row.vue | 29 +- .../batch_comments/components/draft_note.vue | 5 - .../batch_comments/components/preview_dropdown.vue | 111 +--- .../batch_comments/components/preview_item.vue | 17 +- .../batch_comments/components/publish_button.vue | 20 +- .../batch_comments/components/review_bar.vue | 47 +- .../stores/modules/batch_comments/actions.js | 22 - .../modules/batch_comments/mutation_types.js | 7 - .../stores/modules/batch_comments/mutations.js | 16 - .../stores/modules/batch_comments/state.js | 2 - .../behaviors/collapse_sidebar_on_window_resize.js | 10 +- app/assets/javascripts/behaviors/index.js | 3 + .../javascripts/behaviors/load_startup_css.js | 15 + .../javascripts/behaviors/shortcuts/shortcuts.js | 4 +- .../blob/components/blob_header_filepath.vue | 1 + .../components/web_ide_alert.vue | 50 -- .../javascripts/blob/suggest_web_ide_ci/index.js | 20 - app/assets/javascripts/blob/viewer/index.js | 4 +- app/assets/javascripts/blob_edit/blob_bundle.js | 6 - .../boards/components/board_blank_state.vue | 104 --- .../javascripts/boards/components/board_column.vue | 5 +- .../components/board_configuration_options.vue | 65 ++ .../javascripts/boards/components/board_form.vue | 25 +- .../javascripts/boards/components/modal/tabs.vue | 34 +- .../components/sidebar/board_editable_item.vue | 4 +- app/assets/javascripts/boards/ee_functions.js | 2 +- app/assets/javascripts/boards/index.js | 40 +- .../boards/queries/board.mutation.graphql | 11 + app/assets/javascripts/boards/stores/actions.js | 27 +- .../javascripts/boards/stores/boards_store.js | 63 +- .../javascripts/boards/stores/mutation_types.js | 4 +- app/assets/javascripts/boards/stores/mutations.js | 31 +- app/assets/javascripts/boards/stores/state.js | 1 - app/assets/javascripts/build_artifacts.js | 18 +- .../components/triggers_list.vue | 143 +++++ .../ci_settings_pipeline_triggers/index.js | 36 ++ .../components/ci_variable_modal.vue | 16 - .../components/ci_variable_table.vue | 5 +- .../clusters/components/applications.vue | 2 +- .../components/crossplane_provider_stack.vue | 18 +- .../components/fluentd_output_settings.vue | 35 +- .../components/ingress_modsecurity_settings.vue | 42 +- .../clusters/components/knative_domain_editor.vue | 26 +- .../clusters_list/components/clusters.vue | 33 +- .../components/node_error_help_text.vue | 53 ++ app/assets/javascripts/clusters_list/constants.js | 43 +- app/assets/javascripts/clusters_list/index.js | 18 +- .../javascripts/clusters_list/load_clusters.js | 18 + app/assets/javascripts/code_navigation/index.js | 10 +- .../javascripts/code_navigation/store/index.js | 11 +- .../commit/pipelines/pipelines_table.vue | 124 ++-- app/assets/javascripts/commons/index.js | 1 - app/assets/javascripts/commons/jquery.js | 4 - app/assets/javascripts/confirm_danger_modal.js | 10 +- app/assets/javascripts/confirm_modal.js | 12 +- .../eks_cluster/components/create_eks_cluster.vue | 5 + .../components/eks_cluster_configuration_form.vue | 299 ++++----- .../create_cluster/eks_cluster/index.js | 2 + .../create_cluster/eks_cluster/store/actions.js | 5 + .../eks_cluster/store/mutation_types.js | 1 + .../create_cluster/eks_cluster/store/mutations.js | 3 + .../create_cluster/eks_cluster/store/state.js | 1 + .../components/delete_custom_metric_modal.vue | 8 +- .../components/limit_warning_component.vue | 23 +- .../components/stage_staging_component.vue | 8 +- .../cycle_analytics/cycle_analytics_bundle.js | 6 - .../components/deploy_freeze_table.vue | 18 +- .../design_management/components/delete_button.vue | 2 +- .../components/design_sidebar.vue | 2 +- .../design_management/components/list/item.vue | 1 + .../components/toolbar/design_navigation.vue | 4 +- .../design_management/components/toolbar/index.vue | 8 +- .../graphql/queries/get_design_list.query.graphql | 1 + .../design_management/mixins/all_designs.js | 26 +- .../javascripts/design_management/pages/index.vue | 33 +- .../design_management/utils/cache_update.js | 1 + .../utils/design_management_utils.js | 4 + .../diff_notes/components/comment_resolve_btn.js | 65 -- .../diff_notes/components/diff_note_avatars.js | 189 ------ .../diff_notes/components/jump_to_discussion.js | 210 ------- .../components/new_issue_for_discussion.js | 28 - .../diff_notes/components/resolve_btn.js | 145 ----- .../diff_notes/components/resolve_count.js | 28 - .../javascripts/diff_notes/diff_notes_bundle.js | 72 --- .../javascripts/diff_notes/icons/collapse_icon.svg | 1 - .../javascripts/diff_notes/mixins/discussion.js | 37 -- .../javascripts/diff_notes/models/discussion.js | 99 --- app/assets/javascripts/diff_notes/models/note.js | 14 - .../javascripts/diff_notes/services/resolve.js | 86 --- .../javascripts/diff_notes/stores/comments.js | 56 -- app/assets/javascripts/diffs/components/app.vue | 4 +- .../diffs/components/collapsed_files_warning.vue | 2 +- .../javascripts/diffs/components/commit_item.vue | 10 +- .../javascripts/diffs/components/commit_widget.vue | 13 - .../diffs/components/compare_dropdown_layout.vue | 2 +- .../diffs/components/compare_versions.vue | 1 + .../javascripts/diffs/components/diff_content.vue | 8 +- .../javascripts/diffs/components/diff_file.vue | 46 +- .../diffs/components/diff_file_header.vue | 212 ++++--- .../javascripts/diffs/components/diff_row_utils.js | 99 +++ .../javascripts/diffs/components/diff_stats.vue | 2 +- .../diffs/components/diff_table_cell.vue | 206 ------ .../javascripts/diffs/components/edit_button.vue | 64 -- .../diffs/components/inline_diff_table_row.vue | 95 +-- .../diffs/components/parallel_diff_comment_row.vue | 8 +- .../diffs/components/parallel_diff_table_row.vue | 182 ++---- app/assets/javascripts/diffs/diff_file.js | 12 + app/assets/javascripts/diffs/i18n.js | 14 - app/assets/javascripts/diffs/store/actions.js | 9 +- app/assets/javascripts/diffs/store/getters.js | 50 +- app/assets/javascripts/diffs/store/mutations.js | 4 +- app/assets/javascripts/emoji/index.js | 125 ++-- .../components/enable_review_app_button.vue | 2 +- .../environments/components/environments_app.vue | 103 ++- .../environments/components/environments_table.vue | 1 - .../components/stop_environment_modal.vue | 47 +- .../folder/environments_folder_view.vue | 24 +- .../error_tracking/components/stacktrace_entry.vue | 4 +- .../error_tracking_settings/components/app.vue | 18 +- .../components/error_tracking_form.vue | 15 +- .../components/configure_feature_flags_modal.vue | 254 ++++++++ .../feature_flags/components/edit_feature_flag.vue | 184 ++++++ .../components/environments_dropdown.vue | 184 ++++++ .../feature_flags/components/feature_flags.vue | 354 +++++++++++ .../feature_flags/components/feature_flags_tab.vue | 108 ++++ .../components/feature_flags_table.vue | 274 ++++++++ .../javascripts/feature_flags/components/form.vue | 616 ++++++++++++++++++ .../components/new_environments_dropdown.vue | 106 ++++ .../feature_flags/components/new_feature_flag.vue | 134 ++++ .../feature_flags/components/strategy.vue | 327 ++++++++++ .../feature_flags/components/user_lists_table.vue | 122 ++++ app/assets/javascripts/feature_flags/constants.js | 28 + app/assets/javascripts/feature_flags/edit.js | 33 + app/assets/javascripts/feature_flags/index.js | 41 ++ app/assets/javascripts/feature_flags/new.js | 32 + .../javascripts/feature_flags/store/index.js | 18 + .../feature_flags/store/modules/edit/actions.js | 75 +++ .../feature_flags/store/modules/edit/index.js | 10 + .../store/modules/edit/mutation_types.js | 12 + .../feature_flags/store/modules/edit/mutations.js | 45 ++ .../feature_flags/store/modules/edit/state.js | 18 + .../feature_flags/store/modules/helpers.js | 213 +++++++ .../feature_flags/store/modules/index/actions.js | 107 ++++ .../feature_flags/store/modules/index/index.js | 10 + .../store/modules/index/mutation_types.js | 26 + .../feature_flags/store/modules/index/mutations.js | 125 ++++ .../feature_flags/store/modules/index/state.js | 18 + .../feature_flags/store/modules/new/actions.js | 51 ++ .../feature_flags/store/modules/new/index.js | 10 + .../store/modules/new/mutation_types.js | 6 + .../feature_flags/store/modules/new/mutations.js | 21 + .../feature_flags/store/modules/new/state.js | 6 + app/assets/javascripts/feature_flags/utils.js | 48 ++ .../add_extra_tokens_for_merge_requests.js | 43 ++ .../filtered_search/available_dropdown_mappings.js | 5 + .../javascripts/filtered_search/constants.js | 2 +- app/assets/javascripts/frequent_items/utils.js | 2 +- app/assets/javascripts/gfm_auto_complete.js | 29 +- .../components/grafana_integration.vue | 8 +- .../javascripts/groups/components/group_folder.vue | 6 +- .../javascripts/groups/components/item_actions.vue | 2 + .../groups/components/item_stats_value.vue | 3 +- .../javascripts/groups/members/components/app.vue | 7 +- app/assets/javascripts/groups/members/index.js | 3 +- .../javascripts/ide/components/activity_bar.vue | 2 +- .../ide/components/commit_sidebar/actions.vue | 25 +- .../components/commit_sidebar/message_field.vue | 18 +- .../ide/components/editor_mode_dropdown.vue | 6 +- .../ide/components/file_templates/dropdown.vue | 5 +- app/assets/javascripts/ide/components/ide.vue | 58 ++ .../javascripts/ide/components/ide_review.vue | 30 +- .../javascripts/ide/components/ide_side_bar.vue | 18 +- app/assets/javascripts/ide/components/ide_tree.vue | 32 +- .../javascripts/ide/components/ide_tree_list.vue | 30 +- .../javascripts/ide/components/jobs/detail.vue | 7 +- .../ide/components/new_dropdown/modal.vue | 1 + .../ide/components/repo_commit_section.vue | 44 +- .../javascripts/ide/components/repo_editor.vue | 18 + app/assets/javascripts/ide/constants.js | 6 +- .../incidents/components/incidents_list.vue | 196 +++++- app/assets/javascripts/incidents/constants.js | 7 +- .../queries/get_count_by_status.query.graphql | 15 +- .../graphql/queries/get_incidents.query.graphql | 6 +- app/assets/javascripts/incidents/list.js | 6 + .../incidents_settings/components/alerts_form.vue | 22 +- .../components/pagerduty_form.vue | 40 +- app/assets/javascripts/init_issuable_sidebar.js | 8 +- .../edit/components/confirmation_modal.vue | 60 ++ .../edit/components/integration_form.vue | 26 +- .../components/invite_members_modal.vue | 224 +++++++ .../components/invite_members_trigger.vue | 38 ++ app/assets/javascripts/invite_members/event_hub.js | 3 + .../invite_members/init_invite_members_modal.js | 25 + .../invite_members/init_invite_members_trigger.js | 20 + app/assets/javascripts/issuable_context.js | 1 + .../issuable_create/components/issuable_form.vue | 1 + .../components/fields/description_template.vue | 11 +- .../components/incidents/highlight_bar.vue | 17 +- .../components/incidents/incident_tabs.vue | 9 +- app/assets/javascripts/issue_show/stores/index.js | 2 +- .../javascripts/issue_show/utils/parse_data.js | 10 +- app/assets/javascripts/jira_import/index.js | 2 +- .../queries/initiate_jira_import.mutation.graphql | 1 - .../javascripts/jira_import/utils/cache_update.js | 21 +- .../javascripts/jobs/components/commit_block.vue | 33 +- app/assets/javascripts/jobs/components/sidebar.vue | 15 +- app/assets/javascripts/jobs/store/utils.js | 4 +- app/assets/javascripts/layout_nav.js | 9 + app/assets/javascripts/lib/dompurify.js | 53 ++ app/assets/javascripts/lib/graphql.js | 1 + .../javascripts/lib/utils/axios_startup_calls.js | 2 +- app/assets/javascripts/lib/utils/common_utils.js | 1 + app/assets/javascripts/lib/utils/csrf.js | 8 - .../javascripts/lib/utils/datetime_utility.js | 19 + .../javascripts/lib/utils/experimentation.js | 3 + app/assets/javascripts/lib/utils/highlight.js | 2 +- app/assets/javascripts/lib/utils/rails_ujs.js | 20 + app/assets/javascripts/lib/utils/url_utility.js | 33 +- app/assets/javascripts/main.js | 13 +- app/assets/javascripts/members.js | 32 +- app/assets/javascripts/merge_request.js | 74 ++- app/assets/javascripts/merge_request_tabs.js | 4 - app/assets/javascripts/milestone.js | 11 +- .../monitoring/components/alert_widget_form.vue | 19 +- .../monitoring/components/group_empty_state.vue | 8 +- app/assets/javascripts/namespaces/leave_by_url.js | 3 + app/assets/javascripts/notebook/cells/markdown.vue | 2 +- .../javascripts/notebook/cells/output/html.vue | 2 +- app/assets/javascripts/notes.js | 45 -- .../javascripts/notes/components/comment_form.vue | 15 +- .../notes/components/diff_discussion_header.vue | 7 +- .../notes/components/diff_with_note.vue | 2 +- .../notes/components/discussion_counter.vue | 105 ++-- .../notes/components/discussion_filter.vue | 67 +- .../javascripts/notes/components/note_actions.vue | 5 +- .../javascripts/notes/components/note_body.vue | 3 +- .../javascripts/notes/components/note_form.vue | 13 +- .../notes/components/sort_discussion.vue | 46 +- .../notes/components/toggle_replies_widget.vue | 10 +- app/assets/javascripts/notes/index.js | 8 +- app/assets/javascripts/notes/stores/getters.js | 3 + app/assets/javascripts/notifications_dropdown.js | 7 +- .../components/metrics_settings.vue | 8 +- .../javascripts/packages/details/store/getters.js | 2 +- .../packages/list/components/package_title.vue | 47 ++ .../packages/list/components/packages_list_app.vue | 78 +-- .../packages/list/components/packages_sort.vue | 2 +- app/assets/javascripts/packages/list/constants.js | 34 +- app/assets/javascripts/packages/list/utils.js | 5 +- .../shared/components/package_list_row.vue | 16 +- .../packages/shared/components/package_path.vue | 71 +++ .../packages/shared/components/publish_method.vue | 3 +- .../pages/admin/instance_statistics/index.js | 3 + app/assets/javascripts/pages/admin/keys/index.js | 5 + .../javascripts/pages/admin/users/keys/index.js | 5 + .../pages/groups/group_members/index.js | 24 +- .../javascripts/pages/profiles/keys/index.js | 3 + .../javascripts/pages/projects/blob/show/index.js | 44 +- .../pages/projects/clusters/index/index.js | 2 +- .../pages/projects/commit/pipelines/index.js | 12 +- .../pages/projects/commit/show/index.js | 12 +- .../pages/projects/feature_flags/edit/index.js | 3 + .../pages/projects/feature_flags/index/index.js | 3 + .../pages/projects/feature_flags/new/index.js | 3 + .../feature_flags_user_lists/edit/index.js | 19 + .../projects/feature_flags_user_lists/new/index.js | 22 + .../feature_flags_user_lists/show/index.js | 18 + .../pages/projects/incidents/show/index.js | 7 + .../javascripts/pages/projects/issues/show.js | 2 +- .../components/pipeline_schedules_callout.vue | 11 +- .../shared/icons/intro_illustration.svg | 1 - .../pages/projects/settings/ci_cd/show/index.js | 3 + .../javascripts/pages/projects/tags/index/index.js | 12 + .../javascripts/pages/projects/tags/remove_tag.js | 16 + .../javascripts/pages/projects/tags/show/index.js | 10 + app/assets/javascripts/pages/search/show/index.js | 3 + .../performance_bar/performance_bar_log.js | 25 + app/assets/javascripts/performance_constants.js | 22 +- app/assets/javascripts/performance_utils.js | 12 + .../pipeline_new/components/pipeline_new_form.vue | 113 ++-- .../pipelines/components/dag/constants.js | 6 - .../javascripts/pipelines/components/dag/dag.vue | 11 +- .../pipelines/components/dag/dag_graph.vue | 10 +- .../components/graph/action_component.vue | 2 +- .../pipelines/components/graph/graph_component.vue | 40 +- .../components/graph/job_group_dropdown.vue | 21 - .../pipelines/components/graph/job_item.vue | 1 + .../components/graph/stage_column_component.vue | 2 +- .../pipelines/components/header_component.vue | 166 +++-- .../components/legacy_header_component.vue | 132 ++++ .../components/pipelines_list/empty_state.vue | 1 + .../components/pipelines_list/nav_controls.vue | 5 +- .../components/pipelines_list/pipeline_url.vue | 9 +- .../components/pipelines_list/pipelines_table.vue | 4 + .../components/pipelines_list/time_ago.vue | 7 +- app/assets/javascripts/pipelines/constants.js | 10 + .../queries/get_pipeline_header_data.query.graphql | 30 + .../pipelines/mixins/graph_component_mixin.js | 54 -- .../pipelines/pipeline_details_bundle.js | 16 +- .../pipelines/pipeline_details_header.js | 41 ++ .../pipelines/stores/test_reports/utils.js | 12 +- .../profile/account/components/update_username.vue | 10 +- app/assets/javascripts/profile/profile.js | 11 +- app/assets/javascripts/project_find_file.js | 2 +- .../javascripts/projects/commit_box/info/index.js | 18 + .../projects/commit_box/info/load_branches.js | 20 + .../projects/default_project_templates.js | 4 + .../projects/settings/access_dropdown.js | 136 +++- .../javascripts/projects/settings/constants.js | 7 + .../components/service_desk_root.vue | 12 +- .../components/service_desk_setting.vue | 42 +- .../javascripts/protected_branches/constants.js | 2 + .../protected_branches/protected_branch_create.js | 4 + .../details_page/partial_cleanup_alert.vue | 38 ++ .../components/details_page/tags_list_row.vue | 6 +- .../components/list_page/image_list_row.vue | 3 +- .../components/list_page/registry_header.vue | 79 +-- .../explorer/constants/expiration_policies.js | 4 + .../registry/explorer/pages/details.vue | 20 +- .../settings/components/registry_settings_app.vue | 50 +- .../registry/settings/components/settings_form.vue | 134 ++-- .../container_expiration_policy.fragment.graphql | 8 + .../javascripts/registry/settings/graphql/index.js | 14 + .../update_container_expiration_policy.graphql | 10 + .../graphql/queries/get_expiration_policy.graphql | 9 + .../settings/graphql/utils/cache_update.js | 22 + .../registry/settings/registry_settings_bundle.js | 12 +- .../javascripts/registry/settings/store/actions.js | 30 - .../javascripts/registry/settings/store/getters.js | 26 - .../javascripts/registry/settings/store/index.js | 18 - .../registry/settings/store/mutation_types.js | 5 - .../registry/settings/store/mutations.js | 29 - .../javascripts/registry/settings/store/state.js | 42 -- .../shared/components/expiration_policy_fields.vue | 32 +- .../javascripts/registry/shared/constants.js | 24 + app/assets/javascripts/registry/shared/utils.js | 27 + .../components/add_issuable_form.vue | 3 +- .../related_issues/components/issue_token.vue | 2 + .../components/related_issuable_input.vue | 3 +- .../releases/components/app_edit_new.vue | 35 +- .../javascripts/releases/components/app_index.vue | 49 +- .../javascripts/releases/components/app_show.vue | 6 +- .../releases/components/evidence_block.vue | 6 +- .../releases/components/release_block_assets.vue | 2 +- .../releases/components/release_block_header.vue | 8 +- .../components/release_skeleton_loader.vue | 51 ++ .../components/releases_pagination_graphql.vue | 6 +- .../components/releases_pagination_rest.vue | 8 +- app/assets/javascripts/releases/constants.js | 2 + .../releases/queries/all_releases.query.graphql | 11 +- app/assets/javascripts/releases/stores/getters.js | 11 + app/assets/javascripts/releases/stores/index.js | 2 + .../releases/stores/modules/detail/actions.js | 3 + .../stores/modules/detail/mutation_types.js | 1 + .../releases/stores/modules/detail/mutations.js | 5 + .../releases/stores/modules/list/actions.js | 109 ++-- .../releases/stores/modules/list/mutations.js | 7 +- .../releases/stores/modules/list/state.js | 3 +- app/assets/javascripts/releases/util.js | 6 +- .../repository/components/last_commit.vue | 30 +- .../repository/components/tree_content.vue | 5 +- app/assets/javascripts/repository/index.js | 8 +- app/assets/javascripts/repository/log_tree.js | 22 +- app/assets/javascripts/right_sidebar.js | 19 +- .../search/components/dropdown_filter.vue | 111 ++++ .../search/confidential_filter/constants.js | 28 + .../search/confidential_filter/index.js | 39 ++ .../state_filter/components/state_filter.vue | 94 --- .../javascripts/search/state_filter/constants.js | 4 +- .../javascripts/search/state_filter/index.js | 27 +- .../self_monitor/components/self_monitor_form.vue | 7 +- .../serverless/components/functions.vue | 12 +- .../serverless/components/missing_prometheus.vue | 8 +- .../components/confidential/edit_form_buttons.vue | 20 +- .../sidebar/components/labels/sidebar_labels.vue | 1 + .../sidebar/components/lock/edit_form_buttons.vue | 18 +- .../components/reviewers/collapsed_reviewer.vue | 24 + .../reviewers/collapsed_reviewer_list.vue | 107 ++++ .../components/reviewers/reviewer_avatar.vue | 43 ++ .../components/reviewers/reviewer_avatar_link.vue | 84 +++ .../components/reviewers/reviewer_title.vue | 64 ++ .../sidebar/components/reviewers/reviewers.vue | 72 +++ .../components/reviewers/sidebar_reviewers.vue | 107 ++++ .../reviewers/uncollapsed_reviewer_list.vue | 103 +++ .../time_tracking/sidebar_time_tracking.vue | 7 +- app/assets/javascripts/sidebar/mount_sidebar.js | 135 ++-- app/assets/javascripts/sidebar/sidebar_mediator.js | 12 + .../javascripts/sidebar/stores/sidebar_store.js | 29 + app/assets/javascripts/single_file_diff.js | 10 - app/assets/javascripts/snippet/snippet_show.js | 48 +- .../javascripts/snippets/components/edit.vue | 2 +- .../components/snippet_blob_actions_edit.vue | 1 + .../snippets/components/snippet_blob_edit.vue | 2 +- .../snippets/components/snippet_blob_view.vue | 7 +- .../components/snippet_description_edit.vue | 1 + .../snippets/components/snippet_header.vue | 2 + .../fragments/snippetBase.fragment.graphql | 26 +- app/assets/javascripts/snippets/index.js | 16 +- app/assets/javascripts/snippets/mixins/snippets.js | 11 +- .../queries/snippet.blob.content.query.graphql | 10 +- .../snippets/queries/snippet.query.graphql | 12 +- .../components/publish_toolbar.vue | 2 +- .../static_site_editor/graphql/index.js | 2 + .../has_submitted_changes.mutation.graphql | 5 + .../graphql/queries/app_data.query.graphql | 1 + .../graphql/resolvers/has_submitted_changes.js | 17 + .../graphql/resolvers/submit_content_changes.js | 31 +- .../static_site_editor/graphql/typedefs.graphql | 6 + app/assets/javascripts/static_site_editor/index.js | 12 +- .../javascripts/static_site_editor/pages/home.vue | 30 +- .../static_site_editor/pages/success.vue | 46 +- .../static_site_editor/services/front_matterify.js | 73 +++ .../services/parse_source_file.js | 17 +- .../services/submit_content_changes.js | 18 +- .../static_site_editor/services/templater.js | 2 +- app/assets/javascripts/task_list.js | 9 + app/assets/javascripts/tooltips/index.js | 2 + .../user_lists/components/add_user_modal.vue | 72 +++ .../user_lists/components/edit_user_list.vue | 74 +++ .../user_lists/components/new_user_list.vue | 50 ++ .../user_lists/components/user_list.vue | 142 +++++ .../user_lists/components/user_list_form.vue | 97 +++ .../javascripts/user_lists/constants/edit.js | 6 + .../javascripts/user_lists/constants/show.js | 8 + .../javascripts/user_lists/store/edit/actions.js | 22 + .../javascripts/user_lists/store/edit/index.js | 11 + .../user_lists/store/edit/mutation_types.js | 5 + .../javascripts/user_lists/store/edit/mutations.js | 19 + .../javascripts/user_lists/store/edit/state.js | 9 + .../javascripts/user_lists/store/new/actions.js | 15 + .../javascripts/user_lists/store/new/index.js | 11 + .../user_lists/store/new/mutation_types.js | 3 + .../javascripts/user_lists/store/new/mutations.js | 10 + .../javascripts/user_lists/store/new/state.js | 5 + .../javascripts/user_lists/store/show/actions.js | 32 + .../javascripts/user_lists/store/show/index.js | 11 + .../user_lists/store/show/mutation_types.js | 8 + .../javascripts/user_lists/store/show/mutations.js | 29 + .../javascripts/user_lists/store/show/state.js | 9 + app/assets/javascripts/user_lists/store/utils.js | 5 + app/assets/javascripts/user_popovers.js | 2 +- app/assets/javascripts/users_select/index.js | 38 +- .../components/deployment/deployment_actions.vue | 7 +- .../components/mr_widget_header.vue | 3 +- .../states/mr_widget_auto_merge_failed.vue | 14 +- .../components/states/mr_widget_merged.vue | 4 +- .../components/states/mr_widget_missing_branch.vue | 7 +- .../components/states/mr_widget_rebase.vue | 24 +- .../components/states/ready_to_merge.vue | 34 +- .../components/states/work_in_progress.vue | 4 +- .../vue_merge_request_widget/mr_widget_options.vue | 3 +- .../vue_shared/components/alert_details_table.vue | 31 +- .../vue_shared/components/ci_badge_link.vue | 16 +- .../vue_shared/components/clipboard_button.vue | 27 +- .../javascripts/vue_shared/components/commit.vue | 2 +- .../vue_shared/components/confirm_modal.vue | 11 +- .../components/dismissible_feedback_alert.vue | 14 +- .../components/dropdown/dropdown_search_input.vue | 5 + .../components/droplab_dropdown_button.vue | 92 --- .../vue_shared/components/file_finder/index.vue | 11 +- .../components/file_icon/file_icon_map.js | 6 + .../vue_shared/components/gl_mentions.vue | 55 +- .../vue_shared/components/header_ci_component.vue | 44 +- .../vue_shared/components/local_storage_sync.vue | 41 +- .../vue_shared/components/markdown/field.vue | 32 +- .../components/markdown/suggestion_diff.vue | 6 + .../components/markdown/suggestion_diff_header.vue | 7 +- .../vue_shared/components/markdown/suggestions.vue | 9 +- .../components/members/avatars/group_avatar.vue | 34 + .../components/members/avatars/invite_avatar.vue | 32 + .../components/members/avatars/user_avatar.vue | 80 +++ .../vue_shared/components/members/constants.js | 66 ++ .../components/members/table/created_at.vue | 40 ++ .../components/members/table/expires_at.vue | 66 ++ .../components/members/table/member_avatar.vue | 35 ++ .../components/members/table/member_source.vue | 27 + .../components/members/table/members_table.vue | 82 +++ .../members/table/members_table_cell.vue | 50 ++ .../vue_shared/components/members/utils.js | 19 + .../vue_shared/components/modal_copy_button.vue | 21 +- .../vue_shared/components/navigation_tabs.vue | 7 +- .../vue_shared/components/notes/skeleton_note.vue | 2 +- .../vue_shared/components/registry/title_area.vue | 76 ++- .../components/rich_content_editor/constants.js | 2 + .../rich_content_editor/services/editor_service.js | 2 + .../services/renderers/render_html_block.js | 18 +- .../rich_content_editor/services/sanitize_html.js | 22 + .../labels_select_vue/dropdown_contents.vue | 1 + .../dropdown_contents_labels_view.vue | 14 +- .../sidebar/labels_select_vue/dropdown_value.vue | 2 + .../vue_shared/components/todo_button.vue | 2 +- .../vue_shared/components/web_ide_link.vue | 12 +- .../vue_shared/mixins/ci_pagination_api_mixin.js | 4 + .../vue_shared/mixins/related_issuable_mixin.js | 2 +- .../vuex_shared/modules/members/state.js | 3 +- .../javascripts/whats_new/components/app.vue | 45 +- app/assets/javascripts/whats_new/index.js | 1 + app/assets/javascripts/whats_new/store/actions.js | 6 +- app/assets/stylesheets/_page_specific_files.scss | 5 - app/assets/stylesheets/application.scss | 20 +- app/assets/stylesheets/application_utilities.scss | 12 + .../stylesheets/application_utilities_dark.scss | 3 + .../components/design_management/design.scss | 4 + app/assets/stylesheets/components/whats_new.scss | 25 +- app/assets/stylesheets/fontawesome_custom.scss | 9 - app/assets/stylesheets/framework/animations.scss | 3 +- app/assets/stylesheets/framework/buttons.scss | 6 - app/assets/stylesheets/framework/dropdowns.scss | 109 ++-- app/assets/stylesheets/framework/files.scss | 4 +- app/assets/stylesheets/framework/header.scss | 12 - app/assets/stylesheets/framework/icons.scss | 1 + .../framework/secondary_navigation_elements.scss | 4 - app/assets/stylesheets/framework/typography.scss | 4 - app/assets/stylesheets/framework/variables.scss | 4 - app/assets/stylesheets/framework/wells.scss | 6 - .../page_bundles/_ide_theme_overrides.scss | 7 +- app/assets/stylesheets/page_bundles/boards.scss | 613 ++++++++++++++++++ .../stylesheets/page_bundles/cycle_analytics.scss | 355 +++++++++++ app/assets/stylesheets/page_bundles/issues.scss | 8 + app/assets/stylesheets/page_bundles/milestone.scss | 254 ++++++++ .../pages/alert_management/details.scss | 2 +- app/assets/stylesheets/pages/boards.scss | 613 ------------------ app/assets/stylesheets/pages/builds.scss | 11 +- app/assets/stylesheets/pages/commits.scss | 1 - app/assets/stylesheets/pages/cycle_analytics.scss | 353 ----------- app/assets/stylesheets/pages/diff.scss | 19 +- .../pages/experimental_separate_sign_up.scss | 4 + .../pages/incident_management_list.scss | 5 - app/assets/stylesheets/pages/issuable.scss | 13 +- app/assets/stylesheets/pages/labels.scss | 70 --- app/assets/stylesheets/pages/members.scss | 17 + app/assets/stylesheets/pages/merge_requests.scss | 9 +- app/assets/stylesheets/pages/milestone.scss | 252 -------- app/assets/stylesheets/pages/notes.scss | 50 +- app/assets/stylesheets/pages/pipelines.scss | 699 ++++++++++----------- app/assets/stylesheets/pages/profile.scss | 21 +- app/assets/stylesheets/pages/projects.scss | 7 +- app/assets/stylesheets/pages/settings_ci_cd.scss | 4 + app/assets/stylesheets/pages/tags.scss | 3 - app/assets/stylesheets/pages/ui_dev_kit.scss | 17 - app/assets/stylesheets/themes/_dark.scss | 2 + app/assets/stylesheets/utilities.scss | 15 + app/channels/application_cable/connection.rb | 6 +- .../admin/application_settings_controller.rb | 3 + .../concerns/authenticates_2fa_for_admin_mode.rb | 110 ---- app/controllers/admin/integrations_controller.rb | 3 +- app/controllers/admin/runners_controller.rb | 8 +- app/controllers/admin/sessions_controller.rb | 2 +- app/controllers/admin/users_controller.rb | 1 + app/controllers/application_controller.rb | 2 +- app/controllers/boards/issues_controller.rb | 2 + app/controllers/boards/lists_controller.rb | 4 +- app/controllers/clusters/clusters_controller.rb | 29 +- .../concerns/authenticates_with_two_factor.rb | 21 +- ...authenticates_with_two_factor_for_admin_mode.rb | 107 ++++ app/controllers/concerns/boards_actions.rb | 4 +- .../concerns/controller_with_feature_category.rb | 29 +- .../controller_with_feature_category/config.rb | 38 -- .../concerns/enforces_two_factor_authentication.rb | 2 +- app/controllers/concerns/integrations_actions.rb | 2 +- .../concerns/issuable_collections_action.rb | 5 +- app/controllers/concerns/milestone_actions.rb | 14 +- .../concerns/multiple_boards_actions.rb | 6 +- app/controllers/concerns/redis_tracking.rb | 1 - app/controllers/concerns/runner_setup_scripts.rb | 25 + .../concerns/show_inherited_labels_checker.rb | 11 + app/controllers/concerns/wiki_actions.rb | 2 +- app/controllers/confirmations_controller.rb | 2 + app/controllers/dashboard/groups_controller.rb | 2 + app/controllers/dashboard/labels_controller.rb | 2 + app/controllers/dashboard/milestones_controller.rb | 2 + app/controllers/dashboard/projects_controller.rb | 2 + app/controllers/dashboard/snippets_controller.rb | 2 + app/controllers/dashboard/todos_controller.rb | 2 + app/controllers/dashboard_controller.rb | 4 + app/controllers/explore/groups_controller.rb | 2 + app/controllers/explore/projects_controller.rb | 2 + app/controllers/explore/snippets_controller.rb | 2 + app/controllers/groups/group_links_controller.rb | 9 + app/controllers/groups/labels_controller.rb | 28 +- app/controllers/groups/milestones_controller.rb | 2 +- .../groups/registry/repositories_controller.rb | 4 +- .../groups/settings/ci_cd_controller.rb | 6 + app/controllers/import/bulk_imports_controller.rb | 51 ++ app/controllers/import/fogbugz_controller.rb | 2 +- app/controllers/import/github_controller.rb | 2 +- app/controllers/import/manifest_controller.rb | 11 +- app/controllers/invites_controller.rb | 57 +- app/controllers/omniauth_callbacks_controller.rb | 3 +- app/controllers/projects/blob_controller.rb | 3 +- .../daily_build_group_report_results_controller.rb | 7 +- app/controllers/projects/graphs_controller.rb | 1 - app/controllers/projects/group_links_controller.rb | 13 +- app/controllers/projects/incidents_controller.rb | 46 +- app/controllers/projects/issues_controller.rb | 4 +- app/controllers/projects/jobs_controller.rb | 5 - app/controllers/projects/labels_controller.rb | 3 +- .../merge_requests/application_controller.rb | 1 + .../projects/merge_requests/diffs_controller.rb | 2 +- .../projects/merge_requests_controller.rb | 23 +- app/controllers/projects/milestones_controller.rb | 4 +- .../projects/packages/packages_controller.rb | 9 - app/controllers/projects/pipelines_controller.rb | 3 +- .../projects/protected_refs_controller.rb | 2 +- .../projects/registry/repositories_controller.rb | 6 +- .../projects/registry/tags_controller.rb | 9 +- app/controllers/projects/releases_controller.rb | 2 +- app/controllers/projects/runners_controller.rb | 4 + app/controllers/projects/services_controller.rb | 2 +- .../projects/settings/ci_cd_controller.rb | 13 +- .../projects/settings/repository_controller.rb | 2 + .../projects/static_site_editor_controller.rb | 20 +- app/controllers/projects/tags_controller.rb | 23 +- app/controllers/runner_setup_controller.rb | 7 + app/controllers/search_controller.rb | 5 +- app/controllers/uploads_controller.rb | 1 + app/controllers/users_controller.rb | 2 +- app/finders/group_labels_finder.rb | 29 - app/finders/group_members_finder.rb | 28 +- app/finders/groups_finder.rb | 12 +- app/finders/merge_requests/by_approvals_finder.rb | 93 +++ app/finders/merge_requests_finder.rb | 16 +- app/finders/packages/generic/package_finder.rb | 22 + app/graphql/mutations/base_mutation.rb | 1 + app/graphql/mutations/boards/lists/destroy.rb | 41 ++ app/graphql/mutations/ci/base.rb | 7 +- app/graphql/mutations/design_management/move.rb | 11 +- .../metrics/dashboard/annotations/create.rb | 2 +- app/graphql/resolvers/base_resolver.rb | 1 + .../resolvers/board_list_issues_resolver.rb | 2 +- app/graphql/resolvers/board_lists_resolver.rb | 2 +- app/graphql/resolvers/board_resolver.rb | 27 + app/graphql/resolvers/boards_resolver.rb | 2 +- .../resolvers/concerns/issue_resolver_arguments.rb | 6 + app/graphql/resolvers/concerns/looks_ahead.rb | 4 - .../resolvers/concerns/resolves_merge_requests.rb | 2 +- app/graphql/resolvers/projects_resolver.rb | 7 +- app/graphql/resolvers/snippets/blobs_resolver.rb | 40 ++ app/graphql/resolvers/terraform/states_resolver.rb | 23 + .../measurement_identifier_enum.rb | 4 + .../design_collection_copy_state_enum.rb | 27 + .../design_management/design_collection_type.rb | 4 + app/graphql/types/global_id_type.rb | 16 + app/graphql/types/group_type.rb | 2 +- app/graphql/types/issue_sort_enum.rb | 2 + app/graphql/types/issue_type.rb | 21 +- app/graphql/types/merge_request_type.rb | 4 - app/graphql/types/mutation_type.rb | 2 + app/graphql/types/notes/noteable_type.rb | 32 +- app/graphql/types/project_member_type.rb | 7 +- app/graphql/types/project_type.rb | 8 +- app/graphql/types/query_type.rb | 15 +- app/graphql/types/snippet_type.rb | 19 +- app/graphql/types/sort_enum.rb | 15 +- app/graphql/types/terraform/state_type.rb | 37 ++ app/helpers/analytics/navbar_helper.rb | 2 +- app/helpers/analytics/unique_visits_helper.rb | 3 +- app/helpers/application_helper.rb | 18 +- app/helpers/application_settings_helper.rb | 9 +- app/helpers/avatars_helper.rb | 2 +- app/helpers/boards_helper.rb | 1 + app/helpers/clusters_helper.rb | 20 +- app/helpers/emails_helper.rb | 20 + app/helpers/events_helper.rb | 16 +- app/helpers/feature_flags_helper.rb | 19 + app/helpers/gitlab_routing_helper.rb | 12 + app/helpers/gitpod_helper.rb | 10 + app/helpers/groups/group_members_helper.rb | 21 +- app/helpers/invite_members_helper.rb | 7 + app/helpers/issuables_helper.rb | 19 +- app/helpers/issues_helper.rb | 15 + app/helpers/labels_helper.rb | 4 +- app/helpers/merge_requests_helper.rb | 4 - app/helpers/namespaces_helper.rb | 2 +- app/helpers/nav_helper.rb | 3 +- app/helpers/packages_helper.rb | 10 +- app/helpers/page_layout_helper.rb | 8 + app/helpers/preferences_helper.rb | 4 +- app/helpers/profiles_helper.rb | 15 + app/helpers/projects/incidents_helper.rb | 7 +- app/helpers/projects_helper.rb | 17 +- app/helpers/search_helper.rb | 14 +- app/helpers/services_helper.rb | 4 + app/helpers/suggest_pipeline_helper.rb | 2 +- app/helpers/system_note_helper.rb | 6 +- app/helpers/tags_helper.rb | 9 + app/helpers/timeboxes_helper.rb | 4 +- app/helpers/todos_helper.rb | 9 + app/helpers/tree_helper.rb | 10 +- app/helpers/user_callouts_helper.rb | 5 - app/helpers/whats_new_helper.rb | 22 + app/mailers/abuse_report_mailer.rb | 4 +- app/mailers/emails/members.rb | 9 + app/mailers/emails/merge_requests.rb | 11 + app/mailers/emails/projects.rb | 10 +- app/models/alert_management/alert.rb | 2 +- app/models/alert_management/http_integration.rb | 41 ++ .../analytics/instance_statistics/measurement.rb | 22 +- app/models/application_setting.rb | 2 +- app/models/application_setting/term.rb | 2 + app/models/audit_event.rb | 13 +- app/models/authentication_event.rb | 10 + app/models/ci/build.rb | 18 + app/models/ci/build_pending_state.rb | 6 + app/models/ci/build_trace_chunk.rb | 38 +- app/models/ci/build_trace_chunks/database.rb | 2 + app/models/ci/pipeline.rb | 7 +- app/models/clusters/applications/runner.rb | 2 +- app/models/clusters/platforms/kubernetes.rb | 3 +- app/models/commit.rb | 32 +- app/models/commit_status.rb | 9 +- app/models/concerns/approvable_base.rb | 24 + app/models/concerns/avatarable.rb | 15 +- app/models/concerns/checksummable.rb | 8 +- app/models/concerns/counter_attribute.rb | 29 +- app/models/concerns/integration.rb | 4 +- app/models/concerns/issuable.rb | 11 +- app/models/concerns/issue_available_features.rb | 23 + app/models/concerns/mentionable.rb | 16 - app/models/concerns/reactive_caching.rb | 3 +- app/models/concerns/reactive_service.rb | 1 + app/models/concerns/referable.rb | 2 +- app/models/concerns/relative_positioning.rb | 6 + app/models/concerns/update_project_statistics.rb | 5 +- app/models/container_repository.rb | 8 + app/models/data_list.rb | 10 +- app/models/design_management/design.rb | 10 +- app/models/design_management/design_collection.rb | 1 + app/models/environment.rb | 1 + app/models/event.rb | 14 +- app/models/group.rb | 109 ++-- app/models/group_import_state.rb | 3 +- app/models/issuable_severity.rb | 7 + app/models/issue.rb | 17 + app/models/issue_email_participant.rb | 13 + app/models/iteration.rb | 16 +- app/models/member.rb | 13 +- app/models/merge_request.rb | 28 +- app/models/merge_request_context_commit.rb | 4 +- app/models/merge_request_diff.rb | 6 +- app/models/namespace.rb | 50 ++ app/models/note.rb | 2 - app/models/notification_reason.rb | 2 + app/models/notification_recipient.rb | 2 +- app/models/notification_setting.rb | 1 + app/models/operations/feature_flags/strategy.rb | 33 +- app/models/packages/event.rb | 26 + app/models/packages/package.rb | 12 +- app/models/pages_deployment.rb | 4 + app/models/postgresql/replication_slot.rb | 4 +- app/models/project.rb | 33 +- app/models/project_services/drone_ci_service.rb | 4 +- app/models/project_statistics.rb | 31 +- app/models/project_tracing_setting.rb | 15 + app/models/prometheus_alert.rb | 2 + app/models/prometheus_metric.rb | 2 + app/models/repository.rb | 4 +- app/models/resource_label_event.rb | 11 + app/models/resource_state_event.rb | 25 + app/models/resource_timebox_event.rb | 15 + app/models/resource_weight_event.rb | 10 +- app/models/service.rb | 23 +- app/models/service_list.rb | 12 +- app/models/snippet_input_action_collection.rb | 6 +- app/models/snippet_repository.rb | 2 +- app/models/snippet_statistics.rb | 2 + app/models/system_note_metadata.rb | 4 +- app/models/terraform/state.rb | 13 +- app/models/terraform/state_version.rb | 6 + app/models/todo.rb | 2 +- app/models/user.rb | 18 +- app/models/user_callout.rb | 2 +- app/models/user_interacted_project.rb | 2 +- app/models/user_preference.rb | 3 + app/models/wiki.rb | 4 +- app/models/wiki_directory.rb | 39 +- app/models/wiki_page.rb | 23 - app/policies/base_policy.rb | 5 +- app/policies/group_policy.rb | 37 +- app/policies/issue_policy.rb | 9 - app/policies/project_policy.rb | 12 +- app/policies/releases/evidence_policy.rb | 1 + app/policies/terraform/state_policy.rb | 9 + app/presenters/alert_management/alert_presenter.rb | 33 +- app/presenters/event_presenter.rb | 22 + app/presenters/merge_request_presenter.rb | 2 +- app/presenters/project_presenter.rb | 6 +- .../projects/prometheus/alert_presenter.rb | 179 ------ app/presenters/sentry_error_presenter.rb | 2 +- app/presenters/snippet_presenter.rb | 10 +- app/serializers/ci/trigger_entity.rb | 42 ++ app/serializers/ci/trigger_serializer.rb | 7 + app/serializers/cluster_entity.rb | 2 + app/serializers/cluster_serializer.rb | 1 + app/serializers/container_repository_entity.rb | 1 + app/serializers/diff_file_base_entity.rb | 14 +- app/serializers/diffs_entity.rb | 4 +- app/serializers/feature_flag_entity.rb | 48 ++ app/serializers/feature_flag_scope_entity.rb | 12 + app/serializers/feature_flag_serializer.rb | 10 + app/serializers/feature_flag_summary_entity.rb | 19 + app/serializers/feature_flag_summary_serializer.rb | 5 + app/serializers/feature_flags/scope_entity.rb | 8 + app/serializers/feature_flags/strategy_entity.rb | 11 + app/serializers/feature_flags/user_list_entity.rb | 10 + app/serializers/feature_flags_client_entity.rb | 7 + app/serializers/feature_flags_client_serializer.rb | 9 + app/serializers/group_group_link_entity.rb | 20 + app/serializers/merge_request_basic_entity.rb | 1 + .../merge_request_poll_cached_widget_entity.rb | 12 +- .../merge_request_poll_widget_entity.rb | 16 +- app/serializers/merge_request_widget_entity.rb | 6 +- app/serializers/paginated_diff_entity.rb | 2 - app/serializers/pipeline_serializer.rb | 10 +- app/serializers/test_case_entity.rb | 1 + .../admin/propagate_integration_service.rb | 52 +- app/services/admin/propagate_service_template.rb | 6 - .../process_prometheus_alert_service.rb | 2 +- app/services/audit_event_service.rb | 21 +- app/services/boards/create_service.rb | 18 +- app/services/boards/lists/destroy_service.rb | 8 +- app/services/bulk_create_integration_service.rb | 59 ++ app/services/bulk_update_integration_service.rb | 32 + app/services/ci/create_job_artifacts_service.rb | 9 - app/services/ci/create_pipeline_service.rb | 3 +- .../ci/daily_build_group_report_result_service.rb | 2 - app/services/ci/expire_pipeline_cache_service.rb | 13 +- .../ci/pipelines/create_artifact_service.rb | 1 - app/services/ci/process_pipeline_service.rb | 4 +- app/services/ci/retry_build_service.rb | 2 +- app/services/ci/update_build_queue_service.rb | 4 +- app/services/ci/update_build_state_service.rb | 118 +++- app/services/concerns/admin/propagate_service.rb | 51 +- .../design_management/copy_design_collection.rb | 6 + .../copy_design_collection/copy_service.rb | 306 +++++++++ .../copy_design_collection/queue_service.rb | 42 ++ app/services/design_management/design_service.rb | 1 + .../generate_image_versions_service.rb | 3 + .../design_management/runs_design_actions.rb | 11 +- .../design_management/save_designs_service.rb | 9 +- app/services/feature_flags/base_service.rb | 55 ++ app/services/feature_flags/create_service.rb | 52 ++ app/services/feature_flags/destroy_service.rb | 33 + app/services/feature_flags/disable_service.rb | 46 ++ app/services/feature_flags/enable_service.rb | 93 +++ app/services/feature_flags/update_service.rb | 87 +++ app/services/git/branch_hooks_service.rb | 8 + app/services/git/wiki_push_service.rb | 4 +- app/services/groups/create_service.rb | 18 +- .../groups/import_export/import_service.rb | 2 +- app/services/groups/transfer_service.rb | 14 + app/services/groups/update_service.rb | 13 + .../groups/update_shared_runners_service.rb | 32 +- .../incidents/create_service.rb | 6 +- .../incidents/update_severity_service.rb | 38 ++ .../pager_duty/process_webhook_service.rb | 2 +- app/services/issuable/clone/attributes_rewriter.rb | 2 +- app/services/issuable_base_service.rb | 3 +- app/services/issues/move_service.rb | 25 +- app/services/lfs/push_service.rb | 16 +- .../members/invitation_reminder_email_service.rb | 54 ++ app/services/merge_requests/base_service.rb | 9 + app/services/merge_requests/export_csv_service.rb | 50 ++ app/services/merge_requests/ff_merge_service.rb | 2 +- app/services/merge_requests/merge_service.rb | 2 +- .../merge_requests/mergeability_check_service.rb | 2 +- app/services/merge_requests/refresh_service.rb | 2 +- app/services/merge_requests/update_service.rb | 2 + .../metrics/dashboard/custom_dashboard_service.rb | 6 + app/services/namespace_settings/update_service.rb | 25 + .../notification_recipients/builder/default.rb | 3 + app/services/notification_service.rb | 27 + app/services/packages/create_event_service.rb | 37 ++ app/services/packages/create_package_service.rb | 1 + .../generic/create_package_file_service.rb | 38 ++ .../generic/find_or_create_package_service.rb | 15 + app/services/pod_logs/base_service.rb | 2 + app/services/pod_logs/elasticsearch_service.rb | 1 - app/services/pod_logs/kubernetes_service.rb | 1 - app/services/projects/alerting/notify_service.rb | 75 ++- .../container_repository/cleanup_tags_service.rb | 5 +- .../container_repository/delete_tags_service.rb | 9 +- app/services/projects/create_service.rb | 15 +- .../projects/prometheus/alerts/notify_service.rb | 14 +- app/services/projects/transfer_service.rb | 4 + .../projects/update_remote_mirror_service.rb | 10 +- app/services/projects/update_service.rb | 4 +- app/services/quick_actions/target_service.rb | 4 + .../resource_access_tokens/create_service.rb | 13 +- app/services/search/global_service.rb | 10 +- app/services/search/group_service.rb | 2 +- app/services/search/project_service.rb | 18 +- app/services/snippets/base_service.rb | 18 + app/services/snippets/create_service.rb | 9 +- app/services/snippets/update_service.rb | 39 +- app/services/spam/spam_action_service.rb | 2 +- app/services/static_site_editor/config_service.rb | 66 +- app/services/system_note_service.rb | 8 + app/services/system_notes/incident_service.rb | 29 + app/services/system_notes/issuables_service.rb | 61 +- app/services/users/build_service.rb | 3 +- app/uploaders/pages/deployment_uploader.rb | 23 + app/validators/addressable_url_validator.rb | 2 +- app/validators/ip_address_validator.rb | 39 ++ .../admin/application_settings/_abuse.html.haml | 4 +- .../_account_and_limit.html.haml | 3 +- .../application_settings/_diff_limits.html.haml | 3 +- .../_external_authorization_service_form.html.haml | 3 +- .../admin/application_settings/_gitpod.html.haml | 3 +- .../_initial_branch_name.html.haml | 3 +- .../_repository_check.html.haml | 6 +- .../_repository_mirrors_form.html.haml | 3 +- .../_repository_static_objects.html.haml | 3 +- .../_repository_storage.html.haml | 3 +- .../admin/application_settings/_signin.html.haml | 3 +- .../admin/application_settings/_signup.html.haml | 11 +- .../admin/application_settings/_terminal.html.haml | 3 +- .../admin/application_settings/_terms.html.haml | 3 +- .../_visibility_and_access.html.haml | 3 +- .../admin/application_settings/general.html.haml | 3 +- app/views/admin/broadcast_messages/_form.html.haml | 6 +- .../admin/dashboard/_billable_users_text.html.haml | 1 + app/views/admin/dashboard/index.html.haml | 10 +- app/views/admin/dashboard/stats.html.haml | 2 - app/views/admin/groups/_form.html.haml | 2 - app/views/admin/groups/show.html.haml | 2 +- app/views/admin/hook_logs/show.html.haml | 2 +- app/views/admin/hooks/edit.html.haml | 4 +- app/views/admin/hooks/index.html.haml | 2 +- app/views/admin/labels/_form.html.haml | 4 +- app/views/admin/labels/_label.html.haml | 4 +- app/views/admin/labels/index.html.haml | 2 +- app/views/admin/projects/show.html.haml | 5 +- app/views/admin/users/_modals.html.haml | 2 +- app/views/admin/users/_user.html.haml | 7 +- app/views/admin/users/index.html.haml | 3 +- .../clusters/clusters/_advanced_settings.html.haml | 21 +- app/views/clusters/clusters/_buttons.html.haml | 6 - app/views/clusters/clusters/_cluster.html.haml | 19 - .../clusters/clusters/_cluster_list.html.haml | 12 + app/views/clusters/clusters/_empty_state.html.haml | 8 +- .../clusters/_gcp_signup_offer_banner.html.haml | 18 +- .../clusters/_provider_details_form.html.haml | 12 +- app/views/clusters/clusters/aws/_new.html.haml | 1 + app/views/clusters/clusters/gcp/_form.html.haml | 8 +- app/views/clusters/clusters/index.html.haml | 46 +- app/views/clusters/clusters/user/_form.html.haml | 8 +- app/views/dashboard/milestones/index.html.haml | 1 + app/views/dashboard/todos/_todo.html.haml | 2 +- app/views/dashboard/todos/index.html.haml | 2 +- .../mailer/confirmation_instructions.text.erb | 2 +- app/views/discussions/_diff_with_notes.html.haml | 2 +- app/views/discussions/_jump_to_next.html.haml | 9 - .../_new_issue_for_all_discussions.html.haml | 8 - .../_new_issue_for_discussion.html.haml | 10 - app/views/discussions/_notes.html.haml | 22 +- app/views/events/event/_common.html.haml | 2 +- app/views/groups/_invite_members_modal.html.haml | 6 + .../groups/_invite_members_side_nav_link.html.haml | 3 + app/views/groups/issues.html.haml | 5 +- app/views/groups/labels/destroy.js.haml | 2 - app/views/groups/labels/index.html.haml | 4 +- app/views/groups/milestones/index.html.haml | 1 + app/views/groups/milestones/show.html.haml | 1 + .../groups/registry/repositories/index.html.haml | 2 + app/views/groups/settings/_advanced.html.haml | 6 +- app/views/groups/settings/_export.html.haml | 5 +- app/views/groups/settings/_general.html.haml | 3 +- .../groups/settings/_permanent_deletion.html.haml | 3 +- app/views/groups/settings/_permissions.html.haml | 3 +- app/views/groups/show.html.haml | 2 + app/views/ide/_show.html.haml | 3 +- app/views/import/bulk_imports/status.html.haml | 1 + app/views/import/shared/_errors.html.haml | 8 +- app/views/invites/decline.html.haml | 8 + .../jira_connect/subscriptions/index.html.haml | 2 +- app/views/layouts/_head.html.haml | 22 +- app/views/layouts/_page.html.haml | 1 - app/views/layouts/_startup_css.haml | 2 +- app/views/layouts/_startup_css_activation.haml | 1 - app/views/layouts/group.html.haml | 4 +- app/views/layouts/header/_default.html.haml | 6 +- app/views/layouts/header/_new_dropdown.haml | 2 +- app/views/layouts/jira_connect.html.haml | 1 + app/views/layouts/nav/_dashboard.html.haml | 10 +- app/views/layouts/nav/sidebar/_admin.html.haml | 9 +- app/views/layouts/nav/sidebar/_group.html.haml | 2 + app/views/layouts/nav/sidebar/_project.html.haml | 10 +- app/views/layouts/project.html.haml | 4 +- app/views/notify/_failed_builds.html.haml | 2 +- .../notify/autodevops_disabled_email.html.haml | 2 +- .../notify/autodevops_disabled_email.text.erb | 2 +- ...anged_reviewer_of_merge_request_email.html.haml | 2 + ...hanged_reviewer_of_merge_request_email.text.erb | 1 + .../notify/issue_status_changed_email.text.erb | 1 - app/views/notify/pipeline_failed_email.html.haml | 2 +- app/views/notify/pipeline_failed_email.text.erb | 2 +- .../notify/prometheus_alert_fired_email.html.haml | 7 +- .../notify/prometheus_alert_fired_email.text.erb | 6 +- app/views/profiles/keys/_form.html.haml | 6 +- app/views/profiles/keys/_key.html.haml | 11 +- app/views/profiles/keys/_key_details.html.haml | 2 +- app/views/profiles/preferences/_gitpod.html.haml | 4 +- app/views/profiles/preferences/show.html.haml | 2 +- app/views/profiles/two_factor_auths/show.html.haml | 13 +- app/views/projects/_export.html.haml | 5 +- app/views/projects/_files.html.haml | 2 +- app/views/projects/_stat_anchor_list.html.haml | 3 +- app/views/projects/_visibility_modal.html.haml | 2 +- app/views/projects/artifacts/_artifact.html.haml | 2 +- app/views/projects/blob/_content.html.haml | 4 +- app/views/projects/blob/_editor.html.haml | 2 +- app/views/projects/blob/_new_dir.html.haml | 4 +- app/views/projects/blob/_remove.html.haml | 4 +- app/views/projects/blob/_upload.html.haml | 6 +- app/views/projects/blob/_viewer_switcher.html.haml | 4 +- app/views/projects/blob/edit.html.haml | 3 - app/views/projects/buttons/_fork.html.haml | 4 +- app/views/projects/buttons/_remove_tag.html.haml | 6 + app/views/projects/buttons/_star.html.haml | 6 +- app/views/projects/ci/builds/_build.html.haml | 12 +- app/views/projects/ci/lints/show.html.haml | 6 +- app/views/projects/cleanup/_show.html.haml | 3 +- app/views/projects/commit/_commit_box.html.haml | 4 +- app/views/projects/commits/_commits.html.haml | 3 +- app/views/projects/cycle_analytics/show.html.haml | 1 + app/views/projects/default_branch/_show.html.haml | 3 +- app/views/projects/deployments/_commit.html.haml | 2 +- app/views/projects/diffs/_file_header.html.haml | 2 +- app/views/projects/diffs/_line.html.haml | 3 - app/views/projects/diffs/_parallel_view.html.haml | 6 - app/views/projects/diffs/_stats.html.haml | 4 +- app/views/projects/diffs/_text_file.html.haml | 2 +- app/views/projects/edit.html.haml | 21 +- app/views/projects/empty.html.haml | 2 +- app/views/projects/environments/show.html.haml | 6 +- app/views/projects/feature_flags/_errors.html.haml | 4 - app/views/projects/feature_flags/edit.html.haml | 2 +- app/views/projects/forks/_fork_button.html.haml | 4 +- app/views/projects/forks/index.html.haml | 4 +- app/views/projects/group_links/update.js.haml | 4 - app/views/projects/hook_logs/show.html.haml | 2 +- app/views/projects/hooks/edit.html.haml | 4 +- app/views/projects/hooks/index.html.haml | 3 +- app/views/projects/incidents/_new_branch.html.haml | 1 + app/views/projects/incidents/index.html.haml | 2 +- app/views/projects/incidents/show.html.haml | 1 + app/views/projects/issues/_discussion.html.haml | 1 + app/views/projects/issues/_issues.html.haml | 6 +- app/views/projects/issues/_new_branch.html.haml | 2 +- app/views/projects/issues/index.html.haml | 1 + app/views/projects/issues/show.html.haml | 12 +- app/views/projects/jobs/show.html.haml | 4 +- app/views/projects/labels/index.html.haml | 4 +- .../projects/merge_requests/_description.html.haml | 3 +- .../projects/merge_requests/_discussion.html.haml | 11 - .../projects/merge_requests/_mr_title.html.haml | 9 +- .../merge_requests/diffs/_commit_widget.html.haml | 11 - .../merge_requests/diffs/_different_base.html.haml | 11 - .../projects/merge_requests/diffs/_diffs.html.haml | 21 - .../diffs/_not_all_comments_displayed.html.haml | 17 - .../diffs/_version_controls.html.haml | 73 --- .../projects/merge_requests/invalid.html.haml | 15 +- app/views/projects/merge_requests/show.html.haml | 5 +- app/views/projects/milestones/index.html.haml | 1 + app/views/projects/milestones/show.html.haml | 3 +- app/views/projects/milestones/update.js.haml | 2 - app/views/projects/mirrors/_mirror_repos.html.haml | 2 +- app/views/projects/notes/_actions.html.haml | 2 +- app/views/projects/pages/_destroy.haml | 2 +- app/views/projects/pages/_list.html.haml | 4 +- app/views/projects/pages/show.html.haml | 2 +- app/views/projects/pages_domains/_form.html.haml | 3 +- .../projects/pipeline_schedules/index.html.haml | 2 +- app/views/projects/pipelines/_info.html.haml | 4 +- app/views/projects/pipelines/_with_tabs.html.haml | 2 +- app/views/projects/pipelines/new.html.haml | 2 +- app/views/projects/pipelines/show.html.haml | 3 +- .../projects/project_members/import.html.haml | 4 +- .../_create_protected_branch.html.haml | 4 +- .../shared/_create_protected_tag.html.haml | 2 +- .../projects/registry/repositories/index.html.haml | 3 + app/views/projects/registry/settings/_index.haml | 1 + app/views/projects/releases/show.html.haml | 1 + .../prometheus/_configuration_banner.html.haml | 4 +- .../services/prometheus/_custom_metrics.html.haml | 2 +- app/views/projects/settings/_archive.html.haml | 7 +- app/views/projects/settings/_general.html.haml | 3 +- .../operations/_alert_management.html.haml | 2 +- app/views/projects/tags/_tag.html.haml | 8 +- app/views/projects/tags/destroy.js.haml | 4 - app/views/projects/tags/show.html.haml | 3 +- app/views/projects/triggers/_index.html.haml | 35 +- app/views/projects/triggers/_trigger.html.haml | 4 +- app/views/search/_category.html.haml | 1 + app/views/search/_results.html.haml | 10 +- app/views/search/results/_blob.html.haml | 2 +- app/views/search/results/_filters.html.haml | 7 + app/views/shared/_confirm_modal.html.haml | 2 +- app/views/shared/_label.html.haml | 2 +- app/views/shared/_label_row.html.haml | 37 +- app/views/shared/boards/_show.html.haml | 1 + .../deploy_keys/_project_group_form.html.haml | 2 +- app/views/shared/deploy_tokens/_form.html.haml | 2 +- app/views/shared/icons/_next_discussion.svg | 1 - .../issuable/_approved_by_dropdown.html.haml | 16 + .../shared/issuable/_close_reopen_button.html.haml | 7 +- .../_close_reopen_draft_report_toggle.html.haml | 37 ++ app/views/shared/issuable/_sidebar.html.haml | 15 +- .../shared/issuable/_sidebar_reviewers.html.haml | 56 ++ .../shared/issuable/form/_type_selector.html.haml | 2 +- app/views/shared/labels/_form.html.haml | 6 +- app/views/shared/labels/_nav.html.haml | 6 +- app/views/shared/members/_group.html.haml | 11 +- app/views/shared/members/_member.html.haml | 2 +- app/views/shared/milestones/_issuable.html.haml | 2 - app/views/shared/milestones/_issuables.html.haml | 2 +- app/views/shared/milestones/_issues_tab.html.haml | 3 +- .../shared/milestones/_merge_requests_tab.haml | 3 +- app/views/shared/milestones/_milestone.html.haml | 4 +- app/views/shared/milestones/_tabs.html.haml | 17 +- app/views/shared/notes/_edit.html.haml | 2 +- app/views/shared/notifications/_button.html.haml | 2 +- app/views/shared/snippets/_form.html.haml | 16 +- app/views/shared/snippets/_header.html.haml | 8 +- app/views/shared/snippets/_snippet.html.haml | 2 +- app/views/shared/wikis/_pages_wiki_page.html.haml | 2 +- app/views/shared/wikis/_wiki_directory.html.haml | 4 +- app/views/users/show.html.haml | 2 +- app/workers/all_queues.yml | 56 ++ .../count_job_trigger_worker.rb | 3 +- .../periodic_recalculate_worker.rb | 4 +- .../user_refresh_over_user_range_worker.rb | 4 +- app/workers/cleanup_container_repository_worker.rb | 12 +- .../concerns/limited_capacity/job_tracker.rb | 74 +++ app/workers/concerns/limited_capacity/worker.rb | 164 +++++ .../copy_design_collection_worker.rb | 26 + .../design_management/new_version_worker.rb | 4 +- app/workers/git_garbage_collect_worker.rb | 4 +- app/workers/group_import_worker.rb | 2 +- .../add_severity_system_note_worker.rb | 22 + app/workers/issue_placement_worker.rb | 8 +- app/workers/issue_rebalancing_worker.rb | 3 +- .../member_invitation_reminder_emails_worker.rb | 15 + .../metrics/dashboard/sync_dashboards_worker.rb | 22 + app/workers/propagate_integration_group_worker.rb | 19 + .../propagate_integration_inherit_worker.rb | 19 + .../propagate_integration_project_worker.rb | 19 + app/workers/propagate_integration_worker.rb | 3 +- 1170 files changed, 18927 insertions(+), 8759 deletions(-) create mode 100644 app/assets/javascripts/alert_management/components/alert_summary_row.vue create mode 100644 app/assets/javascripts/analytics/instance_statistics/components/app.vue create mode 100644 app/assets/javascripts/analytics/instance_statistics/components/instance_counts.vue create mode 100644 app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_statistics_count.query.graphql create mode 100644 app/assets/javascripts/analytics/instance_statistics/index.js create mode 100644 app/assets/javascripts/analytics/shared/components/metric_card.vue create mode 100644 app/assets/javascripts/behaviors/load_startup_css.js delete mode 100644 app/assets/javascripts/blob/suggest_web_ide_ci/components/web_ide_alert.vue delete mode 100644 app/assets/javascripts/blob/suggest_web_ide_ci/index.js delete mode 100644 app/assets/javascripts/boards/components/board_blank_state.vue create mode 100644 app/assets/javascripts/boards/components/board_configuration_options.vue create mode 100644 app/assets/javascripts/boards/queries/board.mutation.graphql create mode 100644 app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue create mode 100644 app/assets/javascripts/ci_settings_pipeline_triggers/index.js create mode 100644 app/assets/javascripts/clusters_list/components/node_error_help_text.vue create mode 100644 app/assets/javascripts/clusters_list/load_clusters.js delete mode 100644 app/assets/javascripts/commons/jquery.js delete mode 100644 app/assets/javascripts/diff_notes/components/comment_resolve_btn.js delete mode 100644 app/assets/javascripts/diff_notes/components/diff_note_avatars.js delete mode 100644 app/assets/javascripts/diff_notes/components/jump_to_discussion.js delete mode 100644 app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js delete mode 100644 app/assets/javascripts/diff_notes/components/resolve_btn.js delete mode 100644 app/assets/javascripts/diff_notes/components/resolve_count.js delete mode 100644 app/assets/javascripts/diff_notes/diff_notes_bundle.js delete mode 100644 app/assets/javascripts/diff_notes/icons/collapse_icon.svg delete mode 100644 app/assets/javascripts/diff_notes/mixins/discussion.js delete mode 100644 app/assets/javascripts/diff_notes/models/discussion.js delete mode 100644 app/assets/javascripts/diff_notes/models/note.js delete mode 100644 app/assets/javascripts/diff_notes/services/resolve.js delete mode 100644 app/assets/javascripts/diff_notes/stores/comments.js create mode 100644 app/assets/javascripts/diffs/components/diff_row_utils.js delete mode 100644 app/assets/javascripts/diffs/components/diff_table_cell.vue delete mode 100644 app/assets/javascripts/diffs/components/edit_button.vue delete mode 100644 app/assets/javascripts/diffs/i18n.js create mode 100644 app/assets/javascripts/feature_flags/components/configure_feature_flags_modal.vue create mode 100644 app/assets/javascripts/feature_flags/components/edit_feature_flag.vue create mode 100644 app/assets/javascripts/feature_flags/components/environments_dropdown.vue create mode 100644 app/assets/javascripts/feature_flags/components/feature_flags.vue create mode 100644 app/assets/javascripts/feature_flags/components/feature_flags_tab.vue create mode 100644 app/assets/javascripts/feature_flags/components/feature_flags_table.vue create mode 100644 app/assets/javascripts/feature_flags/components/form.vue create mode 100644 app/assets/javascripts/feature_flags/components/new_environments_dropdown.vue create mode 100644 app/assets/javascripts/feature_flags/components/new_feature_flag.vue create mode 100644 app/assets/javascripts/feature_flags/components/strategy.vue create mode 100644 app/assets/javascripts/feature_flags/components/user_lists_table.vue create mode 100644 app/assets/javascripts/feature_flags/constants.js create mode 100644 app/assets/javascripts/feature_flags/edit.js create mode 100644 app/assets/javascripts/feature_flags/index.js create mode 100644 app/assets/javascripts/feature_flags/new.js create mode 100644 app/assets/javascripts/feature_flags/store/index.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/edit/actions.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/edit/index.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/edit/mutation_types.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/edit/mutations.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/edit/state.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/helpers.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/index/actions.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/index/index.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/index/mutation_types.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/index/mutations.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/index/state.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/new/actions.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/new/index.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/new/mutation_types.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/new/mutations.js create mode 100644 app/assets/javascripts/feature_flags/store/modules/new/state.js create mode 100644 app/assets/javascripts/feature_flags/utils.js create mode 100644 app/assets/javascripts/integrations/edit/components/confirmation_modal.vue create mode 100644 app/assets/javascripts/invite_members/components/invite_members_modal.vue create mode 100644 app/assets/javascripts/invite_members/components/invite_members_trigger.vue create mode 100644 app/assets/javascripts/invite_members/event_hub.js create mode 100644 app/assets/javascripts/invite_members/init_invite_members_modal.js create mode 100644 app/assets/javascripts/invite_members/init_invite_members_trigger.js create mode 100644 app/assets/javascripts/lib/dompurify.js create mode 100644 app/assets/javascripts/lib/utils/experimentation.js create mode 100644 app/assets/javascripts/lib/utils/rails_ujs.js create mode 100644 app/assets/javascripts/packages/list/components/package_title.vue create mode 100644 app/assets/javascripts/packages/shared/components/package_path.vue create mode 100644 app/assets/javascripts/pages/admin/instance_statistics/index.js create mode 100644 app/assets/javascripts/pages/admin/keys/index.js create mode 100644 app/assets/javascripts/pages/admin/users/keys/index.js create mode 100644 app/assets/javascripts/pages/projects/feature_flags/edit/index.js create mode 100644 app/assets/javascripts/pages/projects/feature_flags/index/index.js create mode 100644 app/assets/javascripts/pages/projects/feature_flags/new/index.js create mode 100644 app/assets/javascripts/pages/projects/feature_flags_user_lists/edit/index.js create mode 100644 app/assets/javascripts/pages/projects/feature_flags_user_lists/new/index.js create mode 100644 app/assets/javascripts/pages/projects/feature_flags_user_lists/show/index.js create mode 100644 app/assets/javascripts/pages/projects/incidents/show/index.js delete mode 100644 app/assets/javascripts/pages/projects/pipeline_schedules/shared/icons/intro_illustration.svg create mode 100644 app/assets/javascripts/pages/projects/tags/index/index.js create mode 100644 app/assets/javascripts/pages/projects/tags/remove_tag.js create mode 100644 app/assets/javascripts/pages/projects/tags/show/index.js create mode 100644 app/assets/javascripts/performance_utils.js create mode 100644 app/assets/javascripts/pipelines/components/legacy_header_component.vue create mode 100644 app/assets/javascripts/pipelines/graphql/queries/get_pipeline_header_data.query.graphql delete mode 100644 app/assets/javascripts/pipelines/mixins/graph_component_mixin.js create mode 100644 app/assets/javascripts/pipelines/pipeline_details_header.js create mode 100644 app/assets/javascripts/projects/commit_box/info/index.js create mode 100644 app/assets/javascripts/projects/commit_box/info/load_branches.js create mode 100644 app/assets/javascripts/registry/explorer/components/details_page/partial_cleanup_alert.vue create mode 100644 app/assets/javascripts/registry/settings/graphql/fragments/container_expiration_policy.fragment.graphql create mode 100644 app/assets/javascripts/registry/settings/graphql/index.js create mode 100644 app/assets/javascripts/registry/settings/graphql/mutations/update_container_expiration_policy.graphql create mode 100644 app/assets/javascripts/registry/settings/graphql/queries/get_expiration_policy.graphql create mode 100644 app/assets/javascripts/registry/settings/graphql/utils/cache_update.js delete mode 100644 app/assets/javascripts/registry/settings/store/actions.js delete mode 100644 app/assets/javascripts/registry/settings/store/getters.js delete mode 100644 app/assets/javascripts/registry/settings/store/index.js delete mode 100644 app/assets/javascripts/registry/settings/store/mutation_types.js delete mode 100644 app/assets/javascripts/registry/settings/store/mutations.js delete mode 100644 app/assets/javascripts/registry/settings/store/state.js create mode 100644 app/assets/javascripts/releases/components/release_skeleton_loader.vue create mode 100644 app/assets/javascripts/releases/stores/getters.js create mode 100644 app/assets/javascripts/search/components/dropdown_filter.vue create mode 100644 app/assets/javascripts/search/confidential_filter/constants.js create mode 100644 app/assets/javascripts/search/confidential_filter/index.js delete mode 100644 app/assets/javascripts/search/state_filter/components/state_filter.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/collapsed_reviewer.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/collapsed_reviewer_list.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar_link.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/reviewer_title.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/reviewers.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue create mode 100644 app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue create mode 100644 app/assets/javascripts/static_site_editor/graphql/mutations/has_submitted_changes.mutation.graphql create mode 100644 app/assets/javascripts/static_site_editor/graphql/resolvers/has_submitted_changes.js create mode 100644 app/assets/javascripts/static_site_editor/services/front_matterify.js create mode 100644 app/assets/javascripts/user_lists/components/add_user_modal.vue create mode 100644 app/assets/javascripts/user_lists/components/edit_user_list.vue create mode 100644 app/assets/javascripts/user_lists/components/new_user_list.vue create mode 100644 app/assets/javascripts/user_lists/components/user_list.vue create mode 100644 app/assets/javascripts/user_lists/components/user_list_form.vue create mode 100644 app/assets/javascripts/user_lists/constants/edit.js create mode 100644 app/assets/javascripts/user_lists/constants/show.js create mode 100644 app/assets/javascripts/user_lists/store/edit/actions.js create mode 100644 app/assets/javascripts/user_lists/store/edit/index.js create mode 100644 app/assets/javascripts/user_lists/store/edit/mutation_types.js create mode 100644 app/assets/javascripts/user_lists/store/edit/mutations.js create mode 100644 app/assets/javascripts/user_lists/store/edit/state.js create mode 100644 app/assets/javascripts/user_lists/store/new/actions.js create mode 100644 app/assets/javascripts/user_lists/store/new/index.js create mode 100644 app/assets/javascripts/user_lists/store/new/mutation_types.js create mode 100644 app/assets/javascripts/user_lists/store/new/mutations.js create mode 100644 app/assets/javascripts/user_lists/store/new/state.js create mode 100644 app/assets/javascripts/user_lists/store/show/actions.js create mode 100644 app/assets/javascripts/user_lists/store/show/index.js create mode 100644 app/assets/javascripts/user_lists/store/show/mutation_types.js create mode 100644 app/assets/javascripts/user_lists/store/show/mutations.js create mode 100644 app/assets/javascripts/user_lists/store/show/state.js create mode 100644 app/assets/javascripts/user_lists/store/utils.js delete mode 100644 app/assets/javascripts/vue_shared/components/droplab_dropdown_button.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/avatars/group_avatar.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/avatars/invite_avatar.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/avatars/user_avatar.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/constants.js create mode 100644 app/assets/javascripts/vue_shared/components/members/table/created_at.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/table/expires_at.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/table/member_avatar.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/table/member_source.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/table/members_table.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/table/members_table_cell.vue create mode 100644 app/assets/javascripts/vue_shared/components/members/utils.js create mode 100644 app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js create mode 100644 app/assets/stylesheets/application_utilities.scss create mode 100644 app/assets/stylesheets/application_utilities_dark.scss create mode 100644 app/assets/stylesheets/page_bundles/boards.scss create mode 100644 app/assets/stylesheets/page_bundles/cycle_analytics.scss create mode 100644 app/assets/stylesheets/page_bundles/issues.scss create mode 100644 app/assets/stylesheets/page_bundles/milestone.scss delete mode 100644 app/assets/stylesheets/pages/boards.scss delete mode 100644 app/assets/stylesheets/pages/cycle_analytics.scss delete mode 100644 app/assets/stylesheets/pages/milestone.scss delete mode 100644 app/assets/stylesheets/pages/tags.scss delete mode 100644 app/assets/stylesheets/pages/ui_dev_kit.scss delete mode 100644 app/controllers/admin/concerns/authenticates_2fa_for_admin_mode.rb create mode 100644 app/controllers/concerns/authenticates_with_two_factor_for_admin_mode.rb delete mode 100644 app/controllers/concerns/controller_with_feature_category/config.rb create mode 100644 app/controllers/concerns/runner_setup_scripts.rb create mode 100644 app/controllers/concerns/show_inherited_labels_checker.rb create mode 100644 app/controllers/import/bulk_imports_controller.rb create mode 100644 app/controllers/runner_setup_controller.rb delete mode 100644 app/finders/group_labels_finder.rb create mode 100644 app/finders/merge_requests/by_approvals_finder.rb create mode 100644 app/finders/packages/generic/package_finder.rb create mode 100644 app/graphql/mutations/boards/lists/destroy.rb create mode 100644 app/graphql/resolvers/board_resolver.rb create mode 100644 app/graphql/resolvers/snippets/blobs_resolver.rb create mode 100644 app/graphql/resolvers/terraform/states_resolver.rb create mode 100644 app/graphql/types/design_management/design_collection_copy_state_enum.rb create mode 100644 app/graphql/types/terraform/state_type.rb create mode 100644 app/helpers/feature_flags_helper.rb create mode 100644 app/helpers/gitpod_helper.rb create mode 100644 app/helpers/invite_members_helper.rb create mode 100644 app/models/alert_management/http_integration.rb create mode 100644 app/models/concerns/issue_available_features.rb create mode 100644 app/models/issue_email_participant.rb create mode 100644 app/models/packages/event.rb create mode 100644 app/models/project_tracing_setting.rb create mode 100644 app/policies/terraform/state_policy.rb delete mode 100644 app/presenters/projects/prometheus/alert_presenter.rb create mode 100644 app/serializers/ci/trigger_entity.rb create mode 100644 app/serializers/ci/trigger_serializer.rb create mode 100644 app/serializers/feature_flag_entity.rb create mode 100644 app/serializers/feature_flag_scope_entity.rb create mode 100644 app/serializers/feature_flag_serializer.rb create mode 100644 app/serializers/feature_flag_summary_entity.rb create mode 100644 app/serializers/feature_flag_summary_serializer.rb create mode 100644 app/serializers/feature_flags/scope_entity.rb create mode 100644 app/serializers/feature_flags/strategy_entity.rb create mode 100644 app/serializers/feature_flags/user_list_entity.rb create mode 100644 app/serializers/feature_flags_client_entity.rb create mode 100644 app/serializers/feature_flags_client_serializer.rb create mode 100644 app/services/bulk_create_integration_service.rb create mode 100644 app/services/bulk_update_integration_service.rb create mode 100644 app/services/design_management/copy_design_collection.rb create mode 100644 app/services/design_management/copy_design_collection/copy_service.rb create mode 100644 app/services/design_management/copy_design_collection/queue_service.rb create mode 100644 app/services/feature_flags/base_service.rb create mode 100644 app/services/feature_flags/create_service.rb create mode 100644 app/services/feature_flags/destroy_service.rb create mode 100644 app/services/feature_flags/disable_service.rb create mode 100644 app/services/feature_flags/enable_service.rb create mode 100644 app/services/feature_flags/update_service.rb create mode 100644 app/services/incident_management/incidents/update_severity_service.rb create mode 100644 app/services/members/invitation_reminder_email_service.rb create mode 100644 app/services/merge_requests/export_csv_service.rb create mode 100644 app/services/namespace_settings/update_service.rb create mode 100644 app/services/packages/create_event_service.rb create mode 100644 app/services/packages/generic/create_package_file_service.rb create mode 100644 app/services/packages/generic/find_or_create_package_service.rb create mode 100644 app/services/system_notes/incident_service.rb create mode 100644 app/uploaders/pages/deployment_uploader.rb create mode 100644 app/validators/ip_address_validator.rb create mode 100644 app/views/admin/dashboard/_billable_users_text.html.haml delete mode 100644 app/views/clusters/clusters/_buttons.html.haml delete mode 100644 app/views/clusters/clusters/_cluster.html.haml create mode 100644 app/views/clusters/clusters/_cluster_list.html.haml delete mode 100644 app/views/discussions/_jump_to_next.html.haml delete mode 100644 app/views/discussions/_new_issue_for_all_discussions.html.haml delete mode 100644 app/views/discussions/_new_issue_for_discussion.html.haml create mode 100644 app/views/groups/_invite_members_modal.html.haml create mode 100644 app/views/groups/_invite_members_side_nav_link.html.haml delete mode 100644 app/views/groups/labels/destroy.js.haml create mode 100644 app/views/import/bulk_imports/status.html.haml create mode 100644 app/views/invites/decline.html.haml create mode 100644 app/views/notify/changed_reviewer_of_merge_request_email.html.haml create mode 100644 app/views/notify/changed_reviewer_of_merge_request_email.text.erb create mode 100644 app/views/projects/buttons/_remove_tag.html.haml delete mode 100644 app/views/projects/feature_flags/_errors.html.haml delete mode 100644 app/views/projects/group_links/update.js.haml create mode 100644 app/views/projects/incidents/_new_branch.html.haml create mode 100644 app/views/projects/incidents/show.html.haml delete mode 100644 app/views/projects/merge_requests/_discussion.html.haml delete mode 100644 app/views/projects/merge_requests/diffs/_commit_widget.html.haml delete mode 100644 app/views/projects/merge_requests/diffs/_different_base.html.haml delete mode 100644 app/views/projects/merge_requests/diffs/_diffs.html.haml delete mode 100644 app/views/projects/merge_requests/diffs/_not_all_comments_displayed.html.haml delete mode 100644 app/views/projects/merge_requests/diffs/_version_controls.html.haml delete mode 100644 app/views/projects/milestones/update.js.haml delete mode 100644 app/views/projects/tags/destroy.js.haml create mode 100644 app/views/search/results/_filters.html.haml delete mode 100644 app/views/shared/icons/_next_discussion.svg create mode 100644 app/views/shared/issuable/_approved_by_dropdown.html.haml create mode 100644 app/views/shared/issuable/_close_reopen_draft_report_toggle.html.haml create mode 100644 app/views/shared/issuable/_sidebar_reviewers.html.haml create mode 100644 app/workers/concerns/limited_capacity/job_tracker.rb create mode 100644 app/workers/concerns/limited_capacity/worker.rb create mode 100644 app/workers/design_management/copy_design_collection_worker.rb create mode 100644 app/workers/incident_management/add_severity_system_note_worker.rb create mode 100644 app/workers/member_invitation_reminder_emails_worker.rb create mode 100644 app/workers/metrics/dashboard/sync_dashboards_worker.rb create mode 100644 app/workers/propagate_integration_group_worker.rb create mode 100644 app/workers/propagate_integration_inherit_worker.rb create mode 100644 app/workers/propagate_integration_project_worker.rb (limited to 'app') diff --git a/app/assets/javascripts/admin/cohorts/components/usage_ping_disabled.vue b/app/assets/javascripts/admin/cohorts/components/usage_ping_disabled.vue index 2ea55d44420..bc2d96832fa 100644 --- a/app/assets/javascripts/admin/cohorts/components/usage_ping_disabled.vue +++ b/app/assets/javascripts/admin/cohorts/components/usage_ping_disabled.vue @@ -9,13 +9,13 @@ export default { }, inject: { svgPath: { - type: String, + default: '', }, docsLink: { - type: String, + default: '', }, primaryButtonPath: { - type: String, + default: '', }, }, }; diff --git a/app/assets/javascripts/admin/dev_ops_report/components/usage_ping_disabled.vue b/app/assets/javascripts/admin/dev_ops_report/components/usage_ping_disabled.vue index 5429ec403d3..316827e1b07 100644 --- a/app/assets/javascripts/admin/dev_ops_report/components/usage_ping_disabled.vue +++ b/app/assets/javascripts/admin/dev_ops_report/components/usage_ping_disabled.vue @@ -10,16 +10,16 @@ export default { }, inject: { isAdmin: { - type: Boolean, + default: false, }, svgPath: { - type: String, + default: '', }, docsLink: { - type: String, + default: '', }, primaryButtonPath: { - type: String, + default: '', }, }, }; diff --git a/app/assets/javascripts/alert_handler.js b/app/assets/javascripts/alert_handler.js index 8fffb61d1dd..26b0142f6a2 100644 --- a/app/assets/javascripts/alert_handler.js +++ b/app/assets/javascripts/alert_handler.js @@ -1,13 +1,21 @@ -// This allows us to dismiss alerts that we've migrated from bootstrap -// Note: This ONLY works on alerts that are created on page load +// This allows us to dismiss alerts and banners that we've migrated from bootstrap +// Note: This ONLY works on elements that are created on page load // You can follow this effort in the following epic // https://gitlab.com/groups/gitlab-org/-/epics/4070 export default function initAlertHandler() { - const ALERT_SELECTOR = '.gl-alert'; - const CLOSE_SELECTOR = '.gl-alert-dismiss'; + const DISMISSIBLE_SELECTORS = ['.gl-alert', '.gl-banner']; + const DISMISS_LABEL = '[aria-label="Dismiss"]'; + const DISMISS_CLASS = '.gl-alert-dismiss'; - const dismissAlert = ({ target }) => target.closest(ALERT_SELECTOR).remove(); - const closeButtons = document.querySelectorAll(`${ALERT_SELECTOR} ${CLOSE_SELECTOR}`); - closeButtons.forEach(alert => alert.addEventListener('click', dismissAlert)); + DISMISSIBLE_SELECTORS.forEach(selector => { + const elements = document.querySelectorAll(selector); + elements.forEach(element => { + const button = element.querySelector(DISMISS_LABEL) || element.querySelector(DISMISS_CLASS); + if (!button) { + return; + } + button.addEventListener('click', () => element.remove()); + }); + }); } diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue index c6605452616..072ed2fa663 100644 --- a/app/assets/javascripts/alert_management/components/alert_details.vue +++ b/app/assets/javascripts/alert_management/components/alert_details.vue @@ -1,15 +1,16 @@ + diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue index 0a1478ef5fe..df07038151e 100644 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue +++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue @@ -1,9 +1,9 @@ diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue index 0f354e85e96..2e667bf99a8 100644 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue +++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue @@ -1,10 +1,11 @@ diff --git a/app/assets/javascripts/analytics/instance_statistics/components/app.vue b/app/assets/javascripts/analytics/instance_statistics/components/app.vue new file mode 100644 index 00000000000..eb0b67a1629 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/components/app.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/assets/javascripts/analytics/instance_statistics/components/instance_counts.vue b/app/assets/javascripts/analytics/instance_statistics/components/instance_counts.vue new file mode 100644 index 00000000000..1147ce9af73 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/components/instance_counts.vue @@ -0,0 +1,64 @@ + + + diff --git a/app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_statistics_count.query.graphql b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_statistics_count.query.graphql new file mode 100644 index 00000000000..fd8282683d9 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/graphql/queries/instance_statistics_count.query.graphql @@ -0,0 +1,32 @@ +query getInstanceCounts { + projects: instanceStatisticsMeasurements(identifier: PROJECTS, first: 1) { + nodes { + count + } + } + groups: instanceStatisticsMeasurements(identifier: GROUPS, first: 1) { + nodes { + count + } + } + users: instanceStatisticsMeasurements(identifier: USERS, first: 1) { + nodes { + count + } + } + issues: instanceStatisticsMeasurements(identifier: ISSUES, first: 1) { + nodes { + count + } + } + mergeRequests: instanceStatisticsMeasurements(identifier: MERGE_REQUESTS, first: 1) { + nodes { + count + } + } + pipelines: instanceStatisticsMeasurements(identifier: PIPELINES, first: 1) { + nodes { + count + } + } +} diff --git a/app/assets/javascripts/analytics/instance_statistics/index.js b/app/assets/javascripts/analytics/instance_statistics/index.js new file mode 100644 index 00000000000..0d7dcf6ace8 --- /dev/null +++ b/app/assets/javascripts/analytics/instance_statistics/index.js @@ -0,0 +1,24 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import InstanceStatisticsApp from './components/app.vue'; + +Vue.use(VueApollo); + +const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient(), +}); + +export default () => { + const el = document.getElementById('js-instance-statistics-app'); + + if (!el) return false; + + return new Vue({ + el, + apolloProvider, + render(h) { + return h(InstanceStatisticsApp); + }, + }); +}; diff --git a/app/assets/javascripts/analytics/shared/components/metric_card.vue b/app/assets/javascripts/analytics/shared/components/metric_card.vue new file mode 100644 index 00000000000..cee186c057c --- /dev/null +++ b/app/assets/javascripts/analytics/shared/components/metric_card.vue @@ -0,0 +1,80 @@ + + diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index dbc7ff67d9d..a87f89efd70 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -64,6 +64,9 @@ const Api = { issuePath: '/api/:version/projects/:id/issues/:issue_iid', tagsPath: '/api/:version/projects/:id/repository/tags', freezePeriodsPath: '/api/:version/projects/:id/freeze_periods', + usageDataIncrementUniqueUsersPath: '/api/:version/usage_data/increment_unique_users', + featureFlagUserLists: '/api/:version/projects/:id/feature_flags_user_lists', + featureFlagUserList: '/api/:version/projects/:id/feature_flags_user_lists/:list_iid', group(groupId, callback = () => {}) { const url = Api.buildUrl(Api.groupPath).replace(':id', groupId); @@ -111,6 +114,12 @@ const Api = { }); }, + inviteGroupMember(id, data) { + const url = Api.buildUrl(this.groupMembersPath).replace(':id', encodeURIComponent(id)); + + return axios.post(url, data); + }, + groupMilestones(id, options) { const url = Api.buildUrl(this.groupMilestonesPath).replace(':id', encodeURIComponent(id)); @@ -686,9 +695,58 @@ const Api = { return axios.post(url, freezePeriod); }, + trackRedisHllUserEvent(event) { + if (!gon.features?.usageDataApi) { + return null; + } + + const url = Api.buildUrl(this.usageDataIncrementUniqueUsersPath); + const headers = { + 'Content-Type': 'application/json', + }; + + return axios.post(url, { event }, { headers }); + }, + buildUrl(url) { return joinPaths(gon.relative_url_root || '', url.replace(':version', gon.api_version)); }, + + fetchFeatureFlagUserLists(id, page) { + const url = Api.buildUrl(this.featureFlagUserLists).replace(':id', id); + + return axios.get(url, { params: { page } }); + }, + + createFeatureFlagUserList(id, list) { + const url = Api.buildUrl(this.featureFlagUserLists).replace(':id', id); + + return axios.post(url, list); + }, + + fetchFeatureFlagUserList(id, listIid) { + const url = Api.buildUrl(this.featureFlagUserList) + .replace(':id', id) + .replace(':list_iid', listIid); + + return axios.get(url); + }, + + updateFeatureFlagUserList(id, list) { + const url = Api.buildUrl(this.featureFlagUserList) + .replace(':id', id) + .replace(':list_iid', list.iid); + + return axios.put(url, list); + }, + + deleteFeatureFlagUserList(id, listIid) { + const url = Api.buildUrl(this.featureFlagUserList) + .replace(':id', id) + .replace(':list_iid', listIid); + + return axios.delete(url); + }, }; export default Api; diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index cb71047e00c..bc69c02e21e 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -572,7 +572,7 @@ export class AwardsHandler { } findMatchingEmojiElements(query) { - const emojiMatches = this.emoji.filterEmojiNamesByAlias(query); + const emojiMatches = this.emoji.searchEmoji(query).map(({ name }) => name); const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]'); const $matchingElements = $emojiElements.filter( (i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0, diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue index 6afb10dd2ad..0a8479519f1 100644 --- a/app/assets/javascripts/badges/components/badge_form.vue +++ b/app/assets/javascripts/badges/components/badge_form.vue @@ -218,7 +218,7 @@ export default {

-
+
{{ __('Cancel') }} @@ -232,7 +232,7 @@ export default { {{ s__('Badges|Save changes') }}
-
+
{{ s__('Badges|Add badge') }} diff --git a/app/assets/javascripts/badges/components/badge_list_row.vue b/app/assets/javascripts/badges/components/badge_list_row.vue index 3343634ecad..bf950d525bd 100644 --- a/app/assets/javascripts/badges/components/badge_list_row.vue +++ b/app/assets/javascripts/badges/components/badge_list_row.vue @@ -1,6 +1,6 @@ + - - - -
-
+ + + diff --git a/app/assets/javascripts/batch_comments/components/preview_item.vue b/app/assets/javascripts/batch_comments/components/preview_item.vue index c89a6b537ef..dca6d90fbcb 100644 --- a/app/assets/javascripts/batch_comments/components/preview_item.vue +++ b/app/assets/javascripts/batch_comments/components/preview_item.vue @@ -1,5 +1,5 @@ diff --git a/app/assets/javascripts/batch_comments/components/publish_button.vue b/app/assets/javascripts/batch_comments/components/publish_button.vue index 0c79e185f06..ecced36771e 100644 --- a/app/assets/javascripts/batch_comments/components/publish_button.vue +++ b/app/assets/javascripts/batch_comments/components/publish_button.vue @@ -1,7 +1,6 @@ diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js index d9b92113103..ebd821125fb 100644 --- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js @@ -75,15 +75,6 @@ export const updateDiscussionsAfterPublish = ({ dispatch, getters, rootGetters } }), ); -export const discardReview = ({ commit, getters }) => { - commit(types.REQUEST_DISCARD_REVIEW); - - return service - .discard(getters.getNotesData.draftsDiscardPath) - .then(() => commit(types.RECEIVE_DISCARD_REVIEW_SUCCESS)) - .catch(() => commit(types.RECEIVE_DISCARD_REVIEW_ERROR)); -}; - export const updateDraft = ( { commit, getters }, { note, noteText, resolveDiscussion, position, callback }, @@ -108,8 +99,6 @@ export const scrollToDraft = ({ dispatch, rootGetters }, draft) => { const draftID = `note_${draft.id}`; const el = document.querySelector(`#${tabEl} #${draftID}`); - dispatch('closeReviewDropdown'); - window.location.hash = draftID; if (window.mrTabs.currentAction !== tab) { @@ -125,17 +114,6 @@ export const scrollToDraft = ({ dispatch, rootGetters }, draft) => { } }; -export const toggleReviewDropdown = ({ dispatch, state }) => { - if (state.showPreviewDropdown) { - dispatch('closeReviewDropdown'); - } else { - dispatch('openReviewDropdown'); - } -}; - -export const openReviewDropdown = ({ commit }) => commit(types.OPEN_REVIEW_DROPDOWN); -export const closeReviewDropdown = ({ commit }) => commit(types.CLOSE_REVIEW_DROPDOWN); - export const expandAllDiscussions = ({ dispatch, state }) => state.drafts .filter(draft => draft.discussion_id) diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js index c8f0658c21c..df523a692d3 100644 --- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js @@ -11,13 +11,6 @@ export const REQUEST_PUBLISH_REVIEW = 'REQUEST_PUBLISH_REVIEW'; export const RECEIVE_PUBLISH_REVIEW_SUCCESS = 'RECEIVE_PUBLISH_REVIEW_SUCCESS'; export const RECEIVE_PUBLISH_REVIEW_ERROR = 'RECEIVE_PUBLISH_REVIEW_ERROR'; -export const REQUEST_DISCARD_REVIEW = 'REQUEST_DISCARD_REVIEW'; -export const RECEIVE_DISCARD_REVIEW_SUCCESS = 'RECEIVE_DISCARD_REVIEW_SUCCESS'; -export const RECEIVE_DISCARD_REVIEW_ERROR = 'RECEIVE_DISCARD_REVIEW_ERROR'; - export const RECEIVE_DRAFT_UPDATE_SUCCESS = 'RECEIVE_DRAFT_UPDATE_SUCCESS'; -export const OPEN_REVIEW_DROPDOWN = 'OPEN_REVIEW_DROPDOWN'; -export const CLOSE_REVIEW_DROPDOWN = 'CLOSE_REVIEW_DROPDOWN'; - export const TOGGLE_RESOLVE_DISCUSSION = 'TOGGLE_RESOLVE_DISCUSSION'; diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js index 81ceef7b160..731f4b6d12a 100644 --- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js @@ -43,16 +43,6 @@ export default { [types.RECEIVE_PUBLISH_REVIEW_ERROR](state) { state.isPublishing = false; }, - [types.REQUEST_DISCARD_REVIEW](state) { - state.isDiscarding = true; - }, - [types.RECEIVE_DISCARD_REVIEW_SUCCESS](state) { - state.isDiscarding = false; - state.drafts = []; - }, - [types.RECEIVE_DISCARD_REVIEW_ERROR](state) { - state.isDiscarding = false; - }, [types.RECEIVE_DRAFT_UPDATE_SUCCESS](state, data) { const index = state.drafts.findIndex(draft => draft.id === data.id); @@ -60,12 +50,6 @@ export default { state.drafts.splice(index, 1, processDraft(data)); } }, - [types.OPEN_REVIEW_DROPDOWN](state) { - state.showPreviewDropdown = true; - }, - [types.CLOSE_REVIEW_DROPDOWN](state) { - state.showPreviewDropdown = false; - }, [types.TOGGLE_RESOLVE_DISCUSSION](state, draftId) { state.drafts = state.drafts.map(draft => { if (draft.id === draftId) { diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js index 80c710deab0..6b97fc242c8 100644 --- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js @@ -4,6 +4,4 @@ export default () => ({ drafts: [], isPublishing: false, currentlyPublishingDrafts: [], - isDiscarding: false, - showPreviewDropdown: false, }); diff --git a/app/assets/javascripts/behaviors/collapse_sidebar_on_window_resize.js b/app/assets/javascripts/behaviors/collapse_sidebar_on_window_resize.js index d9164f6204a..719d76fef8f 100644 --- a/app/assets/javascripts/behaviors/collapse_sidebar_on_window_resize.js +++ b/app/assets/javascripts/behaviors/collapse_sidebar_on_window_resize.js @@ -8,7 +8,6 @@ import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils'; * @sentrify */ export default () => { - const $sidebarGutterToggle = $('.js-sidebar-toggle'); let bootstrapBreakpoint = bp.getBreakpointSize(); $(window).on('resize.app', () => { @@ -19,8 +18,13 @@ export default () => { const breakpointSizes = ['md', 'sm', 'xs']; if (breakpointSizes.includes(bootstrapBreakpoint)) { - const $gutterIcon = $sidebarGutterToggle.find('i'); - if ($gutterIcon.hasClass('fa-angle-double-right')) { + const $toggleContainer = $('.js-sidebar-toggle-container'); + const isExpanded = $toggleContainer.data('is-expanded'); + const $expandIcon = $('.js-sidebar-expand'); + + if (isExpanded) { + const $sidebarGutterToggle = $expandIcon.closest('.js-sidebar-toggle'); + $sidebarGutterToggle.trigger('click'); } diff --git a/app/assets/javascripts/behaviors/index.js b/app/assets/javascripts/behaviors/index.js index fd12c282b62..613309a1c5a 100644 --- a/app/assets/javascripts/behaviors/index.js +++ b/app/assets/javascripts/behaviors/index.js @@ -13,6 +13,9 @@ import './toggler_behavior'; import './preview_markdown'; import initCollapseSidebarOnWindowResize from './collapse_sidebar_on_window_resize'; import initSelect2Dropdowns from './select2'; +import { loadStartupCSS } from './load_startup_css'; + +loadStartupCSS(); installGlEmojiElement(); diff --git a/app/assets/javascripts/behaviors/load_startup_css.js b/app/assets/javascripts/behaviors/load_startup_css.js new file mode 100644 index 00000000000..1d7bf716475 --- /dev/null +++ b/app/assets/javascripts/behaviors/load_startup_css.js @@ -0,0 +1,15 @@ +export const loadStartupCSS = () => { + // We need to fallback to dispatching `load` in case our event listener was added too late + // or the browser environment doesn't load media=print. + // Do this on `window.load` so that the default deferred behavior takes precedence. + // https://gitlab.com/gitlab-org/gitlab/-/issues/239357 + window.addEventListener( + 'load', + () => { + document + .querySelectorAll('link[media=print]') + .forEach(x => x.dispatchEvent(new Event('load'))); + }, + { once: true }, + ); +}; diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js index 8a8b61a57cd..3cb2d6719c8 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js @@ -117,9 +117,9 @@ export default class Shortcuts { e.preventDefault(); const performanceBarCookieName = 'perf_bar_enabled'; if (parseBoolean(Cookies.get(performanceBarCookieName))) { - Cookies.set(performanceBarCookieName, 'false', { path: '/' }); + Cookies.set(performanceBarCookieName, 'false', { expires: 365, path: '/' }); } else { - Cookies.set(performanceBarCookieName, 'true', { path: '/' }); + Cookies.set(performanceBarCookieName, 'true', { expires: 365, path: '/' }); } refreshCurrentPage(); } diff --git a/app/assets/javascripts/blob/components/blob_header_filepath.vue b/app/assets/javascripts/blob/components/blob_header_filepath.vue index 601b694db87..f99ecba2324 100644 --- a/app/assets/javascripts/blob/components/blob_header_filepath.vue +++ b/app/assets/javascripts/blob/components/blob_header_filepath.vue @@ -43,6 +43,7 @@ export default { :text="blob.path" :gfm="gfmCopyText" :title="__('Copy file path')" + category="tertiary" css-class="btn-clipboard btn-transparent lh-100 position-static" />
diff --git a/app/assets/javascripts/blob/suggest_web_ide_ci/components/web_ide_alert.vue b/app/assets/javascripts/blob/suggest_web_ide_ci/components/web_ide_alert.vue deleted file mode 100644 index 1308ca53e74..00000000000 --- a/app/assets/javascripts/blob/suggest_web_ide_ci/components/web_ide_alert.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - diff --git a/app/assets/javascripts/blob/suggest_web_ide_ci/index.js b/app/assets/javascripts/blob/suggest_web_ide_ci/index.js deleted file mode 100644 index eadf3cd6216..00000000000 --- a/app/assets/javascripts/blob/suggest_web_ide_ci/index.js +++ /dev/null @@ -1,20 +0,0 @@ -import Vue from 'vue'; -import WebIdeAlert from './components/web_ide_alert.vue'; - -export default el => { - const { dismissEndpoint, featureId, editPath } = el.dataset; - - // eslint-disable-next-line no-new - new Vue({ - el, - render(createElement) { - return createElement(WebIdeAlert, { - props: { - dismissEndpoint, - featureId, - editPath, - }, - }); - }, - }); -}; diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js index 05ee8e49eb1..0fb803cdfec 100644 --- a/app/assets/javascripts/blob/viewer/index.js +++ b/app/assets/javascripts/blob/viewer/index.js @@ -179,9 +179,7 @@ export default class BlobViewer { viewer.innerHTML = data.html; viewer.setAttribute('data-loaded', 'true'); - if (window.gon?.features?.codeNavigation) { - eventHub.$emit('showBlobInteractionZones', viewer.dataset.path); - } + eventHub.$emit('showBlobInteractionZones', viewer.dataset.path); return viewer; }); diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js index c9972f0b43c..d1e5dad7971 100644 --- a/app/assets/javascripts/blob_edit/blob_bundle.js +++ b/app/assets/javascripts/blob_edit/blob_bundle.js @@ -7,14 +7,12 @@ import BlobFileDropzone from '../blob/blob_file_dropzone'; import initPopover from '~/blob/suggest_gitlab_ci_yml'; import { disableButtonIfEmptyField, setCookie } from '~/lib/utils/common_utils'; import Tracking from '~/tracking'; -import initWebIdeAlert from '~/blob/suggest_web_ide_ci'; export default () => { const editBlobForm = $('.js-edit-blob-form'); const uploadBlobForm = $('.js-upload-blob-form'); const deleteBlobForm = $('.js-delete-blob-form'); const suggestEl = document.querySelector('.js-suggest-gitlab-ci-yml'); - const alertEl = document.getElementById('js-suggest-web-ide-ci'); if (editBlobForm.length) { const urlRoot = editBlobForm.data('relativeUrlRoot'); @@ -85,8 +83,4 @@ export default () => { }); } } - - if (alertEl) { - initWebIdeAlert(alertEl); - } }; diff --git a/app/assets/javascripts/boards/components/board_blank_state.vue b/app/assets/javascripts/boards/components/board_blank_state.vue deleted file mode 100644 index 55e3e4a6329..00000000000 --- a/app/assets/javascripts/boards/components/board_blank_state.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - diff --git a/app/assets/javascripts/boards/components/board_column.vue b/app/assets/javascripts/boards/components/board_column.vue index 6d216911798..6aff5f0c3c3 100644 --- a/app/assets/javascripts/boards/components/board_column.vue +++ b/app/assets/javascripts/boards/components/board_column.vue @@ -6,7 +6,6 @@ import BoardListHeader from 'ee_else_ce/boards/components/board_list_header.vue' import Tooltip from '~/vue_shared/directives/tooltip'; import EmptyComponent from '~/vue_shared/components/empty_component'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import BoardBlankState from './board_blank_state.vue'; import BoardList from './board_list.vue'; import boardsStore from '../stores/boards_store'; import eventHub from '../eventhub'; @@ -16,7 +15,6 @@ import { ListType } from '../constants'; export default { components: { BoardPromotionState: EmptyComponent, - BoardBlankState, BoardListHeader, BoardList, }, @@ -54,7 +52,7 @@ export default { computed: { ...mapGetters(['getIssues']), showBoardListAndBoardInfo() { - return this.list.type !== ListType.blank && this.list.type !== ListType.promotion; + return this.list.type !== ListType.promotion; }, uniqueKey() { // eslint-disable-next-line @gitlab/require-i18n-strings @@ -148,7 +146,6 @@ export default { :list="list" :loading="list.loading" /> - diff --git a/app/assets/javascripts/boards/components/board_configuration_options.vue b/app/assets/javascripts/boards/components/board_configuration_options.vue new file mode 100644 index 00000000000..ad3d653b905 --- /dev/null +++ b/app/assets/javascripts/boards/components/board_configuration_options.vue @@ -0,0 +1,65 @@ + + + diff --git a/app/assets/javascripts/boards/components/board_form.vue b/app/assets/javascripts/boards/components/board_form.vue index 385dd5fdc71..793c594cf16 100644 --- a/app/assets/javascripts/boards/components/board_form.vue +++ b/app/assets/javascripts/boards/components/board_form.vue @@ -5,6 +5,8 @@ import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; import { visitUrl } from '~/lib/utils/url_utility'; import boardsStore from '~/boards/stores/boards_store'; +import BoardConfigurationOptions from './board_configuration_options.vue'; + const boardDefaults = { id: false, name: '', @@ -13,12 +15,15 @@ const boardDefaults = { assignee: {}, assignee_id: undefined, weight: null, + hide_backlog_list: false, + hide_closed_list: false, }; export default { components: { BoardScope: () => import('ee_component/boards/components/board_scope.vue'), DeprecatedModal, + BoardConfigurationOptions, }, props: { canAdminBoard: { @@ -140,7 +145,17 @@ export default { } else { boardsStore .createBoard(this.board) - .then(resp => resp.data) + .then(resp => { + // This handles 2 use cases + // - In create call we only get one parameter, the new board + // - In update call, due to Promise.all, we get REST response in + // array index 0 + + if (Array.isArray(resp)) { + return resp[0].data; + } + return resp.data ? resp.data : resp; + }) .then(data => { visitUrl(data.board_path); }) @@ -182,7 +197,7 @@ export default {
+ + /* eslint-disable @gitlab/vue-require-i18n-strings */ +import { GlTabs, GlTab, GlBadge } from '@gitlab/ui'; import ModalStore from '../../stores/modal_store'; import modalMixin from '../../mixins/modal_mixins'; export default { + components: { + GlTabs, + GlTab, + GlBadge, + }, mixins: [modalMixin], data() { return ModalStore.store; @@ -19,18 +25,18 @@ export default { }; diff --git a/app/assets/javascripts/boards/components/sidebar/board_editable_item.vue b/app/assets/javascripts/boards/components/sidebar/board_editable_item.vue index 8df03ea581f..ec3c4e309b6 100644 --- a/app/assets/javascripts/boards/components/sidebar/board_editable_item.vue +++ b/app/assets/javascripts/boards/components/sidebar/board_editable_item.vue @@ -36,7 +36,7 @@ export default { } this.edit = true; - this.$emit('changed', this.edit); + this.$emit('open'); window.addEventListener('click', this.collapseWhenOffClick); }, collapse() { @@ -45,7 +45,7 @@ export default { } this.edit = false; - this.$emit('changed', this.edit); + this.$emit('close'); window.removeEventListener('click', this.collapseWhenOffClick); }, }, diff --git a/app/assets/javascripts/boards/ee_functions.js b/app/assets/javascripts/boards/ee_functions.js index 583270fcae5..419a640d5c5 100644 --- a/app/assets/javascripts/boards/ee_functions.js +++ b/app/assets/javascripts/boards/ee_functions.js @@ -1,6 +1,6 @@ export const setPromotionState = () => {}; -export const setWeigthFetchingState = () => {}; +export const setWeightFetchingState = () => {}; export const setEpicFetchingState = () => {}; export const getMilestoneTitle = () => ({}); diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 1173c6d0578..2af96e94d32 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -11,7 +11,7 @@ import toggleLabels from 'ee_else_ce/boards/toggle_labels'; import toggleEpicsSwimlanes from 'ee_else_ce/boards/toggle_epics_swimlanes'; import { setPromotionState, - setWeigthFetchingState, + setWeightFetchingState, setEpicFetchingState, getMilestoneTitle, getBoardsModalData, @@ -84,8 +84,9 @@ export default () => { }, provide: { boardId: $boardApp.dataset.boardId, - groupId: Number($boardApp.dataset.groupId) || null, + groupId: Number($boardApp.dataset.groupId), rootPath: $boardApp.dataset.rootPath, + canUpdate: $boardApp.dataset.canUpdate, }, store, apolloProvider, @@ -131,6 +132,7 @@ export default () => { eventHub.$on('clearDetailIssue', this.clearDetailIssue); sidebarEventHub.$on('toggleSubscription', this.toggleSubscription); eventHub.$on('performSearch', this.performSearch); + eventHub.$on('initialBoardLoad', this.initialBoardLoad); }, beforeDestroy() { eventHub.$off('updateTokens', this.updateTokens); @@ -138,6 +140,7 @@ export default () => { eventHub.$off('clearDetailIssue', this.clearDetailIssue); sidebarEventHub.$off('toggleSubscription', this.toggleSubscription); eventHub.$off('performSearch', this.performSearch); + eventHub.$off('initialBoardLoad', this.initialBoardLoad); }, mounted() { this.filterManager = new FilteredSearchBoards(boardsStore.filter, true, boardsStore.cantEdit); @@ -148,6 +151,18 @@ export default () => { boardsStore.disabled = this.disabled; if (!gon.features.graphqlBoardLists) { + this.initialBoardLoad(); + } + }, + methods: { + ...mapActions([ + 'setInitialBoardData', + 'setFilters', + 'fetchEpicsSwimlanes', + 'resetIssues', + 'resetEpics', + ]), + initialBoardLoad() { boardsStore .all() .then(res => res.data) @@ -160,30 +175,23 @@ export default () => { .catch(() => { Flash(__('An error occurred while fetching the board lists. Please try again.')); }); - } - }, - methods: { - ...mapActions([ - 'setInitialBoardData', - 'setFilters', - 'fetchEpicsSwimlanes', - 'fetchIssuesForAllLists', - ]), + }, updateTokens() { this.filterManager.updateTokens(); }, performSearch() { this.setFilters(convertObjectPropsToCamelCase(urlParamsToObject(window.location.search))); if (gon.features.boardsWithSwimlanes && this.isShowingEpicsSwimlanes) { - this.fetchEpicsSwimlanes(false); - this.fetchIssuesForAllLists(); + this.resetEpics(); + this.fetchEpicsSwimlanes({ withLists: false }); + this.resetIssues(); } }, updateDetailIssue(newIssue, multiSelect = false) { const { sidebarInfoEndpoint } = newIssue; if (sidebarInfoEndpoint && newIssue.subscribed === undefined) { newIssue.setFetchingState('subscriptions', true); - setWeigthFetchingState(newIssue, true); + setWeightFetchingState(newIssue, true); setEpicFetchingState(newIssue, true); boardsStore .getIssueInfo(sidebarInfoEndpoint) @@ -201,7 +209,7 @@ export default () => { } = convertObjectPropsToCamelCase(data); newIssue.setFetchingState('subscriptions', false); - setWeigthFetchingState(newIssue, false); + setWeightFetchingState(newIssue, false); setEpicFetchingState(newIssue, false); newIssue.updateData({ humanTimeSpent: humanTotalTimeSpent, @@ -216,7 +224,7 @@ export default () => { }) .catch(() => { newIssue.setFetchingState('subscriptions', false); - setWeigthFetchingState(newIssue, false); + setWeightFetchingState(newIssue, false); Flash(__('An error occurred while fetching sidebar data')); }); } diff --git a/app/assets/javascripts/boards/queries/board.mutation.graphql b/app/assets/javascripts/boards/queries/board.mutation.graphql new file mode 100644 index 00000000000..ef2b81a7939 --- /dev/null +++ b/app/assets/javascripts/boards/queries/board.mutation.graphql @@ -0,0 +1,11 @@ +mutation UpdateBoard($id: ID!, $hideClosedList: Boolean, $hideBacklogList: Boolean) { + updateBoard( + input: { id: $id, hideClosedList: $hideClosedList, hideBacklogList: $hideBacklogList } + ) { + board { + id + hideClosedList + hideBacklogList + } + } +} diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js index 4b81d9c73ef..a513e02e0ca 100644 --- a/app/assets/javascripts/boards/stores/actions.js +++ b/app/assets/javascripts/boards/stores/actions.js @@ -226,31 +226,8 @@ export default { .catch(() => commit(types.RECEIVE_ISSUES_FOR_LIST_FAILURE, listId)); }, - fetchIssuesForAllLists: ({ state, commit }) => { - commit(types.REQUEST_ISSUES_FOR_ALL_LISTS); - - const { endpoints, boardType, filterParams } = state; - const { fullPath, boardId } = endpoints; - - const variables = { - fullPath, - boardId: fullBoardId(boardId), - filters: filterParams, - isGroup: boardType === BoardType.group, - isProject: boardType === BoardType.project, - }; - - return gqlClient - .query({ - query: listsIssuesQuery, - variables, - }) - .then(({ data }) => { - const { lists } = data[boardType]?.board; - const listIssues = formatListIssues(lists); - commit(types.RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS, listIssues); - }) - .catch(() => commit(types.RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE)); + resetIssues: ({ commit }) => { + commit(types.RESET_ISSUES); }, moveIssue: ( diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js index faf4f9ebfd3..d1a5db1bcc5 100644 --- a/app/assets/javascripts/boards/stores/boards_store.js +++ b/app/assets/javascripts/boards/stores/boards_store.js @@ -2,7 +2,7 @@ /* global List */ /* global ListIssue */ import $ from 'jquery'; -import { sortBy } from 'lodash'; +import { sortBy, pick } from 'lodash'; import Vue from 'vue'; import Cookies from 'js-cookie'; import BoardsStoreEE from 'ee_else_ce/boards/stores/boards_store_ee'; @@ -12,7 +12,7 @@ import { parseBoolean, convertObjectPropsToCamelCase, } from '~/lib/utils/common_utils'; -import { __ } from '~/locale'; +import createDefaultClient from '~/lib/graphql'; import axios from '~/lib/utils/axios_utils'; import { mergeUrlParams } from '~/lib/utils/url_utility'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; @@ -23,7 +23,11 @@ import ListLabel from '../models/label'; import ListAssignee from '../models/assignee'; import ListMilestone from '../models/milestone'; +import createBoardMutation from '../queries/board.mutation.graphql'; + const PER_PAGE = 20; +export const gqlClient = createDefaultClient(); + const boardsStore = { disabled: false, timeTracking: { @@ -114,7 +118,6 @@ const boardsStore = { .catch(() => { // https://gitlab.com/gitlab-org/gitlab-foss/issues/30821 }); - this.removeBlankState(); }, updateNewListDropdown(listId) { $(`.js-board-list-${listId}`).removeClass('is-active'); @@ -124,22 +127,14 @@ const boardsStore = { return !this.state.lists.filter(list => list.type !== 'backlog' && list.type !== 'closed')[0]; }, addBlankState() { - if (!this.shouldAddBlankState() || this.welcomeIsHidden() || this.disabled) return; - - this.addList({ - id: 'blank', - list_type: 'blank', - title: __('Welcome to your Issue Board!'), - position: 0, - }); - }, - removeBlankState() { - this.removeList('blank'); + if (!this.shouldAddBlankState() || this.welcomeIsHidden()) return; - Cookies.set('issue_board_welcome_hidden', 'true', { - expires: 365 * 10, - path: '', - }); + this.generateDefaultLists() + .then(res => res.data) + .then(data => Promise.all(data.map(list => this.addList(list)))) + .catch(() => { + this.removeList(undefined, 'label'); + }); }, findIssueLabel(issue, findLabel) { @@ -542,6 +537,10 @@ const boardsStore = { this.timeTracking.limitToHours = parseBoolean(limitToHours); }, + generateBoardGid(boardId) { + return `gid://gitlab/Board/${boardId}`; + }, + generateBoardsPath(id) { return `${this.state.endpoints.boardsEndpoint}${id ? `/${id}` : ''}.json`; }, @@ -800,9 +799,33 @@ const boardsStore = { } if (boardPayload.id) { - return axios.put(this.generateBoardsPath(boardPayload.id), { board: boardPayload }); + const input = { + ...pick(boardPayload, ['hideClosedList', 'hideBacklogList']), + id: this.generateBoardGid(boardPayload.id), + }; + + return Promise.all([ + axios.put(this.generateBoardsPath(boardPayload.id), { board: boardPayload }), + gqlClient.mutate({ + mutation: createBoardMutation, + variables: input, + }), + ]); } - return axios.post(this.generateBoardsPath(), { board: boardPayload }); + + return axios + .post(this.generateBoardsPath(), { board: boardPayload }) + .then(resp => resp.data) + .then(data => { + gqlClient.mutate({ + mutation: createBoardMutation, + variables: { + ...pick(boardPayload, ['hideClosedList', 'hideBacklogList']), + id: this.generateBoardGid(data.id), + }, + }); + return data; + }); }, deleteBoard({ id }) { diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js index f0a283f6161..7e0597f5332 100644 --- a/app/assets/javascripts/boards/stores/mutation_types.js +++ b/app/assets/javascripts/boards/stores/mutation_types.js @@ -12,11 +12,8 @@ export const UPDATE_LIST_FAILURE = 'UPDATE_LIST_FAILURE'; export const REQUEST_REMOVE_LIST = 'REQUEST_REMOVE_LIST'; export const RECEIVE_REMOVE_LIST_SUCCESS = 'RECEIVE_REMOVE_LIST_SUCCESS'; export const RECEIVE_REMOVE_LIST_ERROR = 'RECEIVE_REMOVE_LIST_ERROR'; -export const REQUEST_ISSUES_FOR_ALL_LISTS = 'REQUEST_ISSUES_FOR_ALL_LISTS'; export const RECEIVE_ISSUES_FOR_LIST_FAILURE = 'RECEIVE_ISSUES_FOR_LIST_FAILURE'; export const RECEIVE_ISSUES_FOR_LIST_SUCCESS = 'RECEIVE_ISSUES_FOR_LIST_SUCCESS'; -export const RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS = 'RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS'; -export const RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE = 'RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE'; export const REQUEST_ADD_ISSUE = 'REQUEST_ADD_ISSUE'; export const RECEIVE_ADD_ISSUE_SUCCESS = 'RECEIVE_ADD_ISSUE_SUCCESS'; export const RECEIVE_ADD_ISSUE_ERROR = 'RECEIVE_ADD_ISSUE_ERROR'; @@ -32,3 +29,4 @@ export const SET_CURRENT_PAGE = 'SET_CURRENT_PAGE'; export const TOGGLE_EMPTY_STATE = 'TOGGLE_EMPTY_STATE'; export const SET_ACTIVE_ID = 'SET_ACTIVE_ID'; export const UPDATE_ISSUE_BY_ID = 'UPDATE_ISSUE_BY_ID'; +export const RESET_ISSUES = 'RESET_ISSUES'; diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js index faeb3e25a71..de18ec4b4f3 100644 --- a/app/assets/javascripts/boards/stores/mutations.js +++ b/app/assets/javascripts/boards/stores/mutations.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import { sortBy, pull } from 'lodash'; import { formatIssue, moveIssueListHelper } from '../boards_util'; import * as mutationTypes from './mutation_types'; -import { __ } from '~/locale'; +import { s__ } from '~/locale'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; const notImplemented = () => { @@ -49,7 +49,7 @@ export default { }, [mutationTypes.CREATE_LIST_FAILURE]: state => { - state.error = __('An error occurred while creating the list. Please try again.'); + state.error = s__('Boards|An error occurred while creating the list. Please try again.'); }, [mutationTypes.REQUEST_ADD_LIST]: () => { @@ -73,7 +73,7 @@ export default { }, [mutationTypes.UPDATE_LIST_FAILURE]: (state, backupList) => { - state.error = __('An error occurred while updating the list. Please try again.'); + state.error = s__('Boards|An error occurred while updating the list. Please try again.'); Vue.set(state, 'boardLists', backupList); }, @@ -98,19 +98,17 @@ export default { }, [mutationTypes.RECEIVE_ISSUES_FOR_LIST_FAILURE]: (state, listId) => { - state.error = __('An error occurred while fetching the board issues. Please reload the page.'); + state.error = s__( + 'Boards|An error occurred while fetching the board issues. Please reload the page.', + ); const listIndex = state.boardLists.findIndex(l => l.id === listId); Vue.set(state.boardLists[listIndex], 'loading', false); }, - [mutationTypes.REQUEST_ISSUES_FOR_ALL_LISTS]: state => { - state.isLoadingIssues = true; - }, - - [mutationTypes.RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS]: (state, { listData, issues }) => { - state.issuesByListId = listData; - state.issues = issues; - state.isLoadingIssues = false; + [mutationTypes.RESET_ISSUES]: state => { + Object.keys(state.issuesByListId).forEach(listId => { + Vue.set(state.issuesByListId, listId, []); + }); }, [mutationTypes.UPDATE_ISSUE_BY_ID]: (state, { issueId, prop, value }) => { @@ -122,11 +120,6 @@ export default { Vue.set(state.issues[issueId], prop, value); }, - [mutationTypes.RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE]: state => { - state.error = __('An error occurred while fetching the board issues. Please reload the page.'); - state.isLoadingIssues = false; - }, - [mutationTypes.REQUEST_ADD_ISSUE]: () => { notImplemented(); }, @@ -162,7 +155,7 @@ export default { state, { originalIssue, fromListId, toListId, originalIndex }, ) => { - state.error = __('An error occurred while moving the issue. Please try again.'); + state.error = s__('Boards|An error occurred while moving the issue. Please try again.'); Vue.set(state.issues, originalIssue.id, originalIssue); removeIssueFromList(state, toListId, originalIssue.id); addIssueToList({ @@ -193,7 +186,7 @@ export default { }, [mutationTypes.ADD_ISSUE_TO_LIST_FAILURE]: (state, { list, issue }) => { - state.error = __('An error occurred while creating the issue. Please try again.'); + state.error = s__('Boards|An error occurred while creating the issue. Please try again.'); removeIssueFromList(state, list.id, issue.id); }, diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js index be937d68c6c..2d388739586 100644 --- a/app/assets/javascripts/boards/stores/state.js +++ b/app/assets/javascripts/boards/stores/state.js @@ -11,7 +11,6 @@ export default () => ({ boardLists: [], issuesByListId: {}, issues: {}, - isLoadingIssues: false, filterParams: {}, error: undefined, // TODO: remove after ce/ee split of board_content.vue diff --git a/app/assets/javascripts/build_artifacts.js b/app/assets/javascripts/build_artifacts.js index 2955f0f014b..8324c649538 100644 --- a/app/assets/javascripts/build_artifacts.js +++ b/app/assets/javascripts/build_artifacts.js @@ -3,6 +3,7 @@ import $ from 'jquery'; import { visitUrl } from './lib/utils/url_utility'; import { parseBoolean } from './lib/utils/common_utils'; +import { hide, initTooltips, show } from '~/tooltips'; export default class BuildArtifacts { constructor() { @@ -10,6 +11,7 @@ export default class BuildArtifacts { this.setupEntryClick(); this.setupTooltips(); } + // eslint-disable-next-line class-methods-use-this disablePropagation() { $('.top-block').on('click', '.download', e => { @@ -19,15 +21,17 @@ export default class BuildArtifacts { e.stopImmediatePropagation(); }); } + // eslint-disable-next-line class-methods-use-this setupEntryClick() { return $('.tree-holder').on('click', 'tr[data-link]', function() { visitUrl(this.dataset.link, parseBoolean(this.dataset.externalLink)); }); } + // eslint-disable-next-line class-methods-use-this setupTooltips() { - $('.js-artifact-tree-tooltip').tooltip({ + initTooltips({ placement: 'bottom', // Stop the tooltip from hiding when we stop hovering the element directly // We handle all the showing/hiding below @@ -38,14 +42,14 @@ export default class BuildArtifacts { // But be placed below and in the middle of the file name $('.js-artifact-tree-row') .on('mouseenter', e => { - $(e.currentTarget) - .find('.js-artifact-tree-tooltip') - .tooltip('show'); + const $el = $(e.currentTarget).find('.js-artifact-tree-tooltip'); + + show($el); }) .on('mouseleave', e => { - $(e.currentTarget) - .find('.js-artifact-tree-tooltip') - .tooltip('hide'); + const $el = $(e.currentTarget).find('.js-artifact-tree-tooltip'); + + hide($el); }); } } diff --git a/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue new file mode 100644 index 00000000000..ad07052a298 --- /dev/null +++ b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue @@ -0,0 +1,143 @@ + + + diff --git a/app/assets/javascripts/ci_settings_pipeline_triggers/index.js b/app/assets/javascripts/ci_settings_pipeline_triggers/index.js new file mode 100644 index 00000000000..182d5ca5ffb --- /dev/null +++ b/app/assets/javascripts/ci_settings_pipeline_triggers/index.js @@ -0,0 +1,36 @@ +import Vue from 'vue'; +import TriggersList from './components/triggers_list.vue'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; + +const parseJsonArray = triggers => { + try { + return convertObjectPropsToCamelCase(JSON.parse(triggers), { deep: true }); + } catch { + return []; + } +}; + +export default (containerId = 'js-ci-pipeline-triggers-list') => { + const containerEl = document.getElementById(containerId); + + // Note: Remove this check when FF `ci_pipeline_triggers_settings_vue_ui` is removed. + if (!containerEl) { + return null; + } + + const triggers = parseJsonArray(containerEl.dataset.triggers); + + return new Vue({ + el: containerEl, + components: { + TriggersList, + }, + render(h) { + return h(TriggersList, { + props: { + triggers, + }, + }); + }, + }); +}; diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue index fbf19847e9d..a2f4bea2f61 100644 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue +++ b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue @@ -6,7 +6,6 @@ import { GlFormCheckbox, GlFormCombobox, GlFormGroup, - GlFormInput, GlFormSelect, GlFormTextarea, GlIcon, @@ -41,7 +40,6 @@ export default { GlFormCheckbox, GlFormCombobox, GlFormGroup, - GlFormInput, GlFormSelect, GlFormTextarea, GlIcon, @@ -122,11 +120,6 @@ export default { return ''; }, tokenValidationState() { - // If the feature flag is off, do not validate. Remove when flag is removed. - if (!this.glFeatures.ciKeyAutocomplete) { - return true; - } - const validator = this.$options.tokens?.[this.variable.key]?.validation; if (validator) { @@ -204,21 +197,12 @@ export default { > - - - - -
+
- + -import { GlDeprecatedDropdown, GlDeprecatedDropdownItem, GlIcon } from '@gitlab/ui'; +import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui'; import { s__ } from '../../locale'; export default { name: 'CrossplaneProviderStack', components: { - GlDeprecatedDropdown, - GlDeprecatedDropdownItem, + GlDropdown, + GlDropdownItem, GlIcon, }, props: { @@ -67,21 +67,17 @@ export default { - - + {{ stack.name }} - - + + {{ validationError }}

{{ s__(`You must select a stack for configuring your cloud provider. Learn more about`) }} diff --git a/app/assets/javascripts/clusters/components/fluentd_output_settings.vue b/app/assets/javascripts/clusters/components/fluentd_output_settings.vue index e6001b11296..b37fc3894f8 100644 --- a/app/assets/javascripts/clusters/components/fluentd_output_settings.vue +++ b/app/assets/javascripts/clusters/components/fluentd_output_settings.vue @@ -1,11 +1,5 @@ + + diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js index 3e8ef3151a6..f39678b73dc 100644 --- a/app/assets/javascripts/clusters_list/constants.js +++ b/app/assets/javascripts/clusters_list/constants.js @@ -1,4 +1,45 @@ -import { __ } from '~/locale'; +import { __, s__ } from '~/locale'; + +export const CLUSTER_ERRORS = { + default: { + tableText: s__('ClusterIntegration|Unknown Error'), + title: s__('ClusterIntegration|Unknown Error'), + description: s__( + 'ClusterIntegration|An unknown error occurred while attempting to connect to Kubernetes.', + ), + troubleshootingTips: [ + s__('ClusterIntegration|Check your cluster status'), + s__('ClusterIntegration|Make sure your API endpoint is correct'), + s__( + 'ClusterIntegration|Node calculations use the Kubernetes Metrics API. Make sure your cluster has metrics installed', + ), + ], + }, + authentication_error: { + tableText: s__('ClusterIntegration|Unable to Authenticate'), + title: s__('ClusterIntegration|Authentication Error'), + description: s__('ClusterIntegration|GitLab failed to authenticate.'), + troubleshootingTips: [ + s__('ClusterIntegration|Check your token'), + s__('ClusterIntegration|Check your CA certificate'), + ], + }, + connection_error: { + tableText: s__('ClusterIntegration|Unable to Connect'), + title: s__('ClusterIntegration|Connection Error'), + description: s__('ClusterIntegration|GitLab failed to connect to the cluster.'), + troubleshootingTips: [ + s__('ClusterIntegration|Check your cluster status'), + s__('ClusterIntegration|Make sure your API endpoint is correct'), + ], + }, + http_error: { + tableText: s__('ClusterIntegration|Unable to Connect'), + title: s__('ClusterIntegration|HTTP Error'), + description: s__('ClusterIntegration|There was an HTTP error when connecting to your cluster.'), + troubleshootingTips: [s__('ClusterIntegration|Check your cluster status')], + }, +}; export const CLUSTER_TYPES = { project_type: __('Project'), diff --git a/app/assets/javascripts/clusters_list/index.js b/app/assets/javascripts/clusters_list/index.js index 51ad8769250..daa82892773 100644 --- a/app/assets/javascripts/clusters_list/index.js +++ b/app/assets/javascripts/clusters_list/index.js @@ -1,20 +1,6 @@ import Vue from 'vue'; -import Clusters from './components/clusters.vue'; -import { createStore } from './store'; +import loadClusters from './load_clusters'; export default () => { - const entryPoint = document.querySelector('#js-clusters-list-app'); - - if (!entryPoint) { - return; - } - - // eslint-disable-next-line no-new - new Vue({ - el: '#js-clusters-list-app', - store: createStore(entryPoint.dataset), - render(createElement) { - return createElement(Clusters); - }, - }); + loadClusters(Vue); }; diff --git a/app/assets/javascripts/clusters_list/load_clusters.js b/app/assets/javascripts/clusters_list/load_clusters.js new file mode 100644 index 00000000000..98bc5880898 --- /dev/null +++ b/app/assets/javascripts/clusters_list/load_clusters.js @@ -0,0 +1,18 @@ +import Clusters from './components/clusters.vue'; +import { createStore } from './store'; + +export default Vue => { + const el = document.querySelector('#js-clusters-list-app'); + + if (!el) { + return null; + } + + return new Vue({ + el, + store: createStore(el.dataset), + render(createElement) { + return createElement(Clusters); + }, + }); +}; diff --git a/app/assets/javascripts/code_navigation/index.js b/app/assets/javascripts/code_navigation/index.js index 362c26ae065..fa5835245bc 100644 --- a/app/assets/javascripts/code_navigation/index.js +++ b/app/assets/javascripts/code_navigation/index.js @@ -1,13 +1,17 @@ import Vue from 'vue'; import Vuex from 'vuex'; -import store from './store'; +import createStore from './store'; import App from './components/app.vue'; -Vue.use(Vuex); - export default initialData => { const el = document.getElementById('js-code-navigation'); + if (!el) return null; + + Vue.use(Vuex); + + const store = createStore(); + store.dispatch('setInitialData', initialData); return new Vue({ diff --git a/app/assets/javascripts/code_navigation/store/index.js b/app/assets/javascripts/code_navigation/store/index.js index fe48f3ac7f5..9b60fc337fe 100644 --- a/app/assets/javascripts/code_navigation/store/index.js +++ b/app/assets/javascripts/code_navigation/store/index.js @@ -3,8 +3,9 @@ import createState from './state'; import actions from './actions'; import mutations from './mutations'; -export default new Vuex.Store({ - actions, - mutations, - state: createState(), -}); +export default () => + new Vuex.Store({ + actions, + mutations, + state: createState(), + }); diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue index 2f4118c1717..188d958ba86 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.vue +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue @@ -1,6 +1,5 @@