@projectcaluma/ember-distribution 1.0.0-beta.1 → 1.0.0-beta.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/addon/abilities/distribution.js +41 -0
  3. package/addon/abilities/inquiry.js +20 -0
  4. package/addon/components/cd-document-header.hbs +20 -0
  5. package/addon/components/cd-icon-button.hbs +27 -0
  6. package/addon/components/{icon-button.js → cd-icon-button.js} +1 -1
  7. package/addon/components/cd-inquiry-answer-form.hbs +78 -0
  8. package/addon/components/{inquiry-answer-form.js → cd-inquiry-answer-form.js} +27 -13
  9. package/addon/components/cd-inquiry-dialog/inquiry-deadline.hbs +29 -0
  10. package/addon/components/{inquiry-dialog → cd-inquiry-dialog}/inquiry-deadline.js +5 -1
  11. package/addon/components/{inquiry-dialog → cd-inquiry-dialog}/inquiry-divider.hbs +2 -1
  12. package/addon/components/{inquiry-dialog → cd-inquiry-dialog}/inquiry-divider.js +1 -1
  13. package/addon/components/cd-inquiry-dialog/inquiry-part.hbs +101 -0
  14. package/addon/components/cd-inquiry-dialog/inquiry-part.js +66 -0
  15. package/addon/components/cd-inquiry-dialog/inquiry.hbs +16 -0
  16. package/addon/components/cd-inquiry-dialog/inquiry.js +11 -0
  17. package/addon/components/cd-inquiry-dialog.hbs +24 -0
  18. package/addon/components/cd-inquiry-dialog.js +93 -0
  19. package/addon/components/cd-inquiry-edit-form.hbs +41 -0
  20. package/addon/components/{inquiry-edit-form.js → cd-inquiry-edit-form.js} +5 -4
  21. package/addon/components/cd-inquiry-new-form.hbs +123 -0
  22. package/addon/components/cd-inquiry-new-form.js +116 -0
  23. package/addon/components/cd-navigation/controls.hbs +32 -0
  24. package/addon/components/cd-navigation/controls.js +95 -0
  25. package/addon/components/cd-navigation/item.hbs +15 -0
  26. package/addon/components/{distribution-navigation → cd-navigation}/item.js +2 -2
  27. package/addon/components/{distribution-navigation → cd-navigation}/section.hbs +9 -7
  28. package/addon/components/{distribution-navigation → cd-navigation}/section.js +1 -1
  29. package/addon/components/{distribution-navigation → cd-navigation}/status-indicator.hbs +2 -1
  30. package/addon/components/{distribution-navigation → cd-navigation}/status-indicator.js +1 -1
  31. package/addon/components/cd-navigation.hbs +14 -0
  32. package/addon/components/cd-navigation.js +53 -0
  33. package/addon/components/cd-notfound.hbs +12 -0
  34. package/addon/components/cd-truncated.hbs +8 -0
  35. package/addon/components/cd-truncated.js +32 -0
  36. package/addon/config.js +3 -1
  37. package/addon/controllers/application.js +10 -0
  38. package/addon/controllers/{distribution/new.js → new.js} +2 -2
  39. package/addon/engine.js +7 -1
  40. package/addon/gql/fragments/inquiry.graphql +21 -12
  41. package/addon/gql/mutations/complete-work-item.graphql +8 -0
  42. package/addon/gql/mutations/withdraw-inquiry.graphql +8 -0
  43. package/addon/gql/queries/control-work-items.graphql +18 -2
  44. package/addon/gql/queries/incomplete-inquiries.graphql +13 -0
  45. package/addon/gql/queries/inquiry-answer.graphql +15 -1
  46. package/addon/gql/queries/inquiry-dialog.graphql +2 -2
  47. package/addon/gql/queries/inquiry-edit.graphql +2 -0
  48. package/addon/gql/queries/inquiry-navigation.graphql +4 -1
  49. package/addon/modifiers/pikaday.js +2 -0
  50. package/addon/routes/{distribution.js → application.js} +1 -1
  51. package/addon/routes/{distribution/index.js → index.js} +2 -2
  52. package/addon/routes/inquiry/detail/answer.js +7 -0
  53. package/addon/routes/inquiry/detail/index.js +7 -0
  54. package/addon/routes/{distribution/inquiry → inquiry}/detail.js +1 -1
  55. package/addon/routes/inquiry/index.js +10 -0
  56. package/addon/routes/{distribution/inquiry.js → inquiry.js} +1 -1
  57. package/addon/routes/new.js +7 -0
  58. package/addon/routes/notfound.js +3 -0
  59. package/addon/routes.js +5 -6
  60. package/addon/services/distribution.js +112 -0
  61. package/addon/templates/application.hbs +18 -0
  62. package/addon/templates/index.hbs +11 -0
  63. package/addon/templates/inquiry/detail/answer.hbs +1 -0
  64. package/addon/templates/inquiry/detail/index.hbs +1 -0
  65. package/addon/templates/{distribution/inquiry → inquiry}/detail.hbs +0 -0
  66. package/addon/templates/{distribution/inquiry → inquiry}/index.hbs +1 -1
  67. package/addon/templates/{distribution/inquiry.hbs → inquiry.hbs} +0 -0
  68. package/addon/templates/{distribution/new.hbs → new.hbs} +1 -1
  69. package/addon/templates/notfound.hbs +1 -0
  70. package/addon/utils/inquiry-deadline.js +4 -7
  71. package/addon/utils/unique-by-groups.js +1 -0
  72. package/app/abilities/distribution.js +1 -0
  73. package/app/components/cd-document-header.js +1 -0
  74. package/app/components/{inquiry-dialog.js → cd-icon-button.js} +1 -1
  75. package/app/components/{inquiry-dialog/inquiry.js → cd-inquiry-answer-form.js} +1 -1
  76. package/app/components/{inquiry-dialog → cd-inquiry-dialog}/inquiry-deadline.js +1 -1
  77. package/app/components/{inquiry-dialog → cd-inquiry-dialog}/inquiry-divider.js +1 -1
  78. package/app/components/{inquiry-dialog → cd-inquiry-dialog}/inquiry-part.js +1 -1
  79. package/app/components/{distribution-navigation.js → cd-inquiry-dialog/inquiry.js} +1 -1
  80. package/app/components/{inquiry-edit-form.js → cd-inquiry-dialog.js} +1 -1
  81. package/app/components/cd-inquiry-edit-form.js +1 -0
  82. package/app/components/{inquiry-answer-form.js → cd-inquiry-new-form.js} +1 -1
  83. package/app/components/cd-navigation/controls.js +1 -0
  84. package/app/components/cd-navigation/item.js +1 -0
  85. package/app/components/cd-navigation/section.js +1 -0
  86. package/app/components/{distribution-navigation/item.js → cd-navigation/status-indicator.js} +1 -1
  87. package/app/components/{inquiry-new-form.js → cd-navigation.js} +1 -1
  88. package/app/components/{icon-button.js → cd-notfound.js} +1 -1
  89. package/app/components/cd-truncated.js +1 -0
  90. package/app/services/distribution.js +1 -0
  91. package/app/styles/@projectcaluma/ember-distribution.scss +2 -0
  92. package/app/styles/_answer-form.scss +4 -0
  93. package/app/styles/_inquiry-divider.scss +22 -0
  94. package/app/styles/_truncated.scss +3 -0
  95. package/index.js +14 -13
  96. package/package.json +31 -26
  97. package/public/assets/distribution.svg +1 -0
  98. package/translations/de.yaml +34 -4
  99. package/translations/en.yaml +35 -4
  100. package/translations/fr.yaml +34 -4
  101. package/addon/components/distribution-navigation/controls.hbs +0 -21
  102. package/addon/components/distribution-navigation/controls.js +0 -45
  103. package/addon/components/distribution-navigation/item.hbs +0 -18
  104. package/addon/components/distribution-navigation.hbs +0 -17
  105. package/addon/components/distribution-navigation.js +0 -81
  106. package/addon/components/icon-button.hbs +0 -20
  107. package/addon/components/inquiry-answer-form.hbs +0 -46
  108. package/addon/components/inquiry-dialog/inquiry-deadline.hbs +0 -6
  109. package/addon/components/inquiry-dialog/inquiry-part.hbs +0 -40
  110. package/addon/components/inquiry-dialog/inquiry-part.js +0 -20
  111. package/addon/components/inquiry-dialog/inquiry.hbs +0 -13
  112. package/addon/components/inquiry-dialog/inquiry.js +0 -7
  113. package/addon/components/inquiry-dialog.hbs +0 -9
  114. package/addon/components/inquiry-dialog.js +0 -42
  115. package/addon/components/inquiry-edit-form.hbs +0 -27
  116. package/addon/components/inquiry-new-form.hbs +0 -110
  117. package/addon/components/inquiry-new-form.js +0 -154
  118. package/addon/routes/distribution/inquiry/detail/answer.js +0 -7
  119. package/addon/routes/distribution/inquiry/detail/index.js +0 -7
  120. package/addon/routes/distribution/inquiry/index.js +0 -10
  121. package/addon/routes/distribution/new.js +0 -7
  122. package/addon/templates/distribution/inquiry/detail/answer.hbs +0 -1
  123. package/addon/templates/distribution/inquiry/detail/index.hbs +0 -1
  124. package/addon/templates/distribution.hbs +0 -8
  125. package/app/components/distribution-navigation/controls.js +0 -1
  126. package/app/components/distribution-navigation/section.js +0 -1
  127. package/app/components/distribution-navigation/status-indicator.js +0 -1
