Skip to content

Commit 1c7e98a

Browse files
committed
initial commit
0 parents  commit 1c7e98a

25 files changed

+2086
-0
lines changed

.dev/localhost.cert

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIFCzCCAvOgAwIBAgIUfLvXiw1GaycV+Ya/jmJ54EqjEb0wDQYJKoZIhvcNAQEL
3+
BQAwFDESMBAGA1UEAwwJMTI3LjAuMC4xMCAXDTI0MDIxNTEyMDMxM1oYDzIwNTEw
4+
NzAyMTIwMzEzWjAUMRIwEAYDVQQDDAkxMjcuMC4wLjEwggIiMA0GCSqGSIb3DQEB
5+
AQUAA4ICDwAwggIKAoICAQDDdhdcQr1JGffkrBK7zDukb79YkD5Hg1FWWgByztdv
6+
dc0jvEnGLqkgaL8NYlmZqh5NRZ7ncp/A3C01wxGMAL1jhjcX56wt0hQRdszGdi0J
7+
XN8Ixqa2JLcNn20D4152HPgB7F/JlTPviW4Bws67sUs3JT0wrdjtx77rg4tPCL/S
8+
qP6N21EHXokVnwQHkFh/MUx1+agHDZL6U9iB0MKVErL/q2HLibQfjkJs5Y6kzdQQ
9+
WwVwbZul8XzEi9lU90hnBqT4wvDxYYzKZD+o4965B0ThhDbuYN8J4VCLE1mOLlhC
10+
bpKfMdwA3Un881MgWQXImGseAu1vYN7a8P3xy1LsLdjb6Du86/fQ8SL3YfH+wlw6
11+
5eQ2J3KYheQgpwlpmIvjLNFqc72ymCIjcWWfW7gT81XmdfhlKObo8HQdrp1uMrSN
12+
78xRLu9kRmL1iqHgqTF8kn3jUAGPr5EoUyzf8z8cX2Px0B7y8x/o845+CySHenZv
13+
AMkxA7N46c4M7o8kwHHm79dQO0Ep6dyiCTTII+DWe5BpbNlq1ddWynk5Rc2KQrvT
14+
oBV0cLpjvXQAlWB9YzqG6J4tvnfO3RjgUNgxfSDF2XW2Wi1mtnsk8m4NDGgOjLz0
15+
lVrPaeEXMDWiofpuMMW02MIYGTTYSFvO/TPO06tjVxq2jDshoUNS9faRhSxuOCEP
16+
CQIDAQABo1MwUTAdBgNVHQ4EFgQU7UYziQNqS7MqiGXjxN5KDKz784UwHwYDVR0j
17+
BBgwFoAU7UYziQNqS7MqiGXjxN5KDKz784UwDwYDVR0TAQH/BAUwAwEB/zANBgkq
18+
hkiG9w0BAQsFAAOCAgEAgZGo35kJFFEYS1iBHeLuo/7grrA2wcjR4e2eONKq21QU
19+
FJfbp+CpWkvMjq0SBq174KgfNpGrKD5KnfpBJoVD/9s43XGSCDzitZeW2mQtQ3uD
20+
nMYWGNE2rceZWmdDOKhhKMeDRdfososIdtFxBYW6nS9Znx2IwAvlDeOobmwgmUzb
21+
C2Y0S3lUnwQ2E7WStIN7zm43aFVRgigIm71sSWKpQoCfoy63ETG4m2q7uu/Ldw3y
22+
vGF2KA//ThrjWljqNu3xIRaSFWYhKJ6/Y78NNsg5vIoiI+Wk4PigY8Z3UQWdGjmW
23+
9tZG7SAN2b4s6Zan2fbF3R4q6H3x3N3ZsjKVlBroyaOLN4WFABIHbU81ggFxIsFO
24+
6RXHfNGDuPuYTrtlogvJ47nI4C5WeUFDWFcZQQ7BrS9ewZcLI5fOvejjlFqvSl87
25+
Y1StpTgVUEFL08bdjyFtAw7miJeofyT8bO1m/0Hg+snBtvBCCAJxflSVuySLp5Bi
26+
EtFxi53J+kezvRm64Y9ub61NGatXUAuPr7Z0P58ES6MgpoYgzUGeybV97MpDsRQb
27+
ze3fzqL5rE3Upb2asgINWjAXDM2Qhr8aY0OVKJQ1P4c+yyddlb3vzNfw0G5W0bsJ
28+
na+/Pfz1M60k1OxsWUGXWOPIEi29VeERDzSwhC4zShPAKYIlqrUpMunHoAGlGvM=
29+
-----END CERTIFICATE-----

