Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /app/assets/javascripts/pages
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/pages')
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue17
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js4
-rw-r--r--app/assets/javascripts/pages/dashboard/todos/index/todos.js36
-rw-r--r--app/assets/javascripts/pages/groups/group_members/index.js10
-rw-r--r--app/assets/javascripts/pages/groups/runners/index/index.js (renamed from app/assets/javascripts/pages/groups/runners/index.js)0
-rw-r--r--app/assets/javascripts/pages/groups/runners/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/branches/new/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue2
-rw-r--r--app/assets/javascripts/pages/projects/google_cloud/configuration/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/google_cloud/databases/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/google_cloud/deployments/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/google_cloud/gcp_regions/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/google_cloud/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/google_cloud/service_accounts/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/jobs/index/index.js22
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/included_in_trial_indicator.vue15
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue8
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue70
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue73
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js58
-rw-r--r--app/assets/javascripts/pages/projects/logs/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js2
-rw-r--r--app/assets/javascripts/pages/projects/project_members/index.js10
-rw-r--r--app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue31
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/constants.js8
-rw-r--r--app/assets/javascripts/pages/projects/work_items/index.js2
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue2
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue286
29 files changed, 366 insertions, 319 deletions
diff --git a/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue
index 5ecacb84d65..ccb449f96e1 100644
--- a/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue
+++ b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue
@@ -12,6 +12,7 @@ import {
import { toSafeInteger } from 'lodash';
import csrf from '~/lib/utils/csrf';
import { __, n__, s__, sprintf } from '~/locale';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import SignupCheckbox from './signup_checkbox.vue';
const DENYLIST_TYPE_RAW = 'raw';
@@ -31,7 +32,12 @@ export default {
GlLink,
SignupCheckbox,
GlModal,
+ PasswordComplexityCheckboxGroup: () =>
+ import(
+ 'ee_component/pages/admin/application_settings/general/components/password_complexity_checkbox_group.vue'
+ ),
},
+ mixins: [glFeatureFlagMixin()],
inject: [
'host',
'settingsPath',
@@ -178,6 +184,9 @@ export default {
this.submitForm();
},
+ setPasswordComplexity({ name, value }) {
+ this.$set(this.form, name, value);
+ },
submitForm() {
this.$refs.form.submit();
},
@@ -291,9 +300,7 @@ export default {
<template #description>
<gl-sprintf
:message="
- s__(
- 'ApplicationSettings|See GitLab\'s %{linkStart}Password Policy Guidelines%{linkEnd}.',
- )
+ s__('ApplicationSettings|See %{linkStart}password policy guidelines%{linkEnd}.')
"
>
<template #link="{ content }">
@@ -305,6 +312,10 @@ export default {
</template>
</gl-form-group>
+ <password-complexity-checkbox-group
+ v-if="glFeatures.passwordComplexity"
+ @set-password-complexity="setPasswordComplexity"
+ />
<gl-form-group
:description="$options.i18n.domainAllowListDescription"
:label="$options.i18n.domainAllowListLabel"
diff --git a/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
index a50d8de0e88..0d5c55cb87b 100644
--- a/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
+++ b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
@@ -18,6 +18,10 @@ export default function initSignupRestrictions(elementSelector = '#js-signup-for
'domainDenylistEnabled',
'denylistTypeRawSelected',
'emailRestrictionsEnabled',
+ 'passwordNumberRequired',
+ 'passwordLowercaseRequired',
+ 'passwordUppercaseRequired',
+ 'passwordSymbolRequired',
],
});
diff --git a/app/assets/javascripts/pages/dashboard/todos/index/todos.js b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
index 44299d235d5..e45a40bd44c 100644
--- a/app/assets/javascripts/pages/dashboard/todos/index/todos.js
+++ b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
@@ -28,20 +28,32 @@ export default class Todos {
}
unbindEvents() {
- $('.js-done-todo, .js-undo-todo, .js-add-todo').off('click', this.updateRowStateClickedWrapper);
- $('.js-todos-mark-all', '.js-todos-undo-all').off('click', this.updateallStateClickedWrapper);
- $('.todo').off('click', this.goToTodoUrl);
- $('.todo').off('auxclick', this.goToTodoUrl);
+ document.querySelectorAll('.js-done-todo, .js-undo-todo, .js-add-todo').forEach((el) => {
+ el.removeEventListener('click', this.updateRowStateClickedWrapper);
+ });
+ document.querySelectorAll('.js-todos-mark-all, .js-todos-undo-all').forEach((el) => {
+ el.removeEventListener('click', this.updateallStateClickedWrapper);
+ });
+ document.querySelectorAll('.todo').forEach((el) => {
+ el.removeEventListener('click', this.goToTodoUrl);
+ el.removeEventListener('auxclick', this.goToTodoUrl);
+ });
}
bindEvents() {
this.updateRowStateClickedWrapper = this.updateRowStateClicked.bind(this);
this.updateAllStateClickedWrapper = this.updateAllStateClicked.bind(this);
- $('.js-done-todo, .js-undo-todo, .js-add-todo').on('click', this.updateRowStateClickedWrapper);
- $('.js-todos-mark-all, .js-todos-undo-all').on('click', this.updateAllStateClickedWrapper);
- $('.todo').on('click', this.goToTodoUrl);
- $('.todo').on('auxclick', this.goToTodoUrl);
+ document.querySelectorAll('.js-done-todo, .js-undo-todo, .js-add-todo').forEach((el) => {
+ el.addEventListener('click', this.updateRowStateClickedWrapper);
+ });
+ document.querySelectorAll('.js-todos-mark-all, .js-todos-undo-all').forEach((el) => {
+ el.addEventListener('click', this.updateAllStateClickedWrapper);
+ });
+ document.querySelectorAll('.todo').forEach((el) => {
+ el.addEventListener('click', this.goToTodoUrl);
+ el.addEventListener('auxclick', this.goToTodoUrl);
+ });
}
initFilters() {
@@ -181,7 +193,13 @@ export default class Todos {
}
updateBadges(data) {
- $(document).trigger('todo:toggle', data.count);
+ const event = new CustomEvent('todo:toggle', {
+ detail: {
+ count: data.count,
+ },
+ });
+
+ document.dispatchEvent(event);
document.querySelector('.js-todos-pending .js-todos-badge').innerHTML = addDelimiter(
data.count,
);
diff --git a/app/assets/javascripts/pages/groups/group_members/index.js b/app/assets/javascripts/pages/groups/group_members/index.js
index c7c2f6f773e..62d47cb49b8 100644
--- a/app/assets/javascripts/pages/groups/group_members/index.js
+++ b/app/assets/javascripts/pages/groups/group_members/index.js
@@ -5,12 +5,11 @@ import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { s__ } from '~/locale';
import { initMembersApp } from '~/members';
-import { MEMBER_TYPES } from '~/members/constants';
+import { MEMBER_TYPES, EE_APP_OPTIONS } from 'ee_else_ce/members/constants';
import { groupLinkRequestFormatter } from '~/members/utils';
const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
-
-initMembersApp(document.querySelector('.js-group-members-list-app'), {
+const APP_OPTIONS = {
[MEMBER_TYPES.user]: {
tableFields: SHARED_FIELDS.concat(['source', 'granted', 'userCreatedAt', 'lastActivityOn']),
tableAttrs: { tr: { 'data-qa-selector': 'member_row' } },
@@ -61,7 +60,10 @@ initMembersApp(document.querySelector('.js-group-members-list-app'), {
tableFields: SHARED_FIELDS.concat('requested'),
requestFormatter: groupMemberRequestFormatter,
},
-});
+ ...EE_APP_OPTIONS,
+};
+
+initMembersApp(document.querySelector('.js-group-members-list-app'), APP_OPTIONS);
initInviteMembersModal();
initInviteGroupsModal();
diff --git a/app/assets/javascripts/pages/groups/runners/index.js b/app/assets/javascripts/pages/groups/runners/index/index.js
index ca1a6bdab75..ca1a6bdab75 100644
--- a/app/assets/javascripts/pages/groups/runners/index.js
+++ b/app/assets/javascripts/pages/groups/runners/index/index.js
diff --git a/app/assets/javascripts/pages/groups/runners/show/index.js b/app/assets/javascripts/pages/groups/runners/show/index.js
new file mode 100644
index 00000000000..c59e3b80dc1
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/runners/show/index.js
@@ -0,0 +1,3 @@
+import { initGroupRunnerShow } from '~/runner/group_runner_show';
+
+initGroupRunnerShow();
diff --git a/app/assets/javascripts/pages/projects/branches/new/index.js b/app/assets/javascripts/pages/projects/branches/new/index.js
index 364223f1898..dbae89b5ade 100644
--- a/app/assets/javascripts/pages/projects/branches/new/index.js
+++ b/app/assets/javascripts/pages/projects/branches/new/index.js
@@ -1,8 +1,7 @@
-import $ from 'jquery';
import NewBranchForm from '~/new_branch_form';
// eslint-disable-next-line no-new
new NewBranchForm(
- $('.js-create-branch-form'),
+ document.querySelector('.js-create-branch-form'),
JSON.parse(document.getElementById('availableRefs').innerHTML),
);
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 701bf0c1e1d..f92a40e057f 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
@@ -329,7 +329,7 @@ export default {
</div>
<p class="gl-mt-n5 gl-text-gray-500">
- {{ s__('ForkProject|Want to house several dependent projects under the same namespace?') }}
+ {{ s__('ForkProject|Want to organize several dependent projects under the same namespace?') }}
<gl-link :href="newGroupPath" target="_blank">
{{ s__('ForkProject|Create a group') }}
</gl-link>
diff --git a/app/assets/javascripts/pages/projects/google_cloud/configuration/index.js b/app/assets/javascripts/pages/projects/google_cloud/configuration/index.js
new file mode 100644
index 00000000000..abececa44ee
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/google_cloud/configuration/index.js
@@ -0,0 +1,3 @@
+import init from '~/google_cloud/configuration/index';
+
+init();
diff --git a/app/assets/javascripts/pages/projects/google_cloud/databases/index.js b/app/assets/javascripts/pages/projects/google_cloud/databases/index.js
new file mode 100644
index 00000000000..5482324f1cd
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/google_cloud/databases/index.js
@@ -0,0 +1,3 @@
+import init from '~/google_cloud/databases/index';
+
+init();
diff --git a/app/assets/javascripts/pages/projects/google_cloud/deployments/index.js b/app/assets/javascripts/pages/projects/google_cloud/deployments/index.js
new file mode 100644
index 00000000000..b5a29b3825b
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/google_cloud/deployments/index.js
@@ -0,0 +1,3 @@
+import init from '~/google_cloud/deployments/index';
+
+init();
diff --git a/app/assets/javascripts/pages/projects/google_cloud/gcp_regions/index.js b/app/assets/javascripts/pages/projects/google_cloud/gcp_regions/index.js
new file mode 100644
index 00000000000..fb66e2fa051
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/google_cloud/gcp_regions/index.js
@@ -0,0 +1,3 @@
+import init from '~/google_cloud/gcp_regions/index';
+
+init();
diff --git a/app/assets/javascripts/pages/projects/google_cloud/index.js b/app/assets/javascripts/pages/projects/google_cloud/index.js
deleted file mode 100644
index 4506ea8efd1..00000000000
--- a/app/assets/javascripts/pages/projects/google_cloud/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import initGoogleCloud from '~/google_cloud/index';
-
-initGoogleCloud();
diff --git a/app/assets/javascripts/pages/projects/google_cloud/service_accounts/index.js b/app/assets/javascripts/pages/projects/google_cloud/service_accounts/index.js
new file mode 100644
index 00000000000..8b644c2b324
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/google_cloud/service_accounts/index.js
@@ -0,0 +1,3 @@
+import init from '~/google_cloud/service_accounts/index';
+
+init();
diff --git a/app/assets/javascripts/pages/projects/jobs/index/index.js b/app/assets/javascripts/pages/projects/jobs/index/index.js
index 75194499a7f..eb3a24f38a8 100644
--- a/app/assets/javascripts/pages/projects/jobs/index/index.js
+++ b/app/assets/javascripts/pages/projects/jobs/index/index.js
@@ -1,23 +1,3 @@
-import Vue from 'vue';
import initJobsTable from '~/jobs/components/table';
-import GlCountdown from '~/vue_shared/components/gl_countdown.vue';
-if (gon.features?.jobsTableVue) {
- initJobsTable();
-} else {
- const remainingTimeElements = document.querySelectorAll('.js-remaining-time');
-
- remainingTimeElements.forEach(
- (el) =>
- new Vue({
- el,
- render(h) {
- return h(GlCountdown, {
- props: {
- endDateString: el.dateTime,
- },
- });
- },
- }),
- );
-}
+initJobsTable();
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/included_in_trial_indicator.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/included_in_trial_indicator.vue
new file mode 100644
index 00000000000..693dc6a15ad
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/included_in_trial_indicator.vue
@@ -0,0 +1,15 @@
+<script>
+import { s__ } from '~/locale';
+
+export default {
+ name: 'IncludedInTrialIndicator',
+ i18n: {
+ trialOnly: s__('LearnGitlab|- Included in trial'),
+ },
+};
+</script>
+<template>
+ <span class="gl-font-style-italic gl-text-gray-500" data-testid="trial-only">
+ {{ $options.i18n.trialOnly }}
+ </span>
+</template>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
index db9ef4df8af..54e15b6552c 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
@@ -38,14 +38,16 @@ export default {
actionsData: this.actions,
};
},
- maxValue: Object.keys(ACTION_LABELS).length,
actionSections: Object.keys(ACTION_SECTIONS),
computed: {
+ maxValue() {
+ return Object.keys(this.actionsData).length;
+ },
progressValue() {
return Object.values(this.actionsData).filter((a) => a.completed).length;
},
progressPercentage() {
- return Math.round((this.progressValue / this.$options.maxValue) * 100);
+ return Math.round((this.progressValue / this.maxValue) * 100);
},
},
mounted() {
@@ -125,7 +127,7 @@ export default {
<template #percentSymbol>%</template>
</gl-sprintf>
</p>
- <gl-progress-bar :value="progressValue" :max="$options.maxValue" />
+ <gl-progress-bar :value="progressValue" :max="maxValue" />
</div>
<div class="row">
<div
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue
deleted file mode 100644
index 09cc0032871..00000000000
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue
+++ /dev/null
@@ -1,70 +0,0 @@
-<script>
-import { GlLink, GlCard, GlIcon } from '@gitlab/ui';
-import { s__ } from '~/locale';
-
-export default {
- name: 'LearnGitlabInfoCard',
- components: { GlLink, GlCard, GlIcon },
- i18n: {
- trial: s__('Learn GitLab|Trial only'),
- },
- props: {
- title: {
- required: true,
- type: String,
- },
- description: {
- required: true,
- type: String,
- },
- actionLabel: {
- required: true,
- type: String,
- },
- url: {
- required: true,
- type: String,
- },
- completed: {
- required: true,
- type: Boolean,
- },
- svg: {
- required: true,
- type: String,
- },
- trialRequired: {
- default: false,
- required: false,
- type: Boolean,
- },
- },
-};
-</script>
-<template>
- <gl-card class="gl-pt-0">
- <div class="gl-text-right gl-h-5">
- <gl-icon
- v-if="completed"
- name="check-circle-filled"
- class="gl-text-green-500"
- :size="16"
- data-testid="completed-icon"
- />
- <span
- v-else-if="trialRequired"
- class="gl-text-gray-500 gl-font-sm gl-font-style-italic"
- data-testid="trial-only"
- >{{ $options.i18n.trial }}</span
- >
- </div>
- <div
- class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
- >
- <img :src="svg" :alt="actionLabel" />
- <h6>{{ title }}</h6>
- <p class="gl-font-sm gl-text-gray-700">{{ description }}</p>
- <gl-link :href="url" target="_blank" rel="noopener noreferrer" />
- </div>
- </gl-card>
-</template>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
index 1912477758b..4eab0cccb06 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
@@ -6,6 +6,7 @@ import { isExperimentVariant } from '~/experimentation/utils';
import eventHub from '~/invite_members/event_hub';
import { s__, __ } from '~/locale';
import { ACTION_LABELS } from '../constants';
+import IncludedInTrialIndicator from './included_in_trial_indicator.vue';
export default {
name: 'LearnGitlabSectionLink',
@@ -15,12 +16,12 @@ export default {
GlButton,
GlPopover,
GitlabExperiment,
+ IncludedInTrialIndicator,
},
directives: {
GlTooltip,
},
i18n: {
- trialOnly: s__('LearnGitlab|Trial only'),
contactAdmin: s__('LearnGitlab|Contact your administrator to start a free Ultimate trial.'),
viewAdminList: s__('LearnGitlab|View administrator list'),
watchHow: __('Watch how'),
@@ -41,12 +42,6 @@ export default {
};
},
computed: {
- linkTitle() {
- return ACTION_LABELS[this.action].title;
- },
- trialOnly() {
- return ACTION_LABELS[this.action].trialRequired;
- },
showInviteModalLink() {
return (
this.action === 'userAdded' && isExperimentVariant('invite_for_help_continuous_onboarding')
@@ -55,49 +50,51 @@ export default {
openInNewTab() {
return ACTION_LABELS[this.action]?.openInNewTab === true || this.value.openInNewTab === true;
},
- linkToVideoTutorial() {
- return ACTION_LABELS[this.action].videoTutorial;
- },
},
methods: {
openModal() {
eventHub.$emit('openModal', { source: 'learn_gitlab' });
},
+ actionLabelValue(value) {
+ return ACTION_LABELS[this.action][value];
+ },
},
};
</script>
<template>
<div class="gl-mb-4">
- <div v-if="trialOnly" class="gl-font-style-italic gl-text-gray-500" data-testid="trial-only">
- {{ $options.i18n.trialOnly }}
- </div>
<div class="flex align-items-center">
<span v-if="value.completed" class="gl-text-green-500">
<gl-icon name="check-circle-filled" :size="16" data-testid="completed-icon" />
- {{ linkTitle }}
+ {{ actionLabelValue('title') }}
+ <included-in-trial-indicator v-if="actionLabelValue('trialRequired')" />
</span>
- <gl-link
- v-else-if="showInviteModalLink"
- data-track-action="click_link"
- :data-track-label="linkTitle"
- data-track-property="Growth::Activation::Experiment::InviteForHelpContinuousOnboarding"
- data-testid="invite-for-help-continuous-onboarding-experiment-link"
- @click="openModal"
- >
- {{ linkTitle }}
- </gl-link>
- <gl-link
- v-else-if="value.enabled"
- :target="openInNewTab ? '_blank' : '_self'"
- :href="value.url"
- data-testid="uncompleted-learn-gitlab-link"
- data-track-action="click_link"
- :data-track-label="linkTitle"
- >
- {{ linkTitle }}
- </gl-link>
+ <div v-else-if="showInviteModalLink">
+ <gl-link
+ data-track-action="click_link"
+ :data-track-label="actionLabelValue('trackLabel')"
+ data-track-property="Growth::Activation::Experiment::InviteForHelpContinuousOnboarding"
+ data-testid="invite-for-help-continuous-onboarding-experiment-link"
+ @click="openModal"
+ >{{ actionLabelValue('title') }}</gl-link
+ >
+
+ <included-in-trial-indicator v-if="actionLabelValue('trialRequired')" />
+ </div>
+ <div v-else-if="value.enabled">
+ <gl-link
+ :target="openInNewTab ? '_blank' : '_self'"
+ :href="value.url"
+ data-testid="uncompleted-learn-gitlab-link"
+ data-track-action="click_link"
+ :data-track-label="actionLabelValue('trackLabel')"
+ >{{ actionLabelValue('title') }}</gl-link
+ >
+
+ <included-in-trial-indicator v-if="actionLabelValue('trialRequired')" />
+ </div>
<template v-else>
- <div data-testid="disabled-learn-gitlab-link">{{ linkTitle }}</div>
+ <div data-testid="disabled-learn-gitlab-link">{{ actionLabelValue('title') }}</div>
<gl-button
:id="popoverId"
category="tertiary"
@@ -127,19 +124,19 @@ export default {
<template #control></template>
<template #candidate>
<gl-button
- v-if="linkToVideoTutorial"
+ v-if="actionLabelValue('videoTutorial')"
v-gl-tooltip
category="tertiary"
icon="live-preview"
:title="$options.i18n.watchHow"
:aria-label="$options.i18n.watchHow"
- :href="linkToVideoTutorial"
+ :href="actionLabelValue('videoTutorial')"
target="_blank"
class="ml-auto"
size="small"
data-testid="video-tutorial-link"
data-track-action="click_video_link"
- :data-track-label="linkTitle"
+ :data-track-label="actionLabelValue('trackLabel')"
data-track-property="Growth::Conversion::Experiment::LearnGitLab"
data-track-experiment="video_tutorials_continuous_onboarding"
/>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
index 05bacd9b350..cb1a0302d91 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
@@ -2,9 +2,10 @@ import { s__ } from '~/locale';
export const ACTION_LABELS = {
gitWrite: {
- title: s__('LearnGitLab|Create or import a repository'),
- actionLabel: s__('LearnGitLab|Create or import a repository'),
+ title: s__('LearnGitLab|Create a repository'),
+ actionLabel: s__('LearnGitLab|Create a repository'),
description: s__('LearnGitLab|Create or import your first repository into your new project.'),
+ trackLabel: 'create_a_repository',
section: 'workspace',
position: 1,
},
@@ -14,20 +15,23 @@ export const ACTION_LABELS = {
description: s__(
'LearnGitLab|GitLab works best as a team. Invite your colleague to enjoy all features.',
),
+ trackLabel: 'invite_your_colleagues',
section: 'workspace',
position: 0,
},
pipelineCreated: {
- title: s__('LearnGitLab|Set up CI/CD'),
- actionLabel: s__('LearnGitLab|Set-up CI/CD'),
+ title: s__("LearnGitLab|Set up your first project's CI/CD"),
+ actionLabel: s__('LearnGitLab|Set up CI/CD'),
description: s__('LearnGitLab|Save time by automating your integration and deployment tasks.'),
+ trackLabel: 'set_up_your_first_project_s_ci_cd',
section: 'workspace',
position: 2,
},
trialStarted: {
- title: s__('LearnGitLab|Start a free Ultimate trial'),
+ title: s__('LearnGitLab|Start a free trial of GitLab Ultimate'),
actionLabel: s__('LearnGitLab|Try GitLab Ultimate for free'),
description: s__('LearnGitLab|Try all GitLab features for 30 days, no credit card required.'),
+ trackLabel: 'start_a_free_trial_of_gitlab_ultimate',
section: 'workspace',
position: 3,
openInNewTab: true,
@@ -38,6 +42,7 @@ export const ACTION_LABELS = {
description: s__(
'LearnGitLab|Prevent unexpected changes to important assets by assigning ownership of files and paths.',
),
+ trackLabel: 'add_code_owners',
trialRequired: true,
section: 'workspace',
position: 4,
@@ -45,9 +50,10 @@ export const ACTION_LABELS = {
videoTutorial: 'https://vimeo.com/670896787',
},
requiredMrApprovalsEnabled: {
- title: s__('LearnGitLab|Add merge request approval'),
+ title: s__('LearnGitLab|Enable require merge approvals'),
actionLabel: s__('LearnGitLab|Enable require merge approvals'),
description: s__('LearnGitLab|Route code reviews to the right reviewers, every time.'),
+ trackLabel: 'enable_require_merge_approvals',
trialRequired: true,
section: 'workspace',
position: 5,
@@ -55,28 +61,52 @@ export const ACTION_LABELS = {
videoTutorial: 'https://vimeo.com/670904904',
},
mergeRequestCreated: {
- title: s__('LearnGitLab|Submit a merge request'),
+ title: s__('LearnGitLab|Submit a merge request (MR)'),
actionLabel: s__('LearnGitLab|Submit a merge request (MR)'),
description: s__('LearnGitLab|Review and edit proposed changes to source code.'),
+ trackLabel: 'submit_a_merge_request_mr',
section: 'plan',
position: 1,
},
- securityScanEnabled: {
- title: s__('LearnGitLab|Run a Security scan using CI/CD'),
- actionLabel: s__('LearnGitLab|Run a Security scan using CI/CD'),
- description: s__('LearnGitLab|Scan your code to uncover vulnerabilities before deploying.'),
- section: 'deploy',
- position: 1,
- },
issueCreated: {
title: s__('LearnGitLab|Create an issue'),
actionLabel: s__('LearnGitLab|Create an issue'),
description: s__(
'LearnGitLab|Create/import issues (tickets) to collaborate on ideas and plan work.',
),
+ trackLabel: 'create_an_issue',
section: 'plan',
position: 0,
},
+ securityScanEnabled: {
+ title: s__('LearnGitLab|Run a Security scan using CI/CD'),
+ actionLabel: s__('LearnGitLab|Run a Security scan using CI/CD'),
+ description: s__('LearnGitLab|Scan your code to uncover vulnerabilities before deploying.'),
+ trackLabel: 'run_a_security_scan_using_ci_cd',
+ section: 'deploy',
+ position: 1,
+ },
+ licenseScanningRun: {
+ title: s__('LearnGitLab|Scan dependencies for licenses'),
+ trackLabel: 'scan_dependencies_for_licenses',
+ trialRequired: true,
+ section: 'deploy',
+ position: 2,
+ },
+ secureDependencyScanningRun: {
+ title: s__('LearnGitLab|Scan dependencies for vulnerabilities'),
+ trackLabel: 'scan_dependencies_for_vulnerabilities',
+ trialRequired: true,
+ section: 'deploy',
+ position: 3,
+ },
+ secureDastRun: {
+ title: s__('LearnGitLab|Analyze your application for vulnerabilities with DAST'),
+ trackLabel: 'analyze_your_application_for_vulnerabilities_with_dast',
+ trialRequired: true,
+ section: 'deploy',
+ position: 4,
+ },
};
export const ACTION_SECTIONS = {
diff --git a/app/assets/javascripts/pages/projects/logs/index.js b/app/assets/javascripts/pages/projects/logs/index.js
deleted file mode 100644
index 0cff1ffc27e..00000000000
--- a/app/assets/javascripts/pages/projects/logs/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import logsBundle from '~/logs';
-
-logsBundle();
diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
index 48e360ce762..2db804e1ad8 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
@@ -9,6 +9,7 @@ import initSourcegraph from '~/sourcegraph';
import ZenMode from '~/zen_mode';
import initAwardsApp from '~/emoji/awards_app';
import MrWidgetHowToMergeModal from '~/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue';
+import { initMrExperienceSurvey } from '~/surveys/merge_request_experience';
import getStateQuery from './queries/get_state.query.graphql';
export default function initMergeRequestShow() {
@@ -18,6 +19,7 @@ export default function initMergeRequestShow() {
initSourcegraph();
initIssuableSidebar();
initAwardsApp(document.getElementById('js-vue-awards-block'));
+ initMrExperienceSurvey();
const el = document.querySelector('.js-mr-status-box');
const { iid, issuableType, projectPath } = el.dataset;
diff --git a/app/assets/javascripts/pages/projects/project_members/index.js b/app/assets/javascripts/pages/projects/project_members/index.js
index bf4fb5f3b7e..9a7fd74fd8c 100644
--- a/app/assets/javascripts/pages/projects/project_members/index.js
+++ b/app/assets/javascripts/pages/projects/project_members/index.js
@@ -1,4 +1,5 @@
-import initImportAProjectModal from '~/invite_members/init_import_a_project_modal';
+import initImportProjectMembersTrigger from '~/invite_members/init_import_project_members_trigger';
+import initImportProjectMembersModal from '~/invite_members/init_import_project_members_modal';
import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteGroupsModal from '~/invite_members/init_invite_groups_modal';
@@ -9,11 +10,12 @@ import { MEMBER_TYPES } from '~/members/constants';
import { groupLinkRequestFormatter } from '~/members/utils';
import { projectMemberRequestFormatter } from '~/projects/members/utils';
-initImportAProjectModal();
+initImportProjectMembersModal();
initInviteMembersModal();
initInviteGroupsModal();
initInviteMembersTrigger();
initInviteGroupTrigger();
+initImportProjectMembersTrigger();
const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
initMembersApp(document.querySelector('.js-project-members-list-app'), {
@@ -38,7 +40,7 @@ initMembersApp(document.querySelector('.js-project-members-list-app'), {
},
},
[MEMBER_TYPES.group]: {
- tableFields: SHARED_FIELDS.concat('granted'),
+ tableFields: SHARED_FIELDS.concat(['source', 'granted']),
tableAttrs: {
table: { 'data-qa-selector': 'groups_list' },
tr: { 'data-qa-selector': 'group_row' },
@@ -46,7 +48,7 @@ initMembersApp(document.querySelector('.js-project-members-list-app'), {
requestFormatter: groupLinkRequestFormatter,
filteredSearchBar: {
show: true,
- tokens: [],
+ tokens: ['groups_with_inherited_permissions'],
searchParam: 'search_groups',
placeholder: s__('Members|Search groups'),
recentSearchesStorageKey: 'project_group_links',
diff --git a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
index 43ab829f5f9..6a9bd34db22 100644
--- a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
+++ b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
@@ -9,6 +9,7 @@ import { initInstallRunner } from '~/pages/shared/mount_runner_instructions';
import initSharedRunnersToggle from '~/projects/settings/mount_shared_runners_toggle';
import initSettingsPanels from '~/settings_panels';
import { initTokenAccess } from '~/token_access';
+import { initCiSecureFiles } from '~/ci_secure_files';
// Initialize expandable settings panels
initSettingsPanels();
@@ -41,3 +42,4 @@ initSharedRunnersToggle();
initInstallRunner();
initRunnerAwsDeployments();
initTokenAccess();
+initCiSecureFiles();
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index 81b0dbec0bd..f2c30870a68 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -61,6 +61,10 @@ export default {
GlFormCheckbox,
GlToggle,
ConfirmDanger,
+ otherProjectSettings: () =>
+ import(
+ 'jh_component/pages/projects/shared/permissions/components/other_project_settings.vue'
+ ),
},
mixins: [settingsMixin, glFeatureFlagsMixin()],
@@ -182,6 +186,10 @@ export default {
required: false,
default: false,
},
+ membersPagePath: {
+ type: String,
+ required: true,
+ },
},
data() {
const defaults = {
@@ -521,12 +529,22 @@ export default {
/>
</div>
</div>
- <span v-if="!visibilityAllowed(visibilityLevel)" class="form-text text-muted">{{
- s__(
- 'ProjectSettings|Visibility options for this fork are limited by the current visibility of the source project.',
- )
- }}</span>
- <span class="form-text text-muted">{{ visibilityLevelDescription }}</span>
+ <span
+ v-if="!visibilityAllowed(visibilityLevel)"
+ class="gl-display-block gl-text-gray-500 gl-mt-2"
+ >{{
+ s__(
+ 'ProjectSettings|Visibility options for this fork are limited by the current visibility of the source project.',
+ )
+ }}</span
+ >
+ <span class="gl-display-block gl-text-gray-500 gl-mt-2">
+ <gl-sprintf :message="visibilityLevelDescription">
+ <template #membersPageLink="{ content }">
+ <gl-link class="gl-link" :href="membersPagePath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
<div v-if="showAdditonalSettings" class="gl-mt-4">
<strong class="gl-display-block">{{ s__('ProjectSettings|Additional options') }}</strong>
<label
@@ -891,6 +909,7 @@ export default {
<template #help>{{ $options.i18n.pucWarningHelpText }}</template>
</gl-form-checkbox>
</project-setting-row>
+ <other-project-settings />
<confirm-danger
v-if="isVisibilityReduced"
button-variant="confirm"
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/constants.js b/app/assets/javascripts/pages/projects/shared/permissions/constants.js
index fb1acd5311c..cfca9d400e3 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/constants.js
+++ b/app/assets/javascripts/pages/projects/shared/permissions/constants.js
@@ -8,12 +8,10 @@ export const visibilityOptions = {
export const visibilityLevelDescriptions = {
[visibilityOptions.PRIVATE]: __(
- 'The project is accessible only by members of the project. Access must be granted explicitly to each user.',
- ),
- [visibilityOptions.INTERNAL]: __('The project can be accessed by any user who is logged in.'),
- [visibilityOptions.PUBLIC]: __(
- 'The project can be accessed by anyone, regardless of authentication.',
+ `Only accessible by %{membersPageLinkStart}project members%{membersPageLinkEnd}. Membership must be explicitly granted to each user.`,
),
+ [visibilityOptions.INTERNAL]: __('Accessible by any user who is logged in.'),
+ [visibilityOptions.PUBLIC]: __('Accessible by anyone, regardless of authentication.'),
};
export const featureAccessLevel = {
diff --git a/app/assets/javascripts/pages/projects/work_items/index.js b/app/assets/javascripts/pages/projects/work_items/index.js
index 11c257611f0..6eef2352e2c 100644
--- a/app/assets/javascripts/pages/projects/work_items/index.js
+++ b/app/assets/javascripts/pages/projects/work_items/index.js
@@ -1,3 +1,5 @@
import { initWorkItemsRoot } from '~/work_items/index';
+import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
initWorkItemsRoot();
+initInviteMembersModal();
diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue
index 7c23f60954a..e92f386a29e 100644
--- a/app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue
@@ -3,6 +3,7 @@ import { GlSkeletonLoader, GlSafeHtmlDirective, GlAlert } from '@gitlab/ui';
import createFlash from '~/flash';
import { __ } from '~/locale';
import axios from '~/lib/utils/axios_utils';
+import { handleLocationHash } from '~/lib/utils/common_utils';
import { renderGFM } from '../render_gfm_facade';
export default {
@@ -43,6 +44,7 @@ export default {
this.$nextTick()
.then(() => {
renderGFM(this.$refs.content);
+ handleLocationHash();
})
.catch(() =>
createFlash({
diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
index 024b3bc9595..3c22844434d 100644
--- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
@@ -1,5 +1,16 @@
<script>
-import { GlForm, GlIcon, GlLink, GlButton, GlSprintf, GlAlert } from '@gitlab/ui';
+import {
+ GlForm,
+ GlIcon,
+ GlLink,
+ GlButton,
+ GlSprintf,
+ GlAlert,
+ GlFormGroup,
+ GlFormInput,
+ GlFormSelect,
+} from '@gitlab/ui';
+import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import axios from '~/lib/utils/axios_utils';
import csrf from '~/lib/utils/csrf';
import { setUrlFragment } from '~/lib/utils/url_utility';
@@ -75,12 +86,16 @@ export default {
},
components: {
GlAlert,
+ GlIcon,
GlForm,
+ GlFormGroup,
+ GlFormInput,
+ GlFormSelect,
GlSprintf,
- GlIcon,
GlLink,
GlButton,
MarkdownField,
+ LocalStorageSync,
ContentEditor: () =>
import(
/* webpackChunkName: 'content_editor' */ '~/content_editor/components/content_editor.vue'
@@ -186,6 +201,10 @@ export default {
this.useContentEditor = !this.useContentEditor;
},
+ setUseContentEditor(value) {
+ this.useContentEditor = value;
+ },
+
async handleFormSubmit(e) {
e.preventDefault();
@@ -305,150 +324,151 @@ export default {
name="wiki[last_commit_sha]"
:value="pageInfo.lastCommitSha"
/>
- <div class="form-group row">
- <div class="col-sm-2 col-form-label">
- <label class="control-label-full-width" for="wiki_title">{{
- $options.i18n.title.label
- }}</label>
- </div>
- <div class="col-sm-10">
- <input
- id="wiki_title"
- v-model="title"
- name="wiki[title]"
- type="text"
- class="form-control"
- data-qa-selector="wiki_title_textbox"
- :required="true"
- :autofocus="!pageInfo.persisted"
- :placeholder="$options.i18n.title.placeholder"
- @input="updateCommitMessage"
- />
- <span class="gl-display-inline-block gl-max-w-full gl-mt-2 gl-text-gray-600">
- <gl-icon class="gl-mr-n1" name="bulb" />
- {{ titleHelpText }}
- <gl-link :href="helpPath" target="_blank">
- {{ $options.i18n.title.helpText.learnMore }}
- </gl-link>
- </span>
- </div>
- </div>
- <div class="form-group row">
- <div class="col-sm-2 col-form-label">
- <label class="control-label-full-width" for="wiki_format">{{
- $options.i18n.format.label
- }}</label>
+
+ <div class="row">
+ <div class="col-sm-9">
+ <gl-form-group :label="$options.i18n.title.label" label-for="wiki_title">
+ <template #description>
+ <gl-icon class="gl-mr-n1" name="bulb" />
+ {{ titleHelpText }}
+ <gl-link :href="helpPath" target="_blank">
+ {{ $options.i18n.title.helpText.learnMore }}
+ </gl-link>
+ </template>
+
+ <gl-form-input
+ id="wiki_title"
+ v-model="title"
+ name="wiki[title]"
+ type="text"
+ class="form-control"
+ data-qa-selector="wiki_title_textbox"
+ :required="true"
+ :autofocus="!pageInfo.persisted"
+ :placeholder="$options.i18n.title.placeholder"
+ @input="updateCommitMessage"
+ />
+ </gl-form-group>
</div>
- <div class="col-sm-10">
- <select
- id="wiki_format"
- v-model="format"
- class="form-control"
- name="wiki[format]"
- :disabled="isContentEditorActive"
- >
- <option v-for="(key, label) of formatOptions" :key="key" :value="key">
- {{ label }}
- </option>
- </select>
+
+ <div class="col-sm-3 row-sm-10">
+ <gl-form-group :label="$options.i18n.format.label" label-for="wiki_format">
+ <gl-form-select
+ id="wiki_format"
+ v-model="format"
+ name="wiki[format]"
+ :disabled="isContentEditorActive"
+ class="form-control"
+ :value="formatOptions.Markdown"
+ >
+ <option v-for="(key, label) of formatOptions" :key="key" :value="key">
+ {{ label }}
+ </option>
+ </gl-form-select>
+ </gl-form-group>
</div>
</div>
- <div class="form-group row" data-testid="wiki-form-content-fieldset">
- <div class="col-sm-2 col-form-label">
- <label class="control-label-full-width" for="wiki_content">{{
- $options.i18n.content.label
- }}</label>
- </div>
- <div class="col-sm-10">
- <div v-if="isMarkdownFormat" class="gl-display-flex gl-justify-content-end gl-mb-3">
- <gl-button
- data-testid="toggle-editing-mode-button"
- data-qa-selector="editing_mode_button"
- :data-qa-mode="toggleEditingModeButtonText"
- variant="link"
- @click="toggleEditingMode"
- >{{ toggleEditingModeButtonText }}</gl-button
- >
- </div>
- <markdown-field
- v-if="!isContentEditorActive"
- :markdown-preview-path="pageInfo.markdownPreviewPath"
- :can-attach-file="true"
- :enable-autocomplete="true"
- :textarea-value="content"
- :markdown-docs-path="pageInfo.markdownHelpPath"
- :uploads-path="pageInfo.uploadsPath"
- :enable-preview="isMarkdownFormat"
- class="bordered-box"
- >
- <template #textarea>
- <textarea
- id="wiki_content"
- ref="textarea"
- v-model="content"
- name="wiki[content]"
- class="note-textarea js-gfm-input js-autosize markdown-area"
- dir="auto"
- data-supports-quick-actions="false"
- data-qa-selector="wiki_content_textarea"
- :autofocus="pageInfo.persisted"
- :aria-label="$options.i18n.content.label"
- :placeholder="$options.i18n.content.placeholder"
- @input="handleContentChange"
+
+ <div class="row" data-testid="wiki-form-content-fieldset">
+ <div class="col-sm-12 row-sm-5">
+ <gl-form-group>
+ <div v-if="isMarkdownFormat" class="gl-display-flex gl-justify-content-end gl-mb-3">
+ <gl-button
+ data-testid="toggle-editing-mode-button"
+ data-qa-selector="editing_mode_button"
+ :data-qa-mode="toggleEditingModeButtonText"
+ variant="link"
+ @click="toggleEditingMode"
+ >{{ toggleEditingModeButtonText }}</gl-button
>
- </textarea>
- </template>
- </markdown-field>
- <div v-if="isContentEditorActive">
- <content-editor
- :render-markdown="renderMarkdown"
- :uploads-path="pageInfo.uploadsPath"
- @initialized="loadInitialContent"
- @change="handleContentEditorChange"
+ </div>
+ <local-storage-sync
+ storage-key="gl-wiki-content-editor-enabled"
+ :value="useContentEditor"
+ @input="setUseContentEditor"
/>
- <input id="wiki_content" v-model.trim="content" type="hidden" name="wiki[content]" />
- </div>
+ <markdown-field
+ v-if="!isContentEditorActive"
+ :markdown-preview-path="pageInfo.markdownPreviewPath"
+ :can-attach-file="true"
+ :enable-autocomplete="true"
+ :textarea-value="content"
+ :markdown-docs-path="pageInfo.markdownHelpPath"
+ :uploads-path="pageInfo.uploadsPath"
+ :enable-preview="isMarkdownFormat"
+ class="bordered-box"
+ >
+ <template #textarea>
+ <textarea
+ id="wiki_content"
+ ref="textarea"
+ v-model="content"
+ name="wiki[content]"
+ class="note-textarea js-gfm-input js-autosize markdown-area"
+ dir="auto"
+ data-supports-quick-actions="false"
+ data-qa-selector="wiki_content_textarea"
+ :autofocus="pageInfo.persisted"
+ :aria-label="$options.i18n.content.label"
+ :placeholder="$options.i18n.content.placeholder"
+ @input="handleContentChange"
+ >
+ </textarea>
+ </template>
+ </markdown-field>
+ <div v-if="isContentEditorActive">
+ <content-editor
+ :render-markdown="renderMarkdown"
+ :uploads-path="pageInfo.uploadsPath"
+ @initialized="loadInitialContent"
+ @change="handleContentEditorChange"
+ />
+ <input id="wiki_content" v-model.trim="content" type="hidden" name="wiki[content]" />
+ </div>
- <div class="clearfix"></div>
- <div class="error-alert"></div>
+ <div class="clearfix"></div>
+ <div class="error-alert"></div>
- <div class="form-text gl-text-gray-600">
- <gl-sprintf v-if="displayWikiSpecificMarkdownHelp" :message="$options.i18n.linksHelpText">
- <template #linkExample
- ><code>{{ linkExample }}</code></template
+ <div class="form-text gl-text-gray-600">
+ <gl-sprintf
+ v-if="displayWikiSpecificMarkdownHelp"
+ :message="$options.i18n.linksHelpText"
>
- <template
- #link="// eslint-disable-next-line vue/no-template-shadow
+ <template #linkExample>
+ <code>{{ linkExample }}</code>
+ </template>
+ <template
+ #link="// eslint-disable-next-line vue/no-template-shadow
{ content }"
- ><gl-link
- :href="wikiSpecificMarkdownHelpPath"
- target="_blank"
- data-testid="wiki-markdown-help-link"
- >{{ content }}</gl-link
- ></template
- >
- </gl-sprintf>
- </div>
+ ><gl-link
+ :href="wikiSpecificMarkdownHelpPath"
+ target="_blank"
+ data-testid="wiki-markdown-help-link"
+ >{{ content }}</gl-link
+ ></template
+ >
+ </gl-sprintf>
+ </div>
+ </gl-form-group>
</div>
</div>
- <div class="form-group row">
- <div class="col-sm-2 col-form-label">
- <label class="control-label-full-width" for="wiki_message">{{
- $options.i18n.commitMessage.label
- }}</label>
- </div>
- <div class="col-sm-10">
- <input
- id="wiki_message"
- v-model.trim="commitMessage"
- name="wiki[message]"
- type="text"
- class="form-control"
- data-qa-selector="wiki_message_textbox"
- :placeholder="$options.i18n.commitMessage.label"
- />
+
+ <div class="row">
+ <div class="col-sm-12 row-sm-5">
+ <gl-form-group :label="$options.i18n.commitMessage.label" label-for="wiki_message">
+ <gl-form-input
+ id="wiki_message"
+ v-model.trim="commitMessage"
+ name="wiki[message]"
+ type="text"
+ class="form-control"
+ data-qa-selector="wiki_message_textbox"
+ :placeholder="$options.i18n.commitMessage.label"
+ />
+ </gl-form-group>
</div>
</div>
+
<div class="form-actions">
<gl-button
category="primary"