allows readOnly to cascade through children

This commit is contained in:
James
2020-07-28 16:50:54 -04:00
parent aefdabfd7e
commit 8fa95b7851
9 changed files with 140 additions and 38 deletions

View File

@@ -32,6 +32,7 @@ const DraggableSection = (props) => {
actionPanelVerticalAlignment,
permissions,
isOpen,
readOnly,
} = props;
const [isHovered, setIsHovered] = useState(false);
@@ -46,6 +47,7 @@ const DraggableSection = (props) => {
<Draggable
draggableId={id}
index={rowIndex}
isDropDisabled={readOnly}
>
{(providedDrag) => (
<div
@@ -73,6 +75,7 @@ const DraggableSection = (props) => {
<SectionTitle
label={singularLabel}
path={`${parentPath}.${rowIndex}.blockName`}
readOnly={readOnly}
/>
<Button
@@ -90,6 +93,7 @@ const DraggableSection = (props) => {
duration={0}
>
<RenderFields
readOnly={readOnly}
customComponentsPath={customComponentsPath}
fieldTypes={fieldTypes}
key={rowIndex}
@@ -102,6 +106,7 @@ const DraggableSection = (props) => {
</AnimateHeight>
</div>
{!readOnly && (
<ActionPanel
rowIndex={rowIndex}
addRow={addRow}
@@ -111,6 +116,7 @@ const DraggableSection = (props) => {
isHovered={isHovered}
{...props}
/>
)}
</div>
</div>
)}
@@ -129,6 +135,7 @@ DraggableSection.defaultProps = {
positionPanelVerticalAlignment: 'sticky',
actionPanelVerticalAlignment: 'sticky',
permissions: {},
readOnly: false,
};
DraggableSection.propTypes = {
@@ -150,6 +157,7 @@ DraggableSection.propTypes = {
positionPanelVerticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']),
actionPanelVerticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']),
permissions: PropTypes.shape({}),
readOnly: PropTypes.bool,
};
export default DraggableSection;

View File

@@ -29,6 +29,9 @@ const ArrayFieldType = (props) => {
minRows,
singularLabel,
permissions,
admin: {
readOnly,
},
} = props;
const [rows, dispatchRows] = useReducer(reducer, []);
@@ -113,6 +116,7 @@ const ArrayFieldType = (props) => {
fields={fields}
permissions={permissions}
value={value}
readOnly={readOnly}
/>
);
};
@@ -125,6 +129,7 @@ ArrayFieldType.defaultProps = {
minRows: undefined,
singularLabel: 'Row',
permissions: {},
admin: {},
};
ArrayFieldType.propTypes = {
@@ -143,6 +148,9 @@ ArrayFieldType.propTypes = {
permissions: PropTypes.shape({
fields: PropTypes.shape({}),
}),
admin: PropTypes.shape({
readOnly: PropTypes.bool,
}),
};
const RenderArray = React.memo((props) => {
@@ -163,6 +171,7 @@ const RenderArray = React.memo((props) => {
fields,
permissions,
value,
readOnly,
} = props;
return (
@@ -183,6 +192,7 @@ const RenderArray = React.memo((props) => {
>
{rows.length > 0 && rows.map((row, i) => (
<DraggableSection
readOnly={readOnly}
key={row.key}
id={row.key}
blockType="array"
@@ -205,7 +215,7 @@ const RenderArray = React.memo((props) => {
</div>
)}
</Droppable>
{!readOnly && (
<div className={`${baseClass}__add-button-wrap`}>
<Button
onClick={() => addRow(value)}
@@ -217,6 +227,7 @@ const RenderArray = React.memo((props) => {
{`Add ${singularLabel}`}
</Button>
</div>
)}
</div>
</DragDropContext>
);
@@ -231,6 +242,7 @@ RenderArray.defaultProps = {
path: '',
customComponentsPath: undefined,
value: undefined,
readOnly: false,
};
RenderArray.propTypes = {
@@ -256,6 +268,7 @@ RenderArray.propTypes = {
permissions: PropTypes.shape({
fields: PropTypes.shape({}),
}).isRequired,
readOnly: PropTypes.bool,
};
export default withCondition(ArrayFieldType);

View File

@@ -33,6 +33,9 @@ const Blocks = (props) => {
required,
validate,
permissions,
admin: {
readOnly,
},
} = props;
const path = pathFromProps || name;
@@ -130,6 +133,7 @@ const Blocks = (props) => {
permissions={permissions}
value={value}
blocks={blocks}
readOnly={readOnly}
/>
);
};
@@ -142,6 +146,7 @@ Blocks.defaultProps = {
maxRows: undefined,
minRows: undefined,
permissions: {},
admin: {},
};
Blocks.propTypes = {
@@ -160,6 +165,9 @@ Blocks.propTypes = {
permissions: PropTypes.shape({
fields: PropTypes.shape({}),
}),
admin: PropTypes.shape({
readOnly: PropTypes.bool,
}),
};
const RenderBlocks = React.memo((props) => {
@@ -181,6 +189,7 @@ const RenderBlocks = React.memo((props) => {
value,
toggleCollapse,
blocks,
readOnly,
} = props;
return (
@@ -195,7 +204,10 @@ const RenderBlocks = React.memo((props) => {
/>
</header>
<Droppable droppableId="blocks-drop">
<Droppable
droppableId="blocks-drop"
isDropDisabled={readOnly}
>
{(provided) => (
<div
ref={provided.innerRef}
@@ -208,6 +220,7 @@ const RenderBlocks = React.memo((props) => {
if (blockToRender) {
return (
<DraggableSection
readOnly={readOnly}
key={row.key}
id={row.key}
blockType="blocks"

View File

@@ -7,7 +7,14 @@ import './index.scss';
const Group = (props) => {
const {
label, fields, name, path: pathFromProps, fieldTypes,
label,
fields,
name,
path: pathFromProps,
fieldTypes,
admin: {
readOnly,
},
} = props;
const path = pathFromProps || name;
@@ -18,6 +25,7 @@ const Group = (props) => {
<div className="field-type group">
<h3>{label}</h3>
<RenderFields
readOnly={readOnly}
fieldTypes={fieldTypes}
customComponentsPath={`${customComponentsPath}${name}.fields.`}
fieldSchema={fields.map((subField) => ({
@@ -32,6 +40,7 @@ const Group = (props) => {
Group.defaultProps = {
label: '',
path: '',
admin: {},
};
Group.propTypes = {
@@ -42,6 +51,9 @@ Group.propTypes = {
name: PropTypes.string.isRequired,
path: PropTypes.string,
fieldTypes: PropTypes.shape({}).isRequired,
admin: PropTypes.shape({
readOnly: PropTypes.bool,
}),
};
export default withCondition(Group);

View File

@@ -59,3 +59,19 @@
}
}
}
.radio-group--read-only {
.radio-input__label {
color: $color-gray;
}
.radio-input--is-selected {
.radio-input {
&__styled-radio {
&:before {
background-color: $color-gray;
}
}
}
}
}

View File

@@ -10,6 +10,8 @@ import { radio } from '../../../../../fields/validations';
import './index.scss';
const baseClass = 'radio-group';
const RadioGroup = (props) => {
const {
name,
@@ -19,6 +21,7 @@ const RadioGroup = (props) => {
label,
admin: {
readOnly,
layout = 'horizontal',
style,
width,
} = {},
@@ -45,9 +48,10 @@ const RadioGroup = (props) => {
const classes = [
'field-type',
'radio-group',
baseClass,
`${baseClass}--layout-${layout}`,
showError && 'error',
readOnly && 'read-only',
readOnly && `${baseClass}--read-only`,
].filter(Boolean).join(' ');
return (
@@ -67,18 +71,22 @@ const RadioGroup = (props) => {
label={label}
required={required}
/>
<ul className={`${baseClass}--group`}>
{options?.map((option) => {
const isSelected = option.value === value;
return (
<li key={option.value}>
<RadioInput
key={option.value}
isSelected={isSelected}
option={option}
onChange={readOnly ? undefined : setValue}
/>
</li>
);
})}
</ul>
</div>
);
};

View File

@@ -0,0 +1,21 @@
@import '../../../../scss/styles.scss';
.radio-group {
&--layout-horizontal {
ul {
display: flex;
flex-wrap: wrap;
}
li {
padding-right: $baseline;
flex-shrink: 0;
}
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
}

View File

@@ -7,11 +7,18 @@ import './index.scss';
const Row = (props) => {
const {
fields, fieldTypes, path, permissions,
fields,
fieldTypes,
path,
permissions,
admin: {
readOnly,
},
} = props;
return (
<RenderFields
readOnly={readOnly}
className="field-type row"
permissions={permissions}
fieldTypes={fieldTypes}
@@ -26,6 +33,7 @@ const Row = (props) => {
Row.defaultProps = {
path: '',
permissions: {},
admin: {},
};
Row.propTypes = {
@@ -35,6 +43,9 @@ Row.propTypes = {
fieldTypes: PropTypes.shape({}).isRequired,
path: PropTypes.string,
permissions: PropTypes.shape({}),
admin: PropTypes.shape({
readOnly: PropTypes.bool,
}),
};
export default withCondition(Row);

View File

@@ -46,7 +46,7 @@ const CreateFirstUser = (props) => {
return (
<MinimalTemplate className={baseClass}>
<h1>Welcome to Payload</h1>
<h1>Welcome</h1>
<p>To begin, create your first user.</p>
<Form
onSuccess={onSuccess}