mirror of
https://github.com/directus/directus.git
synced 2026-01-31 16:48:08 -05:00
Add file library integration for WYSIWYG interface (#3263)
* Add file library integration for WYSIWYG interface * Fix typing; Prevent selecting non-image on image field * Allow imageToken in the interface; addTokenToURL() replace token if presents * Add file library integration for WYSIWYG interface * Fix typing; Prevent selecting non-image on image field * Allow imageToken in the interface; addTokenToURL() replace token if presents Co-authored-by: Nitwel <nitwel@arcor.de>
This commit is contained in:
@@ -272,5 +272,15 @@ export default defineInterface(({ i18n }) => ({
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'imageToken',
|
||||
name: i18n.t('interfaces.markdown.imageToken'),
|
||||
type: 'string',
|
||||
meta: {
|
||||
note: i18n.t('interfaces.markdown.imageToken_label'),
|
||||
width: 'full',
|
||||
interface: 'text-input',
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
@@ -175,7 +175,11 @@ body.dark .tox .tox-toolbar__overflow {
|
||||
/* Modal */
|
||||
|
||||
.tox .tox-dialog-wrap__backdrop {
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
background-color: var(--v-overlay-color);
|
||||
}
|
||||
|
||||
.tox.tox-tinymce-aux {
|
||||
z-index: 400;
|
||||
}
|
||||
|
||||
.tox .tox-dialog {
|
||||
|
||||
@@ -8,6 +8,17 @@
|
||||
@onFocusIn="setFocus(true)"
|
||||
@onFocusOut="setFocus(false)"
|
||||
/>
|
||||
<v-dialog :active="_imageDialogOpen" @toggle="unsetImageUploadHandler" @esc="unsetImageUploadHandler">
|
||||
<v-card>
|
||||
<v-card-title>{{ $t('upload_from_device') }}</v-card-title>
|
||||
<v-card-text>
|
||||
<v-upload @input="onImageUpload" :multiple="false" from-library from-url />
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-button @click="unsetImageUploadHandler" secondary>{{ $t('cancel') }}</v-button>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -37,6 +48,9 @@ import Editor from '@tinymce/tinymce-vue';
|
||||
|
||||
import getEditorStyles from './get-editor-styles';
|
||||
|
||||
import { getPublicURL } from '@/utils/get-root-path';
|
||||
import { addTokenToURL } from '@/api';
|
||||
|
||||
type CustomFormat = {
|
||||
title: string;
|
||||
inline: string;
|
||||
@@ -89,9 +103,16 @@ export default defineComponent({
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
imageToken: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const editorElement = ref<Vue | null>(null);
|
||||
const imageUploadHandler = ref<CallableFunction | null>(null);
|
||||
|
||||
const _imageDialogOpen = computed(() => !!imageUploadHandler.value);
|
||||
|
||||
const _value = computed({
|
||||
get() {
|
||||
@@ -131,11 +152,56 @@ export default defineComponent({
|
||||
extended_valid_elements: 'audio[loop],source',
|
||||
toolbar: toolbarString,
|
||||
style_formats: styleFormats,
|
||||
file_picker_types: 'image media',
|
||||
file_picker_callback: setImageUploadHandler,
|
||||
urlconverter_callback: urlConverter,
|
||||
...(props.tinymceOverrides || {}),
|
||||
};
|
||||
});
|
||||
|
||||
return { editorElement, editorOptions, _value, setFocus };
|
||||
return {
|
||||
editorElement,
|
||||
editorOptions,
|
||||
_value,
|
||||
setFocus,
|
||||
onImageUpload,
|
||||
unsetImageUploadHandler,
|
||||
_imageDialogOpen,
|
||||
};
|
||||
|
||||
function onImageUpload(file: Record<string, any>) {
|
||||
if (imageUploadHandler.value) imageUploadHandler.value(file);
|
||||
unsetImageUploadHandler();
|
||||
}
|
||||
|
||||
function setImageUploadHandler(cb: CallableFunction, value: any, meta: Record<string, any>) {
|
||||
imageUploadHandler.value = (result: Record<string, any>) => {
|
||||
if (meta.filetype === 'image' && !/^image\//.test(result.type)) return;
|
||||
|
||||
const imageUrl = getPublicURL() + 'assets/' + result.id;
|
||||
|
||||
cb(imageUrl, {
|
||||
alt: result.title,
|
||||
title: result.title,
|
||||
width: (result.width || '').toString(),
|
||||
height: (result.height || '').toString(),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function urlConverter(url: string, node: string) {
|
||||
if (url && props.imageToken && ['img', 'source', 'poster', 'audio'].includes(node)) {
|
||||
const baseUrl = getPublicURL() + 'assets/';
|
||||
if (url.includes(baseUrl)) {
|
||||
url = addTokenToURL(url, props.imageToken);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function unsetImageUploadHandler() {
|
||||
imageUploadHandler.value = null;
|
||||
}
|
||||
|
||||
function setFocus(val: boolean) {
|
||||
if (editorElement.value == null) return;
|
||||
|
||||
Reference in New Issue
Block a user