Skip to content

Instantly share code, notes, and snippets.

@urbansky
Created August 27, 2018 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save urbansky/f9c7e40ae765b683c395f191bc6f6671 to your computer and use it in GitHub Desktop.
Save urbansky/f9c7e40ae765b683c395f191bc6f6671 to your computer and use it in GitHub Desktop.
<!-- -------------------- -->
<!-- Index page component -->
<!-- -------------------- -->
<template>
<div>
<v-container v-if="$route.name === 'crm/projects'" class="px-0" fluid>
<v-layout row wrap>
<v-flex>
<v-toolbar flat>
<v-text-field v-model="search" append-icon="search" label="Search" single-line hide-details></v-text-field>
<v-spacer></v-spacer>
<v-btn icon :color="com.toolbarBtnColor" :to="'/crm/' + product + '/projects/add'">
<v-icon>add</v-icon>
</v-btn>
</v-toolbar>
<v-data-table :headers="headers" :items="projectsList" hide-actions :search="search">
<v-progress-linear slot="progress" color="blue" indeterminate></v-progress-linear>
<template slot="items" slot-scope="props">
<td class="text-xs-left projectTitle">
<router-link :to="'/crm/' + product + '/projects/' + props.item.id">{{ props.item.title }}</router-link>
</td>
<td class="text-xs-left">{{ props.item.description }}</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-container>
<router-view></router-view>
</div>
</template>
<script>
import { com } from "./../../../main";
import * as log from 'loglevel';
import { mapGetters } from 'vuex';
export default {
name: 'CrmProjects',
created() {
log.info("Initial fetch projects");
this.$store.dispatch('projects/fetchProjects', this.product);
},
computed: {
...mapGetters("projects", [ 'projectsList'])
},
data () {
return {
com: com,
product: this.$route.params.product,
headers: [
{ text: 'Titel', value: 'title' },
{ text: 'Beschreibung', value: 'description' }
],
search: ""
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.projectTitle {
min-width: 140px;
a {
font-weight: bold;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
</style>
// --------------------
// Show page component
// --------------------
<template>
<v-container grid-list-xl>
<v-layout row wrap>
<v-flex xs12 class="pa-2">
<h1 class="pa-0 ma-0 mt-2 subheading font-weight-bold text-xs-left hidden-lg-and-up">
<v-btn icon :to="`/crm/${product}/projects`" small><v-icon small>fas fa-arrow-left</v-icon></v-btn>
{{ project.title }}
</h1>
<h1 class="pa-0 ma-0 mt-2 display-1 text-xs-left hidden-md-and-down">
<v-btn icon :to="'/crm/' + product + '/projects'"><v-icon>fas fa-arrow-left</v-icon></v-btn>
{{ project.title }}
</h1>
</v-flex>
<v-flex md6>
<HxCard title="Stammdaten">
<template slot="toolbar">
<v-btn icon small :color="com.toolbarBtnColor" :to="`/crm/${product}/projects/${id}/edit`" @click.stop>
<v-icon class="subheading">edit</v-icon>
</v-btn>
</template>
<v-container grid-list-md text-xs-center>
<DataItem label="Titel" divider>{{ project.title }}</DataItem>
<DataItem label="Beschreibung">{{ project.description }}</DataItem>
</v-container>
</HxCard>
</v-flex>
<v-flex md6>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import * as log from 'loglevel';
import { com } from "./../../../main";
import { mapGetters } from 'vuex';
export default {
name: 'ShowProject',
created() {
log.info("Created Project Show");
this.$store.dispatch('projects/setCurrentProject', this.id);
},
computed: {
...mapGetters("projects", [ 'project'])
},
data () {
return {
id: this.$route.params.id,
product: this.$route.params.product,
com: com
}
},
methods: {
}
}
</script>
// --------------------
// Edit page component
// --------------------
<template>
<v-container grid-list-xl text-xs-center>
<v-layout row wrap>
<v-flex xs12 class="pa-2">
<h1 v-if="project" class="pa-0 ma-0 mt-2 headline text-xs-left">
<v-btn icon :to="back"><v-icon>fas fa-arrow-left</v-icon></v-btn>
{{ project.title }}
</h1>
</v-flex>
<v-flex md6>
<HxCard title="Projekt bearbeiten">
<v-btn slot="toolbar" icon small :color="com.toolbarBtnColor" @click.stop="deleteProject">
<v-icon class="subheading">delete</v-icon>
</v-btn>
<v-card-text>
<ProjectForm :back="back" @submit="submit" :project="project"/>
</v-card-text>
</HxCard>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import { com } from "./../../../main";
import { mapGetters } from 'vuex';
export default {
computed: {
back() { return `/crm/${this.product}/projects/${this.id}` },
...mapGetters("projects", {
projectState: 'project'
}),
project() {
// Create a copy, so the form can't modify the state directly
return {
id: this.projectState.id,
title: this.projectState.title,
description: this.projectState.description
}
}
},
data() {
return {
com: com,
id: this.$route.params.id,
product: this.$route.params.product
}
},
methods: {
submit(project) {
this.$store.dispatch('projects/updateProject', { product: this.product, project: project });
this.$router.push(this.back);
},
deleteProject() {
this.$store.dispatch('projects/deleteProject', { product: this.product, project: this.project });
this.$router.push(this.back);
}
}
}
</script>
// -------------------
// Add page component
// -------------------
<template>
<v-container grid-list-xl text-xs-center>
<v-layout row wrap>
<v-flex xs12 class="pa-2">
<h1 class="pa-0 ma-0 mt-2 headline text-xs-left">
<v-btn icon :to="back"><v-icon>fas fa-arrow-left</v-icon></v-btn>
Zurück
</h1>
</v-flex>
<v-flex md6>
<HxCard title="Projekt erstellen">
<v-card-text>
<ProjectForm :back="back" @submit="submit"/>
</v-card-text>
</HxCard>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
export default {
computed: {
back() { return `/crm/${this.product}/projects/` }
},
data () {
return {
product: this.$route.params.product
}
},
methods: {
submit(project) {
this.$store.dispatch('projects/addProject', { product: this.product, project: project });
this.$router.push(this.back);
}
}
}
</script>
// -------------------
// Form widget
// -------------------
<template>
<v-form v-if="project" ref="form" @submit.stop="submit" v-model="valid" lazy-validation>
<v-text-field v-model="project.title" :rules="titleRules" label="Titel"/>
<v-text-field v-model="project.description" label="Beschreibung"/>
<div class="d-flex mt-2">
<v-spacer></v-spacer>
<v-btn :to="back">Zurück</v-btn>
<v-btn :disabled="!valid" type="submit" color="primary" class="mr-0">Speichern</v-btn>
</div>
</v-form>
</template>
<script>
import * as log from 'loglevel';
import { com } from "../main";
export default {
props: {
back: {
required: true,
type: String
},
project: {
default: function () {
return {
title: "",
description: ""
}
},
type: Object
}
},
data () {
return {
valid: true,
titleRules: [ v => !!v || 'Title is required' ]
}
},
methods: {
submit() {
log.info("Submit project form");
if (this.$refs.form.validate()) {
this.$emit('submit', this.project)
}
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment