From 35f61e4f842719dc1af20772ed75d8684bf85968 Mon Sep 17 00:00:00 2001 From: Alex Rock Date: Fri, 26 Apr 2024 01:06:49 -0600 Subject: [PATCH 1/2] feat: update creating new Space example --- app/NewSpace/index.tsx | 148 +++++++++++++++++++++---------------- app/listeners/listeners.ts | 4 +- pages/new-space/index.tsx | 46 +++++++++--- 3 files changed, 122 insertions(+), 76 deletions(-) diff --git a/app/NewSpace/index.tsx b/app/NewSpace/index.tsx index 444df5e..51dc594 100644 --- a/app/NewSpace/index.tsx +++ b/app/NewSpace/index.tsx @@ -1,75 +1,99 @@ "use client"; -import { ISpace, useSpace } from "@flatfile/react"; +import api, { Flatfile } from "@flatfile/api"; +import { + Space, + Workbook, + useEvent, + useFlatfile, + usePlugin, +} from "@flatfile/react"; import Link from "next/link"; import React, { useState } from "react"; +import { workbook } from "../workbooks/workbooks"; +import { recordHook } from "@flatfile/plugin-record-hook"; -const Space = ({ - callback, - config, -}: { - callback: () => void; - config: ISpace; -}) => { - return useSpace({ - ...config, - closeSpace: { +export default function NewSpace({ config }: { config: Flatfile.SpaceConfig }) { + const [success, setSuccess] = useState(false); + const { openPortal, open, closePortal } = useFlatfile(); + + // Can be used for debugging + // useEvent("**", (event) => { + // console.log("EVENT -> ", { event }); + // }); + + usePlugin( + recordHook("contacts", (record) => { + const firstName = record.get("firstName"); + console.log({ firstName }); + record.set("lastName", "Rock"); + return record; + }) + ); + + useEvent( + "job:ready", + { job: "workbook:submitActionFg" }, + async ({ context: { jobId } }) => { + try { + await api.jobs.ack(jobId, { + info: "Getting started.", + progress: 10, + }); + + // Make changes after cells in a Sheet have been updated + console.log("Make changes here when an action is clicked"); + + await api.jobs.complete(jobId, { + outcome: { + acknowledge: true, + message: "This is now complete.", + next: { + type: "wait", + }, + }, + }); + } catch (error: any) { + console.error("Error:", error.stack); + + await api.jobs.fail(jobId, { + outcome: { + message: "This job encountered an error.", + }, + }); + } + } + ); + + useEvent( + "job:outcome-acknowledged", + { operation: "submitActionFg", - onClose: () => callback(), + status: "complete", }, - }); -}; + async (event) => { + // any logic related to the event needed for closing the event + console.log("Window Closed!"); + // close the portal iFrame window + closePortal(); + setSuccess(true); + } + ); -export default function NewSpace({ config }: { config: ISpace }) { - const [showSpace, setShowSpace] = useState(false); - const [success, setSuccess] = useState(false); - const credentials = !!config.publishableKey; return (
- {credentials ? ( - <> -
- -
- {showSpace && ( -
- { - setShowSpace(false); - setSuccess(true); - }} - config={config} - /> -
- )} - - ) : ( -
- - - - - Error! Please add your
publishableKey
and{" "} -
environmentId
-
+ <> +
+
- )} +
+ + + +
+ + {success && (
{ +export const listener = (listener: FlatfileListener) => { listener.on("**", (event) => { console.log(`Received event: ${event.topic}`, { event }); }); @@ -81,4 +81,4 @@ export const listener = FlatfileListener.create((listener) => { } }); }); -}); +}; diff --git a/pages/new-space/index.tsx b/pages/new-space/index.tsx index 58cc037..a75b212 100644 --- a/pages/new-space/index.tsx +++ b/pages/new-space/index.tsx @@ -1,23 +1,43 @@ -import { ISpace, makeTheme } from "@flatfile/react"; +import { ISpace, makeTheme, FlatfileProvider, Space } from "@flatfile/react"; import React from "react"; import NewSpaceApp from "@/app/NewSpace"; import { listener } from "@/app/listeners/listeners"; import { workbook } from "@/app/workbooks/workbooks"; +import { Flatfile } from "@flatfile/api"; export default function newSpace() { const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_FLATFILE_PUBLISHABLE_KEY; - if (!PUBLISHABLE_KEY) return <>No Publishable Key Available; + if (!PUBLISHABLE_KEY) + return ( +
+ + + + + Error! Please add your
publishableKey
and{" "} +
environmentId
+
+
+ ); - const spaceProps: ISpace = { + const spaceProps: Flatfile.SpaceConfig = { name: "Embedded Space", - // to test locally add your publishableKey here, for example: pk_12345, - publishableKey: PUBLISHABLE_KEY, - workbook, - listener, - themeConfig: makeTheme({ primaryColor: "#546a76", textColor: "#fff" }), - sidebarConfig: { - showDataChecklist: false, - showSidebar: false, + metadata: { + theme: makeTheme({ primaryColor: "#546a76", textColor: "#fff" }), + sidebarConfig: { + showDataChecklist: false, + showSidebar: false, + }, }, }; return ( @@ -31,7 +51,9 @@ export default function newSpace() { they left off until the task is done.

- + + +
); From fab5cb8c414a11984c204fab3b71cb01203b9376 Mon Sep 17 00:00:00 2001 From: Alex Rock Date: Fri, 26 Apr 2024 01:39:06 -0600 Subject: [PATCH 2/2] feat: adds example for re-using a space --- app/ReuseSpace/index.tsx | 219 ++++++++++++++---------------------- app/listeners/listeners.ts | 4 +- pages/reuse-space/index.tsx | 87 +++++++++++++- 3 files changed, 171 insertions(+), 139 deletions(-) diff --git a/app/ReuseSpace/index.tsx b/app/ReuseSpace/index.tsx index 7b36806..dd3b4dd 100644 --- a/app/ReuseSpace/index.tsx +++ b/app/ReuseSpace/index.tsx @@ -1,157 +1,106 @@ "use client"; -import { ISpace, useSpace } from "@flatfile/react"; -import React, { Dispatch, SetStateAction, useEffect, useState } from "react"; -import { listener } from "../listeners/listeners"; +import { + FlatfileContext, + Space, + useEvent, + useFlatfile, + usePlugin, +} from "@flatfile/react"; +import React, { useContext, useEffect } from "react"; +import api from "@flatfile/api"; +import { recordHook } from "@flatfile/plugin-record-hook"; -const Space = ({ - setShowSpace, - config, -}: { - setShowSpace: Dispatch>; - config: { - spaceId: string; - environmentId: string; - accessToken: string; - }; -}) => { - const spaceProps: ISpace = { - environmentId: config.environmentId, - listener, - space: { - id: config.spaceId, - accessToken: config.accessToken, - }, - }; - return useSpace({ - ...spaceProps, - closeSpace: { - operation: "simpleSubmitAction", - onClose: () => setShowSpace(false), - }, +export default function ReuseSpace({ spaceId }: { spaceId?: string }) { + const { openPortal, open, closePortal } = useFlatfile(); + const context = useContext(FlatfileContext); + useEffect(() => { + console.log({ context }); + }, [context]); + // Can be used for debugging + useEvent("**", (event) => { + console.log("EVENT -> ", { event }); }); -}; -export default function ReuseSpace({ - spaceId, - environmentId, -}: { - spaceId?: string; - environmentId?: string; -}) { - const [showSpace, setShowSpace] = useState(false); - const [loading, setLoading] = useState(true); - const [data, setData] = useState(); - const [error, setError] = useState(); - - useEffect(() => { - const fetchData = async (spaceId: string) => { - const response = await fetch(`/api/spaces/${spaceId}`); - const json = await response.json(); - if (json.error) { - setError(json.error); - setLoading(false); - return; - } - const spaceInfo = { - spaceId, - accessToken: json.space.data.accessToken, - ...(environmentId ? { environmentId } : {}), - }; + usePlugin( + recordHook("contacts", (record) => { + const firstName = record.get("firstName"); + console.log({ firstName }); + record.set("lastName", "Rock"); + return record; + }) + ); - setData(spaceInfo); - setLoading(false); - }; + useEvent( + "job:ready", + { job: "workbook:submitActionFg" }, + async ({ context: { jobId } }) => { + try { + await api.jobs.ack(jobId, { + info: "Getting started.", + progress: 10, + }); - if (!spaceId) { - setLoading(false); - return; - } + // Make changes after cells in a Sheet have been updated + console.log("Make changes here when an action is clicked"); - fetchData(spaceId).catch((err) => { - setLoading(false); - setError(err); - }); - }, [spaceId, environmentId]); + await api.jobs.complete(jobId, { + outcome: { + acknowledge: true, + message: "This is now complete.", + next: { + type: "wait", + }, + }, + }); + } catch (error: any) { + console.error("Error:", error.stack); - if (loading) { - return ( - - ); - } - if (!spaceId || error) { - return ( -
- - - - - {(!spaceId || !environmentId) && ( - - Please add a
spaceId
and
environmentId
-
- )} - {error && ( - - {error} Make sure to set the
FLATFILE_API_KEY
in your{" "} -
.env
file.
- You can find that in your Flatfile Dashboard under Developer - Settings. -
- )} -
-
- ); - } + await api.jobs.fail(jobId, { + outcome: { + message: "This job encountered an error.", + }, + }); + } + } + ); + useEvent( + "job:outcome-acknowledged", + { + operation: "submitActionFg", + status: "complete", + }, + async (event) => { + // any logic related to the event needed for closing the event + console.log("Window Closed!"); + // close the portal iFrame window + closePortal(); + } + ); return (
- {showSpace && ( -
- {data?.accessToken ? ( - - ) : ( -
- - - - No access token available. -
- )} -
- )} +
+ +
); } diff --git a/app/listeners/listeners.ts b/app/listeners/listeners.ts index 6bd80f3..a7ac818 100644 --- a/app/listeners/listeners.ts +++ b/app/listeners/listeners.ts @@ -5,7 +5,7 @@ import { recordHook } from "@flatfile/plugin-record-hook"; /** * Example Listener */ -export const listener = (listener: FlatfileListener) => { +export const listener = FlatfileListener.create((listener) => { listener.on("**", (event) => { console.log(`Received event: ${event.topic}`, { event }); }); @@ -81,4 +81,4 @@ export const listener = (listener: FlatfileListener) => { } }); }); -}; +}); diff --git a/pages/reuse-space/index.tsx b/pages/reuse-space/index.tsx index 8ba6b53..a4fdc61 100644 --- a/pages/reuse-space/index.tsx +++ b/pages/reuse-space/index.tsx @@ -1,13 +1,91 @@ "use client"; -import React from "react"; +import React, { useEffect, useState } from "react"; import ReuseSpace from "@/app/ReuseSpace"; +import { FlatfileProvider } from "@flatfile/react"; export default function reuseSpace() { const SPACE_ID = process.env.NEXT_PUBLIC_FLATFILE_SPACE_ID; + const [loading, setLoading] = useState(true); + const [data, setData] = useState(); + const [error, setError] = useState(); + if (!SPACE_ID) { return <>No SPACE_ID Provided; } + useEffect(() => { + const fetchData = async (spaceId: string) => { + const response = await fetch(`/api/spaces/${spaceId}`); + const json = await response.json(); + if (json.error) { + setError(json.error); + setLoading(false); + return; + } + const spaceInfo = { + spaceId, + accessToken: json.space.data.accessToken, + }; + console.log({ spaceInfo }); + setData(spaceInfo); + setLoading(false); + }; + + if (!SPACE_ID) { + setLoading(false); + return; + } + + fetchData(SPACE_ID).catch((err) => { + setLoading(false); + setError(err); + }); + }, [SPACE_ID]); + + if (loading) { + return ( + + ); + } + + if (!SPACE_ID || error) { + return ( +
+ + + + + {!SPACE_ID && ( + + Please add a
spaceId
+
+ )} + {error && ( + + {error} Make sure to set the
FLATFILE_API_KEY
in your{" "} +
.env
file.
+ You can find that in your Flatfile Dashboard under Developer + Settings. +
+ )} +
+
+ ); + } + return (

Reuse an existing Space

@@ -17,7 +95,12 @@ export default function reuseSpace() { they left off until the task is done.

- + + +
);