diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index db0888bbd97..f6910a067dd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,7 +59,7 @@ workflow: variables: PG_VERSION: "12" - DEFAULT_CI_IMAGE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.17-node-16.14-postgresql-${PG_VERSION}:git-2.36-lfs-2.9-chrome-101-yarn-1.22-graphicsmagick-1.3.36" + DEFAULT_CI_IMAGE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.17-node-16.14-postgresql-${PG_VERSION}:git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-yarn-1.22-graphicsmagick-1.3.36" RAILS_ENV: "test" NODE_ENV: "test" BUNDLE_WITHOUT: "production:development" @@ -73,6 +73,8 @@ variables: GIT_SUBMODULE_STRATEGY: "none" GET_SOURCES_ATTEMPTS: "3" DEBIAN_VERSION: "bullseye" + CHROME_VERSION: "101" + DOCKER_VERSION: "20.10.14" TMP_TEST_FOLDER: "${CI_PROJECT_DIR}/tmp/tests" GITLAB_WORKHORSE_FOLDER: "gitlab-workhorse" @@ -89,7 +91,6 @@ variables: ES_JAVA_OPTS: "-Xms256m -Xmx256m" ELASTIC_URL: "http://elastic:changeme@elasticsearch:9200" - DOCKER_VERSION: "20.10.1" CACHE_CLASSES: "true" CHECK_PRECOMPILED_ASSETS: "true" FF_USE_FASTZIP: "true" diff --git a/.gitlab/ci/build-images.gitlab-ci.yml b/.gitlab/ci/build-images.gitlab-ci.yml index 6a222d8937f..46d0bb2fb8f 100644 --- a/.gitlab/ci/build-images.gitlab-ci.yml +++ b/.gitlab/ci/build-images.gitlab-ci.yml @@ -29,7 +29,15 @@ build-qa-image: - !reference [.base-image-build, script] - echo $QA_IMAGE - echo $QA_IMAGE_BRANCH - - /kaniko/executor --context=${CI_PROJECT_DIR} --dockerfile=${CI_PROJECT_DIR}/qa/Dockerfile --destination=${QA_IMAGE} --destination=${QA_IMAGE_BRANCH} --cache=true + - | + /kaniko/executor \ + --context=${CI_PROJECT_DIR} \ + --dockerfile=${CI_PROJECT_DIR}/qa/Dockerfile \ + --destination=${QA_IMAGE} \ + --destination=${QA_IMAGE_BRANCH} \ + --build-arg=CHROME_VERSION=${CHROME_VERSION} \ + --build-arg=DOCKER_VERSION=${DOCKER_VERSION} \ + --cache=true # This image is used by: # - The `CNG` pipelines (via the `review-build-cng` job): https://gitlab.com/gitlab-org/build/CNG/-/blob/cfc67136d711e1c8c409bf8e57427a644393da2f/.gitlab-ci.yml#L335 diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml index 1ebc408e0d4..463d110b274 100644 --- a/.gitlab/ci/qa.gitlab-ci.yml +++ b/.gitlab/ci/qa.gitlab-ci.yml @@ -1,5 +1,5 @@ .qa-job-base: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-2.7:bundler-2.3-git-2.33-chrome-99 + image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-2.7:bundler-2.3-git-2.33-chrome-${CHROME_VERSION} extends: - .default-retry - .qa-cache @@ -12,7 +12,7 @@ before_script: - !reference [.default-before_script, before_script] - cd qa/ - - bundle_install_script + - bundle install qa:internal: extends: diff --git a/.gitlab/ci/review-apps/qa.gitlab-ci.yml b/.gitlab/ci/review-apps/qa.gitlab-ci.yml index 58ceb744480..bc75bf51e03 100644 --- a/.gitlab/ci/review-apps/qa.gitlab-ci.yml +++ b/.gitlab/ci/review-apps/qa.gitlab-ci.yml @@ -1,6 +1,6 @@ include: - project: gitlab-org/quality/pipeline-common - ref: 0.6.0 + ref: 0.13.0 file: - /ci/allure-report.yml - /ci/knapsack-report.yml @@ -28,7 +28,7 @@ include: - .qa-cache - .test_variables - .bundler_variables - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-2.7:bundler-2.3-git-2.33-lfs-2.9-chrome-99-docker-20.10.14-gcloud-383-kubectl-1.23 + image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-2.7:bundler-2.3-git-2.33-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23 stage: qa needs: - review-deploy @@ -81,7 +81,7 @@ include: # Store knapsack report as artifact so the same report is reused across all jobs download-knapsack-report: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-2.7:bundler-2.3-git-2.33-chrome-99 + image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-2.7:bundler-2.3-git-2.33-chrome-${CHROME_VERSION} extends: - .qa-cache - .bundler_variables diff --git a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue index f4cc0678c38..3860831169e 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue @@ -42,6 +42,20 @@ const bodyTrClass = export default { i18n, typeSet, + modal: { + actionPrimary: { + text: i18n.deleteIntegration, + attributes: { + variant: 'danger', + }, + }, + actionSecondary: { + text: __('Cancel'), + attributes: { + variant: 'default', + }, + }, + }, components: { GlButtonGroup, GlButton, @@ -204,8 +218,8 @@ export default { { + return joinPaths(urlRoot, url); +}; + +export const getSubGroups = () => { + return axios.get(buildUrl(gon.relative_url_root || '', GROUP_SUBGROUPS_PATH), { + params: { + group_id: gon.current_group_id, + }, + }); +}; diff --git a/app/assets/javascripts/groups/settings/components/access_dropdown.vue b/app/assets/javascripts/groups/settings/components/access_dropdown.vue new file mode 100644 index 00000000000..b8a269de98a --- /dev/null +++ b/app/assets/javascripts/groups/settings/components/access_dropdown.vue @@ -0,0 +1,194 @@ + + + diff --git a/app/assets/javascripts/groups/settings/constants.js b/app/assets/javascripts/groups/settings/constants.js new file mode 100644 index 00000000000..c91c2a20529 --- /dev/null +++ b/app/assets/javascripts/groups/settings/constants.js @@ -0,0 +1,3 @@ +export const LEVEL_TYPES = { + GROUP: 'group', +}; diff --git a/app/assets/javascripts/groups/settings/init_access_dropdown.js b/app/assets/javascripts/groups/settings/init_access_dropdown.js new file mode 100644 index 00000000000..24419280fc0 --- /dev/null +++ b/app/assets/javascripts/groups/settings/init_access_dropdown.js @@ -0,0 +1,36 @@ +import * as Sentry from '@sentry/browser'; +import Vue from 'vue'; +import AccessDropdown from './components/access_dropdown.vue'; + +export const initAccessDropdown = (el) => { + if (!el) { + return false; + } + + const { label, disabled, preselectedItems } = el.dataset; + let preselected = []; + try { + preselected = JSON.parse(preselectedItems); + } catch (e) { + Sentry.captureException(e); + } + + return new Vue({ + el, + render(createElement) { + const vm = this; + return createElement(AccessDropdown, { + props: { + preselectedItems: preselected, + label, + disabled, + }, + on: { + select(selected) { + vm.$emit('select', selected); + }, + }, + }); + }, + }); +}; diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue index 7857b9d86d2..d597c7e53bb 100644 --- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue +++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue @@ -14,6 +14,7 @@ import ExperimentTracking from '~/experimentation/experiment_tracking'; import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants'; import { getParameterValues } from '~/lib/utils/url_utility'; import { + CLOSE_TO_LIMIT_COUNT, USERS_FILTER_ALL, INVITE_MEMBERS_FOR_TASK, MEMBER_MODAL_LABELS, @@ -151,6 +152,16 @@ export default { isOnLearnGitlab() { return this.source === LEARN_GITLAB; }, + closeToLimit() { + if (this.usersLimitDataset.freeUsersLimit && this.usersLimitDataset.membersCount) { + return ( + this.usersLimitDataset.membersCount >= + this.usersLimitDataset.freeUsersLimit - CLOSE_TO_LIMIT_COUNT + ); + } + + return false; + }, reachedLimit() { if (this.usersLimitDataset.freeUsersLimit && this.usersLimitDataset.membersCount) { return this.usersLimitDataset.membersCount >= this.usersLimitDataset.freeUsersLimit; @@ -297,6 +308,7 @@ export default { :is-loading="isLoading" :new-users-to-invite="newUsersToInvite" :root-group-id="rootId" + :close-to-limit="closeToLimit" :reached-limit="reachedLimit" :users-limit-dataset="usersLimitDataset" @reset="resetFields" @@ -314,6 +326,7 @@ export default {