-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
be95dcd
commit 8b68c63
Showing
57 changed files
with
5,357 additions
and
58 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
|
||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.yarn | ||
|
||
# misc | ||
|
||
.DS_Store | ||
\*.pem | ||
|
||
# files | ||
|
||
my-plugin | ||
dev-plugin | ||
dist | ||
|
||
# debug | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log\* | ||
|
||
# local env files | ||
|
||
.env\*.local | ||
|
||
# Packed plugin | ||
|
||
plugin.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Framer Plugin Template | ||
|
||
This is a template for using the Framer Plugin API in a TypeScript project. | ||
|
||
## Quickstart | ||
|
||
First, run the development server: | ||
|
||
```bash | ||
npm run dev | ||
# or | ||
yarn dev | ||
# or | ||
pnpm dev | ||
# or | ||
bun dev | ||
``` | ||
|
||
Learn more: https://www.framer.com/developers/plugins/introduction |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import js from "@eslint/js" | ||
import globals from "globals" | ||
import reactHooks from "eslint-plugin-react-hooks" | ||
import reactRefresh from "eslint-plugin-react-refresh" | ||
import tseslint from "typescript-eslint" | ||
|
||
export default tseslint.config( | ||
{ ignores: ["dist"] }, | ||
{ | ||
extends: [js.configs.recommended, ...tseslint.configs.recommended], | ||
files: ["**/*.{ts,tsx}"], | ||
languageOptions: { | ||
ecmaVersion: 2022, | ||
globals: globals.browser, | ||
}, | ||
plugins: { | ||
"react-hooks": reactHooks, | ||
"react-refresh": reactRefresh, | ||
}, | ||
rules: { | ||
...reactHooks.configs.recommended.rules, | ||
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }], | ||
}, | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"id": "0fb97d", | ||
"name": "Salesforce", | ||
"modes": ["canvas", "configureManagedCollection", "syncManagedCollection"], | ||
"icon": "/salesforce.svg" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/icon.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Salesforce</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
</html> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"name": "salesforce", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", | ||
"preview": "vite preview", | ||
"pack": "npx framer-plugin-tools@latest pack" | ||
}, | ||
"dependencies": { | ||
"@tanstack/react-query": "^5.59.20", | ||
"classnames": "^2.5.1", | ||
"framer-motion": "^11.11.11", | ||
"framer-plugin": "^2.0.4", | ||
"react": "^18", | ||
"react-dom": "^18", | ||
"react-error-boundary": "^4.1.2", | ||
"usehooks-ts": "^3.1.0", | ||
"vite-plugin-mkcert": "^1", | ||
"wouter": "^3.3.5" | ||
}, | ||
"devDependencies": { | ||
"@eslint/js": "^9", | ||
"@types/react": "^18", | ||
"@types/react-dom": "^18", | ||
"@vitejs/plugin-react": "^4.3.1", | ||
"@vitejs/plugin-react-swc": "^3", | ||
"autoprefixer": "^10.4.20", | ||
"eslint": "^9.9.0", | ||
"eslint-plugin-react-hooks": "^5.1.0-rc.0", | ||
"eslint-plugin-react-refresh": "^0.4.9", | ||
"globals": "^15.9.0", | ||
"postcss": "^8.4.47", | ||
"tailwindcss": "^3.4.14", | ||
"typescript": "^5.3", | ||
"typescript-eslint": "^8.0.1", | ||
"vite": "^5", | ||
"vite-plugin-framer": "^1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export default { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
import { framer } from "framer-plugin" | ||
import { useEffect, useState } from "react" | ||
import { useLocation } from "wouter" | ||
import { Router, Route } from "./router" | ||
import { getPluginContext, PluginContext, shouldSyncImmediately, syncAllRecords } from "./cms" | ||
import { assert } from "./utils" | ||
import auth from "./auth" | ||
import { | ||
Account, | ||
AccountEngagementForms, | ||
AccountEngagementFormHandlers, | ||
Auth, | ||
BusinessUnitId, | ||
Messaging, | ||
Sync, | ||
Menu, | ||
ObjectSearch, | ||
Tracking, | ||
TrackingMID, | ||
WebForm, | ||
WebFormFields, | ||
DomainConnection, | ||
} from "./pages" | ||
|
||
const routes: Route[] = [ | ||
{ | ||
path: "/", | ||
element: Auth, | ||
}, | ||
{ | ||
path: "/business-unit-id", | ||
element: BusinessUnitId, | ||
}, | ||
{ | ||
path: "/menu", | ||
element: Menu, | ||
size: { | ||
height: 530, | ||
}, | ||
}, | ||
{ | ||
path: "/account", | ||
element: Account, | ||
title: "Account", | ||
size: { | ||
height: 459, | ||
}, | ||
children: [ | ||
{ | ||
path: "/domain-connection", | ||
element: DomainConnection, | ||
title: "Domain Connection", | ||
size: { | ||
height: 190, | ||
}, | ||
}, | ||
], | ||
}, | ||
{ | ||
path: "/messaging", | ||
element: Messaging, | ||
title: "Messaging", | ||
size: { | ||
height: 361, | ||
}, | ||
}, | ||
{ | ||
path: "/web-form", | ||
element: WebForm, | ||
title: () => `${history.state.title} Form`, | ||
size: { | ||
height: 233, | ||
}, | ||
children: [ | ||
{ | ||
path: "/fields", | ||
element: WebFormFields, | ||
title: () => `${history.state.title} Fields`, | ||
size: { | ||
height: 387, | ||
}, | ||
}, | ||
], | ||
}, | ||
{ | ||
path: "/account-engagement-forms", | ||
title: "Account Engagement Forms", | ||
element: AccountEngagementForms, | ||
children: [ | ||
{ | ||
path: "/handlers", | ||
element: AccountEngagementFormHandlers, | ||
title: "Form Handlers", | ||
}, | ||
], | ||
}, | ||
{ | ||
path: "/object-search", | ||
element: ObjectSearch, | ||
title: () => history.state?.title, | ||
size: { | ||
height: 400, | ||
}, | ||
}, | ||
{ | ||
path: "/tracking", | ||
title: "Tracking", | ||
element: Tracking, | ||
size: { | ||
height: 170, | ||
}, | ||
children: [ | ||
{ | ||
path: "/mid", | ||
element: TrackingMID, | ||
title: "Tracking MID", | ||
size: { | ||
height: 215, | ||
}, | ||
}, | ||
], | ||
}, | ||
{ | ||
path: "/sync", | ||
element: Sync, | ||
size: { | ||
width: 340, | ||
height: 425, | ||
}, | ||
}, | ||
] | ||
|
||
export function App() { | ||
const [, navigate] = useLocation() | ||
const [isLoading, setIsLoading] = useState(true) | ||
const [pluginContext, setPluginContext] = useState<PluginContext | null>(null) | ||
|
||
const isAuthenticated = auth.isAuthenticated() | ||
|
||
useEffect(() => { | ||
const mode = framer.mode | ||
const isInCMSModes = mode === "syncManagedCollection" || mode === "configureManagedCollection" | ||
|
||
async function handleCMSModes() { | ||
const context = await getPluginContext() | ||
const shouldSync = shouldSyncImmediately(context) && mode === "syncManagedCollection" | ||
|
||
setPluginContext(context) | ||
|
||
if (context.type === "update") { | ||
const { objectId, objectLabel, includedFieldIds, collectionFields, slugFieldId, fieldConfigs } = context | ||
|
||
if (shouldSync) { | ||
assert(slugFieldId) | ||
|
||
return syncAllRecords({ | ||
objectId, | ||
objectLabel, | ||
fields: collectionFields, | ||
includedFieldIds, | ||
slugFieldId, | ||
fieldConfigs, | ||
onProgress: () => { | ||
// TODO: Progress indicator. | ||
}, | ||
}).then(() => framer.closePlugin()) | ||
} | ||
|
||
// Manage collection | ||
navigate(`/sync?objectName=${objectId}&objectLabel=${objectLabel}`) | ||
return | ||
} | ||
|
||
// Create collection | ||
navigate("/object-search?redirect=/sync") | ||
} | ||
|
||
async function getContext() { | ||
if (!isAuthenticated) { | ||
navigate("/") | ||
return | ||
} | ||
|
||
if (isInCMSModes) { | ||
return handleCMSModes() | ||
} | ||
|
||
const businessUnitId = auth.getBusinessUnitId() | ||
|
||
// Authenticated but has not completed the setup | ||
if (businessUnitId === null) { | ||
navigate("/business-unit-id") | ||
return | ||
} | ||
|
||
navigate("/menu") | ||
} | ||
|
||
getContext() | ||
.then(() => setIsLoading(false)) | ||
.catch(e => framer.closePlugin(e instanceof Error ? e.message : "Unknown error", { variant: "error" })) | ||
}, [isAuthenticated, navigate]) | ||
|
||
if (isLoading) return null | ||
|
||
return ( | ||
<div className="w-full h-full"> | ||
<Router routes={routes} pluginContext={pluginContext} /> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export type ErrorType = "auth" | ||
|
||
export class PluginError extends Error { | ||
title: string | ||
type?: ErrorType | ||
|
||
constructor(title: string, message: string, type?: ErrorType) { | ||
super(message) | ||
|
||
Object.setPrototypeOf(this, PluginError.prototype) | ||
|
||
this.title = title | ||
this.type = type | ||
} | ||
} |
Oops, something went wrong.