Issue 002: Delete functionality for measures.

This commit is contained in:
Jonathan Bernard 2020-03-14 16:21:39 -05:00
parent 3dd7169b8b
commit baf37698b3
9 changed files with 95 additions and 4 deletions

5
web/package-lock.json generated
View File

@ -9991,6 +9991,11 @@
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"lodash.omit": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
"integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",

View File

@ -27,6 +27,7 @@
"lodash.findindex": "^4.6.0",
"lodash.keyby": "^4.6.0",
"lodash.merge": "^4.6.2",
"lodash.omit": "^4.5.0",
"moment": "^2.24.0",
"register-service-worker": "^1.5.2",
"vue": "^2.6.11",

View File

@ -7,6 +7,7 @@ import Measure from '@/views/Measure.vue';
import Measures from '@/views/Measures.vue';
import NewMeasure from '@/views/NewMeasure.vue';
import NewMeasurement from '@/views/NewMeasurement.vue';
import DeleteMeasure from '@/views/DeleteMeasure.vue';
import NotFound from '@/views/NotFound.vue';
import QuickPanels from '@/views/QuickPanels.vue';
import UserAccount from '@/views/UserAccount.vue';
@ -68,6 +69,11 @@ const router = new Router({
name: 'new-measurement',
component: NewMeasurement
},
{
path: '/delete/measure/:slug',
name: 'delete-measure',
component: DeleteMeasure
},
{
path: '*',
name: 'not-found',

View File

@ -8,6 +8,7 @@ import {
} from 'vuex-module-decorators';
import assign from 'lodash.assign';
import keyBy from 'lodash.keyby';
import omit from 'lodash.omit';
import { User, Measure, MeasureConfig } from '@/models';
import api from '@/services/pm-api-client';
@ -35,7 +36,17 @@ export class MeasureStoreModule extends VuexModule {
return newMeasure;
}
@Action({ rawError: true })
public async deleteMeasure(m: Measure<MeasureConfig>) {
const delResponse = await api.deleteMeasure(m.slug);
this.context.commit('DELETE_MEASURE', m);
}
@Mutation private SET_MEASURE<T extends MeasureConfig>(measure: Measure<T>) {
this.measures = assign({}, this.measures, {[measure.slug]: measure});
}
@Mutation private DELETE_MEASURE<T extends MeasureConfig>(measure: Measure<T>) {
this.measures = assign({}, omit(this.measures, measure.slug));
}
}

View File

@ -0,0 +1,25 @@
<template>
<div v-if="measure">
<div class=header>
<h1>Delete Measure</h1>
<h2>Are you sure you want to delete {{measure.name}}?</h2>
</div>
<form @submit.prevent=deleteMeasure() >
This will delete all measurements associated with this measure. This
cannot be undone.
<div v-if='!waiting' class=form-actions>
<button class=btn-action>Delete</button>
<a class=btn @click="$router.go(-1)">Cancel</a>
</div>
<div v-if='waiting' class=form-waiting>
<div class=wait-spinner>working <fa-icon icon=sync spin /></div>
</div>
</form>
</div>
<div v-else>
<div class=header-action>
<h1>There is no measure named {{$route.params.slug}}.</h1>
</div>
</div>
</template>
<script lang=ts src=./delete-measure.ts></script>

View File

@ -5,8 +5,12 @@
<h1>{{measure.name}}</h1>
<h2>{{measure.description}}</h2>
</div>
<button><fa-icon icon=trash></fa-icon></button>
<router-link :to="'/new/measurement/' + measure.slug" class=btn-action>Add Measurement</router-link>
<router-link title="Delete Measure" :to="'/delete/measure/' + measure.slug" class=btn>
<fa-icon icon=trash></fa-icon>
</router-link>
<router-link :to="'/new/measurement/' + measure.slug" class=btn-action>
Add Measurement
</router-link>
</div>
<MeasureDetails :measure=measure :measurements=measurements />
</div>
@ -17,4 +21,4 @@
</div>
</template>
<script lang="ts" src="./measure.ts"></script>
<style lang="scss" src="./measure.scss"></style>
<style scoped lang="scss" src="./measure.scss"></style>

View File

@ -0,0 +1,38 @@
import { Component, Prop, Vue } from 'vue-property-decorator';
import { Measure as MeasureModel, MeasureConfig } from '@/models';
import { measureStore, measurementStore } from '@/store';
import { logService } from '@/services/logging';
const logger = logService.getLogger('/views/delete-measure');
@Component({})
export class DeleteMeasure extends Vue {
private waiting: boolean = false;
private get measure(): MeasureModel<MeasureConfig> | null {
return measureStore.measures[this.$route.params.slug] || null;
}
private async mounted() {
if (!this.measure) {
await measureStore.fetchMeasure(this.$route.params.slug);
}
}
private async deleteMeasure() {
if (this.measure) {
this.waiting = true;
try {
await measureStore.deleteMeasure(this.measure);
this.$router.push({ name: 'measures' });
} catch (e) {
// TODO: show errors
logger.error('Unable to delete measure. \n\t ' + JSON.stringify(this.measure), e.stack);
} finally {
this.waiting = false;
}
}
}
}
export default DeleteMeasure;

View File

@ -1,6 +1,7 @@
@import '~@/styles/vars';
.header-action button {
.header-action .btn {
color: inherit;
margin-left: auto;
margin-right: 2rem;
background-color: none;