Merge branch 'bug/fixes' into 'master'

Bug/fixes

See merge request framasoft/mobilizon!233
This commit is contained in:
Thomas Citharel 2019-10-10 10:31:43 +02:00
commit 89b599d14b
5 changed files with 216 additions and 173 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <div v-if="editor">
<div class="editor" id="tiptab-editor" :data-actor-id="currentActor && currentActor.id"> <div class="editor" id="tiptab-editor" :data-actor-id="currentActor && currentActor.id">
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive, focused }"> <editor-menu-bar :editor="editor" v-slot="{ commands, isActive, focused }">
<div class="menubar bar-is-hidden" :class="{ 'is-focused': focused }"> <div class="menubar bar-is-hidden" :class="{ 'is-focused': focused }">
@ -8,6 +8,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.bold() }" :class="{ 'is-active': isActive.bold() }"
@click="commands.bold" @click="commands.bold"
type="button"
> >
<b-icon icon="format-bold" /> <b-icon icon="format-bold" />
</button> </button>
@ -16,6 +17,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.italic() }" :class="{ 'is-active': isActive.italic() }"
@click="commands.italic" @click="commands.italic"
type="button"
> >
<b-icon icon="format-italic" /> <b-icon icon="format-italic" />
</button> </button>
@ -24,6 +26,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.underline() }" :class="{ 'is-active': isActive.underline() }"
@click="commands.underline" @click="commands.underline"
type="button"
> >
<b-icon icon="format-underline" /> <b-icon icon="format-underline" />
</button> </button>
@ -32,6 +35,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.heading({ level: 1 }) }" :class="{ 'is-active': isActive.heading({ level: 1 }) }"
@click="commands.heading({ level: 1 })" @click="commands.heading({ level: 1 })"
type="button"
> >
<b-icon icon="format-header-1" /> <b-icon icon="format-header-1" />
</button> </button>
@ -40,6 +44,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.heading({ level: 2 }) }" :class="{ 'is-active': isActive.heading({ level: 2 }) }"
@click="commands.heading({ level: 2 })" @click="commands.heading({ level: 2 })"
type="button"
> >
<b-icon icon="format-header-2" /> <b-icon icon="format-header-2" />
</button> </button>
@ -48,13 +53,24 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.heading({ level: 3 }) }" :class="{ 'is-active': isActive.heading({ level: 3 }) }"
@click="commands.heading({ level: 3 })" @click="commands.heading({ level: 3 })"
type="button"
> >
<b-icon icon="format-header-3" /> <b-icon icon="format-header-3" />
</button> </button>
<button
class="menubar__button"
@click="showLinkMenu(commands.link, isActive.link())"
:class="{ 'is-active': isActive.link() }"
type="button"
>
<b-icon icon="link" />
</button>
<button <button
class="menubar__button" class="menubar__button"
@click="showImagePrompt(commands.image)" @click="showImagePrompt(commands.image)"
type="button"
> >
<b-icon icon="image" /> <b-icon icon="image" />
</button> </button>
@ -63,6 +79,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.bullet_list() }" :class="{ 'is-active': isActive.bullet_list() }"
@click="commands.bullet_list" @click="commands.bullet_list"
type="button"
> >
<b-icon icon="format-list-bulleted" /> <b-icon icon="format-list-bulleted" />
</button> </button>
@ -71,6 +88,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.ordered_list() }" :class="{ 'is-active': isActive.ordered_list() }"
@click="commands.ordered_list" @click="commands.ordered_list"
type="button"
> >
<b-icon icon="format-list-numbered" /> <b-icon icon="format-list-numbered" />
</button> </button>
@ -79,6 +97,7 @@
class="menubar__button" class="menubar__button"
:class="{ 'is-active': isActive.blockquote() }" :class="{ 'is-active': isActive.blockquote() }"
@click="commands.blockquote" @click="commands.blockquote"
type="button"
> >
<b-icon icon="format-quote-close" /> <b-icon icon="format-quote-close" />
</button> </button>
@ -86,6 +105,7 @@
<button <button
class="menubar__button" class="menubar__button"
@click="commands.undo" @click="commands.undo"
type="button"
> >
<b-icon icon="undo" /> <b-icon icon="undo" />
</button> </button>
@ -93,6 +113,7 @@
<button <button
class="menubar__button" class="menubar__button"
@click="commands.redo" @click="commands.redo"
type="button"
> >
<b-icon icon="redo" /> <b-icon icon="redo" />
</button> </button>
@ -100,34 +121,6 @@
</div> </div>
</editor-menu-bar> </editor-menu-bar>
<editor-menu-bubble class="menububble" :editor="editor" @hide="hideLinkMenu" v-slot="{ commands, isActive, getMarkAttrs, menu }">
<div
class="menububble"
:class="{ 'is-active': menu.isActive }"
:style="`left: ${menu.left}px; bottom: ${menu.bottom}px;`"
>
<form class="menububble__form" v-if="linkMenuIsActive" @submit.prevent="setLinkUrl(commands.link, linkUrl)">
<input class="menububble__input" type="text" v-model="linkUrl" placeholder="https://" ref="linkInput" @keydown.esc="hideLinkMenu"/>
<button class="menububble__button" @click="setLinkUrl(commands.link, null)" type="button">
<b-icon icon="delete" />
</button>
</form>
<template v-else>
<button
class="menububble__button"
@click="showLinkMenu(getMarkAttrs('link'))"
:class="{ 'is-active': isActive.link() }"
>
<span>{{ isActive.link() ? 'Update Link' : 'Add Link'}}</span>
<b-icon icon="link" />
</button>
</template>
</div>
</editor-menu-bubble>
<editor-content class="editor__content" :editor="editor" /> <editor-content class="editor__content" :editor="editor" />
</div> </div>
<div class="suggestion-list" v-show="showSuggestions" ref="suggestions"> <div class="suggestion-list" v-show="showSuggestions" ref="suggestions">
@ -186,18 +179,12 @@ import { CURRENT_ACTOR_CLIENT } from '@/graphql/actor';
}, },
}, },
}) })
export default class CreateEvent extends Vue { export default class EditorComponent extends Vue {
@Prop({ required: true }) value!: String; @Prop({ required: true }) value!: string;
currentActor!: IPerson; currentActor!: IPerson;
editor: Editor = null; editor: Editor|null = null;
/**
* Editor Link
*/
linkUrl!: string|null;
linkMenuIsActive: boolean = false;
/** /**
* Editor Suggestions * Editor Suggestions
@ -323,27 +310,28 @@ export default class CreateEvent extends Vue {
@Watch('value') @Watch('value')
onValueChanged(val: string) { onValueChanged(val: string) {
if (!this.editor) return;
if (val !== this.editor.getHTML()) { if (val !== this.editor.getHTML()) {
this.editor.setContent(val); this.editor.setContent(val);
} }
} }
showLinkMenu(attrs: any) { showLinkMenu(command, active: boolean) {
this.linkUrl = attrs.href; if (!this.editor) return;
this.linkMenuIsActive = true; if (active) return command({ href: null });
this.$nextTick(() => { this.$buefy.dialog.prompt({
const linkInput = this.$refs.linkInput as HTMLElement; message: this.$t('Enter the link URL') as string,
linkInput.focus(); inputAttrs: {
}); type: 'url',
} },
hideLinkMenu() { // @ts-ignore https://github.com/buefy/buefy/commit/62539ac4026c8610509850a3a973fc283bac50ef#diff-02b38ee0a78d8316f075e520b3a442ae
this.linkUrl = ''; trapFocus: true,
this.linkMenuIsActive = false; onConfirm: (value) => {
} command({ href: value });
setLinkUrl(command, url: string) { if (!this.editor) return;
command({ href: url });
this.hideLinkMenu();
this.editor.focus(); this.editor.focus();
},
});
} }
upHandler() { upHandler() {
@ -378,6 +366,7 @@ export default class CreateEvent extends Vue {
label: actor.name, label: actor.name,
}, },
}); });
if (!this.editor) return;
this.editor.focus(); this.editor.focus();
} }
@ -447,6 +436,7 @@ export default class CreateEvent extends Vue {
} }
beforeDestroy() { beforeDestroy() {
if (!this.editor) return;
this.editor.destroy(); this.editor.destroy();
} }
} }
@ -539,10 +529,6 @@ export default class CreateEvent extends Vue {
margin: 0; margin: 0;
} }
a {
color: inherit;
}
blockquote { blockquote {
border-left: 3px solid rgba($color-black, 0.1); border-left: 3px solid rgba($color-black, 0.1);
color: rgba($color-black, 0.8); color: rgba($color-black, 0.8);

View File

@ -25,7 +25,13 @@ export default {
</docs> </docs>
<template> <template>
<b-field :label="$t('Enter some tags')"> <b-field>
<template slot="label">
{{ $t('Add some tags') }}
<b-tooltip type="is-dark" :label="$t('You can add tags by hitting the Enter key or by adding a comma')">
<b-icon size="is-small" icon="help-circle-outline"></b-icon>
</b-tooltip>
</template>
<b-taginput <b-taginput
v-model="tagsStrings" v-model="tagsStrings"
:data="filteredTags" :data="filteredTags"

28
js/src/typings/tiptap-extensions.d.ts vendored Normal file
View File

@ -0,0 +1,28 @@
declare module 'tiptap-extensions' {
import Vue from 'vue';
export class Blockquote {}
export class CodeBlock {}
export class HardBreak {}
export class Heading {
constructor(object: object)
}
export class OrderedList {}
export class BulletList {}
export class ListItem {}
export class TodoItem {}
export class TodoList {}
export class Bold {}
export class Code {}
export class Italic {}
export class Link {}
export class Strike {}
export class Underline {}
export class History {}
export class Placeholder {
constructor(object: object)
}
export class Mention {
constructor(object: object)
}
}

24
js/src/typings/tiptap.d.ts vendored Normal file
View File

@ -0,0 +1,24 @@
declare module 'tiptap' {
import Vue from 'vue';
export class Editor {
public constructor({});
public setOptions({}): void;
public setContent(content: string): void;
public focus(): void;
public getHTML(): string;
public destroy(): void;
}
export class Node {}
export class Plugin {
public constructor({});
}
export class EditorMenuBar extends Vue {}
export class EditorContent extends Vue {}
export class EditorMenuBubble extends Vue {}
}

View File

@ -1,4 +1,3 @@
import {ParticipantRole} from "@/types/event.model";
<template> <template>
<section> <section>
<div class="container"> <div class="container">
@ -246,7 +245,7 @@ import {
import { CURRENT_ACTOR_CLIENT, IDENTITIES, LOGGED_USER_DRAFTS, LOGGED_USER_PARTICIPATIONS } from '@/graphql/actor'; import { CURRENT_ACTOR_CLIENT, IDENTITIES, LOGGED_USER_DRAFTS, LOGGED_USER_PARTICIPATIONS } from '@/graphql/actor';
import { IPerson, Person } from '@/types/actor'; import { IPerson, Person } from '@/types/actor';
import PictureUpload from '@/components/PictureUpload.vue'; import PictureUpload from '@/components/PictureUpload.vue';
import Editor from '@/components/Editor.vue'; import EditorComponent from '@/components/Editor.vue';
import DateTimePicker from '@/components/Event/DateTimePicker.vue'; import DateTimePicker from '@/components/Event/DateTimePicker.vue';
import TagInput from '@/components/Event/TagInput.vue'; import TagInput from '@/components/Event/TagInput.vue';
import { TAGS } from '@/graphql/tags'; import { TAGS } from '@/graphql/tags';
@ -257,7 +256,7 @@ import IdentityPickerWrapper from '@/views/Account/IdentityPickerWrapper.vue';
import { RouteName } from '@/router'; import { RouteName } from '@/router';
@Component({ @Component({
components: { IdentityPickerWrapper, AddressAutoComplete, TagInput, DateTimePicker, PictureUpload, Editor }, components: { IdentityPickerWrapper, AddressAutoComplete, TagInput, DateTimePicker, PictureUpload, Editor: EditorComponent },
apollo: { apollo: {
currentActor: { currentActor: {
query: CURRENT_ACTOR_CLIENT, query: CURRENT_ACTOR_CLIENT,