mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-10-08 04:20:58 -04:00
159 lines
5.7 KiB
Vue
159 lines
5.7 KiB
Vue
<template>
|
|
<div :class="['modal', shown ? 'd-block-force' : '', shownFull ? 'modal-shown' : '']" @click="hideClick">
|
|
<div :class="['modal-dialog', 'modal-dialog-centered', 'modal-dialog-scrollable', size ? `modal-${size}` : '']" role="document">
|
|
<div class="modal-content shadow">
|
|
<div v-if="header" class="modal-header">
|
|
<p class="h5 modal-title">
|
|
<Icon v-if="icon" :v="icon" />
|
|
{{ header }}
|
|
</p>
|
|
</div>
|
|
<div v-if="message" class="modal-body">
|
|
<p :class="[margin ? 'py-5 text-center' : '']" v-html="message"></p>
|
|
</div>
|
|
<div v-if="value !== undefined" class="modal-body">
|
|
<ListInput v-if="Array.isArray(value)" v-slot="s" v-model="value">
|
|
<textarea v-model="s.val" class="form-control" rows="5" @keyup="s.update(s.val)" @update="s.update(s.val)"></textarea>
|
|
</ListInput>
|
|
<textarea v-else v-model="value" class="form-control" rows="5"></textarea>
|
|
</div>
|
|
<div v-if="choice" class="modal-footer">
|
|
<button class="btn btn-outline-dark" @click="cancel">
|
|
{{ $t('confirm.no') }}
|
|
</button>
|
|
<button :class="`btn btn-${color || 'primary'}`" @click="confirm">
|
|
{{ $t('confirm.yes') }}
|
|
</button>
|
|
</div>
|
|
<div v-else-if="value !== undefined" class="modal-footer">
|
|
<button class="btn btn-outline-dark" @click="cancel">
|
|
{{ $t('confirm.dismiss') }}
|
|
</button>
|
|
<button :class="`btn btn-${color || 'primary'}`" @click="confirm">
|
|
{{ $t('confirm.save') }}
|
|
</button>
|
|
</div>
|
|
<div v-else class="modal-footer">
|
|
<button :class="`btn btn-${color || 'primary'}`" @click="confirm">
|
|
{{ $t('confirm.ok') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import Vue from 'vue';
|
|
|
|
import type { Color, ModalSize } from '../src/bootstrap.ts';
|
|
|
|
export interface DialogueMessage {
|
|
icon?: string;
|
|
header?: string;
|
|
message?: string;
|
|
margin?: boolean;
|
|
size?: ModalSize;
|
|
}
|
|
|
|
export default Vue.extend({
|
|
data() {
|
|
return {
|
|
shown: false,
|
|
shownFull: false,
|
|
hideTimeout: undefined as ReturnType<typeof setTimeout> | undefined,
|
|
choice: false,
|
|
icon: undefined as string | undefined,
|
|
header: undefined as string | undefined,
|
|
message: undefined as string | undefined,
|
|
margin: true,
|
|
color: null as Color | null,
|
|
value: undefined as string | string[] | undefined,
|
|
size: undefined as ModalSize,
|
|
resolve: undefined as ((value: string | string[] | undefined) => void) | undefined,
|
|
reject: undefined as (() => void) | undefined,
|
|
};
|
|
},
|
|
mounted() {
|
|
window.addEventListener('keydown', (e) => {
|
|
if (!this.shown) {
|
|
return;
|
|
}
|
|
|
|
if (e.keyCode === 27) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
this.cancel();
|
|
} else if (e.keyCode === 13) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
this.confirm();
|
|
}
|
|
});
|
|
},
|
|
methods: {
|
|
show(
|
|
choice: boolean,
|
|
message: string | DialogueMessage,
|
|
color: Color,
|
|
value: string | string[] | undefined,
|
|
size: ModalSize,
|
|
resolve: (value: string | string[] | undefined) => void,
|
|
reject: () => void,
|
|
) {
|
|
clearTimeout(this.hideTimeout);
|
|
this.choice = choice;
|
|
if (typeof message === 'string') {
|
|
message = { message };
|
|
}
|
|
this.icon = message.icon || (choice ? 'map-marker-question' : undefined);
|
|
this.header = message.header;
|
|
this.message = message.message || (choice ? this.$t('confirm.header') : undefined);
|
|
this.margin = message.margin ?? true;
|
|
this.size = message.size ?? size;
|
|
this.color = color;
|
|
this.value = value;
|
|
this.shown = true;
|
|
this.resolve = resolve;
|
|
this.reject = reject;
|
|
requestAnimationFrame(() => this.shownFull = true);
|
|
},
|
|
confirm() {
|
|
const resolve = this.resolve;
|
|
this.hide();
|
|
if (resolve) {
|
|
resolve(this.value);
|
|
}
|
|
},
|
|
cancel() {
|
|
const reject = this.reject;
|
|
this.hide();
|
|
if (reject) {
|
|
reject();
|
|
}
|
|
},
|
|
hide() {
|
|
this.shownFull = false;
|
|
this.hideTimeout = setTimeout(() => {
|
|
this.shown = false;
|
|
this.choice = false;
|
|
this.icon = undefined;
|
|
this.header = undefined;
|
|
this.message = undefined;
|
|
this.margin = true;
|
|
this.color = null;
|
|
this.value = undefined;
|
|
this.size = undefined;
|
|
this.resolve = undefined;
|
|
this.reject = undefined;
|
|
}, 500);
|
|
},
|
|
hideClick(event: Event) {
|
|
if (event.target === this.$el) {
|
|
this.cancel();
|
|
}
|
|
},
|
|
},
|
|
});
|
|
</script>
|