Skip to content

Commit

Permalink
chore(frontend): rewrite report ability to work with ember-data 5.3
Browse files Browse the repository at this point in the history
this changes `ability.canEdit` into 2 parts, `ability.canEdit` which
checks if for if you are superuser, if the report hasn't been verified
and if the report is your own.

the other parts of the ability, checking for reviewer and supervisee have
been moved into `ability.canAedit`, which is an async ability.

places where this is used first check with `canEdit`, if thats false
they `await canAedit(report)`.

this is ugly and hacky but it works.
  • Loading branch information
c0rydoras committed Aug 30, 2024
1 parent 70f76cf commit 4fc0567
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 180 deletions.
68 changes: 49 additions & 19 deletions frontend/app/abilities/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,54 @@ export default class ReportAbility extends Ability {
}

get canEdit() {
const isEditable =
this.user?.isSuperuser ||
(!this.model?.verifiedBy?.get("id") &&
// eslint-disable-next-line ember/no-get
(this.model?.user?.get("id") === this.user?.get("id") ||
// eslint-disable-next-line ember/no-get
(this.model?.user?.get("supervisors") ?? [])
.map((s) => s.id)
.includes(this.user?.get("id"))));
const isReviewer =
(this.model?.taskAssignees ?? [])
.concat(
this.model?.projectAssignees ?? [],
this.model?.customerAssignees ?? []
)
.filter((a) => a?.user)
.map((a) => a.user.get("id"))
.includes(this.user?.get("id")) && !this.model?.verifiedBy?.get("id");
return isEditable || isReviewer;
if (this.user?.isSuperuser) {
return true;
}

if (this.model?.verifiedBy?.get("id")) {
return false;
}

if (this.model?.user?.get("id") === this.user?.get("id")) {
return true;
}

return false;
}

async isReviewer() {
return ((await this.model?.taskAssignees) ?? [])
.concat(
(await this.model?.projectAssignees) ?? [],
(await this.model?.customerAssignees) ?? []
)
.filter((a) => a?.user)
.map((a) => a.user.get("id"))
.includes(this.user?.get("id"));
}

async isSupervisee() {
return ((await this.model?.user?.get("supervisors")) ?? [])
.map((s) => s.id)
.includes(this.user?.get("id"));
}

async canAedit() {
if (this.model?.verifiedBy?.get("id")) {
return false;
}

const isSupervisee = await this.isSupervisee();
if (isSupervisee) {
return true;
}

const isReviewer = await this.isReviewer();

if (isReviewer) {
return true;
}

return false;
}
}
31 changes: 19 additions & 12 deletions frontend/app/analysis/index/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default class AnalysisController extends QPController {
@service store;
@service router;
@service notify;
@service can;
@service abilities;

@tracked _scrollOffset = 0;
@tracked _shouldLoadMore = false;
Expand Down Expand Up @@ -363,17 +363,24 @@ export default class AnalysisController extends QPController {
}

@action
selectRow(report) {
if (this.can.can("edit report", report) || this.canBill) {
const selected = this.selectedReportIds;

if (selected.includes(report.id)) {
this.selectedReportIds = A([
...selected.filter((id) => id !== report.id),
]);
} else {
this.selectedReportIds = A([...selected, report.id]);
}
async selectRow(report, editable) {
if (!editable) {
return;
}

const selected = this.selectedReportIds;

if (selected.includes(report.id)) {
this.selectedReportIds = A([
...selected.filter((id) => id !== report.id),
]);
} else {
this.selectedReportIds = A([...selected, report.id]);
}
}

@action
async canEdit(syncEdit, report) {
return syncEdit ? true : await this.abilities.can("aedit report", report);
}
}
10 changes: 8 additions & 2 deletions frontend/app/analysis/index/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -357,17 +357,20 @@
</colgroup>
<tbody>
{{#each reports as |report|}}
{{#let (or this.canBill (can 'edit report' report)) as |syncEditable|}}
{{#let (this.canEdit syncEditable report) as |promise|}}
<PromiseThing @await={{not syncEditable}} @value={{syncEditable}} @promise={{promise}} as |t|>
{{! template-lint-disable}}
<tr
class="{{if
(includes report.id this.selectedReportIds)
'selected'
}}
{{if
(or this.canBill (await (can 'edit report' report)))
t.value
'pointer'
}}"
{{on "click" (fn this.selectRow report)}}
{{on "click" (fn this.selectRow report t.value)}}
>
<td>{{report.user.username}}</td>
<td>{{moment-format report.date "DD.MM.YYYY"}}</td>
Expand Down Expand Up @@ -399,6 +402,9 @@
@highlight={{true}}
/></td>
</tr>
</PromiseThing>
{{/let}}
{{/let}}
{{/each}}
{{#if this._canLoadMore}}
<tr
Expand Down
5 changes: 5 additions & 0 deletions frontend/app/components/promise-thing.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{{#if @await}}
{{yield (hash value=@value)}}
{{else}}
{{yield (hash value=(await @promise))}}
{{/if}}
19 changes: 10 additions & 9 deletions frontend/app/components/report-row/component.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import Component from "@glimmer/component";
import { dropTask } from "ember-concurrency";
import ReportValidations from "timed/validations/report";

export default class ReportRowComponent extends Component {
@service abilities;

ReportValidations = ReportValidations;

get editable() {
return this.abilities.can("edit report", this.args.report);
}

get title() {
return this.editable
@action
title(editable) {
return editable
? ""
: `This entry was already verified by ${this.args.report.get(
"verifiedBy.fullName"
Expand Down Expand Up @@ -49,4 +43,11 @@ export default class ReportRowComponent extends Component {
cs.task = task;
cs.remainingEffort = task?.mostRecentRemainingEffort;
}

@action
async canEdit(syncEdit) {
return syncEdit
? true
: await this.abilities.can("aedit report", this.args.report);
}
}
Loading

0 comments on commit 4fc0567

Please sign in to comment.