Add dynamic project entry display and creation to frontend

This commit is contained in:
Ramon Wenger 2019-03-13 17:55:13 +01:00
parent 262a2b8cef
commit 8754900e84
10 changed files with 114 additions and 17 deletions

View File

@ -3,7 +3,7 @@
<h3 class="text-form-with-help-text__heading"><span class="text-form-with-help-text__title">{{title}}</span> <h3 class="text-form-with-help-text__heading"><span class="text-form-with-help-text__title">{{title}}</span>
<info-icon class="text-form-with-help-text__icon"></info-icon> <info-icon class="text-form-with-help-text__icon"></info-icon>
</h3> </h3>
<text-form @text-change-value="$emit('change', $event.target.value)" :value="v"></text-form> <text-form @text-change-value="$emit('change', $event)" :value="v"></text-form>
</div> </div>
</template> </template>

View File

@ -6,14 +6,15 @@
import AddWidget from '@/components/AddWidget'; import AddWidget from '@/components/AddWidget';
export default { export default {
props: ['project'],
components: { components: {
AddWidget AddWidget
}, },
methods: { methods: {
addProjectEntry() { addProjectEntry() {
console.log('click'); this.$store.dispatch('addProjectEntry', this.project);
this.$store.dispatch('addProjectEntry', '');
} }
} }
} }

View File

@ -1,13 +1,17 @@
<template> <template>
<modal :hide-header="true"> <modal :hide-header="true">
<div class="project-entry-modal"> <div class="project-entry-modal">
<text-form-with-help-text title="Tätigkeit" :value="value"> <text-form-with-help-text title="Tätigkeit" :value="activity" @change="activity = $event">
</text-form-with-help-text> </text-form-with-help-text>
<text-form-with-help-text title="Reflexion" :value="value"> <text-form-with-help-text title="Reflexion" :value="reflection" @change="reflection = $event">
</text-form-with-help-text> </text-form-with-help-text>
<text-form-with-help-text title="Nächste Schritte" :value="value"> <text-form-with-help-text title="Nächste Schritte" :value="nextSteps" @change="nextSteps = $event">
</text-form-with-help-text> </text-form-with-help-text>
</div> </div>
<div slot="footer">
<a class="button button--primary" data-cy="modal-save-button" v-on:click="save">Speichern</a>
<a class="button" v-on:click="hideModal">Abbrechen</a>
</div>
</modal> </modal>
</template> </template>
@ -15,15 +19,65 @@
import Modal from '@/components/Modal'; import Modal from '@/components/Modal';
import TextFormWithHelpText from '@/components/content-forms/TextFormWithHelpText'; import TextFormWithHelpText from '@/components/content-forms/TextFormWithHelpText';
import NEW_PROJECT_ENTRY_MUTATION from '@/graphql/gql/mutations/addProjectEntry.gql';
import PROJECT_QUERY from '@/graphql/gql/projectQuery.gql';
export default { export default {
components: { components: {
Modal, Modal,
TextFormWithHelpText TextFormWithHelpText
}, },
computed: {
project() {
return this.$store.state.parentProject;
},
slug() {
return this.$route.params.slug;
}
},
methods: {
save() {
this.$apollo.mutate({
mutation: NEW_PROJECT_ENTRY_MUTATION,
variables: {
input: {
projectEntry: Object.assign({}, {
nextSteps: this.nextSteps,
activity: this.activity,
reflection: this.reflection,
project: this.project
})
}
},
update: (store, {data: {addProjectEntry: {projectEntry}}}) => {
const query = PROJECT_QUERY;
const variables = {slug: this.slug};
const data = store.readQuery({query, variables});
if (data.project && data.project.entries) {
data.project.entries.edges.unshift({
node: projectEntry,
__typename: 'ProjectEntryNode'
});
store.writeQuery({query, variables, data});
}
}
}).then(() => {
this.hideModal();
});
},
hideModal() {
this.$store.dispatch('hideModal');
}
},
data() { data() {
return { return {
value: '' activity: '',
reflection: '',
nextSteps: ''
} }
} }
} }

View File

@ -2,27 +2,30 @@
<div class="project-entry"> <div class="project-entry">
<h3 class="project-entry__heading">Tätigkeit</h3> <h3 class="project-entry__heading">Tätigkeit</h3>
<p class="project-entry__paragraph"> <p class="project-entry__paragraph">
Ich führe das Interview mit meiner Kollegin durch. {{activity}}
</p> </p>
<h3 class="project-entry__heading">Reflexion</h3> <h3 class="project-entry__heading">Reflexion</h3>
<p class="project-entry__paragraph"> <p class="project-entry__paragraph">
Da ich geeignete Fragen hatte, konnte meine Kollegin umfangreiche Antworten zum Thema geben. Die Eingangshalle {{reflection}}
eignete sich nicht als Interviewort, da es viele Nebengeräusche hatte. Wir fanden aber dann ein freies
Klassenzimmer. Nicht nur die Fragen sind wichtig. Auch die Ortswahl, wo man das Interview aufzeichnen möchte,
ist sehr wichtig für ein erfolgreiches Interview.
</p> </p>
<h3 class="project-entry__heading"> <h3 class="project-entry__heading">
Nächste Schritte Nächste Schritte
</h3> </h3>
<p class="project-entry__paragraph"> <p class="project-entry__paragraph">
Interview im Raum Mein Lehrbetrieb ablegen. {{nextSteps}}
</p> </p>
<div class="project-entry__date"> <div class="project-entry__date">
21. Juni 2018 {{created | date }}
</div> </div>
</div> </div>
</template> </template>
<script>
export default {
props: ['activity', 'reflection', 'nextSteps', 'created']
}
</script>
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/styles/_variables.scss"; @import "@/styles/_variables.scss";
@import "@/styles/_functions.scss"; @import "@/styles/_functions.scss";

View File

@ -0,0 +1,9 @@
import moment from 'moment';
moment.locale('de');
export const dateFilter = value => {
if (value) {
return moment(String(value)).format('DD. MMMM YYYY');
}
};

View File

@ -0,0 +1,7 @@
fragment ProjectEntryParts on ProjectEntryNode {
id
activity
reflection
nextSteps
created
}

View File

@ -0,0 +1,9 @@
#import "../fragments/projectEntryParts.gql"
mutation AddProjectEntryMutation($input: AddProjectEntryInput!) {
addProjectEntry(input: $input) {
projectEntry {
...ProjectEntryParts
}
errors
}
}

View File

@ -1,6 +1,15 @@
#import "./fragments/projectParts.gql" #import "./fragments/projectParts.gql"
#import "./fragments/projectEntryParts.gql"
query ProjectQuery($id: ID, $slug: String){ query ProjectQuery($id: ID, $slug: String){
project(slug: $slug, id: $id) { project(slug: $slug, id: $id) {
...ProjectParts ...ProjectParts
entries {
edges {
node {
...ProjectEntryParts
}
}
}
} }
} }

View File

@ -10,6 +10,7 @@ import router from './router'
import store from '@/store/index' import store from '@/store/index'
import VueScrollTo from 'vue-scrollto'; import VueScrollTo from 'vue-scrollto';
import VueAnalytics from 'vue-analytics'; import VueAnalytics from 'vue-analytics';
import {dateFilter} from './filters/date-filter'
Vue.config.productionTip = false; Vue.config.productionTip = false;
@ -73,6 +74,8 @@ const apolloProvider = new VueApollo({
defaultClient: apolloClient defaultClient: apolloClient
}); });
Vue.filter('date', dateFilter);
/* eslint-disable no-new */ /* eslint-disable no-new */
new Vue({ new Vue({
el: '#app', el: '#app',

View File

@ -13,9 +13,8 @@
</div> </div>
<div class="project__content"> <div class="project__content">
<add-project-entry class="project__add-entry"></add-project-entry> <add-project-entry class="project__add-entry" :project="project.id"></add-project-entry>
<project-entry></project-entry> <project-entry v-bind="entry" v-for="(entry, index) in project.entries" :key="index"></project-entry>
<project-entry></project-entry>
</div> </div>
</div> </div>
</template> </template>
@ -47,6 +46,9 @@
return { return {
slug: this.slug slug: this.slug
} }
},
update(data) {
return this.$getRidOfEdges(data).project || {};
} }
} }
}, },