diff --git a/alfred/apps.py b/alfred/apps.py index 15c66bfc8..4323d4d71 100644 --- a/alfred/apps.py +++ b/alfred/apps.py @@ -38,10 +38,6 @@ def apps_update(app: str = None): if not os.path.isdir(abs_path): continue - if os.path.isfile(os.path.join(abs_path, "ui.json")): - print(f'{app} : migrate ui.json') - wf_project.migrate_obsolete_ui_json(abs_path, {"writer_version": VERSION}) - if not os.path.isfile(os.path.join(abs_path, ".wf", 'components-workflows_root.jsonl')): wf_project.create_default_workflows_root(abs_path) @@ -51,5 +47,5 @@ def apps_update(app: str = None): else: metadata['writer_version'] = writer.VERSION components = audit_and_fix.fix_components(components) - wf_project.write_files(abs_path, metadata, components) + wf_project.write_files(abs_path, metadata, components, context=wf_project.WfProjectContext(app_path=abs_path)) print(f"{app} : app is up to date") diff --git a/pyproject.toml b/pyproject.toml index 2ae4f7e6d..f95eec470 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "writer" -version = "0.8.3rc18" +version = "0.8.3rc19" description = "An open-source, Python framework for building feature-rich apps that are fully integrated with the Writer platform." authors = ["Writer, Inc."] readme = "README.md" diff --git a/src/ui/src/builder/BuilderApp.vue b/src/ui/src/builder/BuilderApp.vue index 62295be50..b94812682 100644 --- a/src/ui/src/builder/BuilderApp.vue +++ b/src/ui/src/builder/BuilderApp.vue @@ -124,6 +124,7 @@ const wf = inject(injectionKeys.core); const ssbm = inject(injectionKeys.builderManager); const tracking = useWriterTracking(wf); +const toasts = useToasts(); const { candidateId, @@ -146,14 +147,20 @@ const { isCutAllowed, isDeleteAllowed, isGoToParentAllowed, + isGoToChildAllowed, + isGoToNextSiblingAllowed, + isGoToPrevSiblingAllowed, pasteComponent, copyComponent, removeComponentsSubtree, goToParent, + goToChild, + goToNextSibling, + goToPrevSibling, + moveComponentToParent, + moveComponentInsideNextSibling, } = useComponentActions(wf, ssbm, tracking); -const toasts = useToasts(); - const builderMode = computed(() => ssbm.getMode()); const selectedId = computed(() => ssbm.firstSelectedId.value); @@ -192,37 +199,63 @@ async function handleKeydown(ev: KeyboardEvent) { removeComponentsSubtree(...componentIds); return; } - if (ev.key == "ArrowUp" && isModifierKeyActive && ev.shiftKey) { - if (!isGoToParentAllowed(selectedId)) return; - goToParent(selectedId, selectedInstancePath); - return; - } - if (ev.key == "ArrowUp" && isModifierKeyActive) { - moveComponentUp(selectedId); - return; - } - if (ev.key == "ArrowDown" && isModifierKeyActive) { - moveComponentDown(selectedId); - return; - } - if (ev.key == "v" && isModifierKeyActive) { - if (!isPasteAllowed(selectedId)) return; - try { - await pasteComponent(selectedId); - } catch (error) { - toasts.pushToast({ type: "error", message: String(error) }); + if (!isModifierKeyActive) return; + + if (ev.shiftKey) { + switch (ev.key) { + case "ArrowDown": + ev.preventDefault(); + if (isGoToNextSiblingAllowed(selectedId)) + goToNextSibling(selectedId); + break; + case "ArrowUp": + ev.preventDefault(); + if (isGoToPrevSiblingAllowed(selectedId)) + goToPrevSibling(selectedId); + break; + case "ArrowLeft": + ev.preventDefault(); + if (isGoToParentAllowed(selectedId)) + goToParent(selectedId, selectedInstancePath); + break; + case "ArrowRight": + ev.preventDefault(); + if (isGoToChildAllowed(selectedId)) goToChild(selectedId); + break; + } + } else { + switch (ev.key) { + case "ArrowDown": + ev.preventDefault(); + moveComponentDown(selectedId); + break; + case "ArrowUp": + ev.preventDefault(); + moveComponentUp(selectedId); + break; + case "ArrowLeft": + ev.preventDefault(); + moveComponentToParent(selectedId); + break; + case "ArrowRight": + ev.preventDefault(); + moveComponentInsideNextSibling(selectedId); + break; + case "v": + if (!isPasteAllowed(selectedId)) return; + try { + await pasteComponent(selectedId); + } catch (error) { + toasts.pushToast({ type: "error", message: String(error) }); + } + break; + case "c": + if (isCopyAllowed(selectedId)) copyComponent(selectedId); + break; + case "x": + if (isCutAllowed(selectedId)) cutComponent(selectedId); + break; } - return; - } - if (ev.key == "c" && isModifierKeyActive) { - if (!isCopyAllowed(selectedId)) return; - copyComponent(selectedId); - return; - } - if (ev.key == "x" && isModifierKeyActive) { - if (!isCutAllowed(selectedId)) return; - cutComponent(selectedId); - return; } } diff --git a/src/ui/src/builder/settings/BuilderFieldsKeyValue.vue b/src/ui/src/builder/settings/BuilderFieldsKeyValue.vue index ef8964b12..bf66fc8fd 100644 --- a/src/ui/src/builder/settings/BuilderFieldsKeyValue.vue +++ b/src/ui/src/builder/settings/BuilderFieldsKeyValue.vue @@ -1,92 +1,79 @@ + + diff --git a/src/ui/src/builder/settings/BuilderFieldsKeyValueModal.vue b/src/ui/src/builder/settings/BuilderFieldsKeyValueModal.vue new file mode 100644 index 000000000..c9ab36747 --- /dev/null +++ b/src/ui/src/builder/settings/BuilderFieldsKeyValueModal.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/src/ui/src/builder/settings/BuilderTemplateInput.vue b/src/ui/src/builder/settings/BuilderTemplateInput.vue index 65a617522..db254dcbc 100644 --- a/src/ui/src/builder/settings/BuilderTemplateInput.vue +++ b/src/ui/src/builder/settings/BuilderTemplateInput.vue @@ -20,7 +20,10 @@ :value="optionKey" > @@ -46,8 +49,10 @@