diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-06 09:08:18 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-06 09:08:18 +0000 |
commit | eb4b72630a9f479f33858fc9011e18666da3bbba (patch) | |
tree | ce57895d1d9291b9e76dd28fe7c95d776bc54a10 /app | |
parent | c5d8b7e6909eb0478c4b2165689004051cdc7ac5 (diff) | |
download | gitlab-ce-eb4b72630a9f479f33858fc9011e18666da3bbba.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
14 files changed, 204 insertions, 22 deletions
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue index 2e386fd786e..ff7982319e7 100644 --- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue +++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue @@ -140,6 +140,19 @@ export default { this.infiniteScrollingTriggered = false; this.filterSearchTriggered = true; + // all filters have been cleared reset query param + // and refetch jobs/count with defaults + if (!filters.length) { + updateHistory({ + url: setUrlParams({ statuses: null }, window.location.href, true), + }); + + this.$apollo.queries.jobs.refetch({ statuses: null }); + this.$apollo.queries.jobsCount.refetch({ statuses: null }); + + return; + } + // Eventually there will be more tokens available // this code is written to scale for those tokens filters.forEach((filter) => { diff --git a/app/assets/javascripts/oauth_application/components/oauth_secret.vue b/app/assets/javascripts/oauth_application/components/oauth_secret.vue new file mode 100644 index 00000000000..fabda19c27b --- /dev/null +++ b/app/assets/javascripts/oauth_application/components/oauth_secret.vue @@ -0,0 +1,106 @@ +<script> +import { GlButton, GlModal } from '@gitlab/ui'; +import { createAlert, VARIANT_SUCCESS, VARIANT_WARNING } from '~/alert'; +import axios from '~/lib/utils/axios_utils'; +import InputCopyToggleVisibility from '~/vue_shared/components/form/input_copy_toggle_visibility.vue'; +import { + CONFIRM_MODAL, + CONFIRM_MODAL_TITLE, + COPY_SECRET, + DESCRIPTION_SECRET, + RENEW_SECRET, + RENEW_SECRET_FAILURE, + RENEW_SECRET_SUCCESS, + WARNING_NO_SECRET, +} from '../constants'; + +export default { + CONFIRM_MODAL, + CONFIRM_MODAL_TITLE, + COPY_SECRET, + DESCRIPTION_SECRET, + RENEW_SECRET, + name: 'OAuthSecret', + components: { + GlButton, + GlModal, + InputCopyToggleVisibility, + }, + inject: ['initialSecret', 'renewPath'], + data() { + return { + secret: this.initialSecret, + alert: null, + isModalVisible: false, + isLoading: false, + }; + }, + computed: { + actionPrimary() { + return { + text: this.$options.RENEW_SECRET, + attributes: { + variant: 'confirm', + loading: this.isLoading, + }, + }; + }, + }, + created() { + if (!this.secret) { + this.alert = createAlert({ message: WARNING_NO_SECRET, variant: VARIANT_WARNING }); + } + }, + methods: { + displayModal() { + this.isModalVisible = true; + }, + async renewSecret(event) { + event.preventDefault(); + this.isLoading = true; + this.alert?.dismiss(); + + try { + const { data } = await axios.put(this.renewPath); + this.alert = createAlert({ message: RENEW_SECRET_SUCCESS, variant: VARIANT_SUCCESS }); + this.secret = data.secret; + } catch { + this.alert = createAlert({ message: RENEW_SECRET_FAILURE }); + } finally { + this.isLoading = false; + this.isModalVisible = false; + } + }, + }, +}; +</script> + +<template> + <div class="gl-display-flex gl-flex-wrap-wrap gl-gap-5"> + <input-copy-toggle-visibility + v-if="secret" + :copy-button-title="$options.COPY_SECRET" + :value="secret" + class="gl-mt-n3 gl-mb-0" + > + <template #description> + {{ $options.DESCRIPTION_SECRET }} + </template> + </input-copy-toggle-visibility> + + <gl-button category="secondary" class="gl-align-self-start" @click="displayModal">{{ + $options.RENEW_SECRET + }}</gl-button> + + <gl-modal + v-model="isModalVisible" + :title="$options.CONFIRM_MODAL_TITLE" + size="sm" + modal-id="modal-renew-secret" + :action-primary="actionPrimary" + @primary="renewSecret" + > + {{ $options.CONFIRM_MODAL }} + </gl-modal> + </div> +</template> diff --git a/app/assets/javascripts/oauth_application/constants.js b/app/assets/javascripts/oauth_application/constants.js new file mode 100644 index 00000000000..5eaacadda78 --- /dev/null +++ b/app/assets/javascripts/oauth_application/constants.js @@ -0,0 +1,20 @@ +import { __, s__ } from '~/locale'; + +export const CONFIRM_MODAL = s__( + 'AuthorizedApplication|Are you sure you want to renew this secret? Any applications using the old secret will no longer be able to authenticate with GitLab.', +); +export const CONFIRM_MODAL_TITLE = s__('AuthorizedApplication|Renew secret?'); +export const COPY_SECRET = __('Copy secret'); +export const DESCRIPTION_SECRET = __( + 'This is the only time the secret is accessible. Copy the secret and store it securely.', +); +export const RENEW_SECRET = s__('AuthorizedApplication|Renew secret'); +export const RENEW_SECRET_FAILURE = s__( + 'AuthorizedApplication|There was an error trying to renew the application secret. Please try again.', +); +export const RENEW_SECRET_SUCCESS = s__( + 'AuthorizedApplication|Application secret was successfully renewed.', +); +export const WARNING_NO_SECRET = __( + 'The secret is only available when you create the application or renew the secret.', +); diff --git a/app/assets/javascripts/oauth_application/index.js b/app/assets/javascripts/oauth_application/index.js new file mode 100644 index 00000000000..f8f1f647a15 --- /dev/null +++ b/app/assets/javascripts/oauth_application/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue'; +import OAuthSecret from './components/oauth_secret.vue'; + +export const initOAuthApplicationSecret = () => { + const el = document.querySelector('#js-oauth-application-secret'); + + if (!el) { + return null; + } + + const { initialSecret, renewPath } = el.dataset; + + return new Vue({ + el, + name: 'OAuthSecretRoot', + provide: { initialSecret, renewPath }, + render(h) { + return h(OAuthSecret); + }, + }); +}; diff --git a/app/assets/javascripts/pages/admin/applications/index.js b/app/assets/javascripts/pages/admin/applications/index.js index 3397b02aeba..df9e38431b0 100644 --- a/app/assets/javascripts/pages/admin/applications/index.js +++ b/app/assets/javascripts/pages/admin/applications/index.js @@ -1,3 +1,5 @@ import initApplicationDeleteButtons from '~/admin/applications'; +import { initOAuthApplicationSecret } from '~/oauth_application'; initApplicationDeleteButtons(); +initOAuthApplicationSecret(); diff --git a/app/assets/javascripts/pages/groups/settings/applications/index.js b/app/assets/javascripts/pages/groups/settings/applications/index.js new file mode 100644 index 00000000000..4dee5433ec9 --- /dev/null +++ b/app/assets/javascripts/pages/groups/settings/applications/index.js @@ -0,0 +1,3 @@ +import { initOAuthApplicationSecret } from '~/oauth_application'; + +initOAuthApplicationSecret(); diff --git a/app/assets/javascripts/pages/oauth/applications/index.js b/app/assets/javascripts/pages/oauth/applications/index.js new file mode 100644 index 00000000000..4dee5433ec9 --- /dev/null +++ b/app/assets/javascripts/pages/oauth/applications/index.js @@ -0,0 +1,3 @@ +import { initOAuthApplicationSecret } from '~/oauth_application'; + +initOAuthApplicationSecret(); diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb index 76564981c9b..d97fcc5df74 100644 --- a/app/controllers/admin/applications_controller.rb +++ b/app/controllers/admin/applications_controller.rb @@ -47,10 +47,9 @@ class Admin::ApplicationsController < Admin::ApplicationController @application.renew_secret if @application.save - flash.now[:notice] = s_('AuthorizedApplication|Application secret was successfully updated.') - render :show + render json: { secret: @application.plaintext_secret } else - redirect_to admin_application_url(@application) + render json: { errors: @application.errors }, status: :unprocessable_entity end end diff --git a/app/controllers/groups/settings/applications_controller.rb b/app/controllers/groups/settings/applications_controller.rb index 2bf5c95937b..3ae1ae824a0 100644 --- a/app/controllers/groups/settings/applications_controller.rb +++ b/app/controllers/groups/settings/applications_controller.rb @@ -46,10 +46,9 @@ module Groups @application.renew_secret if @application.save - flash.now[:notice] = s_('AuthorizedApplication|Application secret was successfully updated.') - render :show + render json: { secret: @application.plaintext_secret } else - redirect_to group_settings_application_url(@group, @application) + render json: { errors: @application.errors }, status: :unprocessable_entity end end diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb index 7a31738188a..2d5421f9f74 100644 --- a/app/controllers/oauth/applications_controller.rb +++ b/app/controllers/oauth/applications_controller.rb @@ -45,10 +45,9 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController @application.renew_secret if @application.save - flash.now[:notice] = s_('AuthorizedApplication|Application secret was successfully updated.') - render :show + render json: { secret: @application.plaintext_secret } else - redirect_to oauth_application_url(@application) + render json: { errors: @application.errors }, status: :unprocessable_entity end end diff --git a/app/graphql/types/ci/catalog/resource_type.rb b/app/graphql/types/ci/catalog/resource_type.rb new file mode 100644 index 00000000000..b5947826fa1 --- /dev/null +++ b/app/graphql/types/ci/catalog/resource_type.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Types + module Ci + module Catalog + # rubocop: disable Graphql/AuthorizeTypes + class ResourceType < BaseObject + graphql_name 'CiCatalogResource' + + connection_type_class(Types::CountableConnectionType) + + field :id, GraphQL::Types::ID, null: false, description: 'ID of the catalog resource.', + alpha: { milestone: '15.11' } + + field :name, GraphQL::Types::String, null: true, description: 'Name of the catalog resource.', + alpha: { milestone: '15.11' } + + field :description, GraphQL::Types::String, null: true, description: 'Description of the catalog resource.', + alpha: { milestone: '15.11' } + + field :icon, GraphQL::Types::String, null: true, description: 'Icon for the catalog resource.', + method: :avatar_path, alpha: { milestone: '15.11' } + end + # rubocop: enable Graphql/AuthorizeTypes + end + end +end diff --git a/app/models/ci/catalog/resource.rb b/app/models/ci/catalog/resource.rb index 40ec41de6fe..837f1352b4d 100644 --- a/app/models/ci/catalog/resource.rb +++ b/app/models/ci/catalog/resource.rb @@ -13,6 +13,8 @@ module Ci belongs_to :project scope :for_projects, ->(project_ids) { where(project_id: project_ids) } + + delegate :avatar_path, :description, :name, to: :project end end end diff --git a/app/views/shared/doorkeeper/applications/_show.html.haml b/app/views/shared/doorkeeper/applications/_show.html.haml index 19f4c971c1d..6bebbe94a55 100644 --- a/app/views/shared/doorkeeper/applications/_show.html.haml +++ b/app/views/shared/doorkeeper/applications/_show.html.haml @@ -15,16 +15,7 @@ %td = _('Secret') %td - - if @application.plaintext_secret - = render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_options: { class: 'gl-mb-5'}) do |c| - = c.body do - = _('This is the only time the secret is accessible. Copy the secret and store it securely.') - = clipboard_button(clipboard_text: @application.plaintext_secret, button_text: _('Copy'), title: _("Copy secret"), class: "btn btn-default btn-md gl-button") - - else - = render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_options: { class: 'gl-mb-5'}) do |c| - = c.body do - = _('The secret is only available when you create the application or renew the secret.') - = render 'shared/doorkeeper/applications/update_form', path: renew_path + #js-oauth-application-secret{ data: { initial_secret: @application.plaintext_secret, renew_path: renew_path } } %tr %td diff --git a/app/views/shared/doorkeeper/applications/_update_form.html.haml b/app/views/shared/doorkeeper/applications/_update_form.html.haml deleted file mode 100644 index 1bee3288639..00000000000 --- a/app/views/shared/doorkeeper/applications/_update_form.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -- path = local_assigns.fetch(:path) -= form_for(@application, url: path, html: {class: 'gl-display-inline-block', method: "put"}) do |f| - = submit_tag s_('AuthorizedApplication|Renew secret'), data: { confirm: s_("AuthorizedApplication|Are you sure you want to renew this secret? Any applications using the old secret will no longer be able to authenticate with GitLab."), confirm_btn_variant: "danger" }, aria: { label: s_('AuthorizedApplication|Renew secret') }, class: 'gl-button btn btn-md btn-default' |