.dev/localhost.key

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-----BEGIN PRIVATE KEY-----
2+
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
51+
0C66dFZAOvWn1oIUWWms2ytx0rg7sA==
52+
-----END PRIVATE KEY-----

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
6+
[*.{js,jsx,mdx,ts,json,mjs,css}]
7+
charset = utf-8
8+
indent_style = space
9+
indent_size = 2

.eslintignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
dist
3+
.eslintrc.cjs
4+
esbuild.config.js

.eslintrc.cjs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module.exports = {
2+
root: true,
3+
env: {
4+
browser: true,
5+
es6: true,
6+
},
7+
extends: ['eslint:recommended', 'prettier'],
8+
parserOptions: {
9+
sourceType: 'module',
10+
ecmaVersion: 2020,
11+
},
12+
rules: {
13+
'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
14+
'linebreak-style': 0,
15+
16+
/* This rule will warn when it encounters a reference to an identifier that has not yet been declared. */
17+
'no-use-before-define': [
18+
'error',
19+
{
20+
variables: false,
21+
},
22+
],
23+
24+
/* Enforce require() on the top-level module scope */
25+
'global-require': 0,
26+
27+
'max-len': [
28+
'error',
29+
{
30+
code: 120,
31+
},
32+
],
33+
34+
'guard-for-in': 0,
35+
'no-underscore-dangle': 0,
36+
'import/prefer-default-export': 0,
37+
'import/no-anonymous-default-export': 0,
38+
'import/no-extraneous-dependencies': 0,
39+
},
40+
};

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"endOfLine": "lf",
3+
"semi": true,
4+
"singleQuote": true,
5+
"tabWidth": 2,
6+
"trailingComma": "all"
7+
}

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"[css][scss][javascript][typescript][javascriptreact][typescriptreact][json][mdx][html]": {
3+
"editor.formatOnSave": true,
4+
"editor.defaultFormatter": "esbenp.prettier-vscode"
5+
},
6+
}

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
[[_TOC_]]
2+
3+
# Custom Links Plugin
4+
5+
## Quick start
6+
7+
1. `yarn` - to install dependencies
8+
2. `yarn start` - to start development mode - rebuild on file modifications
9+
3. update your `plugin-manifest.json` file to contain the production URL and other plugin information
10+
4. `yarn build` - to build plugins
11+
12+
## Dev environment
13+
14+
Dev environment is configured to use:
15+
16+
* `prettier` - best used with automatic format on save in IDE
17+
* `eslint` - it is built into both `start` and `build` commands
18+
19+
## Output
20+
21+
The plugins are built into a single `dist/index.js` file. The manifest is copied to `dist/plugin-manifest.json` file.
22+
23+
## Deployment
24+
25+
<!-- TO DO -->
26+
27+
## Loading the plugin
28+
29+
**Warning:** While developing, you can use `https://localhost:3053/plugin-manifest.json` address to load the plugin manifest. Make sure your browser trusts the local certificate on the latter, to be able to use it e.g. with `https://editor.flotiq.com`
30+
31+
### URL
32+
33+
**Hint**: You can use localhost url from development mode `https://localhost:3053/index.js`
34+
35+
1. Open Flotiq editor
36+
2. Open Chrome Dev console
37+
3. Execute the following script
38+
```javascript
39+
FlotiqPlugins.loadPlugin('plugin-id', '<URL TO COMPILED JS>')
40+
```
41+
4. Navigate to the view that is modified by the plugin
42+
43+
### Directly
44+
45+
1. Open Flotiq editor
46+
2. Open Chrome Dev console
47+
3. Paste the content of `dist/index.js`
48+
4. Navigate to the view that is modified by the plugin
49+
50+
### Deployment
51+
52+
**Hint**: You can use localhost url from development mode `https://localhost:3053/plugin-manifest.json`
53+
54+
1. Open Flotiq editor
55+
2. Add a new plugin and paste the URL to the hosted `plugin-manifest.json` file
56+
3. Navigate to the view that is modified by the plugin

