confirmation modal

This commit is contained in:
grimhilt 2023-05-23 16:35:23 +02:00
parent 467b0eebe9
commit f42d819e45
6 changed files with 105 additions and 20 deletions

View File

@ -3,12 +3,13 @@ import { defineProps } from "vue";
const props = defineProps({ const props = defineProps({
onClick: { type: Function }, onClick: { type: Function },
text: { type: String }, text: { type: String },
class: { type: String },
}); });
</script> </script>
<template> <template>
<span> <span>
<button @click="props.onClick">{{ props.text }}</button> <button :class="props.class" @click="props.onClick">{{ props.text }}</button>
</span> </span>
</template> </template>
@ -27,5 +28,13 @@ button {
&:hover { &:hover {
opacity: 0.6; opacity: 0.6;
} }
&.danger {
background-color: var(--danger);
}
&.cancel {
background-color: var(--quaternary-background);
}
} }
</style> </style>

View File

@ -1,14 +1,20 @@
<script setup> <script setup lang="ts">
import { defineProps, defineEmits } from "vue"; import { defineProps, defineEmits, withDefaults } from "vue";
const props = defineProps({
type: { type: String, required: true }, export interface Props {
required: { type: Boolean, default: false }, type: string;
onChange: { type: Function }, required: boolean;
placeholder: { type: String }, onChange: any;
label: { type: String }, placeholder: string;
vModel: { type: String }, label: string;
modelValue: {}, vModel: string;
modelValue: any;
}
const props = withDefaults(defineProps<Props>(), {
required: () => false,
}); });
defineEmits(["update:modelValue"]); defineEmits(["update:modelValue"]);
</script> </script>

View File

@ -165,12 +165,11 @@ function mailChange() {
<Input v-model="smtpHost" class="host" type="text" placeholder="host" /> <Input v-model="smtpHost" class="host" type="text" placeholder="host" />
<Input v-model="smtpPort" class="port" type="number" placeholder="port" /> <Input v-model="smtpPort" class="port" type="number" placeholder="port" />
</fieldset> </fieldset>
</template>
<!-- tls --> <!-- tls -->
<div> <template v-slot:actions>
<Button :disabled="error != ''" :onClick="addAccountRequest" text="Add" /> <Button :disabled="error != ''" :onClick="addAccountRequest" text="Add" />
{{ error }} {{ error }}
</div>
</template> </template>
</Modal> </Modal>
</div> </div>

View File

@ -0,0 +1,54 @@
<script setup lang="ts">
import { ref, defineProps, withDefaults } from "vue";
import Modal from "./Modal.vue";
import Button from "../basic/Button.vue";
const modal = ref(true);
export interface Props {
title: string;
isDanger: boolean;
onConfirmation: any;
onCancel?: any;
}
const props = withDefaults(defineProps<Props>(), {
title: () => "Confirmation",
isDanger: () => true,
});
const error = ref("");
const handleContinue = async () => {
try {
if (props.onConfirmation) {
await props.onConfirmation();
}
modal.value = false;
} catch (err: any) {
error.value = err.message;
}
};
const handleCancel = async () => {
if (props.onCancel) {
await props.onCancel();
}
modal.value = false;
};
</script>
<template>
<div>
<Modal v-if="modal" :title="props.title" @close-modal="modal = false">
<template v-slot:body> Are you sure you want to do that ? </template>
<template v-slot:actions>
<Button :onClick="handleCancel" class="cancel" text="Cancel" />
<Button :onClick="handleContinue" :class="props.isDanger ? 'danger' : ''" text="Confirm" />
{{ error }}
</template>
</Modal>
</div>
</template>
<style lang="scss"></style>

View File

@ -33,6 +33,9 @@ onUnmounted(() => {
<div class="modal-body"> <div class="modal-body">
<slot name="body"> This is the default body! </slot> <slot name="body"> This is the default body! </slot>
</div> </div>
<div class="modal-actions">
<slot name="actions"></slot>
</div>
</div> </div>
</div> </div>
</template> </template>
@ -58,13 +61,29 @@ onUnmounted(() => {
border-radius: 5px; border-radius: 5px;
color: var(--primary-text); color: var(--primary-text);
background-color: var(--secondary-background); background-color: var(--secondary-background);
padding: 20px; padding: 10px;
min-width: 220px;
} }
.modal-header { .modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
} }
.modal-body {
margin: 10px;
}
.modal-actions {
display: flex;
align-items: center;
flex-direction: row;
justify-content: flex-end;
gap: 10px;
}
h2 { h2 {
display: inline-block; display: inline-block;
font-size: 2.4rem; font-size: 2.4rem;

View File

@ -2,7 +2,6 @@
import Account from "./Account"; import Account from "./Account";
import AddAccountModal from "@/components/modals/AddAccountModal"; import AddAccountModal from "@/components/modals/AddAccountModal";
import store from "@/store/store"; import store from "@/store/store";
import ConfirmationModal from "@/components/modals/ConfirmationModal.vue";
import { onMounted } from "vue"; import { onMounted } from "vue";
import { computed } from "@vue/reactivity"; import { computed } from "@vue/reactivity";
@ -21,7 +20,6 @@ const accounts = computed(() => store.state.accounts);
<span class="divider"></span> <span class="divider"></span>
<Account v-for="(account, index) in accounts" :key="index" :data="account" /> <Account v-for="(account, index) in accounts" :key="index" :data="account" />
<span class="divider"></span> <span class="divider"></span>
<ConfirmationModal />
<AddAccountModal /> <AddAccountModal />
</div> </div>
</template> </template>