Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
CiotkaCierpienia authored Sep 13, 2024
0 parents commit ef3166f
Show file tree
Hide file tree
Showing 13 changed files with 11,197 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
HTTPS=true
PORT=3050
48 changes: 48 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Build & Release

permissions:
contents: write

on:
push:
branches: [ main ]
workflow_dispatch:
pull_request:

jobs:
build-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18.x
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn
- run: yarn build
- name: Create tar from built plugin
run: |
BUILDFOLDER="build"
MANIFEST=$(find ./$BUILDFOLDER -name plugin-manifest.json)
[ -z $MANIFEST ] && cp plugin-manifest $BUILDFOLDER
MANIFEST="$BUILDFOLDER/plugin-manifest.json"
VERSION=$(jq '.version' $MANIFEST -r)
echo "version=$VERSION"
mkdir -p output
tar -C $BUILDFOLDER -czf output/$VERSION.tar.gz .
ls -la output
echo "version=$VERSION" >> $GITHUB_ENV
- name: Create artifact
uses: actions/upload-artifact@v4
with:
name: plugin-package
path: output
- name: Release built plugin
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: output/*
tag: ${{ env.version }}
overwrite: true
file_glob: true
if: github.ref == 'refs/heads/main'
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/public/plugin-manifest.json
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"[css][scss][javascript][typescript][javascriptreact][typescriptreact][json][mdx][html]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
}
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Example Flotiq Plugin in React

## Quickstart:

1. `yarn`
2. `yarn start`
3. work work work
4. update your `src/plugin-manifest.json` file to contain the production URL and other plugin information
5. `yarn build`
6. paste js code from `./build/static/js/main.xxxxxxxx.js` to Flotiq console
7. navigate to affected Flotiq pages


## Deployment

<!-- TO DO -->

## Loading the plugin

### URL

1. Open Flotiq editor
2. Open Chrome Dev console
3. Execute the following script
```javascript
FlotiqPlugins.loadPlugin('plugin-id', '<URL TO COMPILED JS>')
```
4. Navigate to the view that is modified by the plugin

### Directly

1. Open Flotiq editor
2. Open Chrome Dev console
3. Paste the content of `static/js/main.xxxxxxxx.js`
4. Navigate to the view that is modified by the plugin

### Deployment

1. Open Flotiq editor
2. Add a new plugin and paste the URL to the hosted `plugin-manifest.json` file (you can use `https://localhost:3050/plugin-manifest.json` as long as you have accepted self-signed certificate for this url)
3. Navigate to the view that is modified by the plugin
43 changes: 43 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "flotiq-plugin-unejected",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "concurrently \"yarn start:manifest-watch\" \"yarn react-scripts start\"",
"start:manifest-watch": "cpx -v ./src/plugin-manifest.json ./public/ --watch",
"build": "cpx -v ./src/plugin-manifest.json ./public/ && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"concurrently": "^8.2.2",
"cpx": "^1.5.0"
}
}
20 changes: 20 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!--
This file is only used for developing mode
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>Plugin preview</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="plugin-preview-root"></div>
</body>
</html>
28 changes: 28 additions & 0 deletions src/ShinyRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useCallback, useMemo, useState } from "react";

function ShinyRow({ data }) {
const [toggle, setToggle] = useState(false);
const click = useCallback(() => {
setToggle((t) => !t);
}, []);

const style = useMemo(
() => ({
color: "rgb(0, 131, 252)",
cursor: "pointer",
fontStyle: toggle ? "italic" : "normal",
fontWeight: toggle ? "bold" : "normal",
}),
[toggle]
);

return (
<button
onClick={click}
style={style}
dangerouslySetInnerHTML={{ __html: data }}
/>
);
}

export default ShinyRow;
42 changes: 42 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react";
import ReactDOM from "react-dom/client";
import ShinyRow from "./ShinyRow";
import {
addElementToCache,
getCachedElement,
registerFn,
} from "./plugin-helpers";
import pluginInfo from "./plugin-manifest.json";

const updateApp = (root, data) => {
root.render(<ShinyRow data={data} />);
};

const initApp = (div, data) => {
const root = ReactDOM.createRoot(div);
updateApp(root, data);
return root;
};

registerFn(pluginInfo, (handler) => {
handler.on(
"flotiq.grid.cell::render",
({ data, accessor, contentTypeName, contentObject }) => {
if (accessor !== "title") return null;
const key = `${contentTypeName}-${contentObject.id}-${accessor}`;
const cachedApp = getCachedElement(key);
if (cachedApp) {
updateApp(cachedApp.root, data);
return cachedApp.element;
}

const div = document.createElement("div");
addElementToCache(div, initApp(div, data), key);
return div;
}
);
});

const puginPreviewRoot = document.getElementById("plugin-preview-root");

if (puginPreviewRoot) initApp(puginPreviewRoot, "Hello World!");
27 changes: 27 additions & 0 deletions src/plugin-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const appRoots = {};

export const addElementToCache = (element, root, key) => {
appRoots[key] = {
element,
root,
};

element.addEventListener("flotiq.detached", () => {
setTimeout(() => {
return delete appRoots[key];
}, 50);
});
};

export const getCachedElement = (key) => {
return appRoots[key];
};

export const registerFn = (pluginInfo, callback) => {
if (window.FlotiqPlugins?.add) {
window.FlotiqPlugins.add(pluginInfo, callback);
return;
}
if (!window.initFlotiqPlugins) window.initFlotiqPlugins = [];
window.initFlotiqPlugins.push({ pluginInfo, callback });
};
8 changes: 8 additions & 0 deletions src/plugin-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "flotiq.react-template",
"name": "React Template Plugin",
"version": "0.1.2",
"description": "A react-based example of Flotiq plugin. This will render a shiny title instead of regular title fields",
"repository": "https://github.com/flotiq/flotiq-ui-plugins-templates-react",
"url": "https://localhost:3050/static/js/bundle.js"
}
5 changes: 5 additions & 0 deletions src/setupTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom";
Loading

0 comments on commit ef3166f

Please sign in to comment.