From 68c031b1c2797a8bb5a9c9b3d7ca853b9d6e4372 Mon Sep 17 00:00:00 2001 From: Marcos Candeia Date: Mon, 26 Feb 2024 21:01:39 -0300 Subject: [PATCH 1/2] Create inline action Signed-off-by: Marcos Candeia --- blocks/section.ts | 38 ++++++++++++++++++++++++++++---------- components/Form.tsx | 8 ++++++++ 2 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 components/Form.tsx diff --git a/blocks/section.ts b/blocks/section.ts index 2869b9058..7f3c364f5 100644 --- a/blocks/section.ts +++ b/blocks/section.ts @@ -1,4 +1,5 @@ // deno-lint-ignore-file no-explicit-any +import { PartialProps } from "$fresh/src/runtime/Partial.tsx"; import { ComponentType } from "preact"; import { HttpContext } from "../blocks/handler.ts"; import { PropsLoader, propsLoader } from "../blocks/propsLoader.ts"; @@ -16,7 +17,6 @@ import { } from "../engine/block.ts"; import { Resolver } from "../engine/core/resolver.ts"; import { AppManifest, FunctionContext } from "../types.ts"; -import { PartialProps } from "$fresh/src/runtime/Partial.tsx"; /** * @widget none @@ -55,15 +55,21 @@ export interface ErrorBoundaryParams { export type ErrorBoundaryComponent = ComponentFunc< ErrorBoundaryParams >; -export interface SectionModule extends +export interface SectionModule< + TConfig = any, + TProps = any, + TLoaderProps = TProps, + TActionProps = TProps, +> extends BlockModule< - ComponentFunc, - ReturnType>, + ComponentFunc, + ReturnType>, PreactComponent > { LoadingFallback?: ComponentType; ErrorFallback?: ComponentType<{ error?: Error }>; - loader?: PropsLoader; + loader?: PropsLoader; + action?: PropsLoader; partialMode?: PartialProps["mode"]; } @@ -101,7 +107,10 @@ export const createSectionBlock = ( type: "sections" | "pages", ): Block => ({ type, - introspect: { funcNames: ["loader", "default"], includeReturn: true }, + introspect: { + funcNames: ["loader", "action", "default"], + includeReturn: true, + }, adapt: ( mod: SectionModule, resolver: string, @@ -123,8 +132,8 @@ export const createSectionBlock = ( mod.ErrorFallback, mod.partialMode, ); - const loader = mod.loader; - if (!loader) { + + if (!mod.action && !mod.loader) { return ( props: TProps, ctx: HttpContext, @@ -142,17 +151,26 @@ export const createSectionBlock = ( resolve, } = httpCtx; + const loaderSectionProps = request.method === "POST" + ? mod.action ?? mod.loader + : mod.loader; + + if (!loaderSectionProps) { + return componentFunc(props as unknown as TProps, httpCtx); + } + const ctx = { ...context, state: { ...context.state, $live: props, resolve }, } as FunctionContext; + const fnContext = fnContextFromHttpContext(httpCtx); const p = await wrapCaughtErrors(() => propsLoader( - loader, + loaderSectionProps, ctx.state.$live, request, - fnContextFromHttpContext(httpCtx), + fnContext, ), props ?? {}); return componentFunc(p, httpCtx); diff --git a/components/Form.tsx b/components/Form.tsx new file mode 100644 index 000000000..cd42af546 --- /dev/null +++ b/components/Form.tsx @@ -0,0 +1,8 @@ +import { JSX } from "preact"; +import { usePartialSection } from "../hooks/usePartialSection.ts"; + +export function Form(props: JSX.IntrinsicElements["form"]) { + return ( +
+ ); +} From fdc329936b962d7b7d0456b7a700e775598fa039 Mon Sep 17 00:00:00 2001 From: Marcos Candeia Date: Tue, 27 Feb 2024 10:13:54 -0300 Subject: [PATCH 2/2] Add use action hook Signed-off-by: Marcos Candeia --- blocks/section.ts | 10 +++++++--- components/Form.tsx | 8 -------- hooks/useAction.ts | 8 ++++++++ 3 files changed, 15 insertions(+), 11 deletions(-) delete mode 100644 components/Form.tsx create mode 100644 hooks/useAction.ts diff --git a/blocks/section.ts b/blocks/section.ts index 7f3c364f5..c2d0f0336 100644 --- a/blocks/section.ts +++ b/blocks/section.ts @@ -3,7 +3,7 @@ import { PartialProps } from "$fresh/src/runtime/Partial.tsx"; import { ComponentType } from "preact"; import { HttpContext } from "../blocks/handler.ts"; import { PropsLoader, propsLoader } from "../blocks/propsLoader.ts"; -import { fnContextFromHttpContext, RequestState } from "../blocks/utils.tsx"; +import { RequestState, fnContextFromHttpContext } from "../blocks/utils.tsx"; import StubSection, { Empty } from "../components/StubSection.tsx"; import { withSection } from "../components/section.tsx"; import { Context } from "../deco.ts"; @@ -44,9 +44,13 @@ export const isSection = < return (s as Section)?.metadata?.component === section; }; -export type SectionProps = T extends PropsLoader ? Props +type ReturnProps = TFunc extends PropsLoader ? Props : unknown; +export type SectionProps = + | ReturnProps + | ReturnProps; + export interface ErrorBoundaryParams { error: any; props: TProps; @@ -59,7 +63,7 @@ export interface SectionModule< TConfig = any, TProps = any, TLoaderProps = TProps, - TActionProps = TProps, + TActionProps = TLoaderProps, > extends BlockModule< ComponentFunc, diff --git a/components/Form.tsx b/components/Form.tsx deleted file mode 100644 index cd42af546..000000000 --- a/components/Form.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { JSX } from "preact"; -import { usePartialSection } from "../hooks/usePartialSection.ts"; - -export function Form(props: JSX.IntrinsicElements["form"]) { - return ( - - ); -} diff --git a/hooks/useAction.ts b/hooks/useAction.ts new file mode 100644 index 000000000..3642d290b --- /dev/null +++ b/hooks/useAction.ts @@ -0,0 +1,8 @@ +import { usePartialSection } from "./usePartialSection.ts"; + +/** + * @returns the action url of the current section. + */ +export const useAction = () => { + return usePartialSection()["f-partial"]; +};