mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
add: ctrl/cmd + s to save the document.
This commit is contained in:
+17
-2
@@ -6,14 +6,29 @@ import { defaultKeymap, historyKeymap, indentLess, indentMore } from '@codemirro
|
||||
// main editor keymaps,
|
||||
// these require functions from the component
|
||||
export function createEditorKeymaps(
|
||||
insertNewlineKeepIndent: (view: EditorView) => boolean
|
||||
insertNewlineKeepIndent: (view: EditorView) => boolean,
|
||||
onSave?: () => Promise<void> | void
|
||||
): KeyBinding[] {
|
||||
return [
|
||||
const keymaps: KeyBinding[] = [
|
||||
{ key: 'Tab', run: indentMore },
|
||||
{ key: 'Enter', run: insertNewlineKeepIndent },
|
||||
{ key: 'Shift-Enter', run: insertNewlineKeepIndent },
|
||||
{ key: 'Shift-Tab', run: indentLess }
|
||||
];
|
||||
|
||||
// Add Cmd/Ctrl+S save shortcut if save handler is provided
|
||||
if (onSave) {
|
||||
keymaps.push({
|
||||
key: 'Mod-s',
|
||||
preventDefault: true,
|
||||
run: () => {
|
||||
onSave();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return keymaps;
|
||||
}
|
||||
|
||||
// Secondary keymaps - these are standard CodeMirror keymaps
|
||||
|
||||
+30
-25
@@ -79,6 +79,7 @@
|
||||
readonly?: boolean;
|
||||
wrapLines?: boolean;
|
||||
errorInPlace?: boolean;
|
||||
ctrlSave?: boolean;
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -90,7 +91,8 @@
|
||||
loading = false,
|
||||
readonly = false,
|
||||
wrapLines = true,
|
||||
errorInPlace = true
|
||||
errorInPlace = true,
|
||||
ctrlSave = false
|
||||
}: Props = $props();
|
||||
|
||||
let editorContainer: HTMLDivElement = $state(null);
|
||||
@@ -119,7 +121,7 @@
|
||||
let wasNew = isNew;
|
||||
|
||||
// Generate a stable ID once for new documents
|
||||
const generatedId = ID.unique();
|
||||
let generatedId = $state(ID.unique());
|
||||
|
||||
// Get $id from data
|
||||
const documentId = $derived(
|
||||
@@ -694,6 +696,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Handle save logic - called from both button and keyboard shortcut
|
||||
async function handleSave(): Promise<void> {
|
||||
if (!hasDataChanged) return;
|
||||
|
||||
isSaving = true;
|
||||
|
||||
let dataToSave = data;
|
||||
if (isNew && typeof data === 'object' && data !== null && !Array.isArray(data)) {
|
||||
const dataObj = data;
|
||||
if (!dataObj['$id']) {
|
||||
dataToSave = { $id: generatedId, ...dataObj };
|
||||
}
|
||||
}
|
||||
|
||||
await sleep(2500);
|
||||
await onSave?.(dataToSave);
|
||||
isSaving = false;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if (!editorContainer) return;
|
||||
|
||||
@@ -729,7 +750,9 @@
|
||||
}
|
||||
}),
|
||||
// Override Enter and Shift-Enter to keep current indent, no extra +indentUnit
|
||||
keymap.of(createEditorKeymaps(insertNewlineKeepIndent)),
|
||||
keymap.of(
|
||||
createEditorKeymaps(insertNewlineKeepIndent, ctrlSave ? handleSave : undefined)
|
||||
),
|
||||
keymap.of(secondaryKeymaps),
|
||||
javascript(),
|
||||
customSyntaxHighlighting,
|
||||
@@ -804,6 +827,7 @@
|
||||
$effect(() => {
|
||||
if (isNew && !wasNew) {
|
||||
originalData = $state.snapshot(data);
|
||||
generatedId = ID.unique();
|
||||
}
|
||||
wasNew = isNew;
|
||||
});
|
||||
@@ -857,10 +881,11 @@
|
||||
});
|
||||
|
||||
// React to read-only prop changes via Compartment reconfigure
|
||||
// Also make editor read-only while saving to prevent concurrent edits
|
||||
$effect(() => {
|
||||
if (!editorView) return;
|
||||
editorView.dispatch({
|
||||
effects: readOnlyCompartment.reconfigure(EditorState.readOnly.of(readonly))
|
||||
effects: readOnlyCompartment.reconfigure(EditorState.readOnly.of(readonly || isSaving))
|
||||
});
|
||||
});
|
||||
|
||||
@@ -901,27 +926,7 @@
|
||||
size="xs"
|
||||
disabled={!hasDataChanged}
|
||||
class="icon-button"
|
||||
on:click={async () => {
|
||||
isSaving = true;
|
||||
|
||||
// For new documents, ensure $id is added to data before saving
|
||||
let dataToSave = data;
|
||||
if (
|
||||
isNew &&
|
||||
typeof data === 'object' &&
|
||||
data !== null &&
|
||||
!Array.isArray(data)
|
||||
) {
|
||||
const dataObj = data;
|
||||
if (!dataObj['$id']) {
|
||||
dataToSave = { $id: generatedId, ...dataObj };
|
||||
}
|
||||
}
|
||||
|
||||
await sleep(2500);
|
||||
await onSave?.(dataToSave);
|
||||
isSaving = false;
|
||||
}}>
|
||||
on:click={handleSave}>
|
||||
{#if isSaving}
|
||||
<Spinner size="s" />
|
||||
{:else}
|
||||
|
||||
+1
@@ -651,6 +651,7 @@
|
||||
|
||||
{#snippet noSqlEditor()}
|
||||
<NoSqlEditor
|
||||
ctrlSave
|
||||
isNew={$noSqlDocument.isNew}
|
||||
bind:data={$noSqlDocument.document}
|
||||
onSave={async (document) => await createOrUpdateDocument(document)} />
|
||||
|
||||
Reference in New Issue
Block a user