Skip to content

Commit f65f68a

Browse files
Tweaked UI for Family Plans and allows deletion
1 parent f41d600 commit f65f68a

9 files changed

Lines changed: 160 additions & 25 deletions

File tree

2wr-app/src/api/family-plans-api.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ export default {
88
return (await baseApiInstance.getInstance()).post('familyplans-upsert', plan);
99
},
1010
async deletePlan(plan) {
11-
return (await baseApiInstance.getInstance()).delete('familyplans-delete', plan);
11+
return (await baseApiInstance.getInstance()).delete(`familyplans-delete/${plan.id}`);
1212
}
1313
}

2wr-app/src/assets/app.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@
1111
}
1212
.img-cover {
1313
object-fit: cover;
14+
}
15+
16+
.cursor-pointer {
17+
cursor: pointer;
1418
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<template>
2+
<v-dialog v-model="showDialog">
3+
<v-card>
4+
<v-toolbar v-if="title">
5+
<v-toolbar-title class="text-body-2 font-weight-bold grey--text">
6+
{{ title }}
7+
</v-toolbar-title>
8+
</v-toolbar>
9+
<v-card-text class="pa-4">
10+
{{ message }}
11+
</v-card-text>
12+
<v-card-actions>
13+
<v-spacer></v-spacer>
14+
<v-btn plain text color="grey" @click.native='deny'>{{ denyButtonText }}</v-btn>
15+
<v-btn plain text color="primary" @click.native="confirm">{{ confirmButtonText }}</v-btn>
16+
</v-card-actions>
17+
</v-card>
18+
</v-dialog>
19+
</template>
20+
21+
<script>
22+
import { ref, defineComponent } from "@vue/composition-api";
23+
24+
export default defineComponent({
25+
name: "ConfirmationDialog",
26+
setup() {
27+
28+
const showDialog = ref(false);
29+
const titleText = ref("Confirmation");
30+
const messageText = ref("Are you sure?");
31+
const denyButtonText = ref("cancel");
32+
const confirmButtonText = ref("ok");
33+
let resolveCallback = null;
34+
35+
function open(title, message, options) {
36+
showDialog.value = true;
37+
if (title) titleText.value = title;
38+
if (message) messageText.value = message;
39+
if (options?.denyText) denyButtonText.value = options.denyText;
40+
if (options?.confirmText) confirmButtonText.value = options.confirmText;
41+
return new Promise((resolve) => {
42+
resolveCallback = resolve;
43+
});
44+
}
45+
46+
function closeDialog(result) {
47+
showDialog.value = false;
48+
resolveCallback(result);
49+
}
50+
51+
return {
52+
open,
53+
title: titleText,
54+
message: messageText,
55+
denyButtonText,
56+
confirmButtonText,
57+
showDialog,
58+
confirm:() => closeDialog(true),
59+
deny: () => closeDialog(false)
60+
}
61+
}
62+
})
63+
</script>

2wr-app/src/components/common/globalComponents.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import IconTextBlock from './IconTextBlock.vue';
44
import InfoBar from './InfoBar.vue';
55
import DatePickerInput from "./DatePickerInput.vue";
66
import SecureImg from './SecureImg.vue';
7+
import ConfirmDialog from './ConfirmDialog.vue';
78

89
export default function () {
910
Vue.component("EditableTextBlock", EditableTextBlock);
1011
Vue.component("IconTextBlock", IconTextBlock);
1112
Vue.component("InfoBar", InfoBar);
1213
Vue.component("DatePickerInput", DatePickerInput);
1314
Vue.component("SecureImg", SecureImg);
15+
Vue.component("ConfirmDialog", ConfirmDialog);
1416
}

2wr-app/src/components/prepare/family-plans/family-plans-view.vue

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
<template>
22
<v-container class="py-0" v-if="plan">
3+
<v-fab-transition>
4+
<v-btn
5+
color="red"
6+
dark
7+
absolute
8+
bottom
9+
right
10+
fab
11+
class="mb-12"
12+
@click="deletePlan"
13+
>
14+
<v-icon>mdi-delete-forever</v-icon>
15+
</v-btn>
16+
</v-fab-transition>
17+
318
<InfoBar title="Family Plan"></InfoBar>
419
<v-flex>
5-
<v-row justify="end" class="py-6" @click="toggleAlerts">
20+
<v-row justify="end" class="py-6 cursor-pointer" @click="toggleAlerts" >
621
<div class="text-button px-6">{{ plan.allowAlerts ? 'Alerts Enabled' : 'Alerts Disabled'}}</div>
722
<v-icon
823
plain
924
large
1025
class="mr-6"
26+
:class="{ 'red--text': plan.allowAlerts }"
1127
>{{ plan.allowAlerts ? 'mdi-alarm-light' : 'mdi-alarm-light-off'}}</v-icon
1228
>
1329
</v-row>
@@ -96,6 +112,7 @@
96112
</v-flex>
97113
</v-card>
98114
</div>
115+
<ConfirmDialog ref="theDialog"></ConfirmDialog>
99116
<!-- <pre class="caption">{{ plan }}</pre> -->
100117
</v-container>
101118
</template>
@@ -120,7 +137,7 @@ export default defineComponent({
120137
name: "family-plan-view",
121138
components: { AddressView },
122139
props: { planId: { required: true } },
123-
setup(props) {
140+
setup(props, { refs }) {
124141
const plan = ref(null);
125142
126143
onMounted(() => {
@@ -177,7 +194,22 @@ export default defineComponent({
177194
await updatePlan();
178195
}
179196
}
197+
198+
async function deletePlan() {
199+
if (await refs.theDialog.open()) {
200+
if (!(await store.dispatch(
201+
"familyPlansStore/deletePlanAsync",
202+
plan.value
203+
))) {
204+
store.commit("setError", "Failed to delete plan");
205+
} else {
206+
goBack();
207+
}
208+
}
209+
}
210+
180211
return {
212+
deletePlan,
181213
toggleAlerts,
182214
ensureNamed,
183215
plan,

2wr-app/src/store/modules/prepare/family-plans/actions.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ export default {
2828
commit("clearBusy", null, { root: true });
2929
}
3030
},
31+
async deletePlanAsync({ commit }, plan) {
32+
try {
33+
commit("setBusy", true, { root: true });
34+
commit("setError", "", { root: true });
35+
36+
var response = await familyPlansApi.deletePlan(plan);
37+
38+
if (response.status === 200) {
39+
commit("removeFromFamilyPlans", plan);
40+
return true;
41+
} else {
42+
return false
43+
}
44+
} catch {
45+
commit("setError", "Failed to delete plan.", { root: true });
46+
} finally {
47+
commit("clearBusy", null, { root: true });
48+
}
49+
},
3150
async getAllAsync({ commit, rootState }) {
3251
try {
3352
commit("setBusy", null, { root: true });

2wr-app/src/store/modules/prepare/family-plans/mutations.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ export default {
33
setSharedPlans: (state, plans) => (state.sharedPlans = plans),
44
addToFamilyPlans: (state, newPlan) =>
55
state.familyPlans.splice(state.familyPlans.length, 0, newPlan),
6+
removeFromFamilyPlans: (state, plan) => {
7+
const index = state.familyPlans.indexOf(plan);
8+
if (index > -1) state.familyPlans.splice(index, 1);
9+
},
610
replaceContact: (state, { contact, plan }) => {
711
const index = plan.emergencyContacts.findIndex(i => i.id == contact.id);
812
plan.emergencyContacts.splice(index, 1, contact);
@@ -40,5 +44,4 @@ export default {
4044
addPhotoToPet: (state, { photo, pet }) => {
4145
pet.image = photo;
4246
}
43-
4447
};

TwoWeeksReady.Common/FamilyPlans/FamilyPlan.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ public class FamilyPlan
2121
[JsonProperty("phoneNumber")]
2222
public string PhoneNumber { get; set; }
2323

24-
[JsonProperty("emergecyContacts")]
24+
[JsonProperty("allowAlerts")]
25+
public bool AllowAlerts { get; set; }
26+
27+
[JsonProperty("emergencyContacts")]
2528
public List<Contact> EmergencyContacts { get; set; } = new List<Contact>();
2629

2730
[JsonProperty("routeLocations")]

api/TwoWeeksReady/FamilyPlans/FamilyPlansApi.cs

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.IO;
4-
using System.Linq;
5-
using System.Threading.Tasks;
6-
using AzureFunctions.OidcAuthentication;
1+
using AzureFunctions.OidcAuthentication;
72
using Microsoft.AspNetCore.Http;
83
using Microsoft.AspNetCore.Mvc;
94
using Microsoft.Azure.Documents;
@@ -13,6 +8,11 @@
138
using Microsoft.Azure.WebJobs.Extensions.Http;
149
using Microsoft.Extensions.Logging;
1510
using Newtonsoft.Json;
11+
using System;
12+
using System.Collections.Generic;
13+
using System.IO;
14+
using System.Linq;
15+
using System.Threading.Tasks;
1616
using TwoWeeksReady.Common;
1717
using TwoWeeksReady.Common.FamilyPlans;
1818

@@ -128,8 +128,9 @@ public async Task<IActionResult> UpsertFamilyPlan(
128128

129129
[FunctionName("familyplans-delete")]
130130
public async Task<IActionResult> DeleteFamilyPlan(
131-
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = null)]
131+
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "familyplans-delete/{id}")]
132132
HttpRequest req,
133+
string id,
133134
[CosmosDB(databaseName: DefaultDatabaseName,
134135
collectionName: CollectionName,
135136
ConnectionStringSetting = DefaultDbConnectionName)]
@@ -141,26 +142,34 @@ public async Task<IActionResult> DeleteFamilyPlan(
141142

142143
log.LogInformation($"Deleting a Family Plan");
143144

144-
try
145-
{
146-
var content = await new StreamReader(req.Body).ReadToEndAsync();
147-
var thePlan = JsonConvert.DeserializeObject<FamilyPlan>(content);
145+
Uri collectionUri = UriFactory.CreateDocumentCollectionUri(DefaultDatabaseName, CollectionName);
148146

149-
Uri collectionUri = UriFactory.CreateDocumentCollectionUri(DefaultDatabaseName, CollectionName);
150147

151-
// Update Plan
152-
var docUri = UriFactory.CreateDocumentUri(DefaultDatabaseName, CollectionName, thePlan.Id);
153-
Document document = await client.DeleteDocumentAsync(docUri);
154148

155-
return new OkResult();
149+
//verify existing document (not upserting as this is an update only function)
150+
var options = new FeedOptions()
151+
{
152+
EnableCrossPartitionQuery = true
153+
};
154+
var existingDocument = client.CreateDocumentQuery<FamilyPlan>(collectionUri, options)
155+
.Where(d => d.Id == id)
156+
.AsEnumerable().FirstOrDefault();
156157

157-
}
158-
catch (Exception ex)
158+
if (existingDocument == null)
159159
{
160-
log.LogCritical($"Failed to delete the new Family Plan: {ex}");
160+
log.LogWarning($"{id} not found.");
161+
return new BadRequestObjectResult($"Family Plan not found.");
161162
}
162163

163-
return new BadRequestResult();
164+
var documentUri = UriFactory.CreateDocumentUri(DefaultDatabaseName, CollectionName, id);
165+
166+
await client.DeleteDocumentAsync(documentUri, new RequestOptions
167+
{
168+
PartitionKey = new PartitionKey(existingDocument.UserId)
169+
});
170+
171+
return new OkObjectResult(true);
172+
164173
}
165174

166175
}

0 commit comments

Comments
 (0)