summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pages/shared
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 18:25:58 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 18:25:58 +0000
commita5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 (patch)
treefb69158581673816a8cd895f9d352dcb3c678b1e /app/assets/javascripts/pages/shared
parentd16b2e8639e99961de6ddc93909f3bb5c1445ba1 (diff)
downloadgitlab-ce-a5f4bba440d7f9ea47046a0a561d49adf0a1e6d4.tar.gz
Add latest changes from gitlab-org/gitlab@14-0-stable-eev14.0.0-rc42
Diffstat (limited to 'app/assets/javascripts/pages/shared')
-rw-r--r--app/assets/javascripts/pages/shared/mount_runner_aws_deployments.js17
-rw-r--r--app/assets/javascripts/pages/shared/nav/sidebar_tracking.js44
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue170
-rw-r--r--app/assets/javascripts/pages/shared/wikis/constants.js4
4 files changed, 182 insertions, 53 deletions
diff --git a/app/assets/javascripts/pages/shared/mount_runner_aws_deployments.js b/app/assets/javascripts/pages/shared/mount_runner_aws_deployments.js
new file mode 100644
index 00000000000..f3807a33a2b
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/mount_runner_aws_deployments.js
@@ -0,0 +1,17 @@
+import Vue from 'vue';
+import RunnerAwsDeployments from '~/vue_shared/components/runner_aws_deployments/runner_aws_deployments.vue';
+
+export function initRunnerAwsDeployments(componentId = 'js-runner-aws-deployments') {
+ const el = document.getElementById(componentId);
+
+ if (!el) {
+ return null;
+ }
+
+ return new Vue({
+ el,
+ render(createElement) {
+ return createElement(RunnerAwsDeployments);
+ },
+ });
+}
diff --git a/app/assets/javascripts/pages/shared/nav/sidebar_tracking.js b/app/assets/javascripts/pages/shared/nav/sidebar_tracking.js
new file mode 100644
index 00000000000..79ce1a37d21
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/nav/sidebar_tracking.js
@@ -0,0 +1,44 @@
+function onSidebarLinkClick() {
+ const setDataTrackAction = (element, action) => {
+ element.setAttribute('data-track-action', action);
+ };
+
+ const setDataTrackExtra = (element, value) => {
+ const SIDEBAR_COLLAPSED = 'Collapsed';
+ const SIDEBAR_EXPANDED = 'Expanded';
+ const sidebarCollapsed = document
+ .querySelector('.nav-sidebar')
+ .classList.contains('js-sidebar-collapsed')
+ ? SIDEBAR_COLLAPSED
+ : SIDEBAR_EXPANDED;
+
+ element.setAttribute(
+ 'data-track-extra',
+ JSON.stringify({ sidebar_display: sidebarCollapsed, menu_display: value }),
+ );
+ };
+
+ const EXPANDED = 'Expanded';
+ const FLY_OUT = 'Fly out';
+ const CLICK_MENU_ACTION = 'click_menu';
+ const CLICK_MENU_ITEM_ACTION = 'click_menu_item';
+ const parentElement = this.parentNode;
+ const subMenuList = parentElement.closest('.sidebar-sub-level-items');
+
+ if (subMenuList) {
+ const isFlyOut = subMenuList.classList.contains('fly-out-list') ? FLY_OUT : EXPANDED;
+
+ setDataTrackExtra(parentElement, isFlyOut);
+ setDataTrackAction(parentElement, CLICK_MENU_ITEM_ACTION);
+ } else {
+ const isFlyOut = parentElement.classList.contains('is-showing-fly-out') ? FLY_OUT : EXPANDED;
+
+ setDataTrackExtra(parentElement, isFlyOut);
+ setDataTrackAction(parentElement, CLICK_MENU_ACTION);
+ }
+}
+export const initSidebarTracking = () => {
+ document.querySelectorAll('.nav-sidebar li[data-track-label] > a').forEach((link) => {
+ link.addEventListener('click', onSidebarLinkClick);
+ });
+};
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 43753926039..26f6d1d683a 100644
--- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
@@ -14,8 +14,17 @@ import axios from '~/lib/utils/axios_utils';
import csrf from '~/lib/utils/csrf';
import { setUrlFragment } from '~/lib/utils/url_utility';
import { s__, sprintf } from '~/locale';
+import Tracking from '~/tracking';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import {
+ WIKI_CONTENT_EDITOR_TRACKING_LABEL,
+ CONTENT_EDITOR_LOADED_ACTION,
+ SAVED_USING_CONTENT_EDITOR_ACTION,
+} from '../constants';
+
+const trackingMixin = Tracking.mixin({
+ label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
+});
const MARKDOWN_LINK_TEXT = {
markdown: '[Link Title](page-slug)',
@@ -53,21 +62,30 @@ export default {
),
primaryAction: s__('WikiPage|Retry'),
},
- useNewEditor: s__('WikiPage|Use new editor'),
+ useNewEditor: {
+ primaryLabel: s__('WikiPage|Use the new editor'),
+ secondaryLabel: s__('WikiPage|Try this later'),
+ title: s__('WikiPage|Get a richer editing experience'),
+ text: s__(
+ "WikiPage|Try the new visual Markdown editor. Read the %{linkStart}documentation%{linkEnd} to learn what's currently supported.",
+ ),
+ },
switchToOldEditor: {
- label: s__('WikiPage|Switch to old editor'),
- helpText: s__("WikiPage|Switching will discard any changes you've made in the new editor."),
+ label: s__('WikiPage|Switch me back to the classic editor.'),
+ helpText: s__(
+ "WikiPage|This editor is in beta and may not display the page's contents properly. Switching back to the classic editor will discard changes you've made in the new editor.",
+ ),
modal: {
- title: s__('WikiPage|Are you sure you want to switch to the old editor?'),
- primary: s__('WikiPage|Switch to old editor'),
+ title: s__('WikiPage|Are you sure you want to switch back to the classic editor?'),
+ primary: s__('WikiPage|Switch to classic editor'),
cancel: s__('WikiPage|Keep editing'),
text: s__(
- "WikiPage|Switching to the old editor will discard any changes you've made in the new editor.",
+ "WikiPage|Switching to the classic editor will discard any changes you've made in the new editor.",
),
},
},
- helpText: s__(
- "WikiPage|This editor is in beta and may not display the page's contents properly.",
+ feedbackTip: s__(
+ 'Tell us your experiences with the new Markdown editor %{linkStart}in this feedback issue%{linkEnd}.',
),
},
linksHelpText: s__(
@@ -86,6 +104,7 @@ export default {
},
cancel: s__('WikiPage|Cancel'),
},
+ contentEditorFeedbackIssue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332629',
components: {
GlAlert,
GlForm,
@@ -104,13 +123,14 @@ export default {
directives: {
GlModalDirective,
},
- mixins: [glFeatureFlagMixin()],
+ mixins: [trackingMixin],
inject: ['formatOptions', 'pageInfo'],
data() {
return {
title: this.pageInfo.title?.trim() || '',
format: this.pageInfo.format || 'markdown',
- content: this.pageInfo.content?.trim() || '',
+ content: this.pageInfo.content || '',
+ isContentEditorAlertDismissed: false,
isContentEditorLoading: true,
useContentEditor: false,
commitMessage: '',
@@ -120,6 +140,10 @@ export default {
};
},
computed: {
+ noContent() {
+ if (this.isContentEditorActive) return this.contentEditor?.empty;
+ return !this.content.trim();
+ },
csrfToken() {
return csrf.token;
},
@@ -157,14 +181,17 @@ export default {
wikiSpecificMarkdownHelpPath() {
return setUrlFragment(this.pageInfo.markdownHelpPath, 'wiki-specific-markdown');
},
+ contentEditorHelpPath() {
+ return setUrlFragment(this.pageInfo.helpPath, 'gitlab-flavored-markdown-support');
+ },
isMarkdownFormat() {
return this.format === 'markdown';
},
- showContentEditorButton() {
- return this.isMarkdownFormat && !this.useContentEditor && this.glFeatures.wikiContentEditor;
+ showContentEditorAlert() {
+ return this.isMarkdownFormat && !this.useContentEditor && !this.isContentEditorAlertDismissed;
},
disableSubmitButton() {
- return !this.content || !this.title || this.contentEditorRenderFailed;
+ return this.noContent || !this.title || this.contentEditorRenderFailed;
},
isContentEditorActive() {
return this.isMarkdownFormat && this.useContentEditor;
@@ -188,6 +215,8 @@ export default {
handleFormSubmit() {
if (this.useContentEditor) {
this.content = this.contentEditor.getSerializedContent();
+
+ this.trackFormSubmit();
}
this.isDirty = false;
@@ -236,6 +265,8 @@ export default {
try {
await this.contentEditor.setSerializedContent(this.content);
this.isContentEditorLoading = false;
+
+ this.trackContentEditorLoaded();
} catch (e) {
this.contentEditorRenderFailed = true;
}
@@ -258,6 +289,20 @@ export default {
this.$refs.confirmSwitchToOldEditorModal.show();
}
},
+
+ trackContentEditorLoaded() {
+ this.track(CONTENT_EDITOR_LOADED_ACTION);
+ },
+
+ trackFormSubmit() {
+ if (this.isContentEditorActive) {
+ this.track(SAVED_USING_CONTENT_EDITOR_ACTION);
+ }
+ },
+
+ dismissContentEditorAlert() {
+ this.isContentEditorAlertDismissed = true;
+ },
},
};
</script>
@@ -275,11 +320,9 @@ export default {
:dismissible="false"
variant="danger"
:primary-button-text="$options.i18n.contentEditor.renderFailed.primaryAction"
- @primaryAction="retryInitContentEditor()"
+ @primaryAction="retryInitContentEditor"
>
- <p>
- {{ $options.i18n.contentEditor.renderFailed.message }}
- </p>
+ {{ $options.i18n.contentEditor.renderFailed.message }}
</gl-alert>
<input :value="csrfToken" type="hidden" name="authenticity_token" />
@@ -299,7 +342,7 @@ export default {
<div class="col-sm-10">
<input
id="wiki_title"
- v-model.trim="title"
+ v-model="title"
name="wiki[title]"
type="text"
class="form-control"
@@ -337,46 +380,50 @@ export default {
{{ label }}
</option>
</select>
- <div>
- <gl-button
- v-if="showContentEditorButton"
- category="secondary"
- variant="confirm"
- class="gl-mt-4"
- @click="initContentEditor"
- >{{ $options.i18n.contentEditor.useNewEditor }}</gl-button
- >
- <div v-if="isContentEditorActive" class="gl-mt-4 gl-display-flex">
- <div class="gl-mr-4">
- <gl-button category="secondary" variant="confirm" @click="confirmSwitchToOldEditor">{{
- $options.i18n.contentEditor.switchToOldEditor.label
- }}</gl-button>
- </div>
- <div class="gl-mt-2">
- <gl-icon name="warning" />
- {{ $options.i18n.contentEditor.switchToOldEditor.helpText }}
- </div>
- </div>
- <gl-modal
- ref="confirmSwitchToOldEditorModal"
- modal-id="confirm-switch-to-old-editor"
- :title="$options.i18n.contentEditor.switchToOldEditor.modal.title"
- :action-primary="{ text: $options.i18n.contentEditor.switchToOldEditor.modal.primary }"
- :action-cancel="{ text: $options.i18n.contentEditor.switchToOldEditor.modal.cancel }"
- @primary="switchToOldEditor"
- >
- {{ $options.i18n.contentEditor.switchToOldEditor.modal.text }}
- </gl-modal>
- </div>
</div>
</div>
- <div class="form-group row">
+ <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">
+ <gl-alert
+ v-if="showContentEditorAlert"
+ class="gl-mb-6"
+ variant="info"
+ :primary-button-text="$options.i18n.contentEditor.useNewEditor.primaryLabel"
+ :secondary-button-text="$options.i18n.contentEditor.useNewEditor.secondaryLabel"
+ :dismiss-label="$options.i18n.contentEditor.useNewEditor.secondaryLabel"
+ :title="$options.i18n.contentEditor.useNewEditor.title"
+ @primaryAction="initContentEditor"
+ @secondaryAction="dismissContentEditorAlert"
+ @dismiss="dismissContentEditorAlert"
+ >
+ <gl-sprintf :message="$options.i18n.contentEditor.useNewEditor.text">
+ <template
+ #link="// eslint-disable-next-line vue/no-template-shadow
+ { content }"
+ ><gl-link
+ :href="contentEditorHelpPath"
+ target="_blank"
+ data-testid="content-editor-help-link"
+ >{{ content }}</gl-link
+ ></template
+ >
+ </gl-sprintf>
+ </gl-alert>
+ <gl-modal
+ ref="confirmSwitchToOldEditorModal"
+ modal-id="confirm-switch-to-old-editor"
+ :title="$options.i18n.contentEditor.switchToOldEditor.modal.title"
+ :action-primary="{ text: $options.i18n.contentEditor.switchToOldEditor.modal.primary }"
+ :action-cancel="{ text: $options.i18n.contentEditor.switchToOldEditor.modal.cancel }"
+ @primary="switchToOldEditor"
+ >
+ {{ $options.i18n.contentEditor.switchToOldEditor.modal.text }}
+ </gl-modal>
<markdown-field
v-if="!isContentEditorActive"
:markdown-preview-path="pageInfo.markdownPreviewPath"
@@ -391,7 +438,7 @@ export default {
<textarea
id="wiki_content"
ref="textarea"
- v-model.trim="content"
+ v-model="content"
name="wiki[content]"
class="note-textarea js-gfm-input js-autosize markdown-area"
dir="auto"
@@ -407,6 +454,20 @@ export default {
</markdown-field>
<div v-if="isContentEditorActive">
+ <gl-alert class="gl-mb-6" variant="tip" :dismissable="false">
+ <gl-sprintf :message="$options.i18n.contentEditor.feedbackTip">
+ <template
+ #link="// eslint-disable-next-line vue/no-template-shadow
+ { content }"
+ ><gl-link
+ :href="$options.contentEditorFeedbackIssue"
+ target="_blank"
+ data-testid="wiki-markdown-help-link"
+ >{{ content }}</gl-link
+ ></template
+ >
+ </gl-sprintf>
+ </gl-alert>
<gl-loading-icon v-if="isContentEditorLoading" class="bordered-box gl-w-full gl-py-6" />
<content-editor v-else :content-editor="contentEditor" />
<input id="wiki_content" v-model.trim="content" type="hidden" name="wiki[content]" />
@@ -432,7 +493,10 @@ export default {
>
</gl-sprintf>
<span v-else>
- {{ $options.i18n.contentEditor.helpText }}
+ {{ $options.i18n.contentEditor.switchToOldEditor.helpText }}
+ <gl-button variant="link" @click="confirmSwitchToOldEditor">{{
+ $options.i18n.contentEditor.switchToOldEditor.label
+ }}</gl-button>
</span>
</div>
</div>
diff --git a/app/assets/javascripts/pages/shared/wikis/constants.js b/app/assets/javascripts/pages/shared/wikis/constants.js
new file mode 100644
index 00000000000..b358ac9cf52
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/wikis/constants.js
@@ -0,0 +1,4 @@
+export const WIKI_CONTENT_EDITOR_TRACKING_LABEL = 'wiki_content_editor';
+
+export const CONTENT_EDITOR_LOADED_ACTION = 'content_editor_loaded';
+export const SAVED_USING_CONTENT_EDITOR_ACTION = 'saved_using_content_editor';