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

Update editingIsDisabled conditions #265

Merged
merged 8 commits into from
Jul 20, 2023
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
112 changes: 62 additions & 50 deletions web/app/components/document/sidebar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
}}
"
/>
{{#if this.isDraft}}
{{#if (and this.isDraft this.isOwner)}}
<X::DropdownList
data-test-draft-visibility-dropdown
@items={{this.draftVisibilityOptions}}
Expand Down Expand Up @@ -97,13 +97,10 @@
</X::DropdownList>
{{/if}}
</div>
{{#if this.editingIsDisabled}}
<h1
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-strong"
>{{this.title}}</h1>
{{else}}
{{#if this.isOwner}}
<div class="mb-8">
<EditableField
data-test-document-title-editable
@value={{this.title}}
@onChange={{perform this.save "title"}}
@loading={{this.save.isRunning}}
Expand All @@ -116,8 +113,11 @@
>{{this.title}}</h1>
{{else}}
<h1
data-test-document-title-read-only
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-faint"
>Enter a title here.</h1>
>
Enter a title here.
</h1>
{{/unless}}
</:default>
<:editing as |F|>
Expand All @@ -132,6 +132,11 @@
</:editing>
</EditableField>
</div>
{{else}}
<h1
data-test-document-title-read-only
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-strong"
>{{this.title}}</h1>
{{/if}}
</div>

Expand All @@ -140,12 +145,9 @@
{{! Summary }}
<div class="mb-5">
<Document::Sidebar::SectionHeader @title="Summary" class="mb-2" />
{{#if this.editingIsDisabled}}
<p
class="hds-typography-body-200 hds-font-weight-medium hds-foreground-primary"
>{{this.summary}}</p>
{{else}}
{{#if this.isOwner}}
<EditableField
data-test-document-summary-editable
@value={{this.summary}}
@onChange={{perform this.save "summary"}}
@loading={{this.save.isRunning}}
Expand Down Expand Up @@ -175,6 +177,13 @@
/>
</:editing>
</EditableField>
{{else}}
<p
data-test-document-summary-read-only
class="hds-typography-body-200 hds-font-weight-medium hds-foreground-primary"
>
{{this.summary}}
</p>
{{/if}}
</div>

Expand All @@ -188,9 +197,10 @@

<div class="flex flex-col items-start space-y-2">
<Document::Sidebar::SectionHeader @title="Product/Area" />
{{#if this.isDraft}}
{{#if (and this.isDraft this.isOwner)}}
<div class="w-full relative">
<Inputs::ProductSelect
data-test-document-product-area-editable
@selected={{this.product}}
@onChange={{this.updateProduct.perform}}
@isSaving={{this.save.isRunning}}
Expand All @@ -200,6 +210,7 @@
</div>
{{else}}
<Hds::Badge
data-test-document-product-area-read-only
@text={{@document.product}}
@icon={{get-product-id @document.product}}
/>
Expand All @@ -218,6 +229,7 @@
<Document::Sidebar::SectionHeader @title="Contributors" />
{{#if this.isOwner}}
<EditableField
data-test-document-contributors-editable
@value={{this.contributors}}
@onChange={{perform this.save "contributors"}}
@loading={{this.save.isRunning}}
Expand Down Expand Up @@ -249,27 +261,30 @@
</:editing>
</EditableField>
{{else}}
{{#if this.contributors.length}}
<ol class="person-list">
{{#each this.contributors as |contributor|}}
<li>
<Person
@imgURL={{contributor.imgURL}}
@email={{contributor.email}}
/>
</li>
{{/each}}
</ol>
{{else}}
<em>No contributors</em>
{{/if}}
<div data-test-document-contributors-read-only>
{{#if this.contributors.length}}
<ol class="person-list">
{{#each this.contributors as |contributor|}}
<li>
<Person
@imgURL={{contributor.imgURL}}
@email={{contributor.email}}
/>
</li>
{{/each}}
</ol>
{{else}}
<em>No contributors</em>
{{/if}}
</div>
{{/if}}
</div>

<div class="flex flex-col items-start space-y-2">
<Document::Sidebar::SectionHeader @title="Approvers" />
{{#if this.isOwner}}
<EditableField
data-test-document-approvers-editable
@value={{this.approvers}}
@onChange={{perform this.save "approvers"}}
@loading={{this.save.isRunning}}
Expand Down Expand Up @@ -302,21 +317,23 @@
</:editing>
</EditableField>
{{else}}
{{#if this.approvers.length}}
<ol class="person-list">
{{#each this.approvers as |approver|}}
<li>
<Person::Approver
@document={{@document}}
@imgURL={{approver.imgURL}}
@email={{approver.email}}
/>
</li>
{{/each}}
</ol>
{{else}}
<em>No approvers</em>
{{/if}}
<div data-test-document-approvers-read-only>
{{#if this.approvers.length}}
<ol class="person-list">
{{#each this.approvers as |approver|}}
<li>
<Person::Approver
@document={{@document}}
@imgURL={{approver.imgURL}}
@email={{approver.email}}
/>
</li>
{{/each}}
</ol>
{{else}}
<em>No approvers</em>
{{/if}}
</div>
{{/if}}
</div>

Expand Down Expand Up @@ -346,12 +363,7 @@
</div>

{{#each-in this.customEditableFields as |field attributes|}}
{{#if
(or
(and (not this.editingIsDisabled) (not this.docIsApproved))
attributes.value
)
}}
{{#if (or attributes.value this.isOwner)}}
<div class="flex flex-col items-start space-y-2">
<Document::Sidebar::SectionHeader
@title={{attributes.displayName}}
Expand All @@ -362,15 +374,15 @@
@attributes={{attributes}}
@onChange={{perform this.save field}}
@loading={{this.save.isRunning}}
@disabled={{or this.editingIsDisabled (not this.isOwner)}}
@disabled={{this.editingIsDisabled}}
/>
</div>
{{/if}}
{{/each-in}}
</div>
</div>

{{#if this.userHasEditPrivileges}}
{{#if this.isOwner}}
<div class="sidebar-footer {{if this.editingIsDisabled 'locked'}}">
{{#if this.editingIsDisabled}}
<div class="px-3 -mb-1">
Expand Down
60 changes: 46 additions & 14 deletions web/app/components/document/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,36 +327,68 @@ export default class DocumentSidebarComponent extends Component<DocumentSidebarC
);
}

get docIsApproved() {
/**
* Whether the doc status is approved. Used to determine editing privileges.
* If the doc is approved, editing is exclusive to the doc owner.
*/
private get docIsApproved() {
return this.args.document.status.toLowerCase() === "approved";
}

get docIsInReview() {
/**
* Whether the doc status is in review. Used to determine editing privileges.
* If the doc is in review, editing is exclusive to the doc owner.
*/
private get docIsInReview() {
return dasherize(this.args.document.status) === "in-review";
}

// isOwner returns true if the logged in user is the document owner.
get isOwner() {
/**
* Whether the document viewer is its owner.
* True if the logged in user's email matches the documents owner.
*/
protected get isOwner() {
return this.args.document.owners?.[0] === this.args.profile.email;
}

get userHasEditPrivileges() {
return this.isOwner || this.isContributor || this.isApprover;
}
/**
* Whether the editing of document metadata allowed, excluding the
* product/area field, which is disallowed for published docs.
* If the doc is locked, editing is disabled and a message is shown
* explaining that suggestions must be removed from the header.
*
* If the doc was created off-app, editing is disabled and a message
* is shown explaining that only app-created docs can be edited.
*
* If the doc is in a known state, e.g., draft, in review, or approved,
* editing is disabled for non-doc-owners.
*
* If the doc is in an unknown state, editing is disabled.
*/
protected get editingIsDisabled() {
if (this.docIsLocked) {
return true;
}

get editingIsDisabled() {
if (!this.args.document.appCreated || this.docIsLocked) {
// true is the doc wasn't appCreated or is in a locked state
if (!this.args.document.appCreated) {
return true;
} else if (this.isDraft || this.docIsInReview || this.docIsApproved) {
// true is the doc is a draft/in review/approved and the user is not an owner, contributor, or approver
return !this.userHasEditPrivileges;
}

if (this.isDraft || this.docIsInReview || this.docIsApproved) {
return !this.isOwner;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important to note: This method is called editingIsDisabled.

} else {
// doc is obsolete or some unknown status..
return true;
}
}

/**
* Whether editing is enabled for basic metadata fields.
* Used in the template to make some logic more readable.
*/
protected get editingIsEnabled() {
return !this.editingIsDisabled;
}

@action refreshRoute() {
// We force refresh due to a bug with `refreshModel: true`
// See: https://github.com/emberjs/ember.js/issues/19260
Expand Down
2 changes: 1 addition & 1 deletion web/app/components/inputs/product-select/index.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{! https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/ }}
<div data-test-product-select>
<div data-test-product-select ...attributes>
{{#if this.products}}
{{#if @formatIsBadge}}
<Inputs::BadgeDropdownList
Expand Down
7 changes: 6 additions & 1 deletion web/mirage/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,13 @@ export default function (mirageConfig) {

/**
* Used by the PeopleSelect component to get a list of people.
* Used to confirm that an approver has access to a document.
*/
this.get("/people", (schema) => {
this.get("/people", (schema, request) => {
// This allows the test user to view docs they're an approver on.
if (request.queryParams.emails === "[email protected]") {
return new Response(200, {}, []);
}
return schema.people.all();
});

Expand Down
Loading