Commit 1a57f833 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents eb783efe dd427643
...@@ -129,7 +129,7 @@ module UsersHelper ...@@ -129,7 +129,7 @@ module UsersHelper
} }
end end
def unblock_user_modal_data(user) def user_unblock_data(user)
{ {
path: unblock_admin_user_path(user), path: unblock_admin_user_path(user),
method: 'put', method: 'put',
...@@ -168,6 +168,19 @@ module UsersHelper ...@@ -168,6 +168,19 @@ module UsersHelper
} }
end end
def user_activation_data(user)
{
path: activate_admin_user_path(user),
method: 'put',
modal_attributes: {
title: s_('AdminUsers|Activate user %{username}?') % { username: sanitize_name(user.name) },
message: s_('AdminUsers|You can always deactivate their account again if needed.'),
okVariant: 'info',
okTitle: s_('AdminUsers|Activate')
}.to_json
}
end
def user_deactivation_effects def user_deactivation_effects
header = tag.p s_('AdminUsers|Deactivating a user has the following effects:') header = tag.p s_('AdminUsers|Deactivating a user has the following effects:')
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
%button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) } %button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) }
= s_('AdminUsers|Block') = s_('AdminUsers|Block')
- else - else
%button.btn.btn-default-tertiary.js-confirm-modal-button{ data: unblock_user_modal_data(user) } %button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_unblock_data(user) }
= s_('AdminUsers|Unblock') = s_('AdminUsers|Unblock')
- else - else
%button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) } %button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_block_data(user, user_block_effects) }
...@@ -51,7 +51,8 @@ ...@@ -51,7 +51,8 @@
= s_('AdminUsers|Deactivate') = s_('AdminUsers|Deactivate')
- elsif user.deactivated? - elsif user.deactivated?
%li %li
= link_to _('Activate'), activate_admin_user_path(user), method: :put %button.btn.btn-default-tertiary.js-confirm-modal-button{ data: user_activation_data(user) }
= s_('AdminUsers|Activate')
- if user.access_locked? - if user.access_locked?
%li %li
= link_to _('Unlock'), unlock_admin_user_path(user), method: :put, data: { confirm: _('Are you sure?') } = link_to _('Unlock'), unlock_admin_user_path(user), method: :put, data: { confirm: _('Are you sure?') }
......
...@@ -158,7 +158,8 @@ ...@@ -158,7 +158,8 @@
.card-body .card-body
= render partial: 'admin/users/user_activation_effects' = render partial: 'admin/users/user_activation_effects'
%br %br
= link_to 'Activate user', activate_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: 'Are you sure?' } %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_activation_data(@user) }
= s_('AdminUsers|Activate user')
- elsif @user.can_be_deactivated? - elsif @user.can_be_deactivated?
.card.border-warning .card.border-warning
.card-header.bg-warning.text-white .card-header.bg-warning.text-white
...@@ -182,7 +183,7 @@ ...@@ -182,7 +183,7 @@
%li Log in %li Log in
%li Access Git repositories %li Access Git repositories
%br %br
%button.btn.gl-button.btn-info.js-confirm-modal-button{ data: unblock_user_modal_data(@user) } %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_unblock_data(@user) }
= s_('AdminUsers|Unblock user') = s_('AdminUsers|Unblock user')
- elsif !@user.internal? - elsif !@user.internal?
= render 'admin/users/block_user', user: @user = render 'admin/users/block_user', user: @user
......
---
title: Add confirm modal to reactivate user
merge_request: 48173
author:
type: added
...@@ -224,6 +224,7 @@ Kibana ...@@ -224,6 +224,7 @@ Kibana
Kinesis Kinesis
Knative Knative
Kramdown Kramdown
Kroki
Kubecost Kubecost
kubectl kubectl
Kubernetes Kubernetes
......
# Kroki diagrams **(CORE)** # Kroki diagrams **(CORE ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241744) in GitLab 13.7. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241744) in GitLab 13.7.
...@@ -10,7 +10,7 @@ GitLab you can use it to create diagrams in AsciiDoc and Markdown documents. ...@@ -10,7 +10,7 @@ GitLab you can use it to create diagrams in AsciiDoc and Markdown documents.
When Kroki is enabled, GitLab sends diagrams to an instance of Kroki to display them as images. When Kroki is enabled, GitLab sends diagrams to an instance of Kroki to display them as images.
You can use the free public cloud instance `https://kroki.io` or you can [install Kroki](https://docs.kroki.io/kroki/setup/install/) You can use the free public cloud instance `https://kroki.io` or you can [install Kroki](https://docs.kroki.io/kroki/setup/install/)
on your own infrastructure. on your own infrastructure.
Once you've installed Kroki, make sure to update the server URL to point to your instance. After you've installed Kroki, make sure to update the server URL to point to your instance.
### Docker ### Docker
...@@ -38,12 +38,12 @@ The [`yuzutech/kroki`](https://hub.docker.com/r/yuzutech/kroki) image contains t ...@@ -38,12 +38,12 @@ The [`yuzutech/kroki`](https://hub.docker.com/r/yuzutech/kroki) image contains t
- [WaveDrom](https://wavedrom.com/) - [WaveDrom](https://wavedrom.com/)
If you want to use additional diagram libraries, If you want to use additional diagram libraries,
read the [Kroki installation](https://docs.kroki.io/kroki/setup/install/#_images) to learn how to start Kroki companion containers. read the [Kroki installation](https://docs.kroki.io/kroki/setup/install/#_images) to learn how to start Kroki companion containers.
## Enable Kroki in GitLab **(CORE ONLY)** ## Enable Kroki in GitLab
You need to enable Kroki integration from Settings under Admin Area. You need to enable Kroki integration from Settings under Admin Area.
To do that, log in with an Admin account and follow these steps: To do that, log in with an administrator account and follow these steps:
1. Select the Admin Area (**{admin}**) icon. 1. Select the Admin Area (**{admin}**) icon.
1. Navigate to **Settings > General**. 1. Navigate to **Settings > General**.
......
...@@ -74,7 +74,7 @@ export default { ...@@ -74,7 +74,7 @@ export default {
<security-dashboard-layout> <security-dashboard-layout>
<template #header> <template #header>
<div class="gl-mt-6 gl-display-flex"> <div class="gl-mt-6 gl-display-flex">
<h4 class="gl-flex-grow-1 gl-my-0">{{ __('Vulnerabilities') }}</h4> <h4 class="gl-flex-grow-1 gl-my-0">{{ __('Vulnerability Report') }}</h4>
<csv-export-button :vulnerabilities-export-endpoint="vulnerabilitiesExportEndpoint" /> <csv-export-button :vulnerabilities-export-endpoint="vulnerabilitiesExportEndpoint" />
</div> </div>
<project-pipeline-status :pipeline="pipeline" /> <project-pipeline-status :pipeline="pipeline" />
......
...@@ -40,7 +40,7 @@ export default { ...@@ -40,7 +40,7 @@ export default {
}, },
i18n: { i18n: {
title: __( title: __(
'The Security Dashboard shows the results of the last successful pipeline run on the default branch.', 'The Vulnerability Report shows the results of the last successful pipeline run on the default branch.',
), ),
lastUpdated: __('Last updated'), lastUpdated: __('Last updated'),
autoFixSolutions: s__('AutoRemediation|Auto-fix solutions'), autoFixSolutions: s__('AutoRemediation|Auto-fix solutions'),
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
%section.settings.issues-feature.no-animate#js-issue-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:issues_access_level) == 0)] } %section.settings.issues-feature.no-animate#js-issue-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:issues_access_level) == 0)] }
.settings-header .settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Default issue template') %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Default issue template')
%button.btn.btn-default.js-settings-toggle= expanded ? _('Collapse') : _('Expand') %button.gl-button.btn.btn-default.js-settings-toggle= expanded ? _('Collapse') : _('Expand')
%p= _('Set a default template for issue descriptions.') %p= _('Set a default template for issue descriptions.')
.settings-content .settings-content
...@@ -18,4 +18,4 @@ ...@@ -18,4 +18,4 @@
.text-secondary .text-secondary
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/markdown') } - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/markdown') }
= _('Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe } = _('Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
= f.submit _('Save changes'), class: "btn btn-success" = f.submit _('Save changes'), class: "gl-button btn btn-success"
---
title: Update header text on project level vulnerability report page
merge_request: 48872
author:
type: other
import { GlBanner } from '@gitlab/ui'; import { GlBanner } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { within } from '@testing-library/dom';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import AutoFixUserCallout from 'ee/security_dashboard/components/auto_fix_user_callout.vue'; import AutoFixUserCallout from 'ee/security_dashboard/components/auto_fix_user_callout.vue';
import CsvExportButton from 'ee/security_dashboard/components/csv_export_button.vue'; import CsvExportButton from 'ee/security_dashboard/components/csv_export_button.vue';
...@@ -71,6 +72,12 @@ describe('First class Project Security Dashboard component', () => { ...@@ -71,6 +72,12 @@ describe('First class Project Security Dashboard component', () => {
}); });
}); });
it('should render the header correctly', () => {
expect(
within(wrapper.element).getByRole('heading', { name: 'Vulnerability Report' }),
).not.toBe(null);
});
it('should render the vulnerabilities', () => { it('should render the vulnerabilities', () => {
expect(findVulnerabilities().exists()).toBe(true); expect(findVulnerabilities().exists()).toBe(true);
}); });
......
import { GlLink } from '@gitlab/ui'; import { GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { within } from '@testing-library/dom';
import { merge } from 'lodash'; import { merge } from 'lodash';
import PipelineStatusBadge from 'ee/security_dashboard/components/pipeline_status_badge.vue'; import PipelineStatusBadge from 'ee/security_dashboard/components/pipeline_status_badge.vue';
import ProjectPipelineStatus from 'ee/security_dashboard/components/project_pipeline_status.vue'; import ProjectPipelineStatus from 'ee/security_dashboard/components/project_pipeline_status.vue';
...@@ -55,6 +56,15 @@ describe('Project Pipeline Status Component', () => { ...@@ -55,6 +56,15 @@ describe('Project Pipeline Status Component', () => {
wrapper = createWrapper(); wrapper = createWrapper();
}); });
it('should display the help message properly', () => {
expect(
within(wrapper.element).getByRole('heading', {
name:
'The Vulnerability Report shows the results of the last successful pipeline run on the default branch.',
}),
).not.toBe(null);
});
it('should show the timeAgoTooltip component', () => { it('should show the timeAgoTooltip component', () => {
const TimeComponent = findTimeAgoTooltip(); const TimeComponent = findTimeAgoTooltip();
expect(TimeComponent.exists()).toBeTruthy(); expect(TimeComponent.exists()).toBeTruthy();
......
...@@ -1489,9 +1489,6 @@ msgstr "" ...@@ -1489,9 +1489,6 @@ msgstr ""
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
msgid "Activate"
msgstr ""
msgid "Activate Service Desk" msgid "Activate Service Desk"
msgstr "" msgstr ""
...@@ -2070,6 +2067,15 @@ msgstr "" ...@@ -2070,6 +2067,15 @@ msgstr ""
msgid "AdminUsers|Access the API" msgid "AdminUsers|Access the API"
msgstr "" msgstr ""
msgid "AdminUsers|Activate"
msgstr ""
msgid "AdminUsers|Activate user"
msgstr ""
msgid "AdminUsers|Activate user %{username}?"
msgstr ""
msgid "AdminUsers|Active" msgid "AdminUsers|Active"
msgstr "" msgstr ""
...@@ -2259,6 +2265,9 @@ msgstr "" ...@@ -2259,6 +2265,9 @@ msgstr ""
msgid "AdminUsers|You can always block their account again if needed." msgid "AdminUsers|You can always block their account again if needed."
msgstr "" msgstr ""
msgid "AdminUsers|You can always deactivate their account again if needed."
msgstr ""
msgid "AdminUsers|You can always re-activate their account, their data will remain intact." msgid "AdminUsers|You can always re-activate their account, their data will remain intact."
msgstr "" msgstr ""
...@@ -26931,9 +26940,6 @@ msgstr "" ...@@ -26931,9 +26940,6 @@ msgstr ""
msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}" msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}"
msgstr "" msgstr ""
msgid "The Security Dashboard shows the results of the last successful pipeline run on the default branch."
msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it." msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr "" msgstr ""
...@@ -26943,6 +26949,9 @@ msgstr "" ...@@ -26943,6 +26949,9 @@ msgstr ""
msgid "The URL to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., \"http://localhost:9200, http://localhost:9201\")." msgid "The URL to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., \"http://localhost:9200, http://localhost:9201\")."
msgstr "" msgstr ""
msgid "The Vulnerability Report shows the results of the last successful pipeline run on the default branch."
msgstr ""
msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS." msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS."
msgstr "" msgstr ""
......
...@@ -77,8 +77,8 @@ RSpec.describe 'Admin::Users::User' do ...@@ -77,8 +77,8 @@ RSpec.describe 'Admin::Users::User' do
end end
end end
context 'when deactivating the user' do context 'when deactivating/re-activating the user' do
it 'shows confirmation and allows blocking', :js do it 'shows confirmation and allows deactivating/re-activating', :js do
visit admin_user_path(user) visit admin_user_path(user)
find('button', text: 'Deactivate user').click find('button', text: 'Deactivate user').click
...@@ -94,6 +94,20 @@ RSpec.describe 'Admin::Users::User' do ...@@ -94,6 +94,20 @@ RSpec.describe 'Admin::Users::User' do
expect(page).to have_content('Successfully deactivated') expect(page).to have_content('Successfully deactivated')
expect(page).to have_content('Reactivate this user') expect(page).to have_content('Reactivate this user')
find('button', text: 'Activate user').click
wait_for_requests
expect(page).to have_content('Activate user')
expect(page).to have_content('You can always deactivate their account again if needed.')
find('.modal-footer button', text: 'Activate').click
wait_for_requests
expect(page).to have_content('Successfully activated')
expect(page).to have_content('Deactivate this user')
end end
end end
......
...@@ -207,11 +207,7 @@ RSpec.describe 'Admin::Users' do ...@@ -207,11 +207,7 @@ RSpec.describe 'Admin::Users' do
it 'shows confirmation and allows blocking and unblocking', :js do it 'shows confirmation and allows blocking and unblocking', :js do
expect(page).to have_content(user.email) expect(page).to have_content(user.email)
find("[data-testid='user-action-button-#{user.id}']").click click_action_in_user_dropdown(user.id, 'Block')
within find("[data-testid='user-action-dropdown-#{user.id}']") do
find('li button', text: 'Block').click
end
wait_for_requests wait_for_requests
...@@ -233,13 +229,7 @@ RSpec.describe 'Admin::Users' do ...@@ -233,13 +229,7 @@ RSpec.describe 'Admin::Users' do
expect(page).to have_content(user.email) expect(page).to have_content(user.email)
find("[data-testid='user-action-button-#{user.id}']").click click_action_in_user_dropdown(user.id, 'Unblock')
within find("[data-testid='user-action-dropdown-#{user.id}']") do
find('li button', text: 'Unblock').click
end
wait_for_requests
expect(page).to have_content('Unblock user') expect(page).to have_content('Unblock user')
expect(page).to have_content('You can always block their account again if needed.') expect(page).to have_content('You can always block their account again if needed.')
...@@ -253,17 +243,11 @@ RSpec.describe 'Admin::Users' do ...@@ -253,17 +243,11 @@ RSpec.describe 'Admin::Users' do
end end
end end
context 'when deactivating a user' do context 'when deactivating/re-activating a user' do
it 'shows confirmation and allows deactivating', :js do it 'shows confirmation and allows deactivating and re-activating', :js do
expect(page).to have_content(user.email) expect(page).to have_content(user.email)
find("[data-testid='user-action-button-#{user.id}']").click click_action_in_user_dropdown(user.id, 'Deactivate')
within find("[data-testid='user-action-dropdown-#{user.id}']") do
find('li button', text: 'Deactivate').click
end
wait_for_requests
expect(page).to have_content('Deactivate user') expect(page).to have_content('Deactivate user')
expect(page).to have_content('Deactivating a user has the following effects') expect(page).to have_content('Deactivating a user has the following effects')
...@@ -276,8 +260,36 @@ RSpec.describe 'Admin::Users' do ...@@ -276,8 +260,36 @@ RSpec.describe 'Admin::Users' do
expect(page).to have_content('Successfully deactivated') expect(page).to have_content('Successfully deactivated')
expect(page).not_to have_content(user.email) expect(page).not_to have_content(user.email)
click_link 'Deactivated'
wait_for_requests
expect(page).to have_content(user.email)
click_action_in_user_dropdown(user.id, 'Activate')
expect(page).to have_content('Activate user')
expect(page).to have_content('You can always deactivate their account again if needed.')
find('.modal-footer button', text: 'Activate').click
wait_for_requests
expect(page).to have_content('Successfully activated')
expect(page).not_to have_content(user.email)
end end
end end
def click_action_in_user_dropdown(user_id, action)
find("[data-testid='user-action-button-#{user_id}']").click
within find("[data-testid='user-action-dropdown-#{user_id}']") do
find('li button', text: action).click
end
wait_for_requests
end
end end
describe 'GET /admin/users/new' do describe 'GET /admin/users/new' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment