Skip to content
Merged
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
19 changes: 5 additions & 14 deletions admin-ui/src/features/code/utils/getCodeJavaScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,14 @@ export default function getCodeJavaScript(props: CodeProps) {
if (props.hostUrl) {
hostUrlLine = `\n hostUrl: "${props.hostUrl}",`;
}
return `import createTableFlowImporter from "@tableflow/js";";
return `import createTableFlowImporter from "@tableflow/js";

const args = {
const importer = createTableFlowImporter({
importerId: "${props.importerId || "YOUR_IMPORTER_ID"}",${hostUrlLine}
onRequestClose: () => importer.close(),
onComplete: (data, error) => console.log(data),
darkMode: ${props.theme !== "light"},
primaryColor: "#7a5ef8",
metadata: '{"userId": 1234, "userEmail": "test@example.com"}',
onRequestClose: () => dialog.close(),
onComplete: (data, error) => {
if (error) {
alert(error); // Handle import error
} else {
console.log(data); // Use import data
}
}
}
const importer = createTableFlowImporter(args);
});

const uploadButton = document.getElementById("uploadButton");
uploadButton.addEventListener("click", () => {
Expand Down
13 changes: 2 additions & 11 deletions admin-ui/src/features/code/utils/getCodeReact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,11 @@ function MyComponent() {
<button onClick={() => setIsOpen(true)}>Open TableFlow Importer</button>

<TableFlowImporter
importerId={"${props.importerId || "YOUR_IMPORTER_ID"}"}${hostUrlLine}
isOpen={isOpen}
onRequestClose={() => setIsOpen(false)}
importerId={"${props.importerId || "YOUR_IMPORTER_ID"}"}${hostUrlLine}
darkMode={${props.theme !== "light"}}
primaryColor="#7A5EF8"
closeOnClickOutside={true}
metadata={"{\\"userId\\": 1234, \\"userEmail\\": \\"test@example.com\\"}"}
onComplete={(data, error) => {
if (error) {
alert(error); // Handle import error
} else {
console.log(data); // Use import data
}
}}
onComplete={(data, error) => console.log(data)}
/>
</>
);
Expand Down
46 changes: 23 additions & 23 deletions importer-ui/.prettierrc
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"jsxSingleQuote": false,
"bracketSameLine": true,
"printWidth": 150,
"endOfLine": "auto",
"importOrder": [
"^[^/.]+$",
"^@.+$",
"^\\.\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\.\\./(.*)/((?!\\.)(?!types.).)+$",
"^\\.$",
"^\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\./(.*)/((?!\\.)(?!types.).)+$",
"/types$",
"\\.(css|scss)$",
"\\.(svg|png|jpg|jpeg|gif)$",
".*"
],
"importOrderSeparation": false,
"importOrderSortSpecifiers": true,
"importOrderCaseInsensitive": true
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"jsxSingleQuote": false,
"bracketSameLine": true,
"printWidth": 150,
"endOfLine": "auto",
"importOrder": [
"^[^/.]+$",
"^@.+$",
"^\\.\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\.\\./(.*)/((?!\\.)(?!types.).)+$",
"^\\.$",
"^\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\./(.*)/((?!\\.)(?!types.).)+$",
"/types$",
"\\.(css|scss)$",
"\\.(svg|png|jpg|jpeg|gif)$",
".*"
],
"importOrderSeparation": false,
"importOrderSortSpecifiers": true,
"importOrderCaseInsensitive": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
}
}

&-browse {
color: var(--importer-link);
}

&-dropFilesHereHint {
padding: 0;
background-image: none;
Expand Down
5 changes: 4 additions & 1 deletion importer-ui/src/hooks/useSearchParams.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
type SearchParams = Record<"importerId" | "darkMode" | "primaryColor" | "metadata" | "isOpen" | "onComplete" | "showImportLoadingStatus", string>;
type SearchParams = Record<
"importerId" | "darkMode" | "primaryColor" | "metadata" | "isOpen" | "onComplete" | "customStyles" | "showImportLoadingStatus",
string
>;

export default function useSearchParams() {
const search = new URLSearchParams(document.location.search);
Expand Down
26 changes: 25 additions & 1 deletion importer-ui/src/providers/Embed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@ import useEmbedStore from "../stores/embed";
import { EmbedProps } from "./types";

export default function Embed({ children }: EmbedProps) {
const { importerId, darkMode: darkModeString, primaryColor, metadata, isOpen, onComplete, showImportLoadingStatus } = useSearchParams();
const {
importerId,
darkMode: darkModeString,
primaryColor,
metadata,
isOpen,
onComplete,
customStyles,
showImportLoadingStatus,
} = useSearchParams();

// Set importerId & metadata in embed store
const setEmbedParams = useEmbedStore((state) => state.setEmbedParams);
Expand Down Expand Up @@ -35,5 +44,20 @@ export default function Embed({ children }: EmbedProps) {
}
}, [primaryColor]);

useEffect(() => {
try {
const parsedStyles = customStyles && JSON.parse(customStyles);

customStyles &&
Object.keys(parsedStyles).forEach((key) => {
const root = document.documentElement;
const value = parsedStyles?.[key as any];
root.style.setProperty("--" + key, value);
});
} catch (e) {
console.error('The "customStyles" prop is not a valid JSON string. Please check the documentation for more details.');
}
}, [customStyles]);

return <>{children}</>;
}
25 changes: 25 additions & 0 deletions js-sdk/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"jsxSingleQuote": false,
"bracketSameLine": true,
"printWidth": 150,
"endOfLine": "auto",
"importOrder": [
"^[^/.]+$",
"^@.+$",
"^\\.\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\.\\./(.*)/((?!\\.)(?!types.).)+$",
"^\\.$",
"^\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\./(.*)/((?!\\.)(?!types.).)+$",
"/types$",
"\\.(css|scss)$",
"\\.(svg|png|jpg|jpeg|gif)$",
".*"
],
"importOrderSeparation": false,
"importOrderSortSpecifiers": true,
"importOrderCaseInsensitive": true
}
44 changes: 14 additions & 30 deletions js-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,18 @@ yarn add @tableflow/js
### 2. Add the Importer to your application

Create an importer, define your template, and retrieve data at https://app.tableflow.com/importers
\
The full SDK reference is available in our docs: https://tableflow.com/docs/sdk-reference/javascript

```javascript
import createTableFlowImporter from "@tableflow/js";

const args = {
importerId: "53a84496-819d-4ec6-93b7-b4b56fb676ad", // Replace with your importer ID from https://app.tableflow.com/importers
darkMode: true,
primaryColor: "#7a5ef8",
metadata: '{"userId": 1234, "userEmail": "test@example.com"}',
const importer = createTableFlowImporter({
importerId: "6de452a2-bd1f-4cb3-b29b-0f8a2e3d9353", // Use your importer ID from https://app.tableflow.com/importers
onRequestClose: () => importer.close(),
onComplete: (data, error) => {
if (error) {
alert(error); // Handle import error
} else {
console.log(data); // Use import data
}
}
};
const importer = createTableFlowImporter(args);
onComplete: (data, error) => console.log(data),
darkMode: true,
});

const uploadButton = document.getElementById("uploadButton");
uploadButton.addEventListener("click", () => {
Expand All @@ -64,24 +57,15 @@ Or directly in HTML
<script src="https://unpkg.com/@tableflow/js@latest/build/index.js"></script>
</head>
<body>
<button id="uploadButton">Upload file</button>
<button id="uploadButton">Open TableFlow Importer</button>
<script>
const args = {
importerId: "53a84496-819d-4ec6-93b7-b4b56fb676ad", // Replace with your importer ID from https://app.tableflow.com/importers
darkMode: true,
primaryColor: "#7a5ef8",
metadata: '{"userId": 1234, "userEmail": "test@example.com"}',
const importer = createTableFlowImporter({
importerId: "6de452a2-bd1f-4cb3-b29b-0f8a2e3d9353", // Use your importer ID from https://app.tableflow.com/importers
onRequestClose: () => importer.close(),
onComplete: (data, error) => {
if (error) {
alert(error); // Handle import error
} else {
console.log(data); // Use import data
}
},
};
const importer = createTableFlowImporter(args);

onComplete: (data, error) => console.log(data),
darkMode: true,
});

const uploadButton = document.getElementById("uploadButton");
uploadButton.addEventListener("click", () => {
importer?.showModal();
Expand Down
2 changes: 1 addition & 1 deletion js-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tableflow/js",
"version": "1.7.0",
"version": "1.8.0",
"description": "The JavaScript SDK for TableFlow. Embed an importer to collect and transform CSV files in your application.",
"scripts": {
"build": "rollup -c --bundleConfigAsCjs false",
Expand Down
22 changes: 22 additions & 0 deletions js-sdk/src/index.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ export const App: Story = {
primaryColor: "#7a5ef8",
metadata: '{"userId": 1234, "userEmail": "test@example.com"}',
onComplete: (data: any) => console.log(data),
customStyles: {
"font-family": "cursive",
"font-size": "15px",
"base-spacing": "2rem",
"border-radius": "8px",
"color-primary": "salmon",
"color-primary-hover": "crimson",
"color-secondary": "indianRed",
"color-secondary-hover": "crimson",
"color-text-on-primary": "#fff",
"color-text-on-secondary": "#ffffff",
"color-background": "bisque",
"color-background-modal": "blanchedAlmond",
"color-text": "brown",
"color-text-soft": "rgba(165, 42, 42, .5)",
"importer-link": "indigo",
"color-border": "lightCoral",
"color-input-background": "blanchedAlmond",
"color-input-background-soft": "white",
"color-background-menu-hover": "bisque",
"color-green-ui": "darkGreen",
},
},
};

Expand Down
16 changes: 6 additions & 10 deletions js-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ export default function createTableFlowImporter({
metadata = "{}",
closeOnClickOutside,
onComplete,
customStyles,
className,
showImportLoadingStatus
showImportLoadingStatus,
}: TableFlowImporterProps) {
// CSS classes
const baseClass = "TableFlowImporter";
const themeClass = darkMode && `${baseClass}-dark`;
const dialogClass = [`${baseClass}-dialog`, themeClass, className]
.filter((i) => i)
.join(" ");
const dialogClass = [`${baseClass}-dialog`, themeClass, className].filter((i) => i).join(" ");
const closeClass = `${baseClass}-close`;

// dialog element
Expand All @@ -48,20 +47,17 @@ export default function createTableFlowImporter({
metadata,
isOpen: isOpen.toString(),
onComplete: onComplete ? "true" : "false",
customStyles: JSON.stringify(customStyles),
showImportLoadingStatus: showImportLoadingStatus ? "true" : "false",
};
const searchParams = new URLSearchParams(urlParams);
const defaultImporterUrl = "https://importer.tableflow.com";
const uploaderUrl = `${
hostUrl ? hostUrl : defaultImporterUrl
}?${searchParams}`;
const uploaderUrl = `${hostUrl ? hostUrl : defaultImporterUrl}?${searchParams}`;

try {
JSON.parse(metadata);
} catch (e) {
console.error(
'The "metadata" prop is not a valid JSON string. Please check the documentation for more details.'
);
console.error('The "metadata" prop is not a valid JSON string. Please check the documentation for more details.');
}

function messageListener(e: any) {
Expand Down
3 changes: 3 additions & 0 deletions js-sdk/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CSSProperties } from "react";

export type TableFlowImporterProps = HTMLDialogElement & {
elementId?: string;
isOpen?: boolean;
Expand All @@ -9,5 +11,6 @@ export type TableFlowImporterProps = HTMLDialogElement & {
closeOnClickOutside?: boolean;
metadata?: string;
onComplete?: (data: { data: any; error: any }) => void;
customStyles?: Record<string, string> | CSSProperties;
showImportLoadingStatus?: boolean;
};
45 changes: 23 additions & 22 deletions react-sdk/.prettierrc
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
{
"semi": true,
"singleQuote": false,
"tabWidth": 4,
"jsxSingleQuote": false,
"bracketSameLine": true,
"printWidth": 150,
"endOfLine": "auto",
"importOrder": [
"^[^/.]+$",
"^@.+$",
"^\\.\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\.\\./(.*)/((?!\\.)(?!types.).)+$",
"^\\.$",
"^\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\./(.*)/((?!\\.)(?!types.).)+$",
"/types$",
"\\.(css|scss)$",
"\\.(svg|png|jpg|jpeg|gif)$",
".*"
],
"importOrderSeparation": false,
"importOrderSortSpecifiers": true
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"jsxSingleQuote": false,
"bracketSameLine": true,
"printWidth": 150,
"endOfLine": "auto",
"importOrder": [
"^[^/.]+$",
"^@.+$",
"^\\.\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\.\\./(.*)/((?!\\.)(?!types.).)+$",
"^\\.$",
"^\\./(.*)/[A-Z]((?!\\.)(?!types.).)+$",
"^\\./(.*)/((?!\\.)(?!types.).)+$",
"/types$",
"\\.(css|scss)$",
"\\.(svg|png|jpg|jpeg|gif)$",
".*"
],
"importOrderSeparation": false,
"importOrderSortSpecifiers": true,
"importOrderCaseInsensitive": true
}
Loading