Commit 359961ca authored by Enrique Alcantara's avatar Enrique Alcantara Committed by Himanshu Kapoor

Add button to insert images in content editor

Add a toolbar dropdown button to allow insert an image
by introducing a URL or using a file upload
control.

Changelog: added
parent 01bd975e
<script>
import {
GlDropdown,
GlDropdownForm,
GlButton,
GlFormInputGroup,
GlDropdownDivider,
GlDropdownItem,
GlTooltipDirective as GlTooltip,
} from '@gitlab/ui';
import { Editor as TiptapEditor } from '@tiptap/vue-2';
import { acceptedMimes } from '../extensions/image';
import { getImageAlt } from '../services/utils';
export default {
components: {
GlDropdown,
GlDropdownForm,
GlFormInputGroup,
GlDropdownDivider,
GlDropdownItem,
GlButton,
},
directives: {
GlTooltip,
},
props: {
tiptapEditor: {
type: TiptapEditor,
required: true,
},
},
data() {
return {
imgSrc: '',
};
},
methods: {
cleanFields() {
this.imgSrc = '';
this.$refs.fileUpload.value = '';
},
insertImage() {
const alt = getImageAlt(this.imgSrc);
this.tiptapEditor.chain().focus().setImage({ src: this.imgSrc, alt }).run();
this.cleanFields();
this.emitExecute();
},
emitExecute(source = 'url') {
this.$emit('execute', { contentType: 'image', value: source });
},
openFileUpload() {
this.$refs.fileUpload.click();
},
onUploadChange(e) {
this.tiptapEditor.chain().focus().uploadImage({ file: e.target.files[0] }).run();
this.cleanFields();
this.emitExecute('upload');
},
},
acceptedMimes,
};
</script>
<template>
<gl-dropdown
v-gl-tooltip
:aria-label="__('Insert image')"
:title="__('Insert image')"
size="small"
category="tertiary"
icon="media"
@hidden="cleanFields()"
>
<gl-dropdown-form class="gl-px-3!">
<gl-form-input-group v-model="imgSrc" :placeholder="__('Image URL')">
<template #append>
<gl-button variant="confirm" @click="insertImage">{{ __('Insert') }}</gl-button>
</template>
</gl-form-input-group>
</gl-dropdown-form>
<gl-dropdown-divider />
<gl-dropdown-item @click="openFileUpload">
{{ __('Upload image') }}
</gl-dropdown-item>
<input
ref="fileUpload"
type="file"
name="content_editor_image"
:accept="$options.acceptedMimes"
class="gl-display-none"
@change="onUploadChange"
/>
</gl-dropdown>
</template>
......@@ -4,6 +4,7 @@ import { CONTENT_EDITOR_TRACKING_LABEL, TOOLBAR_CONTROL_TRACKING_ACTION } from '
import { ContentEditor } from '../services/content_editor';
import Divider from './divider.vue';
import ToolbarButton from './toolbar_button.vue';
import ToolbarImageButton from './toolbar_image_button.vue';
import ToolbarLinkButton from './toolbar_link_button.vue';
import ToolbarTableButton from './toolbar_table_button.vue';
import ToolbarTextStyleDropdown from './toolbar_text_style_dropdown.vue';
......@@ -18,6 +19,7 @@ export default {
ToolbarTextStyleDropdown,
ToolbarLinkButton,
ToolbarTableButton,
ToolbarImageButton,
Divider,
},
mixins: [trackingMixin],
......@@ -89,6 +91,12 @@ export default {
@execute="trackToolbarControlExecution"
/>
<divider />
<toolbar-image-button
ref="imageButton"
data-testid="image"
:tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
data-testid="blockquote"
content-type="blockquote"
......@@ -140,3 +148,8 @@ export default {
/>
</div>
</template>
<style>
.gl-spinner-container {
text-align: left;
}
</style>
......@@ -17501,6 +17501,9 @@ msgstr ""
msgid "Input the remote repository URL"
msgstr ""
msgid "Insert"
msgstr ""
msgid "Insert a %{rows}x%{cols} table."
msgstr ""
......@@ -35322,6 +35325,9 @@ msgstr ""
msgid "Upload file"
msgstr ""
msgid "Upload image"
msgstr ""
msgid "Upload license"
msgstr ""
......
......@@ -51,6 +51,7 @@ describe('content_editor/components/top_toolbar', () => {
${'code-block'} | ${{ contentType: 'codeBlock', iconName: 'doc-code', label: 'Insert a code block', editorCommand: 'toggleCodeBlock' }}
${'text-styles'} | ${{}}
${'link'} | ${{}}
${'image'} | ${{}}
`('given a $testId toolbar control', ({ testId, controlProps }) => {
beforeEach(() => {
buildWrapper();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment