Skip to content

Commit

Permalink
Implemented widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed May 6, 2021
1 parent 7fe0da5 commit 8ead05a
Show file tree
Hide file tree
Showing 15 changed files with 851 additions and 69 deletions.
1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"react-bootstrap-typeahead": "^5.1.4",
"react-dom": "^17.0.2",
"react-infinite-scroll-component": "^6.1.0",
"react-jsonschema-form-layout-grid": "^2.1.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"react-scroll": "^1.8.2",
Expand Down
17 changes: 6 additions & 11 deletions ui/public/assets/schema/source/metadata-source.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
"entityId"
],
"properties": {
"entityId": {
"title": "label.entity-id",
"description": "tooltip.entity-id",
"serviceProviderName": {
"title": "label.service-provider-name",
"description": "tooltip.service-provider-name",
"type": "string",
"minLength": 1,
"maxLength": 255
},
"serviceProviderName": {
"title": "label.service-provider-name",
"description": "tooltip.service-provider-name",
"entityId": {
"title": "label.entity-id",
"description": "tooltip.entity-id",
"type": "string",
"minLength": 1,
"maxLength": 255
Expand Down Expand Up @@ -241,7 +241,6 @@
},
"definitions": {
"Contact": {
"title": "label.contact",
"type": "object",
"required": [
"name",
Expand Down Expand Up @@ -301,7 +300,6 @@
},
"Certificate": {
"type": "object",
"title": "label.certificate",
"required": [
"type",
"value"
Expand All @@ -315,7 +313,6 @@
},
"type": {
"title": "label.certificate-type",
"description": "tooltip.certificate-type",
"type": "string",
"widget": {
"id": "radio",
Expand Down Expand Up @@ -353,7 +350,6 @@
},
"AssertionConsumerService": {
"type": "object",
"title": "label.assertion-consumer-service-endpoint",
"required": [
"locationUrl",
"binding"
Expand Down Expand Up @@ -422,7 +418,6 @@
}
},
"LogoutEndpoint": {
"title": "label.new-endpoint",
"description": "tooltip.new-endpoint",
"type": "object",
"fieldsets": [
Expand Down
4 changes: 2 additions & 2 deletions ui/src/app/form/component/IconButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const mappings = {
};

const IconButton = (props) => {
const { icon, className, ...otherProps } = props;
const { icon, ...otherProps } = props;
return (
<Button {...otherProps} variant="light" size="sm">
<Button {...otherProps} variant={props.variant || 'light'}>
{mappings[icon]}
</Button>
);
Expand Down
112 changes: 96 additions & 16 deletions ui/src/app/form/component/templates/ArrayFieldTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ import { utils } from "@rjsf/core";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import Container from "react-bootstrap/Container";
import Accordion from 'react-bootstrap/Accordion';
import Button from 'react-bootstrap/Button';

import AddButton from "../AddButton";
import IconButton from "../IconButton";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCaretDown } from "@fortawesome/free-solid-svg-icons";
import Translate from "../../../i18n/components/translate";

const { isMultiSelect, getDefaultRegistry } = utils;

Expand Down Expand Up @@ -51,21 +56,25 @@ const ArrayFieldDescription = ({
};

// Used in the two templates
const DefaultArrayItem = (props) => {

const ObjectArrayItem = ({type, ...props}) => {
const btnStyle = {
flex: 1,
paddingLeft: 6,
paddingRight: 6,
fontWeight: "bold",
};
return (
<div key={props.key} className="mt-2 bg-light border rounded p-3 list-group">
<Row className="mb-2 d-flex align-items-center">
<Col xs="9" lg="9">{props.children}</Col>

<Col xs="3" lg="3" className="py-4">
<div key={props.key} className={`mt-2 bg-light border rounded p-2 list-group`}>
<Accordion defaultActiveKey="0">
<div className={`list-group-item`}>
<div className="mb-4 pb-2 d-flex justify-content-between align-items-center border-bottom">
<Accordion.Toggle as={Button} variant="link" eventKey="0" className="px-0">
<FontAwesomeIcon icon={faCaretDown} />&nbsp;
<Translate value={'label.new-of-type'} params={{type}} />
</Accordion.Toggle>
{props.hasToolbar && (
<div className="d-flex flex-row">
<div className="d-flex flex-row align-items-center">
{(props.hasMoveUp || props.hasMoveDown) && (
<div className="m-0 p-0">
<IconButton
Expand Down Expand Up @@ -96,8 +105,10 @@ const DefaultArrayItem = (props) => {
)}

{props.hasRemove && (
<div className="m-0 p-0">
<div className="m-0 pb-1">
<IconButton
className="text-danger"
variant='text'
icon="remove"
tabIndex={-1}
style={btnStyle}
Expand All @@ -108,14 +119,79 @@ const DefaultArrayItem = (props) => {
)}
</div>
)}
</Col>
</Row>
</div>
<Accordion.Collapse eventKey="0">
<div className="mr-2 flex-grow-1">{props.children}</div>
</Accordion.Collapse>
</div>
</Accordion>
</div>
);
}

const DefaultArrayItem = (props) => {
const btnStyle = {
flex: 1,
paddingLeft: 6,
paddingRight: 6,
fontWeight: "bold",
};
return (
<div key={props.key} className={`mt-2`}>
<div className="mb-2 d-flex align-items-center">
<div className="mr-2 flex-grow-1">{props.children}</div>
{props.hasToolbar && (
<div className="d-flex flex-row align-items-center">
{(props.hasMoveUp || props.hasMoveDown) && (
<div className="m-0 p-0">
<IconButton
icon="arrow-up"
className="array-item-move-up"
tabIndex={-1}
style={btnStyle}
disabled={
props.disabled || props.readonly || !props.hasMoveUp
}
onClick={props.onReorderClick(props.index, props.index - 1)}
/>
</div>
)}

{(props.hasMoveUp || props.hasMoveDown) && (
<div className="m-0 p-0">
<IconButton
icon="arrow-down"
tabIndex={-1}
style={btnStyle}
disabled={
props.disabled || props.readonly || !props.hasMoveDown
}
onClick={props.onReorderClick(props.index, props.index + 1)}
/>
</div>
)}

{props.hasRemove && (
<div className="m-0 pb-1">
<IconButton
className="text-danger"
variant='text'
icon="remove"
tabIndex={-1}
style={btnStyle}
disabled={props.disabled || props.readonly}
onClick={props.onDropIndexClick(props.index)}
/>
</div>
)}
</div>
)}
</div>
</div>
);
};

const DefaultFixedArrayFieldTemplate = (props) => {
console.log(props)
return (
<fieldset className={props.className}>
<div className="d-flex align-items-center">
Expand All @@ -136,7 +212,7 @@ const DefaultFixedArrayFieldTemplate = (props) => {
</div>


{(props.uiSchema["ui:description"] || props.schema.description) && (
{props.uiSchema["ui:description"] !== false && (props.uiSchema["ui:description"] || props.schema.description) && (
<div
className="field-description"
key={`field-description-${props.idSchema.$id}`}>
Expand Down Expand Up @@ -187,10 +263,14 @@ const DefaultNormalArrayFieldTemplate = (props) => {
)}
</div>
<Container fluid key={`array-item-list-${props.idSchema.$id}`} className="p-0 m-0">
{props.items && props.items.map(p => DefaultArrayItem(p))}

</Container></Col>

{props.items && props.items.map(p =>
props.schema.items.type === 'object' || props.schema.items.$ref ?
ObjectArrayItem({type: props.uiSchema.type, ...p})
:
DefaultArrayItem({...p })
)}
</Container>
</Col>
</Row>
</div>
);
Expand Down
29 changes: 22 additions & 7 deletions ui/src/app/form/component/templates/ObjectFieldTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,44 @@ const ObjectFieldTemplate = ({
schema,
hidden
}) => {

const displayTitle = (uiSchema["ui:title"] || (title && schema.title));

return (
<>
{!hidden &&
<>
{(uiSchema["ui:title"] || (title && schema.title)) && (
{displayTitle && (
<TitleField
id={`${idSchema.$id}-title`}
title={title}
required={required}
/>
)}
{description && (
{displayTitle && description && (
<DescriptionField
id={`${idSchema.$id}-description`}
description={description}
/>
)}
<Container fluid className="p-0">
{properties.map((element, index) => (
<Row key={index}>
<Col xs={12}> {element.content}</Col>
</Row>
))}
<>
{uiSchema.layout ?
<Row>{uiSchema.layout.groups.map((group, rIdx) => (

<Col xs={group.size} key={rIdx}>{properties.filter(p => group.fields.indexOf(p.name) > -1).map((element, eIdx) => (
<React.Fragment key={eIdx}>{element.content}</React.Fragment>
))}</Col>

))}</Row>
:
properties.map((element, index) => (
<Row key={index}>
<Col xs={12}> {element.content}</Col>
</Row>
))
}
</>
</Container>
</>
}
Expand Down
5 changes: 3 additions & 2 deletions ui/src/app/form/component/widgets/OptionWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import { InfoIcon } from "../InfoIcon";

import { Typeahead } from 'react-bootstrap-typeahead';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowDown, faArrowUp } from "@fortawesome/free-solid-svg-icons";
import { faArrowDown, faArrowUp, faAsterisk } from "@fortawesome/free-solid-svg-icons";

const ToggleButton = ({ isOpen, onClick }) => (
<button
type="button"
className="btn btn-outline-secondary toggle-button"
onClick={onClick}
onMouseDown={e => {
Expand Down Expand Up @@ -53,7 +54,7 @@ const OptionWidget = ({
<Form.Label className={`${rawErrors.length > 0 ? "text-danger" : ""}`}>
<span>
<Translate value={label || schema.title} />
{(label || schema.title) && required ? <span className="text-danger">*</span> : null}
{(label || schema.title) && required ? <FontAwesomeIcon icon={faAsterisk} className="text-danger ml-2" size="sm" /> : null}
</span>
{schema.description && <InfoIcon value={schema.description} />}
</Form.Label>
Expand Down
6 changes: 3 additions & 3 deletions ui/src/app/form/component/widgets/RadioWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const RadioWidget = ({
onChange,
onBlur,
onFocus,
...props
}) => {
const { enumOptions, enumDisabled } = options;

Expand All @@ -31,15 +32,14 @@ const RadioWidget = ({
}) => onFocus(id, value);

const inline = Boolean(options && options.inline);

return (
<Form.Group className="mb-0">
<Form.Label className="d-block">
<span>
<Translate value={label || schema.title} />
{(label || schema.title) && required ? <span className="text-danger">*</span> : null}
</span>
{schema.description && <InfoIcon value={schema.description} />}
{schema.description && <InfoIcon value={schema.description} className="ml-2" />}
</Form.Label>
{(enumOptions).map((option, i) => {
const itemDisabled =
Expand All @@ -51,7 +51,7 @@ const RadioWidget = ({
<Form.Check
inline={inline}
label={<Translate value={option.label} />}
id={option.label}
id={`${schema.title}-${i}-${option.label}`}
key={i}
name={id}
type="radio"
Expand Down
6 changes: 4 additions & 2 deletions ui/src/app/form/component/widgets/SelectWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { utils } from "@rjsf/core";

import Translate from "../../../i18n/components/translate";
import { InfoIcon } from "../InfoIcon";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAsterisk } from "@fortawesome/free-solid-svg-icons";

const { asNumber, guessType } = utils;

Expand Down Expand Up @@ -81,9 +83,9 @@ const SelectWidget = ({
<Form.Label className={`${rawErrors.length > 0 ? "text-danger" : ""}`}>
<span>
<Translate value={label || schema.title} />
{(label || schema.title) && required ? <span className="text-danger">*</span> : null}
{(label || schema.title) && required ? <FontAwesomeIcon icon={faAsterisk} className="ml-2 text-danger" size="sm" /> : null}
</span>
{schema.description && <InfoIcon value={schema.description} />}
{schema.description && <InfoIcon value={schema.description} className="ml-2" />}
</Form.Label>
<Form.Control
as="select"
Expand Down
Loading

0 comments on commit 8ead05a

Please sign in to comment.