diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-02 03:17:32 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-02 03:17:32 +0300 |
commit | ef615776bf132cb0c56cafd51ac97fb1b7f26a58 (patch) | |
tree | 6656732d3d9434300c6fcf4057254083c9b269eb /app | |
parent | 7b78125a3829026f54bd87ab560758de3f37ad82 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
10 files changed, 248 insertions, 12 deletions
diff --git a/app/assets/javascripts/content_editor/extensions/footnote_definition.js b/app/assets/javascripts/content_editor/extensions/footnote_definition.js new file mode 100644 index 00000000000..dbab0de3421 --- /dev/null +++ b/app/assets/javascripts/content_editor/extensions/footnote_definition.js @@ -0,0 +1,21 @@ +import { mergeAttributes, Node } from '@tiptap/core'; +import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants'; + +export default Node.create({ + name: 'footnoteDefinition', + + content: 'paragraph', + + group: 'block', + + parseHTML() { + return [ + { tag: 'section.footnotes li' }, + { tag: '.footnote-backref', priority: PARSE_HTML_PRIORITY_HIGHEST, ignore: true }, + ]; + }, + + renderHTML({ HTMLAttributes }) { + return ['li', mergeAttributes(HTMLAttributes), 0]; + }, +}); diff --git a/app/assets/javascripts/content_editor/extensions/footnote_reference.js b/app/assets/javascripts/content_editor/extensions/footnote_reference.js new file mode 100644 index 00000000000..1ac8016f774 --- /dev/null +++ b/app/assets/javascripts/content_editor/extensions/footnote_reference.js @@ -0,0 +1,37 @@ +import { Node, mergeAttributes } from '@tiptap/core'; +import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants'; + +export default Node.create({ + name: 'footnoteReference', + + inline: true, + + group: 'inline', + + atom: true, + + draggable: true, + + selectable: true, + + addAttributes() { + return { + footnoteId: { + default: null, + parseHTML: (element) => element.querySelector('a').getAttribute('id'), + }, + footnoteNumber: { + default: null, + parseHTML: (element) => element.textContent, + }, + }; + }, + + parseHTML() { + return [{ tag: 'sup.footnote-ref', priority: PARSE_HTML_PRIORITY_HIGHEST }]; + }, + + renderHTML({ HTMLAttributes: { footnoteNumber, footnoteId, ...HTMLAttributes } }) { + return ['sup', mergeAttributes(HTMLAttributes), footnoteNumber]; + }, +}); diff --git a/app/assets/javascripts/content_editor/extensions/footnotes_section.js b/app/assets/javascripts/content_editor/extensions/footnotes_section.js new file mode 100644 index 00000000000..914a8934734 --- /dev/null +++ b/app/assets/javascripts/content_editor/extensions/footnotes_section.js @@ -0,0 +1,19 @@ +import { mergeAttributes, Node } from '@tiptap/core'; + +export default Node.create({ + name: 'footnotesSection', + + content: 'footnoteDefinition+', + + group: 'block', + + isolating: true, + + parseHTML() { + return [{ tag: 'section.footnotes > ol' }]; + }, + + renderHTML({ HTMLAttributes }) { + return ['ol', mergeAttributes(HTMLAttributes, { class: 'footnotes gl-font-sm' }), 0]; + }, +}); diff --git a/app/assets/javascripts/content_editor/services/create_content_editor.js b/app/assets/javascripts/content_editor/services/create_content_editor.js index 385f1c63801..f451357e211 100644 --- a/app/assets/javascripts/content_editor/services/create_content_editor.js +++ b/app/assets/javascripts/content_editor/services/create_content_editor.js @@ -19,6 +19,9 @@ import Dropcursor from '../extensions/dropcursor'; import Emoji from '../extensions/emoji'; import Figure from '../extensions/figure'; import FigureCaption from '../extensions/figure_caption'; +import FootnoteDefinition from '../extensions/footnote_definition'; +import FootnoteReference from '../extensions/footnote_reference'; +import FootnotesSection from '../extensions/footnotes_section'; import Frontmatter from '../extensions/frontmatter'; import Gapcursor from '../extensions/gapcursor'; import HardBreak from '../extensions/hard_break'; @@ -94,6 +97,9 @@ export const createContentEditor = ({ Emoji, Figure, FigureCaption, + FootnoteDefinition, + FootnoteReference, + FootnotesSection, Frontmatter, Gapcursor, HardBreak, diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js index 0dd3cb5b73f..38b0438fa3a 100644 --- a/app/assets/javascripts/content_editor/services/markdown_serializer.js +++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js @@ -17,6 +17,9 @@ import Division from '../extensions/division'; import Emoji from '../extensions/emoji'; import Figure from '../extensions/figure'; import FigureCaption from '../extensions/figure_caption'; +import FootnotesSection from '../extensions/footnotes_section'; +import FootnoteDefinition from '../extensions/footnote_definition'; +import FootnoteReference from '../extensions/footnote_reference'; import Frontmatter from '../extensions/frontmatter'; import HardBreak from '../extensions/hard_break'; import Heading from '../extensions/heading'; @@ -156,6 +159,15 @@ const defaultSerializerConfig = { state.write(`:${name}:`); }, + [FootnoteDefinition.name]: (state, node) => { + state.renderInline(node); + }, + [FootnoteReference.name]: (state, node) => { + state.write(`[^${node.attrs.footnoteNumber}]`); + }, + [FootnotesSection.name]: (state, node) => { + state.renderList(node, '', (index) => `[^${index + 1}]: `); + }, [Frontmatter.name]: (state, node) => { const { language } = node.attrs; const syntax = { diff --git a/app/assets/javascripts/ide/components/activity_bar.vue b/app/assets/javascripts/ide/components/activity_bar.vue index c71d911adfb..846b4d92724 100644 --- a/app/assets/javascripts/ide/components/activity_bar.vue +++ b/app/assets/javascripts/ide/components/activity_bar.vue @@ -63,7 +63,7 @@ export default { class="ide-sidebar-link js-ide-review-mode" @click.prevent="changedActivityView($event, $options.leftSidebarViews.review.name)" > - <gl-icon name="file-modified" /> + <gl-icon name="review-list" /> </button> </li> <li> diff --git a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js new file mode 100644 index 00000000000..cdd7a074f34 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js @@ -0,0 +1,27 @@ +import InputCopyToggleVisibility from './input_copy_toggle_visibility.vue'; + +export default { + component: InputCopyToggleVisibility, + title: 'vue_shared/components/form/input_copy_toggle_visibility', +}; + +const defaultProps = { + value: 'hR8x1fuJbzwu5uFKLf9e', + formInputGroupProps: { class: 'gl-form-input-xl' }, +}; + +const Template = (args, { argTypes }) => ({ + components: { InputCopyToggleVisibility }, + props: Object.keys(argTypes), + template: `<input-copy-toggle-visibility + :value="value" + :initial-visibility="initialVisibility" + :show-toggle-visibility-button="showToggleVisibilityButton" + :show-copy-button="showCopyButton" + :form-input-group-props="formInputGroupProps" + :copy-button-title="copyButtonTitle" + />`, +}); + +export const Default = Template.bind({}); +Default.args = defaultProps; diff --git a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue new file mode 100644 index 00000000000..36e3b46a43c --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue @@ -0,0 +1,124 @@ +<script> +import { GlFormInputGroup, GlFormGroup, GlButton, GlTooltipDirective } from '@gitlab/ui'; + +import { __ } from '~/locale'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; + +export default { + name: 'InputCopyToggleVisibility', + i18n: { + toggleVisibilityLabelHide: __('Click to hide'), + toggleVisibilityLabelReveal: __('Click to reveal'), + }, + components: { + GlFormInputGroup, + GlFormGroup, + GlButton, + ClipboardButton, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + value: { + type: String, + required: false, + default: '', + }, + initialVisibility: { + type: Boolean, + required: false, + default: false, + }, + showToggleVisibilityButton: { + type: Boolean, + required: false, + default: true, + }, + showCopyButton: { + type: Boolean, + required: false, + default: true, + }, + copyButtonTitle: { + type: String, + required: false, + default: __('Copy'), + }, + formInputGroupProps: { + type: Object, + required: false, + default() { + return {}; + }, + }, + }, + data() { + return { + valueIsVisible: this.initialVisibility, + }; + }, + computed: { + toggleVisibilityLabel() { + return this.valueIsVisible + ? this.$options.i18n.toggleVisibilityLabelHide + : this.$options.i18n.toggleVisibilityLabelReveal; + }, + toggleVisibilityIcon() { + return this.valueIsVisible ? 'eye-slash' : 'eye'; + }, + computedValueIsVisible() { + return !this.showToggleVisibilityButton || this.valueIsVisible; + }, + displayedValue() { + return this.computedValueIsVisible ? this.value : '*'.repeat(this.value.length || 20); + }, + }, + methods: { + handleToggleVisibilityButtonClick() { + this.valueIsVisible = !this.valueIsVisible; + + this.$emit('visibility-change', this.valueIsVisible); + }, + handleCopyButtonClick() { + this.$emit('copy'); + }, + handleFormInputCopy(event) { + if (this.computedValueIsVisible) { + return; + } + + event.clipboardData.setData('text/plain', this.value); + event.preventDefault(); + }, + }, +}; +</script> +<template> + <gl-form-group v-bind="$attrs"> + <gl-form-input-group + :value="displayedValue" + input-class="gl-font-monospace! gl-cursor-default!" + select-on-click + readonly + v-bind="formInputGroupProps" + @copy="handleFormInputCopy" + > + <template v-if="showToggleVisibilityButton || showCopyButton" #append> + <gl-button + v-if="showToggleVisibilityButton" + v-gl-tooltip.hover="toggleVisibilityLabel" + :aria-label="toggleVisibilityLabel" + :icon="toggleVisibilityIcon" + @click="handleToggleVisibilityButtonClick" + /> + <clipboard-button + v-if="showCopyButton" + :text="value" + :title="copyButtonTitle" + @click="handleCopyButtonClick" + /> + </template> + </gl-form-input-group> + </gl-form-group> +</template> diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 277e0ccbf23..e0126373864 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -1084,16 +1084,6 @@ module Ci runner&.instance_type? end - def job_variables_attributes - strong_memoize(:job_variables_attributes) do - job_variables.map do |variable| - variable.attributes.except('id', 'job_id', 'encrypted_value', 'encrypted_value_iv').tap do |attrs| - attrs[:value] = variable.value - end - end - end - end - protected def run_status_commit_hooks! diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb index 4b592bbbb40..ebb07de9d29 100644 --- a/app/services/ci/retry_build_service.rb +++ b/app/services/ci/retry_build_service.rb @@ -7,7 +7,7 @@ module Ci allow_failure stage stage_id stage_idx trigger_request yaml_variables when environment coverage_regex description tag_list protected needs_attributes - resource_group scheduling_type job_variables_attributes].freeze + resource_group scheduling_type].freeze end def self.extra_accessors |