common/api-helpers.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
let cachedCtds = null;
2+
3+
export const getContentTypes = async (client, toast, t) => {
4+
if (cachedCtds) return cachedCtds;
5+
6+
cachedCtds = client
7+
.getContentTypes({
8+
limit: 1000,
9+
page: 1,
10+
order_by: 'label',
11+
order_direction: 'asc',
12+
})
13+
.then(({ body, status }) => {
14+
if (status < 200 || status >= 300) {
15+
throw new Error();
16+
}
17+
18+
return body.data || [];
19+
})
20+
.catch(() => {
21+
toast.error(t('ContentTypesErrors'));
22+
return [];
23+
});
24+
25+
return cachedCtds;
26+
};

common/plugin-element-cache.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
const appRoots = {};
2+
3+
export const onElementRemoved = (element, callback) => {
4+
new MutationObserver(function () {
5+
if (!document.contains(element)) {
6+
callback();
7+
this.disconnect();
8+
}
9+
}).observe(element.parentElement, { childList: true });
10+
};
11+
12+
export const addElementToCache = (element, key, data = {}) => {
13+
appRoots[key] = {
14+
element,
15+
data,
16+
};
17+
18+
element.addEventListener(
19+
'flotiq.attached',
20+
() => onElementRemoved(element, () => delete appRoots[key]),
21+
true,
22+
);
23+
};
24+
25+
export const getCachedElement = (key) => {
26+
return appRoots[key];
27+
};
28+
29+
export const registerFn = (pluginInfo, callback) => {
30+
if (window.FlotiqPlugins?.add) {
31+
window.FlotiqPlugins.add(pluginInfo, callback);
32+
return;
33+
}
34+
if (!window.initFlotiqPlugins) window.initFlotiqPlugins = [];
35+
window.initFlotiqPlugins.push({ pluginInfo, callback });
36+
};

common/plugin-helpers.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const appRoots = {};
2+
3+
export const onElementRemoved = (element, callback) => {
4+
new MutationObserver(function () {
5+
if (!document.contains(element)) {
6+
callback();
7+
this.disconnect();
8+
}
9+
}).observe(element.parentElement, { childList: true });
10+
};
11+
12+
export const addElementToCache = (element, root, key) => {
13+
appRoots[key] = {
14+
element,
15+
root,
16+
};
17+
18+
element.addEventListener(
19+
'flotiq.attached',
20+
() => onElementRemoved(element, () => delete appRoots[key]),
21+
true,
22+
);
23+
};
24+
25+
export const removeRoot = (key) => {
26+
delete appRoots[key];
27+
};
28+
29+
export const getCachedElement = (key) => {
30+
return appRoots[key];
31+
};
32+
33+
export const registerFn = (pluginInfo, callback) => {
34+
if (window.FlotiqPlugins?.add) {
35+
window.FlotiqPlugins.add(pluginInfo, callback);
36+
return;
37+
}
38+
if (!window.initFlotiqPlugins) window.initFlotiqPlugins = [];
39+
window.initFlotiqPlugins.push({ pluginInfo, callback });
40+
};
41+
42+
/**
43+
* Read key value deep inside object
44+
* @param {string} key
45+
* @param {object} object
46+
* @returns {*} example: read 'object[0].key' from 'object: [{key: value}]
47+
*/
48+
export const deepReadKeyValue = (key, object) => {
49+
return key
50+
.split(/[[.\]]/)
51+
.filter((kp) => !!kp)
52+
.reduce((nestedOptions, keyPart) => {
53+
return nestedOptions?.[keyPart];
54+
}, object);
55+
};

0 commit comments

Comments
 (0)