diff options
Diffstat (limited to 'app/assets/javascripts/pages/projects/forks')
4 files changed, 75 insertions, 33 deletions
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/app.vue b/app/assets/javascripts/pages/projects/forks/new/components/app.vue index 02b357d389b..7fb41c6e7b7 100644 --- a/app/assets/javascripts/pages/projects/forks/new/components/app.vue +++ b/app/assets/javascripts/pages/projects/forks/new/components/app.vue @@ -38,6 +38,10 @@ export default { type: String, required: true, }, + restrictedVisibilityLevels: { + type: Array, + required: true, + }, }, }; </script> @@ -66,6 +70,7 @@ export default { :project-path="projectPath" :project-description="projectDescription" :project-visibility="projectVisibility" + :restricted-visibility-levels="restrictedVisibilityLevels" /> </div> </div> diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue index 07cc0ce46bc..75c3b6d564c 100644 --- a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue +++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue @@ -26,10 +26,10 @@ const PRIVATE_VISIBILITY = 'private'; const INTERNAL_VISIBILITY = 'internal'; const PUBLIC_VISIBILITY = 'public'; -const ALLOWED_VISIBILITY = { - private: [PRIVATE_VISIBILITY], - internal: [INTERNAL_VISIBILITY, PRIVATE_VISIBILITY], - public: [INTERNAL_VISIBILITY, PRIVATE_VISIBILITY, PUBLIC_VISIBILITY], +const VISIBILITY_LEVEL = { + [PRIVATE_VISIBILITY]: 0, + [INTERNAL_VISIBILITY]: 10, + [PUBLIC_VISIBILITY]: 20, }; const initFormField = ({ value, required = true, skipValidation = false }) => ({ @@ -95,6 +95,10 @@ export default { type: String, required: true, }, + restrictedVisibilityLevels: { + type: Array, + required: true, + }, }, data() { const form = { @@ -111,10 +115,7 @@ export default { required: false, skipValidation: true, }), - visibility: initFormField({ - value: this.projectVisibility, - skipValidation: true, - }), + visibility: initFormField({ value: this.getInitialVisibilityValue() }), }, }; return { @@ -127,14 +128,38 @@ export default { projectUrl() { return `${gon.gitlab_url}/`; }, - projectAllowedVisibility() { - return ALLOWED_VISIBILITY[this.projectVisibility]; + projectVisibilityLevel() { + return VISIBILITY_LEVEL[this.projectVisibility]; + }, + namespaceVisibilityLevel() { + const visibility = this.form.fields.namespace.value?.visibility || PUBLIC_VISIBILITY; + return VISIBILITY_LEVEL[visibility]; + }, + visibilityLevelCap() { + return Math.min(this.projectVisibilityLevel, this.namespaceVisibilityLevel); + }, + restrictedVisibilityLevelsSet() { + return new Set(this.restrictedVisibilityLevels); }, - namespaceAllowedVisibility() { - return ( - ALLOWED_VISIBILITY[this.form.fields.namespace.value?.visibility] || - ALLOWED_VISIBILITY[PUBLIC_VISIBILITY] + allowedVisibilityLevels() { + const allowedLevels = Object.entries(VISIBILITY_LEVEL).reduce( + (levels, [levelName, levelValue]) => { + if ( + !this.restrictedVisibilityLevelsSet.has(levelValue) && + levelValue <= this.visibilityLevelCap + ) { + levels.push(levelName); + } + return levels; + }, + [], ); + + if (!allowedLevels.length) { + return [PRIVATE_VISIBILITY]; + } + + return allowedLevels; }, visibilityLevels() { return [ @@ -142,7 +167,9 @@ export default { text: s__('ForkProject|Private'), value: PRIVATE_VISIBILITY, icon: 'lock', - help: s__('ForkProject|The project can be accessed without any authentication.'), + help: s__( + 'ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.', + ), disabled: this.isVisibilityLevelDisabled(PRIVATE_VISIBILITY), }, { @@ -156,9 +183,7 @@ export default { text: s__('ForkProject|Public'), value: PUBLIC_VISIBILITY, icon: 'earth', - help: s__( - 'ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.', - ), + help: s__('ForkProject|The project can be accessed without any authentication.'), disabled: this.isVisibilityLevelDisabled(PUBLIC_VISIBILITY), }, ]; @@ -166,12 +191,9 @@ export default { }, watch: { // eslint-disable-next-line func-names - 'form.fields.namespace.value': function (newVal) { - const { visibility } = newVal; - - if (this.projectAllowedVisibility.includes(visibility)) { - this.form.fields.visibility.value = visibility; - } + 'form.fields.namespace.value': function () { + this.form.fields.visibility.value = + this.restrictedVisibilityLevels.length !== 0 ? null : PRIVATE_VISIBILITY; }, // eslint-disable-next-line func-names 'form.fields.name.value': function (newVal) { @@ -186,11 +208,11 @@ export default { const { data } = await axios.get(this.endpoint); this.namespaces = data.namespaces; }, - isVisibilityLevelDisabled(visibilityLevel) { - return !( - this.projectAllowedVisibility.includes(visibilityLevel) && - this.namespaceAllowedVisibility.includes(visibilityLevel) - ); + isVisibilityLevelDisabled(visibility) { + return !this.allowedVisibilityLevels.includes(visibility); + }, + getInitialVisibilityValue() { + return this.restrictedVisibilityLevels.length !== 0 ? null : this.projectVisibility; }, async onSubmit() { this.form.showValidation = true; @@ -222,7 +244,11 @@ export default { redirectTo(data.web_url); return; } catch (error) { - createFlash({ message: error }); + createFlash({ + message: s__( + 'ForkProject|An error occurred while forking the project. Please try again.', + ), + }); } }, }, @@ -322,7 +348,11 @@ export default { /> </gl-form-group> - <gl-form-group> + <gl-form-group + v-validation:[form.showValidation] + :invalid-feedback="s__('ForkProject|Please select a visibility level')" + :state="form.fields.visibility.state" + > <label> {{ s__('ForkProject|Visibility level') }} <gl-link :href="visibilityHelpPath" target="_blank"> @@ -333,6 +363,7 @@ export default { v-model="form.fields.visibility.value" data-testid="fork-visibility-radio-group" name="visibility" + :aria-label="__('visibility')" required > <gl-form-radio diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue index bc47b124f8b..10753de6cd0 100644 --- a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue +++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue @@ -1,6 +1,6 @@ <script> import { GlTabs, GlTab, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; +import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { __ } from '~/locale'; import ForkGroupsListItem from './fork_groups_list_item.vue'; @@ -44,7 +44,11 @@ export default { .then((response) => { this.namespaces = response.data.namespaces; }) - .catch(() => createFlash(__('There was a problem fetching groups.'))); + .catch(() => + createFlash({ + message: __('There was a problem fetching groups.'), + }), + ); }, }, diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js index 372967c8a1e..1a171252048 100644 --- a/app/assets/javascripts/pages/projects/forks/new/index.js +++ b/app/assets/javascripts/pages/projects/forks/new/index.js @@ -16,6 +16,7 @@ if (gon.features.forkProjectForm) { projectPath, projectDescription, projectVisibility, + restrictedVisibilityLevels, } = mountElement.dataset; // eslint-disable-next-line no-new @@ -38,6 +39,7 @@ if (gon.features.forkProjectForm) { projectPath, projectDescription, projectVisibility, + restrictedVisibilityLevels: JSON.parse(restrictedVisibilityLevels), }, }); }, |