diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-11 12:09:18 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-11 12:09:18 +0300 |
commit | 7240fb1a06c9e1b254719426b1ac96ec2f00fe35 (patch) | |
tree | a2c0e2b679bc34c9446a5e4653f5d63f2292205d /app | |
parent | 62d57690bc54e195b2544091725421144ce76900 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
15 files changed, 144 insertions, 35 deletions
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index d0528204fd5..3ddbcd64511 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -123,7 +123,7 @@ export const handleLocationHash = () => { } if (isInIssuePage()) { - adjustment -= fixedIssuableTitle.offsetHeight; + adjustment -= fixedIssuableTitle?.offsetHeight; } if (isInMRPage()) { diff --git a/app/assets/javascripts/pages/projects/merge_requests/edit/check_form_state.js b/app/assets/javascripts/pages/projects/merge_requests/edit/check_form_state.js new file mode 100644 index 00000000000..74178ab96e3 --- /dev/null +++ b/app/assets/javascripts/pages/projects/merge_requests/edit/check_form_state.js @@ -0,0 +1,24 @@ +import { serializeForm } from '~/lib/utils/forms'; + +const findForm = () => document.querySelector('.merge-request-form'); +const serializeFormData = () => JSON.stringify(serializeForm(findForm())); + +export default () => { + const oldFormData = serializeFormData(); + + const compareFormData = (e) => { + const newFormData = serializeFormData(); + + if (oldFormData !== newFormData) { + e.preventDefault(); + // eslint-disable-next-line no-param-reassign + e.returnValue = ''; // Chrome requires returnValue to be set + } + }; + + window.addEventListener('beforeunload', compareFormData); + + findForm().addEventListener('submit', () => + window.removeEventListener('beforeunload', compareFormData), + ); +}; diff --git a/app/assets/javascripts/pages/projects/merge_requests/edit/index.js b/app/assets/javascripts/pages/projects/merge_requests/edit/index.js index febfecebbd2..399aebb0c83 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/edit/index.js +++ b/app/assets/javascripts/pages/projects/merge_requests/edit/index.js @@ -1,3 +1,7 @@ import initMergeRequest from '~/pages/projects/merge_requests/init_merge_request'; +import initCheckFormState from './check_form_state'; -document.addEventListener('DOMContentLoaded', initMergeRequest); +document.addEventListener('DOMContentLoaded', () => { + initMergeRequest(); + initCheckFormState(); +}); diff --git a/app/assets/javascripts/pages/projects/releases/edit/index.js b/app/assets/javascripts/pages/projects/releases/edit/index.js index efa059dcd6d..ce7fd04209d 100644 --- a/app/assets/javascripts/pages/projects/releases/edit/index.js +++ b/app/assets/javascripts/pages/projects/releases/edit/index.js @@ -1,7 +1,5 @@ import ZenMode from '~/zen_mode'; import initEditRelease from '~/releases/mount_edit'; -document.addEventListener('DOMContentLoaded', () => { - new ZenMode(); // eslint-disable-line no-new - initEditRelease(); -}); +new ZenMode(); // eslint-disable-line no-new +initEditRelease(); diff --git a/app/assets/javascripts/pages/projects/releases/new/index.js b/app/assets/javascripts/pages/projects/releases/new/index.js index 0e314aacf8a..c911c95a396 100644 --- a/app/assets/javascripts/pages/projects/releases/new/index.js +++ b/app/assets/javascripts/pages/projects/releases/new/index.js @@ -1,7 +1,5 @@ import ZenMode from '~/zen_mode'; import initNewRelease from '~/releases/mount_new'; -document.addEventListener('DOMContentLoaded', () => { - new ZenMode(); // eslint-disable-line no-new - initNewRelease(); -}); +new ZenMode(); // eslint-disable-line no-new +initNewRelease(); diff --git a/app/assets/javascripts/terraform/components/states_table.vue b/app/assets/javascripts/terraform/components/states_table.vue index ab039608ef2..7c834a74bd7 100644 --- a/app/assets/javascripts/terraform/components/states_table.vue +++ b/app/assets/javascripts/terraform/components/states_table.vue @@ -1,5 +1,14 @@ <script> -import { GlAlert, GlBadge, GlIcon, GlLink, GlSprintf, GlTable, GlTooltip } from '@gitlab/ui'; +import { + GlAlert, + GlBadge, + GlIcon, + GlLink, + GlLoadingIcon, + GlSprintf, + GlTable, + GlTooltip, +} from '@gitlab/ui'; import { s__ } from '~/locale'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import CiBadge from '~/vue_shared/components/ci_badge_link.vue'; @@ -14,6 +23,7 @@ export default { GlBadge, GlIcon, GlLink, + GlLoadingIcon, GlSprintf, GlTable, GlTooltip, @@ -67,15 +77,20 @@ export default { jobStatus: s__('Terraform|Job status'), locked: s__('Terraform|Locked'), lockedByUser: s__('Terraform|Locked by %{user} %{timeAgo}'), + lockingState: s__('Terraform|Locking state'), name: s__('Terraform|Name'), pipeline: s__('Terraform|Pipeline'), unknownUser: s__('Terraform|Unknown User'), + unlockingState: s__('Terraform|Unlocking state'), updatedUser: s__('Terraform|%{user} updated %{timeAgo}'), }, methods: { createdByUserName(item) { return item.latestVersion?.createdByUser?.name; }, + loadingLockText(item) { + return item.lockedAt ? this.$options.i18n.unlockingState : this.$options.i18n.lockingState; + }, lockedByUserName(item) { return item.lockedByUser?.name || this.$options.i18n.unknownUser; }, @@ -119,7 +134,18 @@ export default { {{ item.name }} </p> - <div v-if="item.lockedAt" :id="`terraformLockedBadgeContainer${item.name}`" class="gl-mx-2"> + <div v-if="item.loadingLock" class="gl-mx-3"> + <p class="gl-display-flex gl-justify-content-start gl-align-items-baseline gl-m-0"> + <gl-loading-icon class="gl-pr-1" /> + {{ loadingLockText(item) }} + </p> + </div> + + <div + v-else-if="item.lockedAt" + :id="`terraformLockedBadgeContainer${item.name}`" + class="gl-mx-3" + > <gl-badge :id="`terraformLockedBadge${item.name}`"> <gl-icon name="lock" /> {{ $options.i18n.locked }} diff --git a/app/assets/javascripts/terraform/components/states_table_actions.vue b/app/assets/javascripts/terraform/components/states_table_actions.vue index ba064825034..aa638be7351 100644 --- a/app/assets/javascripts/terraform/components/states_table_actions.vue +++ b/app/assets/javascripts/terraform/components/states_table_actions.vue @@ -64,6 +64,9 @@ export default { disableModalSubmit() { return this.removeConfirmText !== this.state.name; }, + loading() { + return this.state.loadingLock || this.state.loadingRemove; + }, primaryModalProps() { return { text: this.$options.i18n.modalRemove, @@ -77,9 +80,23 @@ export default { this.removeConfirmText = ''; }, lock() { + this.updateStateCache({ + _showDetails: false, + errorMessages: [], + loadingLock: true, + loadingRemove: false, + }); + this.stateActionMutation(lockState); }, unlock() { + this.updateStateCache({ + _showDetails: false, + errorMessages: [], + loadingLock: true, + loadingRemove: false, + }); + this.stateActionMutation(unlockState); }, updateStateCache(newData) { @@ -96,18 +113,20 @@ export default { remove() { if (!this.disableModalSubmit) { this.hideModal(); + + this.updateStateCache({ + _showDetails: false, + errorMessages: [], + loadingLock: false, + loadingRemove: true, + }); + this.stateActionMutation(removeState); } }, stateActionMutation(mutation) { let errorMessages = []; - this.updateStateCache({ - _showDetails: false, - errorMessages, - loadingActions: true, - }); - this.$apollo .mutate({ mutation, @@ -132,7 +151,8 @@ export default { this.updateStateCache({ _showDetails: Boolean(errorMessages.length), errorMessages, - loadingActions: false, + loadingLock: false, + loadingRemove: false, }); }); }, @@ -146,7 +166,7 @@ export default { icon="ellipsis_v" right :data-testid="`terraform-state-actions-${state.name}`" - :disabled="state.loadingActions" + :disabled="loading" toggle-class="gl-px-3! gl-shadow-none!" > <template #button-content> diff --git a/app/assets/javascripts/terraform/graphql/fragments/state.fragment.graphql b/app/assets/javascripts/terraform/graphql/fragments/state.fragment.graphql index f876fea64ac..fb823336411 100644 --- a/app/assets/javascripts/terraform/graphql/fragments/state.fragment.graphql +++ b/app/assets/javascripts/terraform/graphql/fragments/state.fragment.graphql @@ -4,7 +4,8 @@ fragment State on TerraformState { _showDetails @client errorMessages @client - loadingActions @client + loadingLock @client + loadingRemove @client id name diff --git a/app/assets/javascripts/terraform/graphql/resolvers.js b/app/assets/javascripts/terraform/graphql/resolvers.js index 2845a1e5279..d27379bdd9f 100644 --- a/app/assets/javascripts/terraform/graphql/resolvers.js +++ b/app/assets/javascripts/terraform/graphql/resolvers.js @@ -9,8 +9,11 @@ export default { errorMessages: (state) => { return state.errorMessages || []; }, - loadingActions: (state) => { - return state.loadingActions || false; + loadingLock: (state) => { + return state.loadingLock || false; + }, + loadingRemove: (state) => { + return state.loadingRemove || false; }, }, Mutation: { @@ -32,7 +35,8 @@ export default { // eslint-disable-next-line no-underscore-dangle _showDetails: terraformState._showDetails, errorMessages: terraformState.errorMessages, - loadingActions: terraformState.loadingActions, + loadingLock: terraformState.loadingLock, + loadingRemove: terraformState.loadingRemove, }, }); } diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb index 093cdf258b2..b34b826a695 100644 --- a/app/controllers/groups/boards_controller.rb +++ b/app/controllers/groups/boards_controller.rb @@ -15,9 +15,9 @@ class Groups::BoardsController < Groups::ApplicationController private def assign_endpoint_vars - @boards_endpoint = group_boards_url(group) + @boards_endpoint = group_boards_path(group) @namespace_path = group.to_param - @labels_endpoint = group_labels_url(group) + @labels_endpoint = group_labels_path(group) end def authorize_read_board! diff --git a/app/services/concerns/integrations/project_test_data.rb b/app/services/concerns/integrations/project_test_data.rb index 726f450b41c..f27a4e1c224 100644 --- a/app/services/concerns/integrations/project_test_data.rb +++ b/app/services/concerns/integrations/project_test_data.rb @@ -8,6 +8,10 @@ module Integrations Gitlab::DataBuilder::Push.build_sample(project, current_user) end + def use_newest_record? + Feature.enabled?(:integrations_test_webhook_reorder, project) + end + def note_events_data note = NotesFinder.new(current_user, project: project, target: project).execute.reorder(nil).last # rubocop: disable CodeReuse/ActiveRecord @@ -33,14 +37,24 @@ module Integrations end def job_events_data - build = project.builds.first + build = if use_newest_record? + Ci::JobsFinder.new(current_user: current_user, project: project).execute.first + else + project.builds.first + end + return { error: s_('TestHooks|Ensure the project has CI jobs.') } unless build.present? Gitlab::DataBuilder::Build.build(build) end def pipeline_events_data - pipeline = project.ci_pipelines.newest_first.first + pipeline = if use_newest_record? + Ci::PipelinesFinder.new(project, current_user, order_by: 'id', sort: 'desc').execute.first + else + project.ci_pipelines.newest_first.first + end + return { error: s_('TestHooks|Ensure the project has CI pipelines.') } unless pipeline.present? Gitlab::DataBuilder::Pipeline.build(pipeline) @@ -48,6 +62,7 @@ module Integrations def wiki_page_events_data page = project.wiki.list_pages(limit: 1).first + if !project.wiki_enabled? || page.blank? return { error: s_('TestHooks|Ensure the wiki is enabled and has pages.') } end @@ -56,14 +71,24 @@ module Integrations end def deployment_events_data - deployment = project.deployments.first + deployment = if use_newest_record? + DeploymentsFinder.new(project: project, order_by: 'created_at', sort: 'desc').execute.first + else + project.deployments.first + end + return { error: s_('TestHooks|Ensure the project has deployments.') } unless deployment.present? Gitlab::DataBuilder::Deployment.build(deployment) end def releases_events_data - release = project.releases.first + release = if use_newest_record? + ReleasesFinder.new(project, current_user, order_by: :created_at, sort: :desc).execute.first + else + project.releases.first + end + return { error: s_('TestHooks|Ensure the project has releases.') } unless release.present? release.to_hook_data('create') diff --git a/app/services/test_hooks/system_service.rb b/app/services/test_hooks/system_service.rb index 66d78bfc578..ddec45343e9 100644 --- a/app/services/test_hooks/system_service.rb +++ b/app/services/test_hooks/system_service.rb @@ -6,6 +6,10 @@ module TestHooks private + def use_newest_record? + Feature.enabled?(:integrations_test_webhook_reorder) + end + def data strong_memoize(:data) do case trigger @@ -20,7 +24,12 @@ module TestHooks end def merge_requests_events_data - merge_request = MergeRequest.of_projects(current_user.projects.select(:id)).first + merge_request = if use_newest_record? + MergeRequest.of_projects(current_user.projects.select(:id)).last + else + MergeRequest.of_projects(current_user.projects.select(:id)).first + end + return { error: s_('TestHooks|Ensure one of your projects has merge requests.') } unless merge_request.present? merge_request.to_hook_data(current_user) diff --git a/app/views/projects/issues/import_csv/_button.html.haml b/app/views/projects/issues/import_csv/_button.html.haml index c2a825e0f69..229eb0654a8 100644 --- a/app/views/projects/issues/import_csv/_button.html.haml +++ b/app/views/projects/issues/import_csv/_button.html.haml @@ -2,7 +2,7 @@ - can_edit = can?(current_user, :admin_project, @project) .dropdown.btn-group - %button.btn.gl-button.btn-default.rounded-right.text-center{ class: ('has-tooltip' if type == :icon), title: (_('Import issues') if type == :icon), + %button.btn.gl-button.rounded-right.btn-default.btn-icon.text-center{ class: ('has-tooltip' if type == :icon), title: (_('Import issues') if type == :icon), data: { toggle: 'dropdown', qa_selector: 'import_issues_button' }, 'aria-label' => _('Import issues'), 'aria-haspopup' => 'true', 'aria-expanded' => 'false' } - if type == :icon = sprite_icon('import') diff --git a/app/views/shared/issuable/_feed_buttons.html.haml b/app/views/shared/issuable/_feed_buttons.html.haml index 1fac1d27583..c3e4c3a15cc 100644 --- a/app/views/shared/issuable/_feed_buttons.html.haml +++ b/app/views/shared/issuable/_feed_buttons.html.haml @@ -1,4 +1,4 @@ -= link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') do += link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') do = sprite_icon('rss', css_class: 'qa-rss-icon') -= link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar') do += link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar') do = sprite_icon('calendar') diff --git a/app/views/shared/issuable/csv_export/_button.html.haml b/app/views/shared/issuable/csv_export/_button.html.haml index ab68e1d69b8..8134b7eb161 100644 --- a/app/views/shared/issuable/csv_export/_button.html.haml +++ b/app/views/shared/issuable/csv_export/_button.html.haml @@ -1,4 +1,4 @@ - if current_user - %button.csv_download_link.btn.gl-button.btn-default.has-tooltip{ title: _('Export as CSV'), + %button.csv_download_link.btn.gl-button.btn-default.btn-icon.has-tooltip{ title: _('Export as CSV'), data: { toggle: 'modal', target: ".#{issuable_type}-export-modal", qa_selector: 'export_as_csv_button' } } = sprite_icon('export') |