@@ -0,0 +1,53 @@
1
+ import { inject as service } from "@ember/service";
2
+ import Component from "@glimmer/component";
3
+ import { queryManager } from "ember-apollo-client";
4
+
5
+ import config from "@projectcaluma/ember-distribution/config";
6
+ import uniqueByGroups from "@projectcaluma/ember-distribution/utils/unique-by-groups";
7
+
8
+ export default class CdNavigationComponent extends Component {
9
+ @service("-scheduler") scheduler;
10
+ @service calumaOptions;
11
+ @service distribution;
12
+
13
+ @config config;
14
+
15
+ @queryManager apollo;
16
+
17
+ get inquiries() {
18
+ const findGroupName = (identifiers) => {
19
+ const group = this.scheduler.groupCache.find((group) =>
20
+ identifiers
21
+ .map(String)
22
+ .includes(String(group[this.calumaOptions.groupIdentifierProperty]))
23
+ );
24
+
25
+ return group?.[this.calumaOptions.groupNameProperty] ?? "";
26
+ };
27
+
28
+ return Object.entries(this.distribution.navigation.value ?? {}).reduce(
29
+ (inquiries, [key, objects]) => {
30
+ return {
31
+ ...inquiries,
32
+ // Don't return any data until the internal scheduler has cached
33
+ // groups since we don't want to render empty navigation items
34
+ [key]: this.scheduler.groupCache.length
35
+ ? uniqueByGroups(
36
+ objects.edges.map((edge) => ({
37
+ ...edge.node,
38
+ // Populate the work item with the names of the involved
39
+ // groups so the <DistributionNavigation::Section /> component
40
+ // can sort by them
41
+ addressedGroupName: findGroupName(edge.node.addressedGroups),
42
+ controllingGroupName: findGroupName(
43
+ edge.node.controllingGroups
44
+ ),
45
+ }))
46
+ )
47
+ : [],
48
+ };
49
+ },
50
+ {}
51
+ );
52
+ }
53
+ }
@@ -0,0 +1,12 @@
1
+ <div class="uk-text-center">
2
+ <h1 class="uk-heading-xlarge">
3
+ {{t "caluma.distribution.notfound.title"}}
4
+ </h1>
5
+ <h2 class="uk-heading-small uk-margin-remove-top uk-text-muted">
6
+ {{t "caluma.distribution.notfound.subtitle"}}
7
+ </h2>
8
+ <p class="uk-text-muted">
9
+ {{t "caluma.distribution.notfound.back"}}
10
+ <LinkTo @route="index">{{t "caluma.distribution.notfound.link"}}</LinkTo>
11
+ </p>
12
+ </div>
@@ -0,0 +1,8 @@
1
+ <p class="cd-truncated" ...attributes>
2
+ {{~this.displayedText~}}
3
+ {{#if this.truncate}}
4
+ <a href="" {{on "click" this.toggleExpand}}>
5
+ {{~t (concat "caluma.distribution." (if this.expand "less" "more"))~}}
6
+ </a>
7
+ {{/if}}
8
+ </p>
@@ -0,0 +1,32 @@
1
+ import { action } from "@ember/object";
2
+ import Component from "@glimmer/component";
3
+ import { tracked } from "@glimmer/tracking";
4
+
5
+ export default class CdTruncatedComponent extends Component {
6
+ @tracked expand = false;
7
+
8
+ get length() {
9
+ return parseInt(this.args.length);
10
+ }
11
+
12
+ get displayedText() {
13
+ if (this.truncate && !this.expand) {
14
+ // strip input string to the passed length minus 3 to make sure the output
15
+ // including the 3 dots doesn't exceed the expected length
16
+ return `${this.args.text.substring(0, this.length - 3).trim()}...`;
17
+ }
18
+
19
+ return this.args.text;
20
+ }
21
+
22
+ get truncate() {
23
+ return this.args.text.length > this.length;
24
+ }
25
+
26
+ @action
27
+ toggleExpand(e) {
28
+ e.preventDefault();
29
+
30
+ this.expand = !this.expand;
31
+ }
32
+ }
package/addon/config.js CHANGED
@@ -15,6 +15,7 @@ export default function config(target, property) {
15
15
  get() {
16
16
  return merge(
17
17
  {
18
+ ui: { stack: false, small: false, readonly: false },
18
19
  controls: {
19
20
  createTask: "create-inquiry",
20
21
  completeTask: "complete-distribution",
@@ -26,7 +27,7 @@ export default function config(target, property) {
26
27
  infoQuestion: "inquiry-remark",
27
28
  answer: {
28
29
  statusQuestion: "inquiry-answer-status",
29
- infoQuestion: "inquiry-answer-reason",
30
+ infoQuestions: ["inquiry-answer-reason"],
30
31
  statusMapping: {
31
32
  "inquiry-answer-status-positive": INQUIRY_STATUS.POSITIVE,
32
33
  "inquiry-answer-status-negative": INQUIRY_STATUS.NEGATIVE,
@@ -64,6 +65,7 @@ export default function config(target, property) {
64
65
  },
65
66
  },
66
67
  },
68
+ permissions: {},
67
69
  },
68
70
  getOwner(this).lookup("service:calumaOptions")?.distribution ?? {}
69
71
  );
@@ -0,0 +1,10 @@
1
+ import Controller from "@ember/controller";
2
+ import { inject as service } from "@ember/service";
3
+
4
+ import config from "@projectcaluma/ember-distribution/config";
5
+
6
+ export default class ApplicationController extends Controller {
7
+ @config config;
8
+
9
+ @service distribution;
10
+ }
@@ -3,7 +3,7 @@ import { dedupeTracked, cached } from "tracked-toolbox";
3
3
 
4
4
  import config from "@projectcaluma/ember-distribution/config";
5
5
 
6
- export default class DistributionNewController extends Controller {
6
+ export default class NewController extends Controller {
7
7
  @config config;
8
8
 
9
9
  queryParams = ["types", "search"];
@@ -13,7 +13,7 @@ export default class DistributionNewController extends Controller {
13
13
 
14
14
  @cached
15
15
  get selectedTypes() {
16
- return this.types.split(",");
16
+ return this.types.split(",").filter(Boolean);
17
17
  }
18
18
 
19
19
  set selectedTypes(value) {
package/addon/engine.js CHANGED
@@ -11,7 +11,13 @@ export default class DistributionEngine extends Engine {
11
11
  Resolver = Resolver;
12
12
 
13
13
  dependencies = {
14
- services: ["apollo", "notification", "intl", "caluma-options"],
14
+ services: [
15
+ "apollo",
16
+ "notification",
17
+ "intl",
18
+ "caluma-options",
19
+ "store", // this is just in case that a custom form widget uses the store
20
+ ],
15
21
  };
16
22
  }
17
23
 
@@ -30,6 +30,21 @@ fragment InquiryStatusDocument on Document {
30
30
  }
31
31
  }
32
32
 
33
+ fragment InquiryRequest on Document {
34
+ id
35
+ ...InquiryDeadlineDocument
36
+ info: answers(question: $infoQuestion) {
37
+ edges {
38
+ node {
39
+ id
40
+ ... on StringAnswer {
41
+ value
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+
33
48
  fragment InquiryDialog on WorkItem {
34
49
  id
35
50
  addressedGroups
@@ -42,26 +57,20 @@ fragment InquiryDialog on WorkItem {
42
57
  slug
43
58
  }
44
59
  document {
45
- ...InquiryDeadlineDocument
46
- info: answers(question: $infoQuestion) {
47
- edges {
48
- node {
49
- id
50
- ... on StringAnswer {
51
- value
52
- }
53
- }
54
- }
55
- }
60
+ ...InquiryRequest
56
61
  }
57
62
  childCase {
58
63
  id
59
64
  document {
60
65
  ...InquiryStatusDocument
61
- info: answers(question: $answerInfoQuestion) {
66
+ info: answers(questions: $answerInfoQuestions) {
62
67
  edges {
63
68
  node {
64
69
  id
70
+ question {
71
+ id
72
+ label
73
+ }
65
74
  ... on StringAnswer {
66
75
  value
67
76
  }
@@ -0,0 +1,8 @@
1
+ mutation CompleteWorkItem($workItem: ID!) {
2
+ completeWorkItem(input: { id: $workItem }) {
3
+ workItem {
4
+ id
5
+ status
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ mutation WithdrawInquiry($workItem: ID!) {
2
+ cancelWorkItem(input: { id: $workItem }) {
3
+ workItem {
4
+ id
5
+ status
6
+ }
7
+ }
8
+ }
@@ -1,6 +1,7 @@
1
1
  query ControlWorkItems(
2
2
  $createTask: ID!
3
3
  $completeTask: ID!
4
+ $inquiryTask: ID!
4
5
  $caseId: ID!
5
6
  $currentGroup: String!
6
7
  ) {
@@ -11,11 +12,11 @@ query ControlWorkItems(
11
12
  { status: READY }
12
13
  { addressedGroups: [$currentGroup] }
13
14
  ]
14
- first: 1
15
15
  ) {
16
16
  edges {
17
17
  node {
18
18
  id
19
+ status
19
20
  }
20
21
  }
21
22
  }
@@ -26,11 +27,26 @@ query ControlWorkItems(
26
27
  { status: READY }
27
28
  { addressedGroups: [$currentGroup] }
28
29
  ]
29
- first: 1
30
30
  ) {
31
31
  edges {
32
32
  node {
33
33
  id
34
+ status
35
+ }
36
+ }
37
+ }
38
+ send: allWorkItems(
39
+ filter: [
40
+ { case: $caseId }
41
+ { task: $inquiryTask }
42
+ { status: SUSPENDED }
43
+ { controllingGroups: [$currentGroup] }
44
+ ]
45
+ ) {
46
+ edges {
47
+ node {
48
+ id
49
+ status
34
50
  }
35
51
  }
36
52
  }
@@ -0,0 +1,13 @@
1
+ query InquiryIncomplete($caseId: ID!, $task: ID!) {
2
+ allWorkItems(
3
+ filter: [
4
+ { case: $caseId }
5
+ { task: $task }
6
+ { status: CANCELED, invert: true }
7
+ { status: COMPLETED, invert: true }
8
+ { status: SKIPPED, invert: true }
9
+ ]
10
+ ) {
11
+ totalCount
12
+ }
13
+ }
@@ -1,19 +1,33 @@
1
- query InquiryAnswer($inquiry: ID!, $buttonTasks: [String]!) {
1
+ #import InquiryDeadlineDocument, InquiryRequest from '../fragments/inquiry.graphql'
2
+
3
+ query InquiryAnswer(
4
+ $inquiry: ID!
5
+ $buttonTasks: [String]!
6
+ $infoQuestion: ID!
7
+ $deadlineQuestion: ID!
8
+ ) {
2
9
  allWorkItems(filter: [{ id: $inquiry }]) {
3
10
  edges {
4
11
  node {
5
12
  id
6
13
  status
7
14
  addressedGroups
15
+ controllingGroups
16
+ createdAt
8
17
  task {
9
18
  id
10
19
  slug
11
20
  }
21
+ document {
22
+ ...InquiryRequest
23
+ }
12
24
  childCase {
13
25
  id
14
26
  status
15
27
  document {
16
28
  id
29
+ modifiedContentAt
30
+ modifiedContentByUser
17
31
  }
18
32
  workItems(tasks: $buttonTasks, status: READY) {
19
33
  edges {
@@ -1,11 +1,11 @@
1
- #import InquiryDialog, InquiryDeadlineDocument, InquiryStatusDocument from '../fragments/inquiry.graphql'
1
+ #import InquiryDialog, InquiryDeadlineDocument, InquiryStatusDocument, InquiryRequest from '../fragments/inquiry.graphql'
2
2
 
3
3
  query InquiryDialog(
4
4
  $task: ID!
5
5
  $statusQuestion: ID!
6
6
  $deadlineQuestion: ID!
7
7
  $infoQuestion: ID!
8
- $answerInfoQuestion: ID!
8
+ $answerInfoQuestions: [ID]!
9
9
  $from: [String]!
10
10
  $to: [String]!
11
11
  $caseId: ID!
@@ -11,6 +11,8 @@ query InquiryEdit($inquiry: ID!) {
11
11
  }
12
12
  document {
13
13
  id
14
+ modifiedContentAt
15
+ modifiedContentByUser
14
16
  }
15
17
  }
16
18
  }
@@ -13,6 +13,7 @@ query InquiryNavigation(
13
13
  { case: $caseId }
14
14
  { task: $task }
15
15
  { controllingGroups: [$currentGroup] }
16
+ { status: CANCELED, invert: true }
16
17
  ]
17
18
  order: [{ attribute: CREATED_AT, direction: DESC }]
18
19
  ) {
@@ -28,6 +29,7 @@ query InquiryNavigation(
28
29
  { task: $task }
29
30
  { addressedGroups: [$currentGroup] }
30
31
  { status: SUSPENDED, invert: true }
32
+ { status: CANCELED, invert: true }
31
33
  ]
32
34
  order: [{ attribute: CREATED_AT, direction: DESC }]
33
35
  ) {
@@ -43,7 +45,8 @@ query InquiryNavigation(
43
45
  { task: $task }
44
46
  { controllingGroups: [$currentGroup], invert: true }
45
47
  { addressedGroups: [$currentGroup], invert: true }
46
- { status: COMPLETED }
48
+ { status: SUSPENDED, invert: true }
49
+ { status: CANCELED, invert: true }
47
50
  ]
48
51
  order: [{ attribute: CREATED_AT, direction: DESC }]
49
52
  ) {
@@ -0,0 +1,2 @@
1
+ import "ember-pikaday/pikaday.css";
2
+ export { default } from "ember-pikaday/modifiers/pikaday";
@@ -1,6 +1,6 @@
1
1
  import Route from "@ember/routing/route";
2
2
 
3
- export default class DistributionRoute extends Route {
3
+ export default class ApplicationRoute extends Route {
4
4
  model(params) {
5
5
  return params.case;
6
6
  }
@@ -6,7 +6,7 @@ import config from "@projectcaluma/ember-distribution/config";
6
6
  import inquiryNavigationQuery from "@projectcaluma/ember-distribution/gql/queries/inquiry-navigation.graphql";
7
7
  import uniqueByGroups from "@projectcaluma/ember-distribution/utils/unique-by-groups";
8
8
 
9
- export default class DistributionIndexRoute extends Route {
9
+ export default class IndexRoute extends Route {
10
10
  @service router;
11
11
  @service calumaOptions;
12
12
 
@@ -35,7 +35,7 @@ export default class DistributionIndexRoute extends Route {
35
35
  }, {});
36
36
 
37
37
  if (models.length) {
38
- return this.router.replaceWith("distribution.inquiry", models[0]);
38
+ return this.router.replaceWith("inquiry", models[0]);
39
39
  }
40
40
  }
41
41
  }
@@ -0,0 +1,7 @@
1
+ import Route from "@ember/routing/route";
2
+
3
+ export default class InquiryDetailAnswerRoute extends Route {
4
+ model() {
5
+ return this.modelFor("inquiry.detail");
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ import Route from "@ember/routing/route";
2
+
3
+ export default class InquiryDetailIndexRoute extends Route {
4
+ model() {
5
+ return this.modelFor("inquiry.detail");
6
+ }
7
+ }
@@ -1,6 +1,6 @@
1
1
  import Route from "@ember/routing/route";
2
2
 
3
- export default class DistributionInquiryDetailRoute extends Route {
3
+ export default class InquiryDetailRoute extends Route {
4
4
  model({ inquiry }) {
5
5
  return inquiry;
6
6
  }
@@ -0,0 +1,10 @@
1
+ import Route from "@ember/routing/route";
2
+
3
+ export default class InquiryIndexRoute extends Route {
4
+ model() {
5
+ return {
6
+ ...this.modelFor("inquiry"),
7
+ case: this.modelFor("application"),
8
+ };
9
+ }
10
+ }
@@ -1,6 +1,6 @@
1
1
  import Route from "@ember/routing/route";
2
2
 
3
- export default class DistributionInquiryRoute extends Route {
3
+ export default class InquiryRoute extends Route {
4
4
  model({ from, to }) {
5
5
  return { from, to };
6
6
  }
@@ -0,0 +1,7 @@
1
+ import Route from "@ember/routing/route";
2
+
3
+ export default class NewRoute extends Route {
4
+ model() {
5
+ return this.modelFor("application");
6
+ }
7
+ }
@@ -0,0 +1,3 @@
1
+ import Route from "@ember/routing/route";
2
+
3
+ export default class NotfoundRoute extends Route {}
package/addon/routes.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import buildRoutes from "ember-engines/routes";
2
2
 
3
3
  export default buildRoutes(function () {
4
- this.route("distribution", { path: "/case/:case" }, function () {
5
- this.route("new");
6
- this.route("inquiry", { path: "/from/:from/to/:to" }, function () {
7
- this.route("detail", { path: "/detail/:inquiry" }, function () {
8
- this.route("answer");
9
- });
4
+ this.route("new");
5
+ this.route("inquiry", { path: "/from/:from/to/:to" }, function () {
6
+ this.route("detail", { path: "/:inquiry" }, function () {
7
+ this.route("answer");
10
8
  });
11
9
  });
10
+ this.route("notfound", { path: "/*path" });
12
11
  });
@@ -0,0 +1,112 @@
1
+ import { getOwner } from "@ember/application";
2
+ import Service, { inject as service } from "@ember/service";
3
+ import { queryManager, getObservable } from "ember-apollo-client";
4
+ import { dropTask } from "ember-concurrency";
5
+ import { trackedTask } from "ember-resources/util/ember-concurrency";
6
+
7
+ import { decodeId } from "@projectcaluma/ember-core/helpers/decode-id";
8
+ import config from "@projectcaluma/ember-distribution/config";
9
+ import createInquiryMutation from "@projectcaluma/ember-distribution/gql/mutations/create-inquiry.graphql";
10
+ import controlWorkItemsQuery from "@projectcaluma/ember-distribution/gql/queries/control-work-items.graphql";
11
+ import inquiryNavigationQuery from "@projectcaluma/ember-distribution/gql/queries/inquiry-navigation.graphql";
12
+
13
+ export default class DistributionService extends Service {
14
+ @service("-scheduler") scheduler;
15
+ @service calumaOptions;
16
+ @service router;
17
+ @service intl;
18
+ @service notification;
19
+
20
+ @queryManager apollo;
21
+
22
+ @config config;
23
+
24
+ get caseId() {
25
+ return getOwner(this).lookup("route:application").currentModel;
26
+ }
27
+
28
+ controls = trackedTask(this, this.fetchControls, () => [this.caseId]);
29
+ navigation = trackedTask(this, this.fetchNavigation, () => [this.caseId]);
30
+
31
+ async refetch() {
32
+ await getObservable(this.controls.value)?.refetch();
33
+ await getObservable(this.navigation.value)?.refetch();
34
+ }
35
+
36
+ @dropTask
37
+ *fetchControls(caseId) {
38
+ return yield this.apollo.watchQuery({
39
+ query: controlWorkItemsQuery,
40
+ variables: {
41
+ caseId,
42
+ currentGroup: String(this.calumaOptions.currentGroupId),
43
+ createTask: this.config.controls.createTask,
44
+ completeTask: this.config.controls.completeTask,
45
+ inquiryTask: this.config.inquiry.task,
46
+ },
47
+ });
48
+ }
49
+
50
+ @dropTask
51
+ *fetchNavigation(caseId) {
52
+ const response = yield this.apollo.watchQuery({
53
+ query: inquiryNavigationQuery,
54
+ variables: {
55
+ caseId,
56
+ task: this.config.inquiry.task,
57
+ currentGroup: String(this.calumaOptions.currentGroupId),
58
+ statusQuestion: this.config.inquiry.answer.statusQuestion,
59
+ deadlineQuestion: this.config.inquiry.deadlineQuestion,
60
+ includeNavigationData: true,
61
+ },
62
+ });
63
+
64
+ getObservable(response).subscribe(({ data }) => {
65
+ const groupIds = [
66
+ ...new Set(
67
+ Object.values(data)
68
+ .map((inquiries) => {
69
+ return inquiries.edges.map((edge) => [
70
+ ...edge.node.addressedGroups,
71
+ ...edge.node.controllingGroups,
72
+ ]);
73
+ })
74
+ .flat(2)
75
+ ),
76
+ ];
77
+
78
+ // Resolve all involved groups with the scheduler each time the query is
79
+ // updated. This will only trigger requests for new groups that are not in
80
+ // the cache.
81
+ this.scheduler.resolve(groupIds, "group");
82
+ });
83
+
84
+ return response;
85
+ }
86
+
87
+ @dropTask
88
+ *createInquiry(groups) {
89
+ try {
90
+ // get create inquiry work item to complete
91
+ const createId = decodeId(this.controls.value?.create.edges[0].node.id);
92
+
93
+ // create new inquiries
94
+ yield this.apollo.mutate({
95
+ mutation: createInquiryMutation,
96
+ variables: {
97
+ id: createId,
98
+ context: JSON.stringify({
99
+ addressed_groups: groups.map(String),
100
+ }),
101
+ },
102
+ });
103
+
104
+ // refetch navigation and controls data
105
+ yield this.refetch();
106
+ } catch (e) {
107
+ this.notification.danger(
108
+ this.intl.t("caluma.distribution.new.error", { count: groups.length })
109
+ );
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,18 @@
1
+ {{#if
2
+ (or
3
+ this.distribution.navigation.isRunning this.distribution.controls.isRunning
4
+ )
5
+ }}
6
+ <div class="uk-text-center">
7
+ <UkSpinner @ratio={{2}} />
8
+ </div>
9
+ {{else}}
10
+ <div uk-grid class={{if this.config.ui.stack "uk-grid-small"}}>
11
+ <div class={{if this.config.ui.stack "uk-width-1-1" "uk-width-1-3"}}>
12
+ <CdNavigation @caseId={{@model}} />
13
+ </div>
14
+ <div class={{if this.config.ui.stack "uk-width-1-1" "uk-width-2-3"}}>
15
+ {{outlet}}
16
+ </div>
17
+ </div>
18
+ {{/if}}
@@ -0,0 +1,11 @@
1
+ <div class="uk-text-center uk-text-muted">
2
+ {{svg-jar "distribution" class="uk-inline" width=200}}
3
+ <p class="uk-margin-medium uk-margin-remove-horizontal">
4
+ {{t "caluma.distribution.empty"}}
5
+ </p>
6
+ {{#if (can "create inquiry of distribution")}}
7
+ <LinkTo @route="new" class="uk-button uk-button-primary">
8
+ {{t "caluma.distribution.start"}}
9
+ </LinkTo>
10
+ {{/if}}
11
+ </div>
@@ -0,0 +1 @@
1
+ <CdInquiryAnswerForm @inquiry={{@model}} />
@@ -0,0 +1 @@
1
+ <CdInquiryEditForm @inquiry={{@model}} />