2022-07-12 10:55:28 +02:00
|
|
|
<template>
|
|
|
|
<div class="">
|
|
|
|
<header class="" v-if="title">
|
|
|
|
<h2 class="">{{ title }}</h2>
|
|
|
|
</header>
|
|
|
|
|
|
|
|
<section :class="{ 'flex gap-1': hasIcon }">
|
|
|
|
<div class="" v-if="hasIcon && (icon || iconByType)">
|
|
|
|
<o-icon
|
|
|
|
:icon="icon ? icon : iconByType"
|
2022-07-12 10:55:28 +02:00
|
|
|
:variant="variant"
|
2022-07-12 10:55:28 +02:00
|
|
|
:both="!icon"
|
|
|
|
custom-size="48"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<div class="">
|
|
|
|
<p>
|
|
|
|
<template v-if="$slots.default">
|
|
|
|
<slot />
|
|
|
|
</template>
|
|
|
|
<template v-else>
|
|
|
|
<div v-html="message" />
|
|
|
|
</template>
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<o-field v-if="hasInput">
|
|
|
|
<o-input
|
|
|
|
v-model="prompt"
|
2022-09-20 16:53:26 +02:00
|
|
|
expanded
|
2022-07-12 10:55:28 +02:00
|
|
|
class="input"
|
|
|
|
ref="input"
|
|
|
|
v-bind="inputAttrs"
|
|
|
|
@keydown.enter="confirm"
|
|
|
|
/>
|
|
|
|
</o-field>
|
|
|
|
</div>
|
|
|
|
</section>
|
|
|
|
|
2022-07-12 10:55:28 +02:00
|
|
|
<footer v-if="canCancel" class="flex gap-2 my-2">
|
|
|
|
<o-button ref="cancelButton" outlined @click="cancel('button')">{{
|
2022-07-12 10:55:28 +02:00
|
|
|
cancelText ?? t("Cancel")
|
|
|
|
}}</o-button>
|
2022-07-12 10:55:28 +02:00
|
|
|
<o-button :variant="variant" ref="confirmButton" @click="confirm">{{
|
2022-07-12 10:55:28 +02:00
|
|
|
confirmText ?? t("Confirm")
|
|
|
|
}}</o-button>
|
|
|
|
</footer>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
import { computed, nextTick, ref } from "vue";
|
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
defineProps<{
|
|
|
|
title: string;
|
|
|
|
message: string | string[];
|
|
|
|
icon?: string;
|
|
|
|
hasIcon?: boolean;
|
2022-07-12 10:55:28 +02:00
|
|
|
variant?: string;
|
2022-07-12 10:55:28 +02:00
|
|
|
size?: string;
|
|
|
|
canCancel?: boolean;
|
|
|
|
confirmText?: string;
|
|
|
|
cancelText?: string;
|
2022-08-26 16:08:58 +02:00
|
|
|
onConfirm: (prompt?: string) => any;
|
|
|
|
onCancel?: (source: string) => any;
|
2022-07-12 10:55:28 +02:00
|
|
|
ariaLabel?: string;
|
|
|
|
ariaModal?: boolean;
|
|
|
|
ariaRole?: string;
|
|
|
|
hasInput?: boolean;
|
|
|
|
inputAttrs?: Record<string, any>;
|
|
|
|
}>(),
|
2022-07-12 10:55:28 +02:00
|
|
|
{
|
|
|
|
variant: "primary",
|
|
|
|
canCancel: true,
|
|
|
|
hasInput: false,
|
|
|
|
inputAttrs: () => ({}),
|
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
const emit = defineEmits(["confirm", "cancel", "close"]);
|
|
|
|
|
|
|
|
const { t } = useI18n({ useScope: "global" });
|
|
|
|
|
2022-09-20 16:53:26 +02:00
|
|
|
// const modalOpened = ref(false);
|
2022-07-12 10:55:28 +02:00
|
|
|
|
|
|
|
const prompt = ref<string>(props.hasInput ? props.inputAttrs?.value ?? "" : "");
|
|
|
|
const input = ref();
|
|
|
|
|
2022-09-20 16:53:26 +02:00
|
|
|
// const dialogClass = computed(() => {
|
|
|
|
// return [props.size];
|
|
|
|
// });
|
2022-07-12 10:55:28 +02:00
|
|
|
/**
|
|
|
|
* Icon name (MDI) based on the type.
|
|
|
|
*/
|
|
|
|
const iconByType = computed(() => {
|
2022-07-12 10:55:28 +02:00
|
|
|
switch (props.variant) {
|
2022-07-12 10:55:28 +02:00
|
|
|
case "info":
|
|
|
|
return "information";
|
|
|
|
case "success":
|
|
|
|
return "check-circle";
|
|
|
|
case "warning":
|
|
|
|
return "alert";
|
|
|
|
case "danger":
|
|
|
|
return "alert-circle";
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
|
|
* If it's a prompt Dialog, validate the input.
|
|
|
|
* Call the onConfirm prop (function) and close the Dialog.
|
|
|
|
*/
|
|
|
|
const confirm = () => {
|
2022-10-11 11:14:57 +02:00
|
|
|
console.debug("dialog confirmed", input.value?.$el);
|
2022-07-12 10:55:28 +02:00
|
|
|
if (input.value !== undefined) {
|
2022-09-20 16:53:26 +02:00
|
|
|
const inputElement = input.value.$el.querySelector("input");
|
|
|
|
if (!inputElement.checkValidity()) {
|
|
|
|
nextTick(() => inputElement.select());
|
2022-07-12 10:55:28 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
emit("confirm", prompt.value);
|
|
|
|
props.onConfirm(prompt.value);
|
|
|
|
close();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Close the Dialog.
|
|
|
|
*/
|
|
|
|
const close = () => {
|
|
|
|
emit("close");
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Close the Modal if canCancel and call the onCancel prop (function).
|
|
|
|
*/
|
|
|
|
const cancel = (source: string) => {
|
|
|
|
emit("cancel", source);
|
2022-10-26 18:45:47 +02:00
|
|
|
if (props?.onCancel) {
|
|
|
|
props?.onCancel(source);
|
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
close();
|
|
|
|
};
|
|
|
|
</script>
|