Skip to content

Commit

Permalink
ENH Add Readonly field status
Browse files Browse the repository at this point in the history
  • Loading branch information
Sabina Talipova committed Jan 16, 2024
1 parent f18b830 commit 1cf61bb
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 18 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/styles/bundle.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/src/components/LinkField/LinkField.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ const LinkField = ({
onDelete={onDelete}
onClick={() => { setEditingID(linkID); }}
canDelete={data[linkID]?.canDelete ? true : false}
canCreate={canCreate}
/>);
}
return links;
Expand Down
4 changes: 4 additions & 0 deletions client/src/components/LinkPicker/LinkPicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@
&--published::before {
display: none;
}

&.readonly {
background-color: $gray-100;
}
}

.link-picker__button {
Expand Down
23 changes: 13 additions & 10 deletions client/src/components/LinkPicker/LinkPickerTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ const LinkPickerTitle = ({
typeIcon,
onDelete,
onClick,
canDelete
canDelete,
canCreate,
}) => {
const { loading } = useContext(LinkFieldContext);
const classes = {
'link-picker__link': true,
'form-control': true,
'readonly': !canCreate,
};
if (versionState) {
classes[` link-picker__link--${versionState}`] = true;
Expand All @@ -56,17 +58,17 @@ const LinkPickerTitle = ({
return <div className={className}>
<Button disabled={loading} className={`link-picker__button ${typeIcon}`} color="secondary" onClick={stopPropagation(onClick)}>
<div className="link-picker__link-detail">
<div className="link-picker__title">
<span className="link-picker__title-text">{title}</span>
{getVersionedBadge(versionState)}
</div>
<small className="link-picker__type">
{typeTitle}:&nbsp;
<span className="link-picker__url">{description}</span>
</small>
<div className="link-picker__title">
<span className="link-picker__title-text">{title}</span>
{getVersionedBadge(versionState)}
</div>
<small className="link-picker__type">
{typeTitle}:&nbsp;
<span className="link-picker__url">{description}</span>
</small>
</div>
</Button>
{canDelete &&
{(canDelete && canCreate) &&
<Button disabled={loading} className="link-picker__delete" color="link" onClick={stopPropagation(() => onDelete(id))}>{deleteText}</Button>
}
</div>
Expand All @@ -82,6 +84,7 @@ LinkPickerTitle.propTypes = {
onDelete: PropTypes.func.isRequired,
onClick: PropTypes.func.isRequired,
canDelete: PropTypes.bool.isRequired,
canCreate: PropTypes.bool.isRequired,
};

export default LinkPickerTitle;
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function makeProps(obj = {}) {
typeTitle: 'Phone',
typeIcon: 'font-icon-phone',
canDelete: true,
canCreate: true,
onDelete: () => {},
onClick: () => {},
...obj
Expand Down
20 changes: 19 additions & 1 deletion src/Controllers/LinkFieldController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@
use SilverStripe\LinkField\Services\LinkTypeService;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Security;

class LinkFieldController extends LeftAndMain
{
public const FORM_NAME_TEMPLATE = 'LinkForm_%s';

private static $url_segment = 'linkfield';

private static $required_permission_codes = 'CMS_ACCESS_CMSMain';

private static $url_handlers = [
'linkForm/$ItemID' => 'linkForm',
'GET data/$ItemID' => 'linkData',
Expand Down Expand Up @@ -306,7 +309,9 @@ private function createLinkForm(Link $link, string $operation): Form

// Make readonly if fail can check
if ($operation === 'create' && !$link->canCreate()
|| $operation === 'edit' && !$link->canEdit()) {
|| $operation === 'edit' && !$link->canEdit()
|| $this->isReadOnlyField() && !$link->canEdit()
) {
$form->makeReadonly();
}

Expand All @@ -316,6 +321,19 @@ private function createLinkForm(Link $link, string $operation): Form
return $form;
}

/**
* Get is the owner LinkField is readonly
*/
private function isReadOnlyField(): bool
{
$request = $this->getRequest();
$ownerClass = $request->getVar('ownerClass') ?: $request->postVar('OwnerClass');
$ownerRelation = $this->ownerRelationFromRequest();
$isReadOnly = Injector::inst()->get($ownerClass)->getCMSFields()->dataFieldByName($ownerRelation)?->isReadonly();

return $isReadOnly ?? false;
}

/**
* Get a Link object based on the $ItemID request param
*/
Expand Down
14 changes: 12 additions & 2 deletions src/Form/LinkField.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ public function setValue($value, $data = null)
public function getSchemaStateDefaults()
{
$data = parent::getSchemaStateDefaults();
$data['canCreate'] = $this->getOwner()->canEdit();
$data['canCreate'] = $this->getOwner()->canEdit() && !$this->isReadonly();
return $data;
}

protected function getDefaultAttributes(): array
{
$attributes = parent::getDefaultAttributes();
$attributes['data-value'] = $this->Value();
$attributes['data-can-create'] = $this->getOwner()->canEdit();
$attributes['data-can-create'] = $this->getOwner()->canEdit() && !$this->isReadonly();
$ownerFields = $this->getOwnerFields();
$attributes['data-owner-id'] = $ownerFields['ID'];
$attributes['data-owner-class'] = $ownerFields['Class'];
Expand All @@ -62,4 +62,14 @@ public function getSchemaDataDefaults()
$data['ownerRelation'] = $ownerFields['Relation'];
return $data;
}

/**
* Changes this field to the readonly field.
*/
public function performReadonlyTransformation()
{
$copy = $this->castedCopy(LinkField_Readonly::class);

return $copy;
}
}
27 changes: 27 additions & 0 deletions src/Form/LinkField_Readonly.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types=1);

namespace SilverStripe\LinkField\Form;

use SilverStripe\Forms\HiddenField;
use SilverStripe\Forms\ReadonlyField;

class LinkField_Readonly extends LinkField
{

protected $readonly = true;

public function Field($properties = [])
{
// Readonly field for display
$field = new LinkField($this->name, $this->title);
$field->setValue($this->Value());
$field->setForm($this->form);

// Store values to hidden field
$valueField = new HiddenField($this->name);
$valueField->setValue($this->Value());
$valueField->setForm($this->form);

return $field->Field() . $valueField->Field();
}
}
16 changes: 13 additions & 3 deletions src/Form/MultiLinkField.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ public function getSchemaStateDefaults()
{
$data = parent::getSchemaStateDefaults();
$data['value'] = $this->getValueArray();
$data['canCreate'] = $this->getOwner()->canEdit();
$data['canCreate'] = $this->getOwner()->canEdit() && !$this->isReadonly();
return $data;
}

protected function getDefaultAttributes(): array
{
$attributes = parent::getDefaultAttributes();
$attributes['data-value'] = $this->getValueArray();
$attributes['data-can-create'] = $this->getOwner()->canEdit();
$attributes['data-can-create'] = $this->getOwner()->canEdit() && !$this->isReadonly();
$ownerFields = $this->getOwnerFields();
$attributes['data-owner-id'] = $ownerFields['ID'];
$attributes['data-owner-class'] = $ownerFields['Class'];
Expand All @@ -72,7 +72,7 @@ protected function getDefaultAttributes(): array
/**
* Extracts the value of this field, normalised as a non-associative array.
*/
private function getValueArray(): array
protected function getValueArray(): array
{
return $this->convertValueToArray($this->Value());
}
Expand Down Expand Up @@ -154,5 +154,15 @@ private function loadFrom(DataObject $record): void
// Load ids from relation
$value = array_values($relation->getIDList() ?? []);
parent::setValue($value);
}

/**
* Changes this field to the readonly field.
*/
public function performReadonlyTransformation()
{
$copy = $this->castedCopy(MultiLinkField_Readonly::class);

return $copy;
}
}
27 changes: 27 additions & 0 deletions src/Form/MultiLinkField_Readonly.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types=1);

namespace SilverStripe\LinkField\Form;

use SilverStripe\Forms\HiddenField;
use SilverStripe\Forms\ReadonlyField;

class MultiLinkField_Readonly extends MultiLinkField
{

protected $readonly = true;

public function Field($properties = [])
{
// Readonly field for display
$field = new MultiLinkField($this->name, $this->title);
$field->setValue($this->getValueArray());
$field->setForm($this->form);

// Store values to hidden field
$valueField = new HiddenField($this->name);
$valueField->setValue($this->getValueArray());
$valueField->setForm($this->form);

return $field->Field() . $valueField->Field();
}
}

0 comments on commit 1cf61bb

Please sign in to comment.