@projectcaluma/ember-distribution 11.0.0-beta.34 → 11.0.0-beta.35

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,101 +4,131 @@ import { DateTime } from "luxon";
4
4
 
5
5
  import config from "@projectcaluma/ember-distribution/config";
6
6
 
7
+ /**
8
+ * This class contains all permission definitions for inquiries. To improve
9
+ * performance there are a few helpers and rules for optimal permission
10
+ * computation. The permissions need to be ordered by how expensive their
11
+ * computation is: the least expensive first and the most expensive last and so
12
+ * on:
13
+ *
14
+ * 1. Static config properties (e.g. `enableReminders`)
15
+ * 2. Base permission which checks for the correct task and the readonly config
16
+ * 3. Simple work item property checks (e.g. `isReady` or `isSuspended`)
17
+ * 4. Addressed / controlling group affiliation (e.g. `isAddressed` or `isControlling`)
18
+ * 5. All other computations (e.g. whether the deadline is overdue)
19
+ * 6. Custom permissions served by the host app (using `hasCustomPermission`)
20
+ */
7
21
  export default class InquiryAbility extends Ability {
8
22
  @service calumaOptions;
9
23
 
10
24
  @config config;
11
25
 
12
- get canEdit() {
26
+ hasCustomPermission(permissionName, ...args) {
27
+ return this.config.permissions[permissionName]?.(...args) ?? true;
28
+ }
29
+
30
+ get hasBasePermission() {
13
31
  return (
14
32
  !this.config.ui.readonly &&
15
- this.model?.task.slug === this.config.inquiry.task &&
16
- ["SUSPENDED", "READY"].includes(this.model?.status) &&
17
- this.model?.controllingGroups
18
- .map(String)
19
- .includes(String(this.calumaOptions.currentGroupId))
33
+ this.model?.task.slug === this.config.inquiry.task
34
+ );
35
+ }
36
+
37
+ get isReady() {
38
+ return this.model.status === "READY";
39
+ }
40
+
41
+ get isSuspended() {
42
+ return this.model.status === "SUSPENDED";
43
+ }
44
+
45
+ get isAddressed() {
46
+ return this.model.addressedGroups
47
+ .map(String)
48
+ .includes(String(this.calumaOptions.currentGroupId));
49
+ }
50
+
51
+ get isControlling() {
52
+ return this.model.controllingGroups
53
+ .map(String)
54
+ .includes(String(this.calumaOptions.currentGroupId));
55
+ }
56
+
57
+ get canEdit() {
58
+ return (
59
+ this.hasBasePermission &&
60
+ // Since editing in the status ready has the same character as sending an
61
+ // inquiry, we need to make sure that permission would be given
62
+ (this.isSuspended ||
63
+ (this.isReady &&
64
+ this.hasCustomPermission("sendInquiry", this.model))) &&
65
+ this.isControlling
20
66
  );
21
67
  }
22
68
 
23
69
  get canSend() {
24
70
  return (
25
- !this.config.ui.readonly &&
26
- this.model?.task.slug === this.config.inquiry.task &&
27
- this.model?.status === "SUSPENDED" &&
28
- (this.config.permissions.sendInquiry?.(this.model) ?? true) &&
29
- this.model?.controllingGroups
30
- .map(String)
31
- .includes(String(this.calumaOptions.currentGroupId))
71
+ this.hasBasePermission &&
72
+ this.isSuspended &&
73
+ this.isControlling &&
74
+ this.hasCustomPermission("sendInquiry", this.model)
32
75
  );
33
76
  }
34
77
 
35
78
  get canWithdraw() {
36
79
  return (
37
- !this.config.ui.readonly &&
38
- this.model?.task.slug === this.config.inquiry.task &&
39
- this.model?.status === "SUSPENDED" &&
40
- (this.config.permissions.withdrawInquiry?.(this.model) ?? true) &&
41
- this.model?.controllingGroups
42
- .map(String)
43
- .includes(String(this.calumaOptions.currentGroupId))
80
+ this.hasBasePermission &&
81
+ this.isSuspended &&
82
+ this.isControlling &&
83
+ this.hasCustomPermission("withdrawInquiry", this.model)
44
84
  );
45
85
  }
46
86
 
47
87
  get canAnswer() {
48
- return (
49
- !this.config.ui.readonly &&
50
- this.model?.task.slug === this.config.inquiry.task &&
51
- this.model?.status === "READY" &&
52
- this.model?.addressedGroups
53
- .map(String)
54
- .includes(String(this.calumaOptions.currentGroupId))
55
- );
88
+ return this.hasBasePermission && this.isReady && this.isAddressed;
56
89
  }
57
90
 
58
91
  get canEditAnswerForm() {
59
92
  return (
60
- !this.config.ui.readonly &&
61
93
  this.canAnswer &&
62
- this.model?.childCase.workItems.edges.some(
63
- (edge) => edge.node.task.__typename === "CompleteWorkflowFormTask"
94
+ this.model.childCase.workItems.edges.some(
95
+ (edge) =>
96
+ edge.node.status === "READY" &&
97
+ edge.node.task.__typename === "CompleteWorkflowFormTask"
64
98
  )
65
99
  );
66
100
  }
67
101
 
68
102
  get canCompleteChildWorkItem() {
69
103
  return (
70
- this.config.permissions.completeInquiryChildWorkItem?.(
104
+ this.hasBasePermission &&
105
+ this.hasCustomPermission(
106
+ "completeInquiryChildWorkItem",
71
107
  this.model,
72
108
  this.task
73
- ) ?? true
109
+ )
74
110
  );
75
111
  }
76
112
 
77
113
  get canReopen() {
78
114
  return (
115
+ this.hasBasePermission &&
79
116
  this.model.isRedoable &&
80
- this.model?.controllingGroups
81
- .map(String)
82
- .includes(String(this.calumaOptions.currentGroupId)) &&
83
- (this.config.permissions.reopenInquiry?.(this.model) ?? true)
117
+ this.isControlling &&
118
+ this.hasCustomPermission("reopenInquiry", this.model)
84
119
  );
85
120
  }
86
121
 
87
122
  get canSendReminder() {
88
- const deadline = DateTime.fromISO(
89
- this.model.document?.deadline.edges[0]?.node.value
90
- );
91
-
92
123
  return (
93
- !this.config.ui.readonly &&
94
124
  this.config.enableReminders &&
95
- this.model?.task.slug === this.config.inquiry.task &&
96
- this.model?.status === "READY" &&
97
- this.model?.controllingGroups
98
- .map(String)
99
- .includes(String(this.calumaOptions.currentGroupId)) &&
100
- deadline.diffNow("days").days <= 0 &&
101
- (this.config.permissions.sendReminder?.(this.model) ?? true)
125
+ this.hasBasePermission &&
126
+ this.isReady &&
127
+ this.isControlling &&
128
+ DateTime.fromISO(
129
+ this.model.document?.deadline.edges[0]?.node.value
130
+ ).diffNow("days").days <= 0 &&
131
+ this.hasCustomPermission("sendReminder", this.model)
102
132
  );
103
133
  }
104
134
  }
@@ -28,6 +28,7 @@ fragment InquiryAnswerButtons on Case {
28
28
  id
29
29
  status
30
30
  closedAt
31
+ closedByUser
31
32
  task {
32
33
  id
33
34
  slug
@@ -39,6 +40,7 @@ fragment InquiryAnswerButtons on Case {
39
40
 
40
41
  fragment InquiryAnswer on Document {
41
42
  ...InquiryAnswerStatus
43
+ modifiedContentAt
42
44
  info: answers(filter: [{ questions: $answerInfoQuestions }]) {
43
45
  edges {
44
46
  node {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectcaluma/ember-distribution",
3
- "version": "11.0.0-beta.34",
3
+ "version": "11.0.0-beta.35",
4
4
  "description": "Ember engine for the Caluma distribution module.",
5
5
  "keywords": [
6
6
  "ember-addon",
@@ -23,9 +23,9 @@
23
23
  "@embroider/macros": "^1.9.0",
24
24
  "@glimmer/component": "^1.1.2",
25
25
  "@glimmer/tracking": "^1.1.2",
26
- "@projectcaluma/ember-core": "^11.0.0-beta.34",
27
- "@projectcaluma/ember-form": "^11.0.0-beta.34",
28
- "@projectcaluma/ember-workflow": "^11.0.0-beta.34",
26
+ "@projectcaluma/ember-core": "^11.0.0-beta.35",
27
+ "@projectcaluma/ember-form": "^11.0.0-beta.35",
28
+ "@projectcaluma/ember-workflow": "^11.0.0-beta.35",
29
29
  "ember-apollo-client": "~4.0.2",
30
30
  "ember-auto-import": "^2.4.3",
31
31
  "ember-can": "^4.2.0",
@@ -51,7 +51,7 @@
51
51
  "@ember/test-helpers": "2.7.0",
52
52
  "@embroider/test-setup": "1.8.3",
53
53
  "@faker-js/faker": "7.6.0",
54
- "@projectcaluma/ember-testing": "11.0.0-beta.34",
54
+ "@projectcaluma/ember-testing": "11.0.0-beta.35",
55
55
  "broccoli-asset-rev": "3.0.0",
56
56
  "ember-cli": "4.8.0",
57
57
  "ember-cli-code-coverage": "1.0.3",
@@ -15,7 +15,7 @@ caluma:
15
15
  demandes ouvertes}} </b> sur la circulation actuelle. Si vous clôturez la
16
16
  circulation, toutes les demandes ouvertes seront annulées. Voulez-vous
17
17
  continuer ?"
18
- complete-confirm-empty: "Vous voulez vraiment fermer la circulation ?"
18
+ complete-confirm-empty: "Vous voulez vraiment clore la circulation ?"
19
19
  skip-confirm: "Vous voulez vraiment sauter la circulation ?"
20
20
  reopen-confirm: "Vous voulez vraiment rouvrir la circulation ?"
21
21
  send-error: "Erreur lors de l'envoi des demandes ouvertes"
@@ -77,11 +77,11 @@ caluma:
77
77
  title: "Nouvelle demande"
78
78
  search: "Chercher..."
79
79
  suggestions: "Propositions"
80
- empty: "Aucune services n'a été trouvée"
80
+ empty: "Aucune service n'a été trouvée"
81
81
  groups: "{count} {count, plural, =1 {service} other {services}}"
82
82
  selected: "{count, plural, =1 {sélectionné} other {sélectionnés}}"
83
83
  reset: "Réinitialiser"
84
- create-draft: "Créer un brouillon"
84
+ create-draft: "Créer le brouillon"
85
85
  continue: "Continuer"
86
86
  back: "Retour"
87
87
  error: "Error lors de la création {count, plural, =1 {de la demande} other {des demandes}}"
@@ -90,7 +90,7 @@ caluma:
90
90
  link: "Envoyer un rappel"
91
91
  confirm: "Voulez-vous vraiment envoyer un rappel pour cette demande ?"
92
92
  title: "Rappels envoyés"
93
- no-reminders: Aucun rappel n'a encore été envoyé pour cette demande.
93
+ no-reminders: "Aucun rappel n'a encore été envoyé pour cette demande."
94
94
  success: "Le rappel a été envoyé avec succès"
95
95
  error: "Erreur lors de l'envoi du rappel"
96
96