Skip to content

Commit

Permalink
#25835 added basic config for plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
KrzysztofBrylski committed Dec 3, 2024
1 parent 83cf6d3 commit 5b0a9ff
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 62 deletions.
Empty file added .prettierrc
Empty file.
62 changes: 62 additions & 0 deletions i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import i18n from 'i18next';

i18n.init({
fallbackLng: 'en',
supportedLngs: ['en', 'pl'],
resources: {
en: {
translation: {
Source: 'Column field name',
SourceHelpText:
'Pick the field which will be used to organize cards in columns, each possible value -> new column. Allowed types: {{types}}',
ContentType: 'Content Type',
ContentTypeHelpText: '',
Title: 'Title',
TitleHelpText:
'Pick the field which will be used to display title in card preview. Allowed types: {{types}}',
Image: 'Image',
ImageHelpText:
'Pick the field which will be used to display image in card preview (optional). Allowed types: {{types}}',
AdditionalFields: 'Additional Fields',
AdditionalFieldsHelpText:
'Pick the fields which will be used to display additional fields in card preview (optional). Allowed types: {{types}}',
FieldRequired: 'Field is required',
WrongFieldType: 'This field type is not supported',
CardDelete: 'Content objects deleted (1)',
FetchError:
'Error occurred while connecting to the server, please try again later.',
NonRequiredFieldsInCTD:
'Make sure the selected content type contains fields that can be used in the plugin. Allowed types: {{types}}',
StateUpdateError: 'Failed to update card status',
},
},
pl: {
translation: {
Source: 'Pole kolumny',
SourceHelpText:
'Wybierz pole, które będzie użyte do organizowania kart w kolumnach, każda możliwa wartość -> nowa kolumna. Dozwolone typy: {{types}}',
ContentType: 'Typ zawartości',
ContentTypeHelpText: '',
Title: 'Tytuł',
TitleHelpText:
'Wybierz pole, które będzie użyte do wyświetlania tytułu w podglądzie karty. Dozwolone typy: {{types}}',
Image: 'Obraz',
ImageHelpText:
'Wybierz pole, które będzie użyte do wyświetlania obrazu w podglądzie karty (opcjonalne). Dozwolone typy: {{types}}',
AdditionalFields: 'Dodatkowe Pole 1',
AdditionalFieldsHelpText:
'Wybierz pola, które będą użyte do wyświetlania dodatkowych pól w podglądzie karty (opcjonalne). Dozwolone typy: {{types}}',
FieldRequired: 'Pole jest wymagane',
WrongFieldType: 'Ten typ pola nie jest wspierany',
CardDelete: 'Usunięto obiekty (1)',
FetchError:
'Wystąpił błąd połączenia z serwerem, spróbuj ponownie później.',
NonRequiredFieldsInCTD:
'pewnij się, że wybrany typ definicji zawiera pola, które mogą być wykorzystane we wtyczce. Dozwolone typy: {{types}}',
StateUpdateError: 'Nie udało się zaktualizować karty',
},
},
},
});

export default i18n;
44 changes: 44 additions & 0 deletions plugins/common/plugin-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const appRoots = {};

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

let detachTimeoutId;

element.addEventListener('flotiq.attached', () => {
if (detachTimeoutId) {
clearTimeout(detachTimeoutId);
detachTimeoutId = null;
}
});

element.addEventListener('flotiq.detached', () => {
detachTimeoutId = setTimeout(() => {
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 });
};

export const addObjectToCache = (key, data = {}) => {
appRoots[key] = data;
};

export const removeRoot = (key) => {
delete appRoots[key];
};
101 changes: 101 additions & 0 deletions plugins/common/valid-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import pluginInfo from '../plugin-manifest.json';

export const validSourceFields = ['select', 'radio'];

export const validCardTitleFields = ['text'];

export const validCardImageFields = ['datasource'];

export const validCardAdditionalFields = [
'text',
'number',
'select',
'dateTime',
'checkbox',
'radio',
'richtext',
'textarea',
];

export const getValidFields = (contentTypes) => {
const sourceFields = {};
const sourceFieldsKeys = {};

const cardTitleFields = {};
const cardTitleFieldsKeys = {};

const cardImageFields = {};
const cardImageFieldsKeys = {};

const cardAdditionalFields = {};
const cardAdditionalFieldsKeys = {};

contentTypes
?.filter(({ internal }) => !internal)
?.map(({ name, label }) => ({ value: name, label }));

(contentTypes || []).forEach(({ name, metaDefinition }) => {
sourceFields[name] = [];
sourceFieldsKeys[name] = [];

cardTitleFields[name] = [];
cardTitleFieldsKeys[name] = [];

cardImageFields[name] = [];
cardImageFieldsKeys[name] = [];

cardAdditionalFields[name] = [];
cardAdditionalFieldsKeys[name] = [];

Object.entries(metaDefinition?.propertiesConfig || {}).forEach(
([key, fieldConfig]) => {
const inputType = fieldConfig?.inputType;

if (validSourceFields?.includes(inputType)) {
sourceFields[name].push({ value: key, label: fieldConfig.label });
sourceFieldsKeys[name].push(key);
}

if (validCardTitleFields?.includes(inputType)) {
cardTitleFields[name].push({
value: key,
label: fieldConfig.label,
});
cardTitleFieldsKeys[name].push(key);
}

if (
validCardImageFields?.includes(inputType) &&
fieldConfig?.validation?.relationContenttype === '_media'
) {
cardImageFields[name].push({
value: key,
label: fieldConfig.label,
});
cardImageFieldsKeys[name].push(key);
}

if (validCardAdditionalFields?.includes(inputType)) {
cardAdditionalFields[name].push({
value: key,
label: fieldConfig.label,
});
cardAdditionalFieldsKeys[name].push(key);
}
},
);
});

return {
sourceFields,
sourceFieldsKeys,
cardTitleFields,
cardTitleFieldsKeys,
cardImageFields,
cardImageFieldsKeys,
cardAdditionalFields,
cardAdditionalFieldsKeys,
};
};

export const validFieldsCacheKey = `${pluginInfo.id}-form-valid-fields`;
92 changes: 92 additions & 0 deletions plugins/field-config/plugin-form/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { getCachedElement } from '../../../../surferseo-plugin/plugins/common/plugin-helpers';
import {
validCardAdditionalFields,
validCardTitleFields,
validFieldsCacheKey,
validSourceFields,
} from '../../common/valid-fields';
import i18n from '../../../../surferseo-plugin/i18n';

const insertSelectOptions = (config, options = [], emptyOptionMessage) => {
config.additionalHelpTextClasses = 'break-normal';

if (options.length === 0) {
config.options = [
{ value: 'empty', label: emptyOptionMessage, disabled: true },
];
return;
}
config.options = options;
};

export const handlePluginFormConfig = ({ name, config, formik }) => {
const { index, type } =
name.match(/kanbanBoard\[(?<index>\d+)\].(?<type>\w+)/)?.groups || {};

if (index == null || !type) return;
const ctd = formik.values.kanbanBoard[index].content_type;
const {
sourceFields,
cardTitleFields,
cardImageFields,
cardAdditionalFields,
} = getCachedElement(validFieldsCacheKey);

const keysToClearOnCtdChange = [
'source',
'title',
'image',
'additional_fields',
];

switch (type) {
case 'content_type':
config.onChange = (_, value) => {
if (value == null) formik.setFieldValue(name, '');
else formik.setFieldValue(name, value);

keysToClearOnCtdChange.forEach((key) => {
formik.setFieldValue(`kanbanBoard[${index}].${key}`, '');
});
};
break;
case 'source':
insertSelectOptions(
config,
sourceFields?.[ctd],
i18n.t('NonRequiredFieldsInCTD', {
types: validSourceFields.join(', '),
}),
);
break;
case 'title':
insertSelectOptions(
config,
cardTitleFields?.[ctd],
i18n.t('NonRequiredFieldsInCTD', {
types: validCardTitleFields.join(', '),
}),
);
break;
case 'image':
insertSelectOptions(
config,
cardImageFields?.[ctd],
i18n.t('NonRequiredFieldsInCTD', {
types: ['Relation to media, media'],
}),
);
break;
case 'additional_fields':
insertSelectOptions(
config,
cardAdditionalFields?.[ctd],
i18n.t('NonRequiredFieldsInCTD', {
types: validCardAdditionalFields.join(', '),
}),
);
break;
default:
break;
}
};
62 changes: 0 additions & 62 deletions plugins/grid-renderers/index.js

This file was deleted.

Empty file added plugins/manage/index.js
Empty file.
Loading

0 comments on commit 5b0a9ff

Please sign in to comment.