Skip to content

Commit

Permalink
Merge pull request #5 from flotiq/feature/maciejl/24765
Browse files Browse the repository at this point in the history
ref #24765 - update "Go to page" link with parsed key, add disabled on create new item, add "build on save" configuration, update on submit, fix multiple instance message, button loader
  • Loading branch information
rgembalik committed Jun 19, 2024
2 parents f3e2b55 + 1a32bc2 commit 2bd4acb
Show file tree
Hide file tree
Showing 18 changed files with 478 additions and 287 deletions.
Binary file modified .docs/images/netlify_plugin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"recommendations": [
// code quality plugins
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",

// plugin that helps with html strings in js files
"tobermory.es6-string-html"
]
}
12 changes: 5 additions & 7 deletions common/plugin-element-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ export const addElementToCache = (element, key, data = {}) => {
data,
};

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

export const getCachedElement = (key) => {
Expand Down
28 changes: 28 additions & 0 deletions common/plugin-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Read key value deep inside object
* @param {string} key
* @param {object} object
* @returns {*} example: read 'object[0].key' from 'object: [{key: value}]
*/
export const deepReadKeyValue = (key, object) => {
return key
.split(/[[.\]]/)
.filter((kp) => !!kp)
.reduce((nestedOptions, keyPart) => {
return nestedOptions?.[keyPart];
}, object);
};

/**
* Generate string based on tempalte and object with values
*
* @param {string} value - template string with keys in {{}}
* @param {*} object - object with values
* @returns {string}
*/
export const getKeyPattern = (value, object) => {
return value.replace(/{(?<key>[^{}]+)}/g, (...params) => {
const { key } = params[4];
return deepReadKeyValue(key, object) || '';
});
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
},
"dependencies": {
"chalk": "^5.3.0",
"esbuild-plugin-copy": "^2.1.1"
"esbuild-plugin-copy": "^2.1.1",
"semver": "^7.6.2"
}
}
2 changes: 1 addition & 1 deletion plugin-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "flotiq.deploy-netlify",
"name": "Deploy Netlify",
"description": "Integration with Netlify deploy. With this plugin, you can easily trigger Netlify builds within Content Object changes on form submission. You will also be able to quickly navigate to your Netlify pages from the Flotiq content editor.",
"version": "1.1.2",
"version": "1.1.3",
"repository": "https://github.com/flotiq/flotiq-ui-plugin-deploy-netlify",
"url": "https://localhost:3053/index.js",
"permissions": []
Expand Down
67 changes: 67 additions & 0 deletions plugins/build-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { getKeyPattern } from '../common/plugin-helpers';

/**
*
* @param {object} buttonSettings
* @param {*} contentObject
* @param {string} id
* @returns
*/
export const onBuildHandler = (buttonSettings, contentObject, id) => {
const buildWebhookURL = getKeyPattern(
buttonSettings?.build_webhook_url,
contentObject,
);
const buildInstance = getKeyPattern(
buttonSettings?.build_instance_url,
contentObject,
);
const buttonId = `${id}-button`;
const statusBoxId = `${id}-status`;

const statusMessageContainer = document.getElementById(statusBoxId);
const buttonElement = document.getElementById(buttonId);

const updateStatus = (message) => {
statusMessageContainer.innerHTML = message;
};

const pluginLink = /* html */ `
<a
class="plugin-deploy-netlify__link"
href="${buildInstance}"
target="_blank">
Go to page: ${buildInstance}
</a>
`;

if (!buildWebhookURL) {
updateStatus(pluginLink);
return;
} else {
updateStatus('Updating preview link...');
}

buttonElement.disabled = true;
buttonElement.classList.add('plugin-deploy-netlify__button--loading');
return fetch(buildWebhookURL, {
mode: 'no-cors',
method: 'POST',
body: JSON.stringify(contentObject),
headers: {
'content-type': 'application/json;charset=UTF-8',
},
})
.then(() => updateStatus(pluginLink))
.catch((error) => {
if (error.message) {
updateStatus(error.message);
} else {
updateStatus('Failed to fetch');
}
})
.finally(() => {
buttonElement.disabled = false;
buttonElement.classList.remove('plugin-deploy-netlify__button--loading');
});
};
61 changes: 23 additions & 38 deletions plugins/form-submit/index.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,29 @@
export const handleAfterSubmitPlugin = (
{ success, contentObject },
toast,
getPluginSettings,
) => {
import { onBuildHandler } from '../build-handler';

export const handleAfterSubmitPlugin = (data, getPluginSettings) => {
const { success, contentObject } = data;
const ctdName = contentObject?.internal?.contentType;
const settings = getPluginSettings();
const netlifySettings = getPluginSettings();

if (!success || !ctdName || !netlifySettings) return;

if (!success || !ctdName || !settings) return;
const settings = JSON.parse(netlifySettings);

const settingsForCtd = JSON.parse(settings)?.builds?.filter(
(plugin) =>
plugin.content_types.length === 0 ||
plugin.content_types.find((ctd) => ctd === ctdName),
);
const settingsForCtd = settings?.builds
?.filter(
(buttonSettings) =>
buttonSettings.content_types.length === 0 ||
buttonSettings.content_types.find((ctd) => ctd === ctdName),
)
.filter((buttonSettings) => buttonSettings.build_on_save);

if (!settingsForCtd.length) return null;
if (!settingsForCtd.length) return;

settingsForCtd.map((item) =>
fetch(item.build_webhook_url, {
method: `POST`,
body: '{}',
headers: {
'content-type': 'application/json;charset=UTF-8',
},
})
.then(async ({ ok, status }) => {
if (!ok)
throw Error(
`Failed to fetch Netlify build URL: ${item.build_instance_url}. Status: ${status}`,
);
})
.catch((error) => {
console.log(error);
if (error.message) {
toast.error(error.message);
} else {
toast.error(
`Failed to fetch Netlify build URL: ${item.build_instance_url}`,
);
}
}),
);
settingsForCtd.forEach((buttonSettings, index) => {
onBuildHandler(
buttonSettings,
contentObject,
`netlify-item-child-${index}`,
);
});
};
Binary file added plugins/img/netlify-logo-black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added plugins/img/netlify-logo-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 10 additions & 6 deletions plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,26 @@ import cssString from 'inline:./sidebar-panel/style/style.css';
import { handlePanelPlugin } from './sidebar-panel';
import { handleManagePlugin } from './manage';
import { handleAfterSubmitPlugin } from './form-submit';
import { handleMigrate } from './migrations';

registerFn(pluginInfo, (handler, _, { toast, getPluginSettings }) => {
if (!document.getElementById(`${pluginInfo.id}-styles`)) {
const style = document.createElement('style');
registerFn(pluginInfo, (handler, _, { getPluginSettings }) => {
let style = document.getElementById(`${pluginInfo.id}-styles`);
if (!style) {
style = document.createElement('style');
style.id = `${pluginInfo.id}-styles`;
style.textContent = cssString;
document.head.appendChild(style);
}
style.textContent = cssString;

handler.on('flotiq.plugins.manage::form-schema', (data) =>
handleManagePlugin(data, pluginInfo),
);
handler.on('flotiq.form.sidebar-panel::add', (data) =>
handlePanelPlugin(data, pluginInfo),
handlePanelPlugin(data, getPluginSettings, pluginInfo),
);
handler.on('flotiq.form::after-submit', (data) =>
handleAfterSubmitPlugin(data, toast, getPluginSettings),
handleAfterSubmitPlugin(data, getPluginSettings, pluginInfo),
);

handler.on('flotiq.plugin::migrate', handleMigrate);
});
98 changes: 4 additions & 94 deletions plugins/manage/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { getSettingsSchema } from './settings-schema';

let configCache = null;

export const handleManagePlugin = (
Expand All @@ -10,103 +12,11 @@ export const handleManagePlugin = (

const ctds = (contentTypes || [])
.filter((ctd) => !ctd.internal || ctd.name === '_media')
.map(({ name }) => name);
.map(({ name, label }) => ({ value: name, label }));

configCache = {};

configCache.schema = {
id: pluginInfo.id,
name: 'netlify_build',
label: 'Netlify build',
workflowId: 'generic',
internal: false,
schemaDefinition: {
type: 'object',
allOf: [
{
$ref: '#/components/schemas/AbstractContentTypeSchemaDefinition',
},
{
type: 'object',
properties: {
builds: {
type: 'array',
items: {
type: 'object',
required: ['build_instance_url'],
properties: {
build_instance_url: {
type: 'string',
minLength: 1,
},
build_webhook_url: {
type: 'string',
},
content_types: {
type: 'array',
minLength: 1,
},
displayName: {
type: 'string',
default: 'Build site',
},
},
},
},
},
},
],
required: [],
additionalProperties: false,
},
metaDefinition: {
order: ['builds'],
propertiesConfig: {
builds: {
items: {
order: [
'build_instance_url',
'build_webhook_url',
'displayName',
'content_types',
],
propertiesConfig: {
build_instance_url: {
label: 'Build Instance URL',
unique: false,
helpText: '',
inputType: 'text',
},
build_webhook_url: {
label: 'Build Webhook URL',
unique: false,
helpText: '',
inputType: 'text',
},
content_types: {
label: 'Content types',
unique: false,
options: ctds,
helpText: '',
inputType: 'select',
isMultiple: true,
},
displayName: {
label: 'Display name',
unique: false,
helpText: '',
inputType: 'text',
},
},
},
label: 'Builds',
unique: false,
helpText: '',
inputType: 'object',
},
},
},
};
configCache.schema = getSettingsSchema(pluginInfo, ctds);

modalInstance.promise.then(() => (configCache = null));

Expand Down
Loading

0 comments on commit 2bd4acb

Please sign in to comment.