79 lines
2.6 KiB
Vue
79 lines
2.6 KiB
Vue
<script setup>
|
|
|
|
import { ref, watch, nextTick, useTemplateRef } from 'vue';
|
|
import { Button, FormGroup, TextInput } from '@cloudron/pankow';
|
|
import { marked } from 'marked';
|
|
|
|
const props = defineProps({
|
|
label: { type: String, required: true },
|
|
helpUrl: { type: String, required: false },
|
|
value: { type: String, required: true },
|
|
disabled: { type: Boolean, default: false },
|
|
required: { type: Boolean, default: false },
|
|
saving: { type: Boolean, default: false },
|
|
multiline: { type: Boolean, default: false },
|
|
markdown: { type: Boolean, default: false },
|
|
rows: { type: Number, default: 2 },
|
|
maxlength: { type: Number, default: -1 },
|
|
});
|
|
|
|
const emit = defineEmits(['save']);
|
|
|
|
const editing = ref(false);
|
|
const draftValue = ref(props.value);
|
|
const textInput = useTemplateRef('textInput');
|
|
|
|
watch(() => props.value, (newVal) => {
|
|
if (!editing.value) draftValue.value = newVal;
|
|
});
|
|
|
|
watch(() => props.saving, (isSaving) => {
|
|
if (!isSaving && editing.value) {
|
|
editing.value = false;
|
|
}
|
|
});
|
|
|
|
function startEdit() {
|
|
if (props.disabled) return;
|
|
editing.value = true;
|
|
draftValue.value = props.value;
|
|
nextTick(() => {
|
|
textInput.value.focus();
|
|
});
|
|
}
|
|
|
|
function save() {
|
|
if (props.required && !draftValue.value) return;
|
|
emit('save', draftValue.value);
|
|
}
|
|
|
|
function cancel() {
|
|
editing.value = false;
|
|
}
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<FormGroup>
|
|
<label>{{ label }} <sup v-if="helpUrl"><a :href="helpUrl" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
|
<div v-if="editing" style="display: flex; align-items: center; gap: 6px">
|
|
<TextInput v-if="!multiline" ref="textInput" v-model="draftValue" @keydown.enter="save()" :disabled="saving" :required="required ? true : null" :maxlength="maxlength === -1 ? null : maxlength"/>
|
|
<textarea v-else ref="textInput" :rows="rows" cols="80" v-model="draftValue" :disabled="saving" :required="required ? true : null" :maxlength="maxlength === -1 ? null : maxlength"></textarea>
|
|
<Button tool @click="save" :disabled="saving || (required && !draftValue)">{{ $t('main.dialog.save') }}</Button>
|
|
<Button tool plain secondary @click="cancel" :disabled="saving">{{ $t('main.dialog.cancel') }}</Button>
|
|
</div>
|
|
<div v-else>
|
|
<div v-if="markdown" v-html="marked.parseInline(value)"></div>
|
|
<div v-else>{{ value }}</div>
|
|
</div>
|
|
</FormGroup>
|
|
|
|
<div>
|
|
<div v-if="editing" style="display: flex; align-items: center; gap: 10px">
|
|
</div>
|
|
<div v-else>
|
|
<Button tool plain @click="startEdit" v-if="!disabled">{{ $t('main.dialog.edit') }}</Button>
|
|
</div>
|
|
</div>
|
|
</template>
|