Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(form): add published version of fields #55

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
<p align="center"><img src="https://raw.githubusercontent.com/cern-sis/react-formule/master/docs/logo.png" width="350px"/></p>
<div align="center">

<h3 align="center"> 🕹️ <a href="https://cern-sis.github.io/react-formule/">DEMO</a> 🕹️</h3>
<img src="https://raw.githubusercontent.com/cern-sis/react-formule/master/docs/logo_horizontal.png" width="800px" />

[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
[![Try our demo](https://img.shields.io/badge/try_our-🕹️_demo_🕹️-deepskyblue.svg?style=for-the-badge)](https://cern-sis.github.io/react-formule/)

</div>

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
[![NPM Version](https://img.shields.io/npm/v/react-formule?style=flat-square&color=orchid)](https://www.npmjs.com/package/react-formule?activeTab=readme)
[![GitHub commits since tagged version](https://img.shields.io/github/commits-since/cern-sis/react-formule/latest?style=flat-square&color=orange)](https://github.com/cern-sis/react-formule/commits/master/)
[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/cern-sis/react-formule?style=flat-square)](https://github.com/cern-sis/react-formule/pulls)
[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-blue.svg?style=flat-square)](https://github.com/cern-sis/react-formule/issues)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-blue.svg?style=flat-square)](http://commitizen.github.io/cz-cli/)
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/cern-sis/react-formule/cypress.yml?style=flat-square&label=cypress)](https://github.com/cern-sis/react-formule/actions/workflows/cypress.yml)
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/cern-sis/react-formule/deploy-demo.yml?style=flat-square&label=deploy-demo)](https://github.com/cern-sis/react-formule/actions/workflows/commit-lint.yml)

## :horse: What is Formule?

Expand All @@ -27,8 +38,8 @@ Formule consists of the following main components:
- The form editor, which has been split into three different components that work together for more flexibility:
- **`SelectOrEdit`** (or, separately, **`SelectFieldType`** and **`PropertyEditor`**): You can select fields to add to the form and customize their properties.
- **`SchemaPreview`**: A tree view of the fields where you can rearrange or select fields to be edited.
- **`FormPreview`**: A live, iteractive preview of the form.
- **`FormuleForm`**: You can use it to display a form (JSON Schema) generated by Formule.
- **`FormPreview`**: A live, iteractive preview of the form which lets you toggle between the editable and the published version. If you only want to show the editable version, use **`EditablePreview`** instead.
- **`FormuleForm`**: You can use it to display a form (JSON Schema) generated by Formule. The editable version will be displayed by default. You can pass `isPublished` if you want to see the published version.

It also exports the following functions:

Expand Down
Binary file added docs/logo_horizontal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 20 additions & 5 deletions formule-demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ function App() {
width={1000}
footer={null}
>
<Row gutter={10}>
<Row gutter={[10, 10]}>
<Col
xs={12}
xs={24}
style={{
overflowX: "hidden",
height: "100%",
Expand All @@ -49,7 +49,7 @@ function App() {
<CodeViewer
value={JSON.stringify(formuleState?.current.schema, null, 2)}
lang="json"
height="50vh"
height="45vh"
reset
/>
</Col>
Expand All @@ -64,7 +64,22 @@ function App() {
<CodeViewer
value={JSON.stringify(formuleState?.current.uiSchema, null, 2)}
lang="json"
height="50vh"
height="25vh"
reset
/>
</Col>
<Col
xs={12}
style={{
overflowX: "hidden",
height: "100%",
}}
>
<Typography.Text strong>Form data</Typography.Text>
<CodeViewer
value={JSON.stringify(formuleState?.formData, null, 2)}
lang="json"
height="25vh"
reset
/>
</Col>
Expand Down Expand Up @@ -105,7 +120,7 @@ function App() {
style={{
overflowX: "hidden",
height: "100%",
padding: "0px 15px",
padding: "0px 25px",
}}
>
<FormPreview liveValidate={true} />
Expand Down
5 changes: 5 additions & 0 deletions formule-demo/src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ export const theme = {
colorBgLayout: "#f0f2f5",
fontFamily: "Titillium Web",
},
components: {
Segmented: {
trackBg: "#E4E8EC",
},
},
};
58 changes: 58 additions & 0 deletions src/admin/components/EditablePreview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useContext } from "react";
import Form from "../../forms/Form";
import { shoudDisplayGuideLinePopUp } from "../utils";
import { Row, Empty, Space, Typography } from "antd";
import { useSelector } from "react-redux";
import CustomizationContext from "../../contexts/CustomizationContext";

const EditablePreview = ({ hideTitle, liveValidate }) => {
const schema = useSelector((state) => state.schemaWizard.current.schema);
const uiSchema = useSelector((state) => state.schemaWizard.current.uiSchema);
const formData = useSelector((state) => state.schemaWizard.formData);

const customizationContext = useContext(CustomizationContext);

return (
<>
{!hideTitle && (
<Typography.Title
level={4}
style={{ textAlign: "center", margin: "15px 0" }}
>
Editable Preview
</Typography.Title>
)}
{shoudDisplayGuideLinePopUp(schema) ? (
<Row
justify="center"
align="middle"
style={{ height: "100%", flex: 1 }}
>
<Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
description={
<Space direction="vertical">
<Typography.Title level={5}>
Your form is empty
</Typography.Title>
<Typography.Text type="secondary">
Add fields to the drop area to initialize your form
</Typography.Text>
</Space>
}
/>
</Row>
) : (
<Form
schema={customizationContext.transformSchema(schema)}
uiSchema={uiSchema}
formData={formData || {}}
onChange={() => {}}
liveValidate={liveValidate}
/>
)}
</>
);
};

export default EditablePreview;
71 changes: 30 additions & 41 deletions src/admin/components/FormPreview.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useContext } from "react";
import { useContext, useState } from "react";
import Form from "../../forms/Form";
import { shoudDisplayGuideLinePopUp } from "../utils";
import { Row, Empty, Space, Typography, Col } from "antd";
import { Segmented, Row } from "antd";
import { useSelector } from "react-redux";
import EditablePreview from "./EditablePreview";
import { EditOutlined, EyeOutlined } from "@ant-design/icons";
import CustomizationContext from "../../contexts/CustomizationContext";

const FormPreview = ({ liveValidate, hideAnchors }) => {
Expand All @@ -12,6 +13,12 @@ const FormPreview = ({ liveValidate, hideAnchors }) => {

const customizationContext = useContext(CustomizationContext);

const [segment, setSegment] = useState("editable");

const handleSegmentChange = (value) => {
setSegment(value);
};

return (
<div
style={{
Expand All @@ -21,45 +28,27 @@ const FormPreview = ({ liveValidate, hideAnchors }) => {
}}
data-cy="formPreview"
>
<Typography.Title
level={4}
style={{ textAlign: "center", margin: "15px 0" }}
>
Preview
</Typography.Title>
{shoudDisplayGuideLinePopUp(schema) ? (
<Row
justify="center"
align="middle"
style={{ height: "100%", flex: 1 }}
>
<Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
description={
<Space direction="vertical">
<Typography.Title level={5}>
Your form is empty
</Typography.Title>
<Typography.Text type="secondary">
Add fields to the drop area to initialize your form
</Typography.Text>
</Space>
}
/>
</Row>
<Row justify="center" style={{ margin: "15px" }}>
<Segmented
options={[
{ label: "Editable", value: "editable", icon: <EditOutlined /> },
{ label: "Published", value: "published", icon: <EyeOutlined /> },
]}
style={{ fontWeight: "bold" }}
value={segment}
onChange={handleSegmentChange}
/>
</Row>
{segment === "editable" ? (
<EditablePreview hideTitle liveValidate={liveValidate} />
) : (
<Row justify="center">
<Col xs={22} sm={20}>
<Form
schema={customizationContext.transformSchema(schema)}
uiSchema={uiSchema}
formData={formData || {}}
onChange={() => {}}
liveValidate={liveValidate}
hideAnchors={hideAnchors}
/>
</Col>
</Row>
<Form
schema={customizationContext.transformSchema(schema)}
uiSchema={uiSchema}
formData={formData}
hideAnchors={hideAnchors}
isPublished
/>
)}
</div>
);
Expand Down
7 changes: 3 additions & 4 deletions src/admin/components/SchemaTree.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import CustomizationContext from "../../contexts/CustomizationContext";
import { useContext } from "react";

const SchemaTree = () => {
const schema = useSelector((state) => state.schemaWizard.current.schema);
const uiSchema = useSelector((state) => state.schemaWizard.current.uiSchema);

const schema = useSelector((state) => state.schemaWizard.current.schema)
const uiSchema = useSelector((state) => state.schemaWizard.current.uiSchema)

const customizationContext = useContext(CustomizationContext)
const customizationContext = useContext(CustomizationContext);

return (
<Form
Expand Down
6 changes: 3 additions & 3 deletions src/admin/formComponents/ArrayFieldTemplate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import FieldTemplate from "./FieldTemplate";
import { _validate } from "../utils";
import DropArea from "./DropArea";

const ArrayFieldTemplate = props => {
const ArrayFieldTemplate = (props) => {
const [display, setDisplay] = useState(false);

let schemaPath = [];
let uiSchemaPath = [];
if (props.rawErrors) {
let _rawErrors = props.rawErrors.filter(i => (i.schema ? i : false));
let _rawErrors = props.rawErrors.filter((i) => (i.schema ? i : false));
let { schema, uiSchema } = _rawErrors[0];
schemaPath = schema;
uiSchemaPath = uiSchema;
Expand Down Expand Up @@ -77,4 +77,4 @@ ArrayFieldTemplate.propTypes = {
id: PropTypes.string,
};

export default ArrayFieldTemplate
export default ArrayFieldTemplate;
16 changes: 8 additions & 8 deletions src/admin/formComponents/FieldTemplate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { isItTheArrayField, _validate } from "../utils/index";
import DropArea from "./DropArea";
import { addByPath } from "../../store/schemaWizard";

const FieldTemplate = props => {
const FieldTemplate = (props) => {
const {
schema,
uiSchema = {},
Expand All @@ -20,22 +20,22 @@ const FieldTemplate = props => {
id,
} = props;

const dispatch = useDispatch()
const dispatch = useDispatch();

const [display, setDisplay] = useState(false);

let path = {
schema: [
...formContext.schema,
...(rawErrors.find(e => typeof e === "object").schema || []),
...(rawErrors.find((e) => typeof e === "object").schema || []),
],
uiSchema: [
...formContext.uiSchema,
...(rawErrors.find(e => typeof e === "object").uiSchema || []),
...(rawErrors.find((e) => typeof e === "object").uiSchema || []),
],
};

const shouldBoxHideChildren = uiSchema => {
const shouldBoxHideChildren = (uiSchema) => {
return uiSchema["ui:field"] !== undefined;
};

Expand All @@ -55,7 +55,7 @@ const FieldTemplate = props => {
return (
<HoverBox
allowsChildren
addProperty={(path, value) => dispatch(addByPath({path, value}))}
addProperty={(path, value) => dispatch(addByPath({ path, value }))}
key={id}
path={path}
shouldHideChildren={shouldBoxHideChildren(uiSchema)}
Expand Down Expand Up @@ -108,7 +108,7 @@ const FieldTemplate = props => {
// The HoverBox wrapper here is needed to allow dropping items into objects
// or arrays directly without having to expand them first
<HoverBox
addProperty={(path, value) => dispatch(addByPath({path, value}))}
addProperty={(path, value) => dispatch(addByPath({ path, value }))}
key={id}
path={path}
shouldHideChildren={shouldBoxHideChildren(uiSchema)}
Expand All @@ -130,4 +130,4 @@ FieldTemplate.propTypes = {
schema: PropTypes.object,
};

export default FieldTemplate
export default FieldTemplate;
1 change: 0 additions & 1 deletion src/assets/react.svg

This file was deleted.

Loading
Loading