mirror of https://github.com/Fabio286/antares.git
feat: ability to edit notes
This commit is contained in:
parent
eaaf1b756a
commit
08e5a13f72
|
@ -0,0 +1,116 @@
|
|||
<template>
|
||||
<ConfirmModal
|
||||
size="medium"
|
||||
:disable-autofocus="true"
|
||||
:close-on-confirm="!!localNote.note.length"
|
||||
:confirm-text="t('general.save')"
|
||||
@confirm="updateNote"
|
||||
@hide="$emit('hide')"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<BaseIcon
|
||||
icon-name="mdiNoteEditOutline"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.editNote') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<form class="form">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-8">
|
||||
<label class="form-label">{{ t('connection.connection') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localNote.cUid"
|
||||
class="form-select"
|
||||
:options="connectionOptions"
|
||||
option-track-by="code"
|
||||
option-label="name"
|
||||
@change="null"
|
||||
/>
|
||||
</div>
|
||||
<div class="column col-4">
|
||||
<label class="form-label">{{ t('application.tag') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localNote.type"
|
||||
class="form-select"
|
||||
:options="noteTags"
|
||||
option-track-by="code"
|
||||
option-label="name"
|
||||
@change="null"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('general.content') }}</label>
|
||||
<BaseTextEditor
|
||||
v-model="localNote.note"
|
||||
:mode="editorMode"
|
||||
:show-line-numbers="false"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { inject, onBeforeMount, PropType, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import BaseTextEditor from '@/components/BaseTextEditor.vue';
|
||||
import { ConnectionNote, TagCode, useScratchpadStore } from '@/stores/scratchpad';
|
||||
|
||||
const { t } = useI18n();
|
||||
const { editNote } = useScratchpadStore();
|
||||
|
||||
const emit = defineEmits(['hide']);
|
||||
|
||||
const props = defineProps({
|
||||
note: {
|
||||
type: Object as PropType<ConnectionNote>,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const noteTags = inject<{code: TagCode; name: string}[]>('noteTags');
|
||||
const connectionOptions = inject<{code: string; name: string}[]>('connectionOptions');
|
||||
|
||||
const editorMode = ref('markdown');
|
||||
const localNote: Ref<ConnectionNote> = ref({
|
||||
uid: 'dummy',
|
||||
cUid: null,
|
||||
title: undefined,
|
||||
note: '',
|
||||
date: new Date(),
|
||||
type: 'note',
|
||||
isArchived: false
|
||||
});
|
||||
|
||||
const updateNote = () => {
|
||||
if (localNote.value.note) {
|
||||
if (!localNote.value.title)// Set a default title
|
||||
localNote.value.title = `${localNote.value.type.toLocaleUpperCase()}: ${localNote.value.uid}`;
|
||||
|
||||
localNote.value.date = new Date();
|
||||
editNote(localNote.value);
|
||||
emit('hide');
|
||||
}
|
||||
};
|
||||
|
||||
watch(() => localNote.value.type, () => {
|
||||
if (localNote.value.type === 'query')
|
||||
editorMode.value = 'sql';
|
||||
else
|
||||
editorMode.value = 'markdown';
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
localNote.value = props.note;
|
||||
});
|
||||
|
||||
</script>
|
|
@ -3,6 +3,7 @@
|
|||
size="medium"
|
||||
:disable-autofocus="true"
|
||||
:close-on-confirm="!!newNote.note.length"
|
||||
:confirm-text="t('general.save')"
|
||||
@confirm="createNote"
|
||||
@hide="$emit('hide')"
|
||||
>
|
|
@ -30,7 +30,8 @@
|
|||
<div class="tile-content-message" :class="[{'opened': isSelected}]">
|
||||
<code
|
||||
v-if="note.type === 'query'"
|
||||
class="cut-text"
|
||||
ref="noteParagraph"
|
||||
class="tile-paragraph"
|
||||
v-html="highlightWord(note.note)"
|
||||
/>
|
||||
<div
|
||||
|
@ -47,7 +48,7 @@
|
|||
<button
|
||||
v-if="note.type === 'todo' && !note.isArchived"
|
||||
class="btn btn-link pl-1"
|
||||
@click="$emit('archive-note', note.uid)"
|
||||
@click.stop="$emit('archive-note', note.uid)"
|
||||
>
|
||||
<BaseIcon
|
||||
icon-name="mdiCheck"
|
||||
|
@ -58,7 +59,7 @@
|
|||
<button
|
||||
v-if="note.type === 'todo' && note.isArchived"
|
||||
class="btn btn-link pl-1"
|
||||
@click="$emit('restore-note', note.uid)"
|
||||
@click.stop="$emit('restore-note', note.uid)"
|
||||
>
|
||||
<BaseIcon
|
||||
icon-name="mdiRestore"
|
||||
|
@ -69,7 +70,7 @@
|
|||
<button
|
||||
v-if="note.type === 'query'"
|
||||
class="btn btn-link pl-1"
|
||||
@click="copyText(note.note)"
|
||||
@click.stop="copyText(note.note)"
|
||||
>
|
||||
<BaseIcon
|
||||
icon-name="mdiContentCopy"
|
||||
|
@ -80,7 +81,7 @@
|
|||
<button
|
||||
v-if=" !note.isArchived"
|
||||
class="btn btn-link pl-1"
|
||||
@click="null"
|
||||
@click.stop="$emit('edit-note')"
|
||||
>
|
||||
<BaseIcon
|
||||
icon-name="mdiPencil"
|
||||
|
@ -88,7 +89,7 @@
|
|||
:size="22"
|
||||
/> {{ t('general.edit') }}
|
||||
</button>
|
||||
<button class="btn btn-link pl-1" @click="$emit('delete-note', note.uid)">
|
||||
<button class="btn btn-link pl-1" @click.stop="$emit('delete-note', note.uid)">
|
||||
<BaseIcon
|
||||
icon-name="mdiDeleteForever"
|
||||
class="pr-1"
|
||||
|
@ -131,7 +132,14 @@ const { t } = useI18n();
|
|||
const { formatDate } = useFilters();
|
||||
const { getConnectionName } = useConnectionsStore();
|
||||
|
||||
defineEmits(['delete-note', 'select-note', 'toggle-note', 'archive-note', 'restore-note']);
|
||||
defineEmits([
|
||||
'edit-note',
|
||||
'delete-note',
|
||||
'select-note',
|
||||
'toggle-note',
|
||||
'archive-note',
|
||||
'restore-note'
|
||||
]);
|
||||
|
||||
const noteParagraph: Ref<HTMLDivElement> = ref(null);
|
||||
const noteHeight = ref(useElementBounding(noteParagraph)?.height);
|
||||
|
@ -188,7 +196,7 @@ const highlightWord = (string: string) => {
|
|||
right: 2px;
|
||||
top: 0px;
|
||||
opacity: .7;
|
||||
z-index: 9;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.tile-icon {
|
||||
|
@ -233,13 +241,14 @@ const highlightWord = (string: string) => {
|
|||
}
|
||||
}
|
||||
|
||||
code {
|
||||
code, pre {
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
font-size: 100%;
|
||||
// color: $primary-color;
|
||||
opacity: 0.8;
|
||||
font-weight: 600;
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
.tile-subtitle {
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
:selected-note="selectedNote"
|
||||
@select-note="selectedNote = note.uid"
|
||||
@toggle-note="toggleNote"
|
||||
@edit-note="startEditNote(note)"
|
||||
@delete-note="deleteNote"
|
||||
@archive-note="archiveNote"
|
||||
@restore-note="restoreNote"
|
||||
|
@ -139,7 +140,12 @@
|
|||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
<ModalNewNote v-if="isAddModal" @hide="isAddModal = false" />
|
||||
<ModalNoteNew v-if="isAddModal" @hide="isAddModal = false" />
|
||||
<ModalNoteEdit
|
||||
v-if="isEditModal"
|
||||
:note="noteToEdit"
|
||||
@hide="closeEditModal"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -161,11 +167,12 @@ import { useI18n } from 'vue-i18n';
|
|||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue';
|
||||
import ModalNewNote from '@/components/ModalNewNote.vue';
|
||||
import ModalNoteEdit from '@/components/ModalNoteEdit.vue';
|
||||
import ModalNoteNew from '@/components/ModalNoteNew.vue';
|
||||
import ScratchpadNote from '@/components/ScratchpadNote.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { TagCode, useScratchpadStore } from '@/stores/scratchpad';
|
||||
import { ConnectionNote, TagCode, useScratchpadStore } from '@/stores/scratchpad';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
@ -194,6 +201,7 @@ const localSearchTerm = ref('');
|
|||
const showArchived = ref(false);
|
||||
const isAddModal = ref(false);
|
||||
const isEditModal = ref(false);
|
||||
const noteToEdit: Ref<ConnectionNote> = ref(null);
|
||||
const selectedTag = ref('all');
|
||||
const selectedNote = ref(null);
|
||||
|
||||
|
@ -241,6 +249,11 @@ const toggleNote = (uid: string) => {
|
|||
selectedNote.value = selectedNote.value !== uid ? uid : null;
|
||||
};
|
||||
|
||||
const startEditNote = (note: ConnectionNote) => {
|
||||
isEditModal.value = true;
|
||||
noteToEdit.value = note;
|
||||
};
|
||||
|
||||
const archiveNote = (uid: string) => {
|
||||
const remappedNotes = connectionNotes.value.map(n => {
|
||||
if (n.uid === uid)
|
||||
|
@ -264,6 +277,11 @@ const deleteNote = (uid: string) => {
|
|||
changeNotes(otherNotes);
|
||||
};
|
||||
|
||||
const closeEditModal = () => {
|
||||
isEditModal.value = false;
|
||||
noteToEdit.value = null;
|
||||
};
|
||||
|
||||
watch(searchTerm, () => {
|
||||
clearTimeout(searchTermInterval.value);
|
||||
|
||||
|
@ -310,6 +328,7 @@ onBeforeUnmount(() => {
|
|||
position: fixed;
|
||||
margin-top: -40px;
|
||||
margin-left: 580px;
|
||||
z-index: 9;
|
||||
}
|
||||
.archived-button {
|
||||
border-radius: 50%;
|
||||
|
|
|
@ -391,6 +391,7 @@ export const enUS = {
|
|||
note: 'Note | Notes',
|
||||
thereAreNoNotesYet: 'There are no notes yet',
|
||||
addNote: 'Add note',
|
||||
editNote: 'Edit note',
|
||||
showArchivedNotes: 'Show archived notes',
|
||||
hideArchivedNotes: 'Hide archived notes',
|
||||
tag: 'Tag' // Note tag
|
||||
|
|
|
@ -32,6 +32,15 @@ export const useScratchpadStore = defineStore('scratchpad', {
|
|||
...this.connectionNotes
|
||||
];
|
||||
persistentStore.set('connectionNotes', this.connectionNotes);
|
||||
},
|
||||
editNote (note: ConnectionNote) {
|
||||
this.connectionNotes = (this.connectionNotes as ConnectionNote[]).map(n => {
|
||||
if (n.uid === note.uid)
|
||||
n = note;
|
||||
|
||||
return n;
|
||||
});
|
||||
persistentStore.set('connectionNotes', this.connectionNotes);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue