Всем привет!
Сегодня я покажу как можно оживлять формы в prisma-cms. Только сразу уточню, что для этого уже потребуется немного попрограммировать, то есть мы будем расширять имеющийся функционал, точнее просто добавим одну кнопку.
Задача следующая: есть Услуги и есть Категории услуг. Вот надо в форму создания Услуги добавить возможность задавать Категорию. Для этого у нас практически все есть во фронт-редакторе "из коробки": EditableObject позволяет создавать/редактировать объекты, а Query+Connector позволяет в форму добавить список Категорий. Но список Категорий-то мы получим, но как нам сделать, чтобы мы могли по клику указывать эту Категорию Услуге? Для этого нам надо создать свою кнопку Категории, чтобы по клику и выполнялось нужное нам действие. Вот посмотрите как это выглядит, а ниже я покажу рабочий код и объясню его.
Итак, как вы видели в ролике, у нас обычный текстовый вывод менялся на компонент SetServiceCategory. Вот его код:
import React from 'react';
import EditorComponent from '@prisma-cms/front-editor/lib/components/App/components/';
import { Button } from 'material-ui';
import { ObjectContext } from '@prisma-cms/front-editor/lib/components/App/components/public/Connectors/Connector/ListView';
import { EditableObjectContext } from '@prisma-cms/front-editor/lib/components/App/context';
export class SetServiceCategory extends EditorComponent {
static Name = 'SetServiceCategory';
renderPanelView() {
const {
classes,
} = this.getEditorContext();
return super.renderPanelView(
<div
className={classes.panelButton}
>
SetServiceCategory
</div>
);
}
canBeChild(child) {
return false;
}
renderChildren() {
return <ObjectContext.Consumer>
{context => {
const {
object,
...otherContext
} = context;
if (!object) {
return null;
}
let output = null;
const {
id: objectId,
name,
} = object;
if (!objectId) {
return null;
}
output = <EditableObjectContext.Consumer>
{editableObjectContext => {
const {
updateObject,
getEditor,
inEditMode,
canEdit,
getObjectWithMutations,
} = editableObjectContext;
const object = getObjectWithMutations();
if (!object) {
return null;
}
const {
Category,
} = object;
const categoryId = Category ? (Category.id || (Category.connect && Category.connect.id)) : null;
return getEditor({
Editor: (props) => {
return <Button
size="small"
variant={categoryId && categoryId === objectId ? "raised" : undefined}
onClick={event => {
updateObject({
Category: {
connect: {
id: objectId,
},
},
});
}}
>
{name}
</Button>
},
});
}}
</EditableObjectContext.Consumer>
return output;
}}
</ObjectContext.Consumer>;
}
}
export default SetServiceCategory;
Про основные моменты, касающиеся базового компонента фронт-редактора, написано здесь: Добавление кастомных компонентов в @prisma-cms/front-editor. Так же напомню, что есть специальное расширение для редактора VS Code: Расширение prisma-cms для редактора VS Code. Ускоряем процесс программирования.
А мы сосредоточимся сейчас на самом главном - методе renderChildren(), который и выводит нашу новую кнопку. Саму кнопку найти в этом коде не сложно, но нам важнее разобраться с ее обертками - ObjectContext.Consumer и EditableObjectContext.Consumer.
ObjectContext.Consumer позволяет получить данные текущего объекта. В нашем случае это объект Категория на каждой итерации вывода данных Категорий, полученных в запросе. Подробнее об этом читайте пор ObjectView и ListView.
EditableObjectContext.Consumer позволяет получить данные редактируемого объекта, и не только данные, но и методы создания редактируемых полей, проверки может ли быть объект редактируемым, его измененные данные и метод обновления его данных. Читайте подробней про EditableObject.
Таким образом, на каждой итерации вывода массива Категорий, мы получаем данные этой Категории (id и name) и проверяем выбрана эта Категория или нет (если выбрана, кнопку делаем жирной). А по клику через updateObject(), полученный из EditableObjectContext.Consumer, мы обновляем наш объект Услуги, то есть задаем ей Категорию. Здесь следует четко понимать, что на самом деле мы еще не обновляем в этот момент Услугу, а только задаем ей новое свойство. При этом Услуга еще в режиме Черновик. Реальное же обновление будет выполнено по клику на кнопку Сохранить (красная дискета), вот тогда данные будут отправлены на сервер, и если все ОК, то Услуга будет сохранена.