Wire up portfolio frontend to backend

This commit is contained in:
Ramon Wenger 2019-03-07 10:54:27 +01:00
parent 485a6ca4eb
commit 474110126d
10 changed files with 131 additions and 18 deletions

View File

@ -14,12 +14,23 @@
import ProjectWidget from '@/components/portfolio/ProjectWidget';
import AddProject from '@/components/portfolio/AddProject';
import PROJECTS_QUERY from '@/graphql/gql/allProjects.gql';
export default {
components: {
ProjectWidget,
AddProject
},
apollo: {
projects: {
query: PROJECTS_QUERY,
update(data) {
return this.$getRidOfEdges(data).projects
}
},
},
data() {
return {
projects: [

View File

@ -1,5 +1,5 @@
<template>
<page-form title="Neues Projekt">
<page-form @save="$emit('save', localProject)" title="Neues Projekt">
<page-form-input label="Titel" v-model="localProject.title"></page-form-input>
<page-form-input label="Beschreibung" type="textarea" v-model="localProject.description"></page-form-input>
<page-form-input label="Ziele" type="textarea" v-model="localProject.objectives"></page-form-input>
@ -11,8 +11,9 @@
<button
type="submit"
class="button button--primary"
:class="{'button--disabled': true}"
:disabled="true"
data-cy="save-project-button"
:class="{'button--disabled': !formValid}"
:disabled="!formValid"
>Speichern
</button>
<router-link to="/portfolio" tag="button" class="button">Abbrechen</router-link>
@ -34,6 +35,12 @@
ColorChooser
},
computed: {
formValid() {
return this.localProject.title && this.localProject.description && this.localProject.objectives;
}
},
data() {
return {
localProject: Object.assign({}, this.project),

View File

@ -0,0 +1,10 @@
#import "./fragments/projectParts.gql"
query ProjectsQuery {
projects {
edges {
node {
...ProjectParts
}
}
}
}

View File

@ -0,0 +1,8 @@
fragment ProjectParts on ProjectNode {
id
title
appearance
description
slug
objectives
}

View File

@ -0,0 +1,9 @@
#import "../fragments/projectParts.gql"
mutation AddProjectMutation($input: AddProjectInput!){
addProject(input: $input){
project {
...ProjectParts
}
errors
}
}

View File

@ -0,0 +1,8 @@
#import "../fragments/projectParts.gql"
mutation UpdateProjectMutation($input: UpdateProjectInput!){
updateProject(input: $input) {
project {
...ProjectParts
}
}
}

View File

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

View File

@ -1,10 +1,16 @@
<template>
<project-form :project="project"></project-form>
<project-form
@save="saveProject"
:project="project"
></project-form>
</template>
<script>
import ProjectForm from '@/components/portfolio/ProjectForm';
import ADD_PROJECT_MUTATION from '@/graphql/gql/mutations/addProject.gql';
import PROJECTS_QUERY from '@/graphql/gql/allProjects.gql';
const defaultAppearance = 'blue';
export default {
@ -15,12 +21,41 @@
computed: {
project() {
return {
title: 'title',
description: 'description',
objectives: 'objectives',
title: '',
description: '',
objectives: '',
appearance: defaultAppearance
}
}
},
methods: {
saveProject(project) {
this.$apollo.mutate({
mutation: ADD_PROJECT_MUTATION,
variables: {
input: {
project: project
}
},
update: (store, {data: {addProject: {project}}}) => {
try {
const data = store.readQuery({query: PROJECTS_QUERY});
if (data.projects) {
data.projects.edges.push({
node: project,
__typename: 'ProjectNode'
});
store.writeQuery({query: PROJECTS_QUERY, data});
}
} catch (e) {
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
}
}
}).then(() => {
this.$router.push('/portfolio');
});
}
}
}
</script>

View File

@ -1,21 +1,14 @@
<template>
<div class="project">
<div class="project__header">
<h1 class="project__title">Quartalsarbeit: Mein Lehrbetrieb</h1>
<h1 class="project__title">{{project.title}}</h1>
<p class="project__description">
Das ist eine Beschreibung und kann maximal 200 Zeichen enthalten. Das ist eine Beschreibung und kann maximal 200
Zeichen enthalten. Das ist eine Beschreibung und kann maximal 200 Zeichen enthalten.
{{project.description}}
</p>
<h2 class="project__objectives-title">Ziele</h2>
<ul class="project__objectives">
<li class="project__objective">Ich kann ein Interview mit geeigneten Fragen vorbereiten.</li>
<li class="project__objective">Ich kann ein Interview führen und auf interessante oder ausweichende
Antworten näher eingehen.
</li>
<li class="project__objective">Ich kann ein mündlich geführtes Interview in Standardsprache
aufzeichnen.
</li>
<li class="project__objective" :key="index" v-for="(objective, index) in objectives">{{objective}}</li>
</ul>
</div>
@ -31,13 +24,39 @@
import ProjectEntry from '@/components/portfolio/ProjectEntry';
import AddProjectEntry from '@/components/portfolio/AddProjectEntry';
import PROJECT_QUERY from '@/graphql/gql/projectQuery.gql';
export default {
props: ['slug'],
components: {
AddProjectEntry,
ProjectEntry
},
computed: {
objectives() {
return this.project.objectives ? this.project.objectives.split('\n') : [];
}
},
apollo: {
project: {
query: PROJECT_QUERY,
variables() {
return {
slug: this.slug
}
}
}
},
data() {
return {
project: {}
}
},
created() {
this.$store.dispatch('setSpecialContainerClass', 'red');
},

View File

@ -51,7 +51,7 @@ const routes = [
{path: '/basic-knowledge/:slug', name: 'basic-knowledge', component: basicknowledge, meta: {layout: 'simple'}},
{path: '/submission/:id', name: 'submission', component: submission, meta: {layout: 'simple'}},
{path: '/portfolio', name: 'portfolio', component: portfolio},
{path: '/portfolio/:slug', name: 'project', component: project},
{path: '/portfolio/:slug', name: 'project', component: project, props: true},
{path: '/new-project/', name: 'new-project', component: newProject},
{
path: '/book',