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>
<info-icon class="text-form-with-help-text__icon"></info-icon>
</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>
</template>

View File

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

View File

@ -1,13 +1,17 @@
<template>
<modal :hide-header="true">
<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 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 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>
</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>
</template>
@ -15,15 +19,65 @@
import Modal from '@/components/Modal';
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 {
components: {
Modal,
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() {
return {
value: ''
activity: '',
reflection: '',
nextSteps: ''
}
}
}

View File

@ -2,27 +2,30 @@
<div class="project-entry">
<h3 class="project-entry__heading">Tätigkeit</h3>
<p class="project-entry__paragraph">
Ich führe das Interview mit meiner Kollegin durch.
{{activity}}
</p>
<h3 class="project-entry__heading">Reflexion</h3>
<p class="project-entry__paragraph">
Da ich geeignete Fragen hatte, konnte meine Kollegin umfangreiche Antworten zum Thema geben. Die Eingangshalle
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.
{{reflection}}
</p>
<h3 class="project-entry__heading">
Nächste Schritte
</h3>
<p class="project-entry__paragraph">
Interview im Raum Mein Lehrbetrieb ablegen.
{{nextSteps}}
</p>
<div class="project-entry__date">
21. Juni 2018
{{created | date }}
</div>
</div>
</template>
<script>
export default {
props: ['activity', 'reflection', 'nextSteps', 'created']
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.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/projectEntryParts.gql"
query ProjectQuery($id: ID, $slug: String){
project(slug: $slug, id: $id) {
...ProjectParts
entries {
edges {
node {
...ProjectEntryParts
}
}
}
}
}

View File

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

View File

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