Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/react/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ const config: StorybookConfig = {
directory: "../src/experimental",
titlePrefix: "Components",
},
{
directory: "../src/co-creation",
titlePrefix: "CoCreation",
},
...(process.env.STORYBOOK_PUBLIC_BUILD
? []
: [
Expand Down
31 changes: 15 additions & 16 deletions packages/react/docs/development/using-f0-source.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ consumer of `f0`

Building the library will be necessary to use it in the same way as in
production, but in some scenarios (like local development) we can skip
publishing and reinstalling (check how to: [in local development](#local) or
[in coder](#coder))
publishing and reinstalling (check how to: [in local development](#local)

## How to

Expand All @@ -41,7 +40,7 @@ This applies when both `f0` and `factorial`'s monorepo are in the local computer
5. Run `pnpm link --global @factorialco/f0-react` to use the local version of
the package

### How to use local version of `f0` in coder {#cder}
### How to use local version of `f0` using sync

This applies when `f0` is in your local computer and `factorial`'s monorepo is
in coder's dev environment
Expand All @@ -50,25 +49,25 @@ in coder's dev environment

- [rsync](https://linux.die.net/man/1/rsync) in your local computer:
`brew install rsync`
- [coder cli](https://coder.com/docs/install/cli) in your local computer
- ![Coder ssh](images/coder.png)
- Configure coder cli if its the first time you connect by ssh:
`coder login https://coder.factorial.dev`
- Create if not exists `packages/react/.env.local` and add this line
`CODER_REMOTE=[YOUR_CODER_SSH_CONNECTION_STRING]`, for example:
`CODER_REMOTE=coder.sergiocarracedo-dev-env`
- (optional) Create if not exists `packages/react/.env.local` and add this line
`F0_REMOTE_SYNC=[your application]`, for example:
`F0_REMOTE_SYNC=/home/sergio/factorial/frontend`
> This file is in the `.gitignore` file, so it won't be pushed to the
> repository
- Add folligin to target workspace vite.config.ts

```
watch: {
ignored: ['!**/node_modules/@factorialco/f0-react/**'],
}
```

**Steps:**

1. Go to the `f0` folder: `cd f0/packages/react`
2. Run `pnpm dev:coder` to rebuild the project on any change and sync that build
to coder workspace
3. On the `factorial` project you may need to clean vite cache (rm -Rf
frontend/node_modules/.vite) and restart frontend service: make
session.frontend
2. Run `pnpm dev:sync [target]` to rebuild the project on any change and sync
that build to target. e.g. `pnpm dev:sync /works/factorial/frontend`

> Now on each change in the `f0`'s source code, the changes will be reflected in
> the coder workspace and the frontend will be reloaded using always the latest
> the target project and the frontend will be reloaded using always the latest
> `f0`'s code.
9 changes: 7 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
"scripts": {
"dev": "storybook dev -p 6006",
"dev:docs": "DOCS_MODE=true pnpm run dev",
"dev:coder": "pnpm build --watch -- --buildSync",
"dev:sync": "pnpm build:prepare && tsx scripts/dev-sync.ts",
"start": "pnpm run dev",
"build:types": "tsc --project ./tsconfig-build.json",
"build:prepare": "pnpm run build:types && run-p build-icons",
"size": "pnpm run build && size-limit",
"build": "tsc --project ./tsconfig-build.json && run-p build-icons && BUILD_TYPES=true vite build -- --tailwind",
"build:tsup": "tsup && pnpm run build:tailwind && run-p build-icons",
Expand Down Expand Up @@ -162,6 +164,7 @@
"storybook": "^9.1.3",
"storybook-addon-tag-badges": "^2.0.2",
"tsup": "^8.3.5",
"tsx": "^4.20.6",
"typescript": "^5.7.2",
"user-agent-data-types": "^0.4.2",
"vite": "^6.3.5",
Expand All @@ -177,7 +180,7 @@
"@atlaskit/pragmatic-drag-and-drop-flourish": "^2.0.4",
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.5",
"@factorialco/f0-core": "workspace:*",
"@factorialco/f0-core": "latest",
"@radix-ui/number": "^1.1.1",
"@radix-ui/primitive": "^1.1.2",
"@radix-ui/react-collection": "^1.1.7",
Expand Down Expand Up @@ -230,6 +233,8 @@
"aria-hidden": "^1.2.6",
"cva": "1.0.0-beta.3",
"dompurify": "^3.2.6",
"echarts": "6",
"echarts-for-react": "3.0.4",
"embla-carousel-autoplay": "^8.5.2",
"embla-carousel-react": "^8.6.0",
"embla-carousel-wheel-gestures": "^8.0.1",
Expand Down
22 changes: 22 additions & 0 deletions packages/react/scripts/dev-sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env tsx
import { spawn } from "node:child_process"

const syncPath = process.argv[2]

if (!syncPath) {
console.error("Error: Please provide a sync path")
console.error("Usage: pnpm dev:sync <path>")
process.exit(1)
}

// Run vite build directly in watch mode with buildSync flag
const args = ["vite", "build", "--watch", "--", `--buildSync=${syncPath}`]

const proc = spawn("pnpm", args, {
stdio: "inherit",
shell: true,
})

proc.on("exit", (code) => {
process.exit(code || 0)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { PageLayout } from "@/components/layouts/page/PageLayout"
import type { Meta, StoryObj } from "@storybook/react-vite"
import { useCocreationGroup } from "../components/CoCreationGroup"
import {
CoCreationGroup,
cocreationModes,
} from "../components/CoCreationGroup/CoCreationGroup"
import { CoCreationBlockInstance, CoCreationBlockManifest } from "../types"
import { AvatarCCBManifest } from "./blocks/Avatar"
import { ChartCCBManifest } from "./blocks/Chart"
import { KeyValueCCBManifest } from "./blocks/KeyValue"
import { LongTextCCBManifest } from "./blocks/LongText"
import { TextCCBManifest } from "./blocks/Text"

const meta = {
title: "CoCreationGroup",
component: CoCreationGroup,
parameters: {
layout: "centered",
docs: {
description: {
component:
"A component that allows to create a group of blocks using the agent.",
},
},
},
tags: ["autodocs", "experimental"],
argTypes: {
mode: {
description: "The mode of the co-creation group",
options: cocreationModes,
control: { type: "select" },
},
},
decorators: [
(Story, { args }) => {
const { instructions } = useCocreationGroup({
blockManifests: args.blockManifests,
agentInstructions: args.agentInstructions,
agentContext: args.agentContext,
mode: args.mode,
})

return (
<PageLayout
aside={
<>
<h4>Agent intructions</h4>
{instructions.map((instruction) => (
<p key={instruction}>
<pre>{instruction}</pre>
</p>
))}
</>
}
>
<Story args={args} />
</PageLayout>
)
},
],
} satisfies Meta<typeof CoCreationGroup>

export default meta
type Story = StoryObj<typeof meta>

const avaliableBlocks: CoCreationBlockManifest[] = [
TextCCBManifest,
KeyValueCCBManifest,
AvatarCCBManifest,
LongTextCCBManifest,
ChartCCBManifest,
]

const blocks: CoCreationBlockInstance[] = [
{
id: "1",
type: "text",
props: {
text: "Hello, world!",
},
},
{
id: "2",
type: "avatar",
props: {
avatar: {
type: "person",
firstName: "John",
lastName: "Doe",
},
},
},
{
id: "3",
type: "longText",
props: {
text: [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi interdum nisl laoreet, commodo ex id, faucibus purus. Phasellus varius ligula magna. Integer neque nulla, rhoncus vel sagittis et, consequat non velit. Vestibulum sagittis tristique gravida. Aliquam scelerisque iaculis lacinia. Fusce malesuada eros id leo commodo rutrum. Sed lectus turpis, auctor sit amet sem vitae, hendrerit tristique nibh. In imperdiet nisi mi, ultricies bibendum erat scelerisque in. Fusce pulvinar, nunc eu ultrices blandit, felis est consequat ex, quis consectetur nisl mauris id nulla.",
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque consectetur venenatis ex. Aenean mattis tortor mauris, quis semper turpis aliquet sed. Aenean lacus lectus, tincidunt nec varius eleifend, semper at mauris. Integer molestie urna vel nisl sagittis, at tempus enim sagittis. Integer quis arcu eros. Etiam sit amet tincidunt sem. Proin euismod dui vitae fringilla eleifend. Etiam pellentesque vulputate purus id pharetra. Integer viverra leo eget elit venenatis viverra. Quisque auctor mi orci, eget posuere dolor vulputate at. Praesent ac volutpat ligula. Nulla et augue ac nunc vehicula scelerisque. Maecenas ac tristique lectus. In hac habitasse platea dictumst. Maecenas scelerisque felis pulvinar purus rhoncus, ac rutrum turpis sollicitudin.",
"In ornare mollis ipsum vitae consectetur. Fusce rutrum neque sed ullamcorper porttitor. In luctus dignissim lectus, at mollis ex venenatis eu. Etiam at ex nec urna elementum ultrices ac ut nunc. Nullam cursus dictum convallis. Vivamus urna felis, tincidunt at massa quis, sollicitudin semper nulla. Vivamus nisi dui, venenatis id aliquam at, fermentum sed lectus. Nulla eget odio quis metus lacinia placerat ut quis massa. Maecenas vel feugiat ligula. Nam vitae tempus nunc. Aenean pulvinar nibh a augue malesuada, sit amet accumsan erat mattis. Praesent facilisis justo purus, id finibus nibh pellentesque vel.",
],
title: "Long Text",
description: "This is a long text description",
},
},
]

// Basic Variants
export const Default: Story = {
args: {
blockInstances: blocks,
blockManifests: avaliableBlocks,
agentInstructions: [
"I want to represent the user data using the blocks available ",
],
mode: "co-creation",
agentContext: [
"The user data is:",
"John Doe",
"email: [email protected]",
"phone: +34 666 666 666",
"address: 123 Main St, City, Country",
],
},
}
25 changes: 25 additions & 0 deletions packages/react/src/co-creation/__stories__/blocks/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { CoCreationBlockManifest } from "@/co-creation/types"
import z from "zod"

export const AvatarProps = z.object({
type: z.enum(["person"]).describe("The type of the avatar"),
firstName: z.string().describe("The first name of the person"),
lastName: z.string().describe("The last name of the person"),
})

export const Avatar = (props: z.infer<typeof AvatarProps>) => {
return (
<>
This should be an avatar {props.type} with name {props.firstName}{" "}
{props.lastName}
</>
//<F0AvatarPerson firstName={props.firstName} lastName={props.lastName} />
)
}

export const AvatarCCBManifest: CoCreationBlockManifest = {
id: "avatar",
description: "A block that displays an avatar",
component: Avatar,
propsSchema: AvatarProps,
}
24 changes: 24 additions & 0 deletions packages/react/src/co-creation/__stories__/blocks/Chart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { CoCreationBlockManifest } from "@/co-creation/types"
import { F0ECharts } from "@/components/Charts/F0ECharts"
import z from "zod"

export const ChartProps = z.object({
title: z.string().describe("The chart title"),
chartOptions: z.object({}).describe("ECharts-compatible options"),
})

export const Chart = (props: z.infer<typeof ChartProps>) => {
return (
<>
<h3>{props.title}</h3>
<F0ECharts options={props.chartOptions} />
</>
)
}

export const ChartCCBManifest: CoCreationBlockManifest = {
id: "chart",
description: "A block that displays a chart",
component: Chart,
propsSchema: ChartProps,
}
23 changes: 23 additions & 0 deletions packages/react/src/co-creation/__stories__/blocks/KeyValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { CoCreationBlockManifest } from "@/co-creation/types"
import z from "zod"

export const KeyValueProps = z.object({
label: z.string().describe("The label to display"),
value: z.string().describe("The value to display"),
})

export const KeyValue = (props: z.infer<typeof KeyValueProps>) => {
return (
<div className="flex flex-col content-between gap-1">
<p className="text-f1-foreground-secondary">{props.label}</p>
<p className="text-f1-foreground">{props.value}</p>
</div>
)
}

export const KeyValueCCBManifest: CoCreationBlockManifest = {
id: "keyValue",
description: "A block that displays a key and a value",
component: KeyValue,
propsSchema: KeyValueProps,
}
27 changes: 27 additions & 0 deletions packages/react/src/co-creation/__stories__/blocks/LongText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { CoCreationBlockManifest } from "@/co-creation/types"
import z from "zod"

export const LongTextProps = z.object({
text: z
.union([z.string(), z.array(z.string())])
.describe("The text to display. Can be a string or an array of strings"),
title: z.string().optional().describe("The title to display"),
description: z.string().optional().describe("The description to display"),
})

export const LongText = (props: z.infer<typeof LongTextProps>) => {
return (
<section>
{props.title && <h2>{props.title}</h2>}
{props.description && <h6>{props.description}</h6>}
{props.text && <p>{props.text}</p>}
</section>
)
}

export const LongTextCCBManifest: CoCreationBlockManifest = {
id: "longText",
description: "A block that displays a title and a description",
component: LongText,
propsSchema: LongTextProps,
}
31 changes: 31 additions & 0 deletions packages/react/src/co-creation/__stories__/blocks/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { CoCreationBlockManifest } from "@/co-creation/types"
import z from "zod"

export const TextProps = z.object({
text: z.string().describe("The text to display"),
})

export const Text = (props: z.infer<typeof TextProps>) => {
return <div>{props.text}</div>
}

export const TextCCBManifest: CoCreationBlockManifest = {
id: "text",
description: "A block that displays a text",
component: Text,
propsSchema: TextProps,
actions: () => [
{
label: "Duplicate",
onClick: () => {
console.log("duplicate")
},
},
{
label: "Delete",
onClick: () => {
console.log("delete")
},
},
],
}
Loading
Loading