-
Notifications
You must be signed in to change notification settings - Fork 15
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
ENH Add Readonly field status #172
ENH Add Readonly field status #172
Conversation
237f785
to
f34fcee
Compare
c98121f
to
1cf61bb
Compare
$request = $this->getRequest(); | ||
$ownerClass = $request->getVar('ownerClass') ?: $request->postVar('OwnerClass'); | ||
$ownerRelation = $this->ownerRelationFromRequest(); | ||
$isReadOnly = Injector::inst()->get($ownerClass)->getCMSFields()->dataFieldByName($ownerRelation)?->isReadonly(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method gets Owner's (e.g. Page) fields and check is this LinkField is read only.
$ownerRelation = $this->ownerRelationFromRequest(); | ||
$isReadOnly = Injector::inst()->get($ownerClass)->getCMSFields()->dataFieldByName($ownerRelation)?->isReadonly(); | ||
|
||
return $isReadOnly ?? false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isReadOnly
can be null
in some cases.
I'm not doing an actual review of this yet - just answering the question in the note:
Readonly is more important than |
562eccf
to
70d245d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested locally yet
I really dislike the how 'readonly' has been stuffed into the value of 'canCreate'. It makes things much harder to understand what's going on.
Instead you should make 'readonly' its own separate key / prop
@@ -105,6 +105,10 @@ | |||
&--published::before { | |||
display: none; | |||
} | |||
|
|||
&.readonly { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&.readonly { | |
&--readonly { |
Safer to use a BEM class rather than a generic/global readonly
that may accidentally get values set from somewhere else
You'll need to update this is bunch of places in this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
</div> | ||
</Button> | ||
{canDelete && | ||
{(canDelete && canCreate) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic looks wrong, shouldn't have a canCreate
check for a delete button
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. I have to use readonly
, since we should hide "Archive" button if user cannot edit link field.
@@ -449,6 +467,11 @@ private function ownerRelationFromRequest(): string | |||
if (!$ownerRelation) { | |||
$this->jsonError(404, _t(__CLASS__ . '.INVALID_OWNER_RELATION', 'Invalid ownerRelation')); | |||
} | |||
|
|||
if (strpos($ownerRelation, '_Readonly') !== false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we doing this with $ownerRelation? Owner relation should be what's set in the private static $has_many, not the _Readonly
added to form fields when they are set to read only mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
private function isReadOnlyField(): bool | ||
{ | ||
$request = $this->getRequest(); | ||
$ownerClass = $request->getVar('ownerClass') ?: $request->postVar('OwnerClass'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a new private method getOwnerClassFromRequest() so that it's consistent with the rest of the file and throw a 404 error if the owner class !is_a DataObject
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
$request = $this->getRequest(); | ||
$ownerClass = $request->getVar('ownerClass') ?: $request->postVar('OwnerClass'); | ||
$ownerRelation = $this->ownerRelationFromRequest(); | ||
$isReadOnly = Injector::inst()->get($ownerClass)->getCMSFields()->dataFieldByName($ownerRelation)?->isReadonly(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$isReadOnly = Injector::inst()->get($ownerClass)->getCMSFields()->dataFieldByName($ownerRelation)?->isReadonly(); | |
return (bool) Injector::inst()->get($ownerClass)->getCMSFields()->dataFieldByName($ownerRelation)?->isReadonly(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't take into account scenarios where the form was set to readonly, which I believe is what happens when the user doesn't have edit permission for the owner record (e.g. a page).
|
||
return $isReadOnly ?? false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return $isReadOnly ?? false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
7ea3d91
to
512f05b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still able to sort links in a MultiLinkField when it's in a readonly state
Also needs a rebase
$form->makeReadonly(); | ||
$form->setMessage(_t(__CLASS__ . '.READ_ONLY_MESSAGE', 'You do not have enough permissions to edit this form'), 'info'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we should be setting a form message here. Can you find any other examples of us doing this?
If we do keep it, the message is wrong when the form has been manually set to read only rather than because of a lack of permissions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@emteknetnz, I could not find any similar example. I think it was new requirements from Design team. I moved logic only for readonly field.
@@ -89,3 +91,17 @@ test('LinkPickerTitle main button should not fire the onClick callback while loa | |||
fireEvent.click(container.querySelector('button.link-picker__button')); | |||
expect(mockOnClick).toHaveBeenCalledTimes(0); | |||
}); | |||
|
|||
test('LinkPickerTitle render() should have readonly class if cannot edit', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test('LinkPickerTitle render() should have readonly class if cannot edit', () => { | |
test('LinkPickerTitle render() should have readonly class if set to readonly', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
expect(container.querySelectorAll('.link-picker__link--readonly')).toHaveLength(1); | ||
}); | ||
|
||
test('LinkPickerTitle render() should not have readonly class if can edit', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test('LinkPickerTitle render() should not have readonly class if can edit', () => { | |
test('LinkPickerTitle render() should not have readonly class if set to readonly', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
1994149
to
2192224
Compare
$form->makeReadonly(); | ||
} | ||
|
||
if ($this->isReadOnlyField()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message feels even more out of place now
It will now only show if $this->isReadOnlyField()
is explicitly called, though not if $this->canEdit()
is false or if the owner page/element canEdit()
returns false which seems worse because it's inconsistent.
We also don't show this message anywhere else in the CMS as far as we know
I think we should just remove this message, it's seems pretty obvious that the form is readonly because the background of all the form elements if grey
Perhaps raise a new card to add this to globally add this message to forms through the CMS instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
2192224
to
59d2873
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge conflicts, needs a rebase + run yarn build
59d2873
to
0f62e1d
Compare
Description
The developer can set readonly using the
setReadonly
method and in the CMS the user will not be able to edit or delete record data. The user will only be able to view these records.Also, this state will be used if the user can only view the page, but not edit it.
Test steps
Note
There is some problem here, how this should work if the user can edit the page, but
LinkField
is set to read only. Which should take precedence overcanEdit
orReadOnly
? Since if the field is read only, then a user withcanEdit
permission will not be able to create a link. Should there be a super user who can create links? Based on this discussion: #141 (comment)Parent issue