Use EditableField for notes editor

This commit is contained in:
Girish Ramakrishnan
2025-09-17 11:24:00 +02:00
parent 76ec0b6d74
commit 7c0f4ad255
2 changed files with 25 additions and 52 deletions
+19 -50
View File
@@ -1,24 +1,23 @@
<script setup>
import { onMounted, ref, useTemplateRef, inject } from 'vue';
import { onMounted, ref, inject } from 'vue';
import { Button } from '@cloudron/pankow';
import { prettyDate } from '@cloudron/pankow/utils';
import { stripSsoInfo } from '../../utils.js';
import { marked } from 'marked';
import AppsModel from '../../models/AppsModel.js';
import EditableField from '../../components/EditableField.vue';
import SettingsItem from '../../components/SettingsItem.vue';
const appsModel = AppsModel.create();
const props = defineProps([ 'app' ]);
const emit = defineEmits([ 'changed' ]);
const notesTextarea = useTemplateRef('notesTextarea');
const showDoneChecklist = ref(false);
const hasOldChecklist = ref(false);
const editing = ref(false);
const busy = ref(false);
const placeholder = 'Add admin notes here...';
const noteContent = ref('');
const profile = inject('profile');
async function onAckChecklistItem(item, key) {
@@ -31,42 +30,26 @@ async function onAckChecklistItem(item, key) {
hasOldChecklist.value = true;
}
async function onSubmit() {
busy.value = true;
// Notes
const notes = ref('');
const savingNotes = ref(false);
// skip saving if unchanged from postInstall
if (noteContent.value === props.app.manifest.postInstallMessage) {
busy.value = false;
editing.value = false;
return;
}
async function onNotesSave(newNotes) {
savingNotes.value = true;
const [error] = await appsModel.configure(props.app.id, 'notes', { notes: noteContent.value });
if (error) {
busy.value = false;
return console.error(error);
}
const [error] = await appsModel.configure(props.app.id, 'notes', { notes: newNotes });
savingNotes.value = false;
if (error) return console.error(error);
// let main view know about this
emit('changed');
editing.value = false;
busy.value = false;
}
function onEdit() {
editing.value = true;
setTimeout(() => notesTextarea.value.focus(), 200);
}
function onDismiss() {
editing.value = false;
noteContent.value = props.app.notes === null ? props.app.manifest.postInstallMessage : props.app.notes;
notes.value = newNotes;
if (!notes.value) notes.value = placeholder;
}
onMounted(() => {
hasOldChecklist.value = !!Object.keys(props.app.checklist).find((k) => { return props.app.checklist[k].acknowledged; });
noteContent.value = props.app.notes === null ? props.app.manifest.postInstallMessage : props.app.notes;
notes.value = props.app.notes;
if (notes.value === null && props.app.manifest.postInstallMessage) notes.value = stripSsoInfo(props.app.manifest.postInstallMessage, props.app.sso).trim();
if (!notes.value) notes.value = placeholder;
editing.value = false;
busy.value = false;
@@ -127,23 +110,9 @@ onMounted(() => {
<br/>
<p>
<label class="control-label">{{ $t('app.info.notes.title') }}</label><i v-show="!editing" class="info-edit-indicator fa fa-pencil-alt" @click="onEdit()"></i>
</p>
<div>
<div v-show="!editing">
<div v-if="noteContent" v-html="marked.parse(stripSsoInfo(noteContent, app.sso))"></div>
<div v-else class="text-muted hand" @click="onEdit()">{{ placeholder }}</div>
</div>
<div v-show="editing">
<textarea ref="notesTextarea" style="white-space: pre-wrap; margin-bottom: 5px; width: 100%" v-model="noteContent" rows="10"></textarea>
<div style="display: flex; gap: 5px">
<Button secondary @click="onDismiss()" v-show="!busy">{{ $t('main.dialog.cancel') }}</Button>
<Button @click="onSubmit()" :disabled="busy" :loading="busy">{{ $t('app.display.saveAction') }}</Button>
</div>
</div>
</div>
<SettingsItem>
<EditableField :label="$t('app.info.notes.title')" multiline markdown rows="8" :saving="savingNotes" :value="notes" @save="onNotesSave"/>
</SettingsItem>
</div>
</template>