Skip to content

Commit

Permalink
feat: backwards compatible content helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
johannschopplich committed Dec 10, 2024
1 parent 532cee3 commit 3873526
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 23 deletions.
6 changes: 6 additions & 0 deletions src/composables/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { usePanel } from "./panel";

/**
* Returns Kirby's Panel API.
*
* @remarks
* This composable is a simple shortcut to `window.panel.api`.
*/
export function useApi() {
return usePanel().api;
}
6 changes: 6 additions & 0 deletions src/composables/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { usePanel } from "./panel";

/**
* Returns the Panel Vue instance.
*
* @remarks
* This composable is a simple shortcut to `window.panel.app`.
*/
export function useApp() {
return usePanel().app;
}
55 changes: 35 additions & 20 deletions src/composables/content.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,56 @@
import type { PanelContent } from "../types/panel";
import { computed } from "..";
import { isKirby5 } from "./compatibility";
import { usePanel } from "./panel";
import { useStore } from "./store";

/**
* Reactive getters and methods to work with content of the current view.
*
* @remarks
* This composable follows the Kirby 5 content API while staying compatible with Kirby 4 (falling back to the Vuex store of Kirby 4).
*/

export function useContent() {
const panel = usePanel();
const store = useStore();
const _isKirby5 = isKirby5();

if (!panel.content) {
throw new Error(
"The content object is not available. It requires Kirby 5 or higher.",
);
}
const currentContent = _isKirby5
? computed(() => panel.view.props.content)
: computed(() => store.getters["content/values"]());
const contentChanges = _isKirby5
? computed(() => panel.content.changes())
: computed(() => store.getters["content/changes"]());
const hasChanges = _isKirby5
? computed(() => store.getters["content/hasChanges"]())
: computed(() => Object.keys(contentChanges.value).length > 0);

const currentContent = computed(() => panel.view.props.content);
const contentChanges = computed(() => panel.content.changes());
const hasChanges = computed(
() => Object.keys(contentChanges.value).length > 0,
);
const content = _isKirby5 ? panel.content : ({} as PanelContent);

/**
* Updates the form values of the current view without saving.
*
* @remarks
* Technically almost identical to `panel.content.update()`, except that it doesn't save the changes.
* Updates the form values of the current view without saving them.
*/
const update = (values?: Record<string, any>) => {
if (!values || Object.keys(values).length === 0) {
return;
}

panel.view.props.content = {
...panel.view.props.originals,
...values,
};
if (!_isKirby5) {
for (const [key, value] of Object.entries(values)) {
store.dispatch("content/update", [key, value]);
}

return contentChanges.value;
}

return content.merge(values);
};

return {
// Reactive objects
content: panel.content,
// Properties
content,
// Reactive getters
currentContent,
contentChanges,
hasChanges,
Expand Down
6 changes: 6 additions & 0 deletions src/composables/panel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { Panel } from "../types/panel";

/**
* Returns the reactive Kirby Panel object.
*
* @remarks
* This composable is a simple shortcut to `window.panel`.
*/
export function usePanel(): Panel {
return window.panel;
}
3 changes: 3 additions & 0 deletions src/composables/section.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { useApi } from "./api";

/**
* Provides section methods for loading section data.
*/
export function useSection() {
const api = useApi();

Expand Down
11 changes: 8 additions & 3 deletions src/composables/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ interface PanelAppStoreGetters {
interface PanelAppStore {
state: PanelAppStoreState;
getters: PanelAppStoreGetters;
commit: (arg1: any, arg2: any, arg3: any) => any;
dispatch: (arg1: any, arg2: any) => any;
}

/** @deprecated The Vuex store is removed in Kirby 5 */
/**
* Returns the Vuex store of the Panel app.
*
* @deprecated The Vuex store is removed in Kirby 5. Use the `useContent` composable instead.
*/
export function useStore() {
// @ts-expect-error: Removed in Kirby 5
const store = usePanel().app.$store as Readonly<PanelAppStore>;
const store = (usePanel() as any).app.$store as Readonly<PanelAppStore>;

if (!store) {
throw new Error(
Expand Down

0 comments on commit 3873526

Please sign in to comment.