summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-19 18:09:17 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-19 18:09:17 +0000
commit0eb4fd2f32e6804bc85868ba167170238e346279 (patch)
treec020e787ea29c77e1e9f53c21940f88a87a6e905 /app
parent78d8830cec030ff12afed3c8ae1dddec454d0a24 (diff)
downloadgitlab-ce-0eb4fd2f32e6804bc85868ba167170238e346279.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/registry/explorer/components/project_empty_state.vue63
-rw-r--r--app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue92
-rw-r--r--app/assets/javascripts/registry/explorer/constants.js8
-rw-r--r--app/assets/javascripts/registry/explorer/pages/list.vue10
-rw-r--r--app/assets/javascripts/registry/explorer/stores/getters.js16
-rw-r--r--app/controllers/groups/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb2
-rw-r--r--app/views/admin/groups/show.html.haml7
-rw-r--r--app/views/admin/users/_user.html.haml95
-rw-r--r--app/views/ci/variables/_index.html.haml2
10 files changed, 205 insertions, 92 deletions
diff --git a/app/assets/javascripts/registry/explorer/components/project_empty_state.vue b/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
index 556df10ea5b..0ce38c4a9ec 100644
--- a/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
+++ b/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
@@ -1,7 +1,9 @@
<script>
import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
+import { mapState, mapGetters } from 'vuex';
+import { s__ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-import { mapState } from 'vuex';
+import { COPY_LOGIN_TITLE, COPY_BUILD_TITLE, COPY_PUSH_TITLE, QUICK_START } from '../constants';
export default {
name: 'ProjectEmptyState',
@@ -11,20 +13,24 @@ export default {
GlSprintf,
GlLink,
},
+ i18n: {
+ quickStart: QUICK_START,
+ copyLoginTitle: COPY_LOGIN_TITLE,
+ copyBuildTitle: COPY_BUILD_TITLE,
+ copyPushTitle: COPY_PUSH_TITLE,
+ introText: s__(
+ `ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}`,
+ ),
+ notLoggedInMessage: s__(
+ `ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password.`,
+ ),
+ addImageText: s__(
+ 'ContainerRegistry|You can add an image to this registry with the following commands:',
+ ),
+ },
computed: {
...mapState(['config']),
- dockerBuildCommand() {
- // eslint-disable-next-line @gitlab/require-i18n-strings
- return `docker build -t ${this.config.repositoryUrl} .`;
- },
- dockerPushCommand() {
- // eslint-disable-next-line @gitlab/require-i18n-strings
- return `docker push ${this.config.repositoryUrl}`;
- },
- dockerLoginCommand() {
- // eslint-disable-next-line @gitlab/require-i18n-strings
- return `docker login ${this.config.registryHostUrlWithPort}`;
- },
+ ...mapGetters(['dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand']),
},
};
</script>
@@ -36,28 +42,15 @@ export default {
>
<template #description>
<p class="js-no-container-images-text">
- <gl-sprintf
- :message="
- s__(`ContainerRegistry|With the Container Registry, every project can have its own space to
- store its Docker images. %{docLinkStart}More Information%{docLinkEnd}`)
- "
- >
+ <gl-sprintf :message="$options.i18n.introText">
<template #docLink="{content}">
<gl-link :href="config.helpPagePath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
- <h5>{{ s__('ContainerRegistry|Quick Start') }}</h5>
+ <h5>{{ $options.i18n.quickStart }}</h5>
<p class="js-not-logged-in-to-registry-text">
- <gl-sprintf
- :message="
- s__(`ContainerRegistry|If you are not already logged in, you need to authenticate to
- the Container Registry by using your GitLab username and password. If you have
- %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a
- %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd}
- instead of a password.`)
- "
- >
+ <gl-sprintf :message="$options.i18n.notLoggedInMessage">
<template #twofaDocLink="{content}">
<gl-link :href="config.twoFactorAuthHelpLink" target="_blank">{{ content }}</gl-link>
</template>
@@ -73,18 +66,14 @@ export default {
<span class="input-group-append">
<clipboard-button
:text="dockerLoginCommand"
- :title="s__('ContainerRegistry|Copy login command')"
+ :title="$options.i18n.copyLoginTitle"
class="input-group-text"
/>
</span>
</div>
<p></p>
<p>
- {{
- s__(
- 'ContainerRegistry|You can add an image to this registry with the following commands:',
- )
- }}
+ {{ $options.i18n.addImageText }}
</p>
<div class="input-group append-bottom-10">
@@ -92,7 +81,7 @@ export default {
<span class="input-group-append">
<clipboard-button
:text="dockerBuildCommand"
- :title="s__('ContainerRegistry|Copy build command')"
+ :title="$options.i18n.copyBuildTitle"
class="input-group-text"
/>
</span>
@@ -103,7 +92,7 @@ export default {
<span class="input-group-append">
<clipboard-button
:text="dockerPushCommand"
- :title="s__('ContainerRegistry|Copy push command')"
+ :title="$options.i18n.copyPushTitle"
class="input-group-text"
/>
</span>
diff --git a/app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue b/app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue
new file mode 100644
index 00000000000..99361b6e08d
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue
@@ -0,0 +1,92 @@
+<script>
+import { GlDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
+import { mapGetters } from 'vuex';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import {
+ QUICK_START,
+ LOGIN_COMMAND_LABEL,
+ COPY_LOGIN_TITLE,
+ BUILD_COMMAND_LABEL,
+ COPY_BUILD_TITLE,
+ PUSH_COMMAND_LABEL,
+ COPY_PUSH_TITLE,
+} from '../constants';
+
+export default {
+ components: {
+ GlDropdown,
+ GlFormGroup,
+ GlFormInputGroup,
+ ClipboardButton,
+ },
+ i18n: {
+ dropdownTitle: QUICK_START,
+ loginCommandLabel: LOGIN_COMMAND_LABEL,
+ copyLoginTitle: COPY_LOGIN_TITLE,
+ buildCommandLabel: BUILD_COMMAND_LABEL,
+ copyBuildTitle: COPY_BUILD_TITLE,
+ pushCommandLabel: PUSH_COMMAND_LABEL,
+ copyPushTitle: COPY_PUSH_TITLE,
+ },
+ computed: {
+ ...mapGetters(['dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand']),
+ },
+};
+</script>
+<template>
+ <gl-dropdown :text="$options.i18n.dropdownTitle" variant="primary" size="sm" right>
+ <!-- This li is used as a container since gl-dropdown produces a root ul, this mimics the functionality exposed by b-dropdown-form -->
+ <li role="presentation" class="px-2 py-1 dropdown-menu-large">
+ <form>
+ <gl-form-group
+ label-size="sm"
+ label-for="docker-login-btn"
+ :label="$options.i18n.loginCommandLabel"
+ >
+ <gl-form-input-group id="docker-login-btn" :value="dockerLoginCommand" readonly>
+ <template #append>
+ <clipboard-button
+ class="border"
+ :text="dockerLoginCommand"
+ :title="$options.i18n.copyLoginTitle"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+
+ <gl-form-group
+ label-size="sm"
+ label-for="docker-build-btn"
+ :label="$options.i18n.buildCommandLabel"
+ >
+ <gl-form-input-group id="docker-build-btn" :value="dockerBuildCommand" readonly>
+ <template #append>
+ <clipboard-button
+ class="border"
+ :text="dockerBuildCommand"
+ :title="$options.i18n.copyBuildTitle"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+
+ <gl-form-group
+ class="mb-0"
+ label-size="sm"
+ label-for="docker-push-btn"
+ :label="$options.i18n.pushCommandLabel"
+ >
+ <gl-form-input-group id="docker-push-btn" :value="dockerPushCommand" readonly>
+ <template #append>
+ <clipboard-button
+ class="border"
+ :text="dockerPushCommand"
+ :title="$options.i18n.copyPushTitle"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+ </form>
+ </li>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/constants.js b/app/assets/javascripts/registry/explorer/constants.js
index ef72c085972..f5d935a2d70 100644
--- a/app/assets/javascripts/registry/explorer/constants.js
+++ b/app/assets/javascripts/registry/explorer/constants.js
@@ -47,3 +47,11 @@ export const EXPIRATION_POLICY_ALERT_FULL_MESSAGE = s__(
export const EXPIRATION_POLICY_ALERT_SHORT_MESSAGE = s__(
'ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}',
);
+
+export const QUICK_START = s__('ContainerRegistry|Quick Start');
+export const LOGIN_COMMAND_LABEL = s__('ContainerRegistry|Login');
+export const COPY_LOGIN_TITLE = s__('ContainerRegistry|Copy login command');
+export const BUILD_COMMAND_LABEL = s__('ContainerRegistry|Build an image');
+export const COPY_BUILD_TITLE = s__('ContainerRegistry|Copy build command');
+export const PUSH_COMMAND_LABEL = s__('ContainerRegistry|Push an image');
+export const COPY_PUSH_TITLE = s__('ContainerRegistry|Copy push command');
diff --git a/app/assets/javascripts/registry/explorer/pages/list.vue b/app/assets/javascripts/registry/explorer/pages/list.vue
index c6ba06cd68c..7e321e927d3 100644
--- a/app/assets/javascripts/registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/registry/explorer/pages/list.vue
@@ -16,6 +16,7 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import ProjectEmptyState from '../components/project_empty_state.vue';
import GroupEmptyState from '../components/group_empty_state.vue';
import ProjectPolicyAlert from '../components/project_policy_alert.vue';
+import QuickstartDropdown from '../components/quickstart_dropdown.vue';
export default {
name: 'RegistryListApp',
@@ -26,6 +27,7 @@ export default {
GroupEmptyState,
ProjectPolicyAlert,
ClipboardButton,
+ QuickstartDropdown,
GlButton,
GlIcon,
GlModal,
@@ -62,6 +64,9 @@ export default {
this.requestImagesList({ page });
},
},
+ showQuickStartDropdown() {
+ return Boolean(!this.isLoading && !this.config?.isGroupPage && this.images?.length);
+ },
},
methods: {
...mapActions(['requestImagesList', 'requestDeleteImage']),
@@ -114,7 +119,10 @@ export default {
<template v-else>
<div>
- <h4>{{ s__('ContainerRegistry|Container Registry') }}</h4>
+ <div class="d-flex justify-content-between align-items-center">
+ <h4>{{ s__('ContainerRegistry|Container Registry') }}</h4>
+ <quickstart-dropdown v-if="showQuickStartDropdown" class="d-none d-sm-block" />
+ </div>
<p>
<gl-sprintf
:message="
diff --git a/app/assets/javascripts/registry/explorer/stores/getters.js b/app/assets/javascripts/registry/explorer/stores/getters.js
index 5619b73d495..1136257a024 100644
--- a/app/assets/javascripts/registry/explorer/stores/getters.js
+++ b/app/assets/javascripts/registry/explorer/stores/getters.js
@@ -1,6 +1,20 @@
-// eslint-disable-next-line import/prefer-default-export
export const tags = state => {
// to show the loader inside the table we need to pass an empty array to gl-table whenever the table is loading
// this is to take in account isLoading = true and state.tags =[1,2,3] during pagination and delete
return state.isLoading ? [] : state.tags;
};
+
+export const dockerBuildCommand = state => {
+ /* eslint-disable @gitlab/require-i18n-strings */
+ return `docker build -t ${state.config.repositoryUrl} .`;
+};
+
+export const dockerPushCommand = state => {
+ /* eslint-disable @gitlab/require-i18n-strings */
+ return `docker push ${state.config.repositoryUrl}`;
+};
+
+export const dockerLoginCommand = state => {
+ /* eslint-disable @gitlab/require-i18n-strings */
+ return `docker login ${state.config.registryHostUrlWithPort}`;
+};
diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb
index 3d347429398..ffa3f2c3364 100644
--- a/app/controllers/groups/settings/ci_cd_controller.rb
+++ b/app/controllers/groups/settings/ci_cd_controller.rb
@@ -7,7 +7,7 @@ module Groups
before_action :authorize_admin_group!
before_action :authorize_update_max_artifacts_size!, only: [:update]
before_action do
- push_frontend_feature_flag(:new_variables_ui, @group, default_enabled: true)
+ push_frontend_feature_flag(:new_variables_ui, @group)
end
before_action :define_variables, only: [:show, :create_deploy_token]
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 43c798bfc6e..aac6ecb07e4 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -6,7 +6,7 @@ module Projects
before_action :authorize_admin_pipeline!
before_action :define_variables
before_action do
- push_frontend_feature_flag(:new_variables_ui, @project, default_enabled: true)
+ push_frontend_feature_flag(:new_variables_ui, @project)
end
def show
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 160c3b4d06d..91ccfb07f49 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -78,14 +78,15 @@
.card-footer
= paginate @projects, param_name: 'projects_page', theme: 'gitlab'
- - if @group.shared_projects.any?
+ - shared_projects = @group.shared_projects.sort_by(&:name)
+ - unless shared_projects.empty?
.card
.card-header
= _('Projects shared with %{group_name}') % { group_name: @group.name }
%span.badge.badge-pill
- #{@group.shared_projects.count}
+ #{shared_projects.size}
%ul.content-list
- - @group.shared_projects.sort_by(&:name).each do |project|
+ - shared_projects.each do |project|
%li
%strong
= link_to project.full_name, [:admin, project.namespace.becomes(Namespace), project]
diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml
index 978e830d0e4..440eaac1917 100644
--- a/app/views/admin/users/_user.html.haml
+++ b/app/views/admin/users/_user.html.haml
@@ -14,51 +14,52 @@
= _('Last activity')
.table-mobile-content
= user.last_activity_on.nil? ? _('Never') : l(user.last_activity_on, format: :admin)
- .table-section.section-20.table-button-footer
- .table-action-buttons
- = link_to _('Edit'), edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn btn-default'
- - unless user == current_user
- %button.dropdown-new.btn.btn-default{ type: 'button', data: { toggle: 'dropdown' } }
- = sprite_icon('settings')
- = sprite_icon('chevron-down')
- %ul.dropdown-menu.dropdown-menu-right
- %li.dropdown-header
- = _('Settings')
- %li
- - if user.ldap_blocked?
- %span.small
- = s_('AdminUsers|Cannot unblock LDAP blocked users')
- - elsif user.blocked?
- = link_to _('Unblock'), unblock_admin_user_path(user), method: :put
- - else
- %button.btn{ data: { 'gl-modal-action': 'block',
- url: block_admin_user_path(user),
- username: sanitize_name(user.name) } }
- = s_('AdminUsers|Block')
- - if user.can_be_deactivated?
+ - unless user.internal?
+ .table-section.section-20.table-button-footer
+ .table-action-buttons
+ = link_to _('Edit'), edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn btn-default'
+ - unless user == current_user
+ %button.dropdown-new.btn.btn-default{ type: 'button', data: { toggle: 'dropdown' } }
+ = sprite_icon('settings')
+ = sprite_icon('chevron-down')
+ %ul.dropdown-menu.dropdown-menu-right
+ %li.dropdown-header
+ = _('Settings')
%li
- %button.btn{ data: { 'gl-modal-action': 'deactivate',
- url: deactivate_admin_user_path(user),
- username: sanitize_name(user.name) } }
- = s_('AdminUsers|Deactivate')
- - elsif user.deactivated?
- %li
- = link_to _('Activate'), activate_admin_user_path(user), method: :put
- - if user.access_locked?
- %li
- = link_to _('Unlock'), unlock_admin_user_path(user), method: :put, data: { confirm: _('Are you sure?') }
- - if can?(current_user, :destroy_user, user)
- %li.divider
- - if user.can_be_removed?
- %li
- %button.delete-user-button.btn.text-danger{ data: { 'gl-modal-action': 'delete',
- delete_user_url: admin_user_path(user),
- block_user_url: block_admin_user_path(user),
- username: sanitize_name(user.name) } }
- = s_('AdminUsers|Delete user')
- %li
- %button.delete-user-button.btn.text-danger{ data: { 'gl-modal-action': 'delete-with-contributions',
- delete_user_url: admin_user_path(user, hard_delete: true),
- block_user_url: block_admin_user_path(user),
- username: sanitize_name(user.name) } }
- = s_('AdminUsers|Delete user and contributions')
+ - if user.ldap_blocked?
+ %span.small
+ = s_('AdminUsers|Cannot unblock LDAP blocked users')
+ - elsif user.blocked?
+ = link_to _('Unblock'), unblock_admin_user_path(user), method: :put
+ - else
+ %button.btn{ data: { 'gl-modal-action': 'block',
+ url: block_admin_user_path(user),
+ username: sanitize_name(user.name) } }
+ = s_('AdminUsers|Block')
+ - if user.can_be_deactivated?
+ %li
+ %button.btn{ data: { 'gl-modal-action': 'deactivate',
+ url: deactivate_admin_user_path(user),
+ username: sanitize_name(user.name) } }
+ = s_('AdminUsers|Deactivate')
+ - elsif user.deactivated?
+ %li
+ = link_to _('Activate'), activate_admin_user_path(user), method: :put
+ - if user.access_locked?
+ %li
+ = link_to _('Unlock'), unlock_admin_user_path(user), method: :put, data: { confirm: _('Are you sure?') }
+ - if can?(current_user, :destroy_user, user)
+ %li.divider
+ - if user.can_be_removed?
+ %li
+ %button.delete-user-button.btn.text-danger{ data: { 'gl-modal-action': 'delete',
+ delete_user_url: admin_user_path(user),
+ block_user_url: block_admin_user_path(user),
+ username: sanitize_name(user.name) } }
+ = s_('AdminUsers|Delete user')
+ %li
+ %button.delete-user-button.btn.text-danger{ data: { 'gl-modal-action': 'delete-with-contributions',
+ delete_user_url: admin_user_path(user, hard_delete: true),
+ block_user_url: block_admin_user_path(user),
+ username: sanitize_name(user.name) } }
+ = s_('AdminUsers|Delete user and contributions')
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index aadb2c62d83..f11c730eba6 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -5,7 +5,7 @@
- link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/README', anchor: 'protected-variables') }
= s_('Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
-- if Feature.enabled?(:new_variables_ui, @project || @group, default_enabled: true)
+- if Feature.enabled?(:new_variables_ui, @project || @group)
- is_group = !@group.nil?
#js-ci-project-variables{ data: { endpoint: save_endpoint, project_id: @project&.id || '', group: is_group.to_s, maskable_regex: ci_variable_maskable_regex} }