Refactor adding tags to an event
Also refactor extracting tags from content, now uses Pleroma's Formatter Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -72,6 +72,7 @@ export default class App extends Vue {
|
||||
@import "~bulma/sass/components/modal.sass";
|
||||
@import "~bulma/sass/components/navbar.sass";
|
||||
@import "~bulma/sass/components/pagination.sass";
|
||||
@import "~bulma/sass/components/dropdown.sass";
|
||||
@import "~bulma/sass/elements/box.sass";
|
||||
@import "~bulma/sass/elements/button.sass";
|
||||
@import "~bulma/sass/elements/container.sass";
|
||||
@@ -91,9 +92,11 @@ export default class App extends Vue {
|
||||
@import "~buefy/src/scss/components/datepicker";
|
||||
@import "~buefy/src/scss/components/notices";
|
||||
@import "~buefy/src/scss/components/dropdown";
|
||||
@import "~buefy/src/scss/components/autocomplete";
|
||||
@import "~buefy/src/scss/components/form";
|
||||
@import "~buefy/src/scss/components/modal";
|
||||
@import "~buefy/src/scss/components/tag";
|
||||
@import "~buefy/src/scss/components/taginput";
|
||||
@import "~buefy/src/scss/components/upload";
|
||||
|
||||
.router-enter-active,
|
||||
|
||||
54
js/src/components/Event/TagInput.vue
Normal file
54
js/src/components/Event/TagInput.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<b-field label="Enter some tags">
|
||||
<b-taginput
|
||||
v-model="tags"
|
||||
:data="filteredTags"
|
||||
autocomplete
|
||||
:allow-new="true"
|
||||
:field="path"
|
||||
icon="label"
|
||||
placeholder="Add a tag"
|
||||
@typing="getFilteredTags">
|
||||
</b-taginput>
|
||||
</b-field>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
||||
import { get } from 'lodash';
|
||||
import { ITag } from '@/types/tag.model';
|
||||
@Component
|
||||
export default class TagInput extends Vue {
|
||||
|
||||
@Prop({ required: false, default: () => [] }) data!: object[];
|
||||
@Prop({ required: true, default: 'value' }) path!: string;
|
||||
@Prop({ required: true }) value!: string;
|
||||
|
||||
filteredTags: object[] = [];
|
||||
tags: object[] = [];
|
||||
|
||||
getFilteredTags(text) {
|
||||
this.filteredTags = this.data.filter((option) => {
|
||||
return get(option, this.path)
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.indexOf(text.toLowerCase()) >= 0;
|
||||
});
|
||||
}
|
||||
|
||||
@Watch('tags')
|
||||
onTagsChanged (tags) {
|
||||
const tagEntities = tags.map((tag) => {
|
||||
if (TagInput.isTag(tag)) {
|
||||
return tag;
|
||||
}
|
||||
return { title: tag, slug: tag } as ITag;
|
||||
});
|
||||
console.log('tags changed', tagEntities);
|
||||
this.$emit('input', tagEntities);
|
||||
}
|
||||
|
||||
static isTag(x: any): x is ITag {
|
||||
return x.slug !== undefined;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -143,7 +143,8 @@ export const CREATE_EVENT = gql`
|
||||
$organizerActorId: ID!,
|
||||
$category: String!,
|
||||
$beginsOn: DateTime!,
|
||||
$picture: PictureInput!
|
||||
$picture: PictureInput,
|
||||
$tags: [String]
|
||||
) {
|
||||
createEvent(
|
||||
title: $title,
|
||||
@@ -151,7 +152,8 @@ export const CREATE_EVENT = gql`
|
||||
beginsOn: $beginsOn,
|
||||
organizerActorId: $organizerActorId,
|
||||
category: $category,
|
||||
picture: $picture
|
||||
picture: $picture,
|
||||
tags: $tags
|
||||
) {
|
||||
id,
|
||||
uuid,
|
||||
@@ -203,8 +205,10 @@ export const LEAVE_EVENT = gql`
|
||||
export const DELETE_EVENT = gql`
|
||||
mutation DeleteEvent($id: Int!, $actorId: Int!) {
|
||||
deleteEvent(
|
||||
id: $id,
|
||||
eventId: $id,
|
||||
actorId: $actorId
|
||||
)
|
||||
) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
16
js/src/graphql/tags.ts
Normal file
16
js/src/graphql/tags.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
export const TAGS = gql`
|
||||
query {
|
||||
tags {
|
||||
id,
|
||||
related {
|
||||
id,
|
||||
slug,
|
||||
title
|
||||
}
|
||||
slug,
|
||||
title
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -75,6 +75,8 @@ export interface IEvent {
|
||||
onlineAddress?: string;
|
||||
phoneAddress?: string;
|
||||
physicalAddress?: IAddress;
|
||||
|
||||
tags: ITag[];
|
||||
}
|
||||
|
||||
|
||||
@@ -99,4 +101,5 @@ export class EventModel implements IEvent {
|
||||
onlineAddress: string = '';
|
||||
phoneAddress: string = '';
|
||||
picture: IAbstractPicture|null = null;
|
||||
tags: ITag[] = [];
|
||||
}
|
||||
|
||||
@@ -6,10 +6,14 @@
|
||||
<div v-if="$apollo.loading">Loading...</div>
|
||||
<div class="columns is-centered" v-else>
|
||||
<form class="column is-two-thirds-desktop" @submit="createEvent">
|
||||
<picture-upload v-model="pictureFile" />
|
||||
|
||||
<b-field :label="$gettext('Title')">
|
||||
<b-input aria-required="true" required v-model="event.title" maxlength="64" />
|
||||
</b-field>
|
||||
|
||||
<tag-input v-model="event.tags" :data="tags" path="title" />
|
||||
|
||||
<date-time-picker v-model="event.beginsOn" :label="$gettext('Starts on…')" :step="15"/>
|
||||
<date-time-picker v-model="event.endsOn" :label="$gettext('Ends on…')" :step="15" />
|
||||
|
||||
@@ -28,8 +32,6 @@
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<picture-upload v-model="pictureFile" />
|
||||
|
||||
<button class="button is-primary">
|
||||
<translate>Create my event</translate>
|
||||
</button>
|
||||
@@ -52,13 +54,19 @@ import { IPerson, Person } from '@/types/actor';
|
||||
import PictureUpload from '@/components/PictureUpload.vue';
|
||||
import Editor from '@/components/Editor.vue';
|
||||
import DateTimePicker from '@/components/Event/DateTimePicker.vue';
|
||||
import TagInput from '@/components/Event/TagInput.vue';
|
||||
import { TAGS } from '@/graphql/tags';
|
||||
import { ITag } from '@/types/tag.model';
|
||||
|
||||
@Component({
|
||||
components: { DateTimePicker, PictureUpload, Editor },
|
||||
components: { TagInput, DateTimePicker, PictureUpload, Editor },
|
||||
apollo: {
|
||||
loggedPerson: {
|
||||
query: LOGGED_PERSON,
|
||||
},
|
||||
tags: {
|
||||
query: TAGS,
|
||||
},
|
||||
},
|
||||
})
|
||||
export default class CreateEvent extends Vue {
|
||||
@@ -123,11 +131,12 @@ export default class CreateEvent extends Vue {
|
||||
* Transform general variables
|
||||
*/
|
||||
let pictureObj = {};
|
||||
let obj = {
|
||||
const obj = {
|
||||
organizerActorId: this.loggedPerson.id,
|
||||
beginsOn: this.event.beginsOn.toISOString(),
|
||||
tags: this.event.tags.map((tag: ITag) => tag.title),
|
||||
};
|
||||
let res = Object.assign({}, this.event, obj);
|
||||
const res = Object.assign({}, this.event, obj);
|
||||
|
||||
/**
|
||||
* Transform picture files
|
||||
|
||||
Reference in New Issue
Block a user