@things-factory/worklist 10.1.256 → 10.1.257

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist-client/activity-state-counts.d.ts +3 -3
  2. package/dist-client/activity-state-counts.js +6 -5
  3. package/dist-client/activity-state-counts.js.map +1 -1
  4. package/dist-client/chip-counts.d.ts +1 -1
  5. package/dist-client/chip-counts.js +1 -1
  6. package/dist-client/chip-counts.js.map +1 -1
  7. package/dist-client/chip-filters.d.ts +3 -2
  8. package/dist-client/chip-filters.js +5 -3
  9. package/dist-client/chip-filters.js.map +1 -1
  10. package/dist-client/components/activity-/bowner-view.js +26 -40
  11. package/dist-client/components/activity-/bowner-view.js.map +1 -1
  12. package/dist-client/components/activity-instance-preview.js +37 -49
  13. package/dist-client/components/activity-instance-preview.js.map +1 -1
  14. package/dist-client/components/activity-intro-view.js +26 -40
  15. package/dist-client/components/activity-intro-view.js.map +1 -1
  16. package/dist-client/components/activity-reporter-view.js +26 -40
  17. package/dist-client/components/activity-reporter-view.js.map +1 -1
  18. package/dist-client/components/activity-starter-form.d.ts +2 -3
  19. package/dist-client/components/activity-starter-form.js +52 -64
  20. package/dist-client/components/activity-starter-form.js.map +1 -1
  21. package/dist-client/components/mutation-outcome.d.ts +6 -0
  22. package/dist-client/components/mutation-outcome.js +9 -0
  23. package/dist-client/components/mutation-outcome.js.map +1 -1
  24. package/dist-client/components/say-outcome.d.ts +3 -0
  25. package/dist-client/components/say-outcome.js +3 -0
  26. package/dist-client/components/say-outcome.js.map +1 -1
  27. package/dist-client/entity360/person-open-work-section.d.ts +2 -3
  28. package/dist-client/entity360/person-open-work-section.js +17 -31
  29. package/dist-client/entity360/person-open-work-section.js.map +1 -1
  30. package/dist-client/pages/activity/activity-list-page.d.ts +4 -2
  31. package/dist-client/pages/activity/activity-list-page.js +6 -11
  32. package/dist-client/pages/activity/activity-list-page.js.map +1 -1
  33. package/dist-client/pages/activity/activity-page.d.ts +13 -7
  34. package/dist-client/pages/activity/activity-page.js +111 -167
  35. package/dist-client/pages/activity/activity-page.js.map +1 -1
  36. package/dist-client/pages/activity-approval/activity-approval-page.d.ts +14 -8
  37. package/dist-client/pages/activity-approval/activity-approval-page.js +107 -123
  38. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  39. package/dist-client/pages/activity-catalog/activity-catalog-page.d.ts +10 -9
  40. package/dist-client/pages/activity-catalog/activity-catalog-page.js +38 -70
  41. package/dist-client/pages/activity-catalog/activity-catalog-page.js.map +1 -1
  42. package/dist-client/pages/activity-catalog/activity-detail-page.d.ts +6 -6
  43. package/dist-client/pages/activity-catalog/activity-detail-page.js +30 -57
  44. package/dist-client/pages/activity-catalog/activity-detail-page.js.map +1 -1
  45. package/dist-client/pages/activity-instance/activity-instance-list-page.js +2 -2
  46. package/dist-client/pages/activity-instance/activity-instance-list-page.js.map +1 -1
  47. package/dist-client/pages/activity-instance/activity-instance-search-page.d.ts +6 -3
  48. package/dist-client/pages/activity-instance/activity-instance-search-page.js +27 -29
  49. package/dist-client/pages/activity-instance/activity-instance-search-page.js.map +1 -1
  50. package/dist-client/pages/activity-instance/activity-instance-start-page.d.ts +15 -8
  51. package/dist-client/pages/activity-instance/activity-instance-start-page.js +130 -239
  52. package/dist-client/pages/activity-instance/activity-instance-start-page.js.map +1 -1
  53. package/dist-client/pages/activity-instance/activity-instance-view.d.ts +2 -2
  54. package/dist-client/pages/activity-instance/activity-instance-view.js +109 -118
  55. package/dist-client/pages/activity-instance/activity-instance-view.js.map +1 -1
  56. package/dist-client/pages/activity-thread/activity-thread-page.d.ts +15 -6
  57. package/dist-client/pages/activity-thread/activity-thread-page.js +128 -131
  58. package/dist-client/pages/activity-thread/activity-thread-page.js.map +1 -1
  59. package/dist-client/pages/activity-thread/activity-thread-view-page.d.ts +6 -6
  60. package/dist-client/pages/activity-thread/activity-thread-view-page.js +28 -53
  61. package/dist-client/pages/activity-thread/activity-thread-view-page.js.map +1 -1
  62. package/dist-client/pages/todo/approval-done-list-page.d.ts +3 -3
  63. package/dist-client/pages/todo/approval-done-list-page.js +5 -14
  64. package/dist-client/pages/todo/approval-done-list-page.js.map +1 -1
  65. package/dist-client/pages/todo/approval-pending-list-page.d.ts +19 -9
  66. package/dist-client/pages/todo/approval-pending-list-page.js +46 -59
  67. package/dist-client/pages/todo/approval-pending-list-page.js.map +1 -1
  68. package/dist-client/pages/todo/draft-list-page.d.ts +8 -2
  69. package/dist-client/pages/todo/draft-list-page.js +24 -23
  70. package/dist-client/pages/todo/draft-list-page.js.map +1 -1
  71. package/dist-client/pages/todo/pickable-list-page.d.ts +3 -3
  72. package/dist-client/pages/todo/pickable-list-page.js +5 -14
  73. package/dist-client/pages/todo/pickable-list-page.js.map +1 -1
  74. package/dist-client/pages/todo/todo-list-page.d.ts +11 -5
  75. package/dist-client/pages/todo/todo-list-page.js +33 -36
  76. package/dist-client/pages/todo/todo-list-page.js.map +1 -1
  77. package/dist-client/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +14 -12
@@ -3,13 +3,37 @@ import '@material/web/button/elevated-button.js';
3
3
  import gql from 'graphql-tag';
4
4
  import { css, html, LitElement } from 'lit';
5
5
  import { customElement, property } from 'lit/decorators.js';
6
- import { client } from '@operato/graphql';
6
+ import { QueryController } from '@operato/graphql';
7
7
  import { i18next, localize } from '@operato/i18n';
8
8
  import { ScrollbarStyles } from '@operato/styles';
9
9
  let ActivityReporterView = class ActivityReporterView extends localize(i18next)(LitElement) {
10
10
  constructor() {
11
11
  super(...arguments);
12
12
  this.activityInstance = {};
13
+ /* The activity the id names (ADR-0190). */
14
+ this.activity = new QueryController(this, gql `
15
+ query activity($id: String!) {
16
+ activity(id: $id) {
17
+ id
18
+ name
19
+ description
20
+ state
21
+ thumbnail
22
+ model {
23
+ name
24
+ description
25
+ active
26
+ tag
27
+ inout
28
+ type
29
+ unit
30
+ options
31
+ quantifier
32
+ spec
33
+ }
34
+ }
35
+ }
36
+ `, { variables: () => (this.activityId ? { id: this.activityId } : undefined) });
13
37
  }
14
38
  static { this.styles = [
15
39
  ScrollbarStyles,
@@ -36,7 +60,7 @@ let ActivityReporterView = class ActivityReporterView extends localize(i18next)(
36
60
  `
37
61
  ]; }
38
62
  render() {
39
- const { name, description, thumbnail } = this.activity || {};
63
+ const { name, description, thumbnail } = this.activity.data?.activity || {};
40
64
  return html `
41
65
  <content>
42
66
  <section>
@@ -50,49 +74,11 @@ let ActivityReporterView = class ActivityReporterView extends localize(i18next)(
50
74
  </content>
51
75
  `;
52
76
  }
53
- firstUpdated() {
54
- this.fetchActivity(this.activityId);
55
- }
56
- async fetchActivity(id) {
57
- const response = await client.query({
58
- query: gql `
59
- query activity($id: String!) {
60
- activity(id: $id) {
61
- id
62
- name
63
- description
64
- state
65
- thumbnail
66
- model {
67
- name
68
- description
69
- active
70
- tag
71
- inout
72
- type
73
- unit
74
- options
75
- quantifier
76
- spec
77
- }
78
- }
79
- }
80
- `,
81
- variables: {
82
- id
83
- }
84
- });
85
- this.activity = response.data.activity;
86
- }
87
77
  };
88
78
  __decorate([
89
79
  property({ type: String }),
90
80
  __metadata("design:type", String)
91
81
  ], ActivityReporterView.prototype, "activityId", void 0);
92
- __decorate([
93
- property({ type: Object }),
94
- __metadata("design:type", Object)
95
- ], ActivityReporterView.prototype, "activity", void 0);
96
82
  __decorate([
97
83
  property({ type: Object }),
98
84
  __metadata("design:type", Object)
@@ -1 +1 @@
1
- {"version":3,"file":"activity-reporter-view.js","sourceRoot":"","sources":["../../client/components/activity-reporter-view.ts"],"names":[],"mappings":";AAAA,OAAO,yCAAyC,CAAA;AAEhD,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGjD,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAAhE;;QA4B8B,qBAAgB,GAAQ,EAAE,CAAA;IAuDxD,CAAC;aAlFQ,WAAM,GAAG;QACd,eAAe;QACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;KAoBF;KACF,AAvBY,CAuBZ;IAMD,MAAM;QACJ,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAA;QAE5D,OAAO,IAAI,CAAA;;;uBAGQ,IAAI;8BACG,WAAW;;;;qBAIpB,SAAS;;;KAGzB,CAAA;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACrC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,EAAE;QACpB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;OAsBT;YACD,SAAS,EAAE;gBACT,EAAE;aACH;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAA;IACxC,CAAC;;AAxD2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;wDAAoB;AACnB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;sDAAc;AACb;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;8DAA2B;AA5BlD,oBAAoB;IADzB,aAAa,CAAC,wBAAwB,CAAC;GAClC,oBAAoB,CAmFzB","sourcesContent":["import '@material/web/button/elevated-button.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\n\n@customElement('activity-reporter-view')\nclass ActivityReporterView extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n }\n\n content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: var(--spacing-medium);\n overflow: auto;\n }\n\n section {\n display: flex;\n flex-direction: column;\n }\n `\n ]\n\n @property({ type: String }) activityId?: string\n @property({ type: Object }) activity: any\n @property({ type: Object }) activityInstance: any = {}\n\n render() {\n const { name, description, thumbnail } = this.activity || {}\n\n return html`\n <content>\n <section>\n <div>name: ${name}</div>\n <div>description: ${description}</div>\n </section>\n\n <section>\n <img src=${thumbnail} />\n </section>\n </content>\n `\n }\n\n firstUpdated() {\n this.fetchActivity(this.activityId)\n }\n\n async fetchActivity(id) {\n const response = await client.query({\n query: gql`\n query activity($id: String!) {\n activity(id: $id) {\n id\n name\n description\n state\n thumbnail\n model {\n name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n }\n }\n }\n `,\n variables: {\n id\n }\n })\n\n this.activity = response.data.activity\n }\n}\n"]}
1
+ {"version":3,"file":"activity-reporter-view.js","sourceRoot":"","sources":["../../client/components/activity-reporter-view.ts"],"names":[],"mappings":";AAAA,OAAO,yCAAyC,CAAA;AAEhD,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGjD,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAAhE;;QA2B8B,qBAAgB,GAAQ,EAAE,CAAA;QAEtD,2CAA2C;QACnC,aAAQ,GAAG,IAAI,eAAe,CACpC,IAAI,EACJ,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;KAsBF,EACD,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAC7E,CAAA;IAkBH,CAAC;aAzEQ,WAAM,GAAG;QACd,eAAe;QACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;KAoBF;KACF,AAvBY,CAuBZ;IAkCD,MAAM;QACJ,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAA;QAE3E,OAAO,IAAI,CAAA;;;uBAGQ,IAAI;8BACG,WAAW;;;;qBAIpB,SAAS;;;KAGzB,CAAA;IACH,CAAC;;AA/C2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;wDAAoB;AACnB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;8DAA2B;AA3BlD,oBAAoB;IADzB,aAAa,CAAC,wBAAwB,CAAC;GAClC,oBAAoB,CA0EzB","sourcesContent":["import '@material/web/button/elevated-button.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\n\n@customElement('activity-reporter-view')\nclass ActivityReporterView extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n }\n\n content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: var(--spacing-medium);\n overflow: auto;\n }\n\n section {\n display: flex;\n flex-direction: column;\n }\n `\n ]\n\n @property({ type: String }) activityId?: string\n @property({ type: Object }) activityInstance: any = {}\n\n /* The activity the id names (ADR-0190). */\n private activity = new QueryController(\n this,\n gql`\n query activity($id: String!) {\n activity(id: $id) {\n id\n name\n description\n state\n thumbnail\n model {\n name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n }\n }\n }\n `,\n { variables: () => (this.activityId ? { id: this.activityId } : undefined) }\n )\n\n render() {\n const { name, description, thumbnail } = this.activity.data?.activity || {}\n\n return html`\n <content>\n <section>\n <div>name: ${name}</div>\n <div>description: ${description}</div>\n </section>\n\n <section>\n <img src=${thumbnail} />\n </section>\n </content>\n `\n }\n}\n"]}
@@ -8,11 +8,10 @@ declare const ActivityStarterForm_base: (new (...args: any[]) => LitElement) & t
8
8
  export declare class ActivityStarterForm extends ActivityStarterForm_base {
9
9
  static styles: import("lit").CSSResult[];
10
10
  activityId?: string;
11
- activity: any;
11
+ private activityRead;
12
+ private get activity();
12
13
  activityInstance: any;
13
14
  render(): import("lit-html").TemplateResult<1>;
14
- firstUpdated(): void;
15
- fetchActivity(id: any): Promise<void>;
16
15
  draftActivityInstance(): Promise<void>;
17
16
  openActivityInstanceStart(activityInstance: any): void;
18
17
  }
@@ -8,7 +8,7 @@ import gql from 'graphql-tag';
8
8
  import { css, html, LitElement } from 'lit';
9
9
  import { customElement, property, state } from 'lit/decorators.js';
10
10
  import { navigate } from '@operato/shell';
11
- import { client } from '@operato/graphql';
11
+ import { client, QueryController } from '@operato/graphql';
12
12
  import { i18next, localize } from '@operato/i18n';
13
13
  import { ranMutation } from './say-outcome.js';
14
14
  import { notify } from '@operato/layout';
@@ -16,7 +16,54 @@ import { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles';
16
16
  let ActivityStarterForm = class ActivityStarterForm extends localize(i18next)(LitElement) {
17
17
  constructor() {
18
18
  super(...arguments);
19
- this.activity = {};
19
+ /* The activity the form drafts from (ADR-0190). */
20
+ this.activityRead = new QueryController(this, gql `
21
+ query activity($id: String!) {
22
+ activity(id: $id) {
23
+ id
24
+ name
25
+ description
26
+ state
27
+ multiple
28
+ startingType
29
+ assignees {
30
+ type
31
+ value
32
+ assignee {
33
+ id
34
+ name
35
+ description
36
+ controlNo
37
+ }
38
+ }
39
+ approvalLine {
40
+ type
41
+ participation
42
+ notifyAfter
43
+ value
44
+ approver {
45
+ id
46
+ name
47
+ description
48
+ controlNo
49
+ }
50
+ }
51
+ thumbnail
52
+ model {
53
+ name
54
+ description
55
+ active
56
+ tag
57
+ inout
58
+ type
59
+ unit
60
+ options
61
+ quantifier
62
+ spec
63
+ }
64
+ }
65
+ }
66
+ `, { variables: () => (this.activityId ? { id: this.activityId } : undefined) });
20
67
  this.activityInstance = {};
21
68
  }
22
69
  static { this.styles = [
@@ -66,6 +113,9 @@ let ActivityStarterForm = class ActivityStarterForm extends localize(i18next)(Li
66
113
  }
67
114
  `
68
115
  ]; }
116
+ get activity() {
117
+ return this.activityRead.data?.activity ?? {};
118
+ }
69
119
  render() {
70
120
  var { thumbnail, startingType } = this.activity || {};
71
121
  var { name, description } = this.activityInstance;
@@ -111,64 +161,6 @@ let ActivityStarterForm = class ActivityStarterForm extends localize(i18next)(Li
111
161
  </div>
112
162
  `;
113
163
  }
114
- firstUpdated() {
115
- this.fetchActivity(this.activityId);
116
- }
117
- async fetchActivity(id) {
118
- const response = await client.query({
119
- query: gql `
120
- query activity($id: String!) {
121
- activity(id: $id) {
122
- id
123
- name
124
- description
125
- state
126
- multiple
127
- startingType
128
- assignees {
129
- type
130
- value
131
- assignee {
132
- id
133
- name
134
- description
135
- controlNo
136
- }
137
- }
138
- approvalLine {
139
- type
140
- participation
141
- notifyAfter
142
- value
143
- approver {
144
- id
145
- name
146
- description
147
- controlNo
148
- }
149
- }
150
- thumbnail
151
- model {
152
- name
153
- description
154
- active
155
- tag
156
- inout
157
- type
158
- unit
159
- options
160
- quantifier
161
- spec
162
- }
163
- }
164
- }
165
- `,
166
- variables: {
167
- id
168
- }
169
- });
170
- this.activity = response.data.activity;
171
- }
172
164
  async draftActivityInstance() {
173
165
  var { id: activityId } = this.activity;
174
166
  var { id, name, description, priority, threadsMin, threadsMax, dueAt, input, assignees, approvalLine } = this.activityInstance;
@@ -249,10 +241,6 @@ __decorate([
249
241
  property({ type: String }),
250
242
  __metadata("design:type", String)
251
243
  ], ActivityStarterForm.prototype, "activityId", void 0);
252
- __decorate([
253
- state(),
254
- __metadata("design:type", Object)
255
- ], ActivityStarterForm.prototype, "activity", void 0);
256
244
  __decorate([
257
245
  state(),
258
246
  __metadata("design:type", Object)
@@ -1 +1 @@
1
- {"version":3,"file":"activity-starter-form.js","sourceRoot":"","sources":["../../client/components/activity-starter-form.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/textfield/outlined-text-field.js'\nimport '@material/web/textfield/filled-text-field.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@things-factory/organization'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { navigate } from '@operato/shell'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { ranMutation } from './say-outcome.js'\nimport { notify } from '@operato/layout'\nimport { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'\n\n@customElement('activity-starter-form')\nexport class ActivityStarterForm extends localize(i18next)(LitElement) {\n static styles = [\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n color: var(--md-sys-color-on-surface);\n background-color: var(--md-sys-color-surface);\n }\n\n content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: var(--spacing-medium);\n gap: var(--spacing-medium);\n overflow: auto;\n }\n\n content > div {\n display: flex;\n flex-direction: column;\n }\n\n content label {\n font: var(--label-font);\n }\n content input,\n content textarea {\n border-radius: var(--border-radius);\n border: var(--border-dim-color);\n padding: var(--input-padding);\n margin: var(--input-margin);\n font: var(--input-font);\n }\n\n content [desc] {\n font-size: 0.9em;\n }\n\n #description {\n flex: 1;\n }\n `\n ]\n\n @property({ type: String }) activityId?: string\n\n @state() activity: any = {}\n @state() activityInstance: any = {}\n\n render() {\n var { thumbnail, startingType } = this.activity || {}\n var { name, description } = this.activityInstance\n\n return html`\n <content>\n <div desc>\n <span>${i18next.t('text.activity-draft-how')}</span>\n <span\n >${i18next.t('text.activity-draft-where', {\n action: i18next.t(startingType == 'issue' ? 'button.issue' : 'button.post')\n })}</span\n >\n </div>\n\n <md-outlined-text-field\n id=\"name\"\n type=\"text\"\n label=${String(i18next.t('label.title'))}\n .value=${name || this.activity?.name || ''}\n @change=${e => (this.activityInstance.name = e.currentTarget.value)}\n >\n </md-outlined-text-field>\n\n <md-filled-text-field\n id=\"description\"\n type=\"textarea\"\n label=${String(i18next.t('label.description'))}\n resize=\"none\"\n .value=${description || this.activity?.description || ''}\n @change=${e => {\n this.activityInstance.description = e.currentTarget.value\n }}\n >\n </md-filled-text-field>\n </content>\n\n <div class=\"footer\">\n <div filler></div>\n <button @click=${e => history.back()}><md-icon>close</md-icon>${i18next.t('button.close')}</button>\n <button @click=${this.draftActivityInstance.bind(this)} done>\n <md-icon>save</md-icon>${i18next.t('button.draft')}\n </button>\n </div>\n `\n }\n\n firstUpdated() {\n this.fetchActivity(this.activityId)\n }\n\n async fetchActivity(id) {\n const response = await client.query({\n query: gql`\n query activity($id: String!) {\n activity(id: $id) {\n id\n name\n description\n state\n multiple\n startingType\n assignees {\n type\n value\n assignee {\n id\n name\n description\n controlNo\n }\n }\n approvalLine {\n type\n participation\n notifyAfter\n value\n approver {\n id\n name\n description\n controlNo\n }\n }\n thumbnail\n model {\n name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n }\n }\n }\n `,\n variables: {\n id\n }\n })\n\n this.activity = response.data.activity\n }\n\n async draftActivityInstance() {\n var { id: activityId } = this.activity\n var { id, name, description, priority, threadsMin, threadsMax, dueAt, input, assignees, approvalLine } =\n this.activityInstance\n\n name ||= this.activity.name\n description ||= this.activity.description\n assignees ||= this.activity.assignees\n approvalLine ||= this.activity.approvalLine\n\n var activityInstance = {\n id,\n activityId,\n name,\n description,\n priority,\n threadsMax,\n threadsMin,\n dueAt,\n input,\n assignees,\n approvalLine\n }\n\n const outcome = await ranMutation(() => client.mutate({\n mutation: gql`\n mutation ($activityInstance: ActivityInstanceDraft!) {\n draftActivityInstance(activityInstance: $activityInstance) {\n id\n name\n description\n input\n output\n state\n assignees {\n type\n value\n assignee {\n id\n name\n description\n controlNo\n }\n }\n approvalLine {\n type\n participation\n notifyAfter\n value\n approver {\n id\n name\n description\n controlNo\n }\n }\n threadsMin\n threadsMax\n }\n }\n `,\n variables: {\n activityInstance\n }\n }))\n\n if (!outcome.ok) { return\n }\n\n this.activityInstance = outcome.data.draftActivityInstance\n notify({\n message: i18next.t('text.info_x_successfully', {\n x: `${i18next.t('label.activity-instance')} ${i18next.t('text.draft')}`\n })\n })\n\n this.openActivityInstanceStart(this.activityInstance)\n }\n\n openActivityInstanceStart(activityInstance) {\n navigate(`activity-instance-start/${activityInstance.id}?title=${activityInstance.name}`, false, this)\n }\n}\n"]}
1
+ {"version":3,"file":"activity-starter-form.js","sourceRoot":"","sources":["../../client/components/activity-starter-form.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/textfield/outlined-text-field.js'\nimport '@material/web/textfield/filled-text-field.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@things-factory/organization'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { navigate } from '@operato/shell'\nimport { client, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { ranMutation } from './say-outcome.js'\nimport { notify } from '@operato/layout'\nimport { CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'\n\n@customElement('activity-starter-form')\nexport class ActivityStarterForm extends localize(i18next)(LitElement) {\n static styles = [\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n color: var(--md-sys-color-on-surface);\n background-color: var(--md-sys-color-surface);\n }\n\n content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: var(--spacing-medium);\n gap: var(--spacing-medium);\n overflow: auto;\n }\n\n content > div {\n display: flex;\n flex-direction: column;\n }\n\n content label {\n font: var(--label-font);\n }\n content input,\n content textarea {\n border-radius: var(--border-radius);\n border: var(--border-dim-color);\n padding: var(--input-padding);\n margin: var(--input-margin);\n font: var(--input-font);\n }\n\n content [desc] {\n font-size: 0.9em;\n }\n\n #description {\n flex: 1;\n }\n `\n ]\n\n @property({ type: String }) activityId?: string\n\n /* The activity the form drafts from (ADR-0190). */\n private activityRead = new QueryController(\n this,\n gql`\n query activity($id: String!) {\n activity(id: $id) {\n id\n name\n description\n state\n multiple\n startingType\n assignees {\n type\n value\n assignee {\n id\n name\n description\n controlNo\n }\n }\n approvalLine {\n type\n participation\n notifyAfter\n value\n approver {\n id\n name\n description\n controlNo\n }\n }\n thumbnail\n model {\n name\n description\n active\n tag\n inout\n type\n unit\n options\n quantifier\n spec\n }\n }\n }\n `,\n { variables: () => (this.activityId ? { id: this.activityId } : undefined) }\n )\n\n private get activity(): any {\n return this.activityRead.data?.activity ?? {}\n }\n\n @state() activityInstance: any = {}\n\n render() {\n var { thumbnail, startingType } = this.activity || {}\n var { name, description } = this.activityInstance\n\n return html`\n <content>\n <div desc>\n <span>${i18next.t('text.activity-draft-how')}</span>\n <span\n >${i18next.t('text.activity-draft-where', {\n action: i18next.t(startingType == 'issue' ? 'button.issue' : 'button.post')\n })}</span\n >\n </div>\n\n <md-outlined-text-field\n id=\"name\"\n type=\"text\"\n label=${String(i18next.t('label.title'))}\n .value=${name || this.activity?.name || ''}\n @change=${e => (this.activityInstance.name = e.currentTarget.value)}\n >\n </md-outlined-text-field>\n\n <md-filled-text-field\n id=\"description\"\n type=\"textarea\"\n label=${String(i18next.t('label.description'))}\n resize=\"none\"\n .value=${description || this.activity?.description || ''}\n @change=${e => {\n this.activityInstance.description = e.currentTarget.value\n }}\n >\n </md-filled-text-field>\n </content>\n\n <div class=\"footer\">\n <div filler></div>\n <button @click=${e => history.back()}><md-icon>close</md-icon>${i18next.t('button.close')}</button>\n <button @click=${this.draftActivityInstance.bind(this)} done>\n <md-icon>save</md-icon>${i18next.t('button.draft')}\n </button>\n </div>\n `\n }\n\n async draftActivityInstance() {\n var { id: activityId } = this.activity\n var { id, name, description, priority, threadsMin, threadsMax, dueAt, input, assignees, approvalLine } =\n this.activityInstance\n\n name ||= this.activity.name\n description ||= this.activity.description\n assignees ||= this.activity.assignees\n approvalLine ||= this.activity.approvalLine\n\n var activityInstance = {\n id,\n activityId,\n name,\n description,\n priority,\n threadsMax,\n threadsMin,\n dueAt,\n input,\n assignees,\n approvalLine\n }\n\n const outcome = await ranMutation(() => client.mutate({\n mutation: gql`\n mutation ($activityInstance: ActivityInstanceDraft!) {\n draftActivityInstance(activityInstance: $activityInstance) {\n id\n name\n description\n input\n output\n state\n assignees {\n type\n value\n assignee {\n id\n name\n description\n controlNo\n }\n }\n approvalLine {\n type\n participation\n notifyAfter\n value\n approver {\n id\n name\n description\n controlNo\n }\n }\n threadsMin\n threadsMax\n }\n }\n `,\n variables: {\n activityInstance\n }\n }))\n\n if (!outcome.ok) { return\n }\n\n this.activityInstance = outcome.data.draftActivityInstance\n notify({\n message: i18next.t('text.info_x_successfully', {\n x: `${i18next.t('label.activity-instance')} ${i18next.t('text.draft')}`\n })\n })\n\n this.openActivityInstanceStart(this.activityInstance)\n }\n\n openActivityInstanceStart(activityInstance) {\n navigate(`activity-instance-start/${activityInstance.id}?title=${activityInstance.name}`, false, this)\n }\n}\n"]}
@@ -53,5 +53,11 @@ export type MutationOutcome =
53
53
  export declare function outcomeOf(response: any): MutationOutcome;
54
54
  /** Reading a thrown error — the road a 401 takes. */
55
55
  export declare function outcomeOfThrow(thrown: any): MutationOutcome;
56
+ /**
57
+ * Reading a failed save's `error` as a MutationController keeps it: the ApolloError carrying the server's GraphQL
58
+ * errors (the resolved road), or what the request threw (the 401's road). Both roads are read above; this only
59
+ * says which one the error came by.
60
+ */
61
+ export declare function mutationOutcome(error: unknown): MutationOutcome;
56
62
  /** The i18n key for a failure, so every screen says the same thing about the same thing. */
57
63
  export declare function outcomeKey(outcome: MutationOutcome): string;
@@ -59,6 +59,15 @@ export function outcomeOfThrow(thrown) {
59
59
  }
60
60
  return { ok: false, kind: 'failed', said };
61
61
  }
62
+ /**
63
+ * Reading a failed save's `error` as a MutationController keeps it: the ApolloError carrying the server's GraphQL
64
+ * errors (the resolved road), or what the request threw (the 401's road). Both roads are read above; this only
65
+ * says which one the error came by.
66
+ */
67
+ export function mutationOutcome(error) {
68
+ const errors = error?.graphQLErrors;
69
+ return errors?.length ? outcomeOf({ errors }) : outcomeOfThrow(error);
70
+ }
62
71
  /** The sentence a session failure carries. Matched loosely because the wording is not ours. */
63
72
  function looksSignedOut(message) {
64
73
  const text = String(message || '').toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"mutation-outcome.js","sourceRoot":"","sources":["../../client/components/mutation-outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAYH,mCAAmC;AACnC,MAAM,UAAU,SAAS,CAAC,QAAa;IACrC,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAA;IAErC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,QAAQ,EAAE,IAAI,EAAE,CAAC;QACrC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAA;IAC1C,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,IAAI,WAAW,CAAC,CAAA;IAErF,IAAI,SAAS,EAAE,CAAC;QACd,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC;YACrC,QAAQ,EAAE,SAAS,CAAC,UAAU,EAAE,QAAQ;SACzC,CAAA;IACH,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;IAE7E,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAA;IACjF,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,CAAA;AAC9E,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,cAAc,CAAC,MAAW;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,MAAM,IAAI,EAAE,CAAC,CAAA;IAEpD;;;;;OAKG;IACH,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,UAAU,IAAI,GAAG,IAAI,MAAM,EAAE,YAAY,EAAE,UAAU,IAAI,GAAG,EAAE,CAAC;QACjG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;IAChD,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;AAC5C,CAAC;AAED,+FAA+F;AAC/F,SAAS,cAAc,CAAC,OAAY;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IAEhD,OAAO,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAA;AAC3G,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,UAAU,CAAC,OAAwB;IACjD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO;QACL,SAAS,EAAE,6BAA6B;QACxC,YAAY,EAAE,+BAA+B;QAC7C,MAAM,EAAE,4BAA4B;KACrC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AACjB,CAAC","sourcesContent":["/**\n * What came back from a mutation, in the terms a screen has to speak.\n *\n * ── Two failures that arrive by different roads ───────────────────────────\n * A privilege refusal is a GraphQL error. The server marks it itself\n * ([읽었음] auth-base/server/service/privilege/privilege-rejection.ts:61) with\n * `extensions: { code: 'FORBIDDEN', requires }`, and `mutate` is configured with\n * `errorPolicy: 'all'` ([읽었음] operato/webcomponents/graphql/src/graphql-client.ts:18), so it\n * **resolves** with `errors` rather than throwing.\n *\n * A missing or expired session never reaches GraphQL at all:\n *\n * [확인함] curl -X POST http://localhost:4000/graphql -d '{\"query\":\"{ __typename }\"}'\n * HTTP 401 · body: No auth token\n *\n * That is an HTTP failure with a plain-text body, so it arrives as a thrown error, not as `errors`.\n * A handler that only looks at `errors` misses it, and the throw takes the rest of the handler with\n * it. Both roads are handled here so a caller does not have to remember there are two.\n *\n * ── Why they must not share a sentence ────────────────────────────────────\n * Telling someone whose session expired to ask an administrator for a privilege sends them to the\n * wrong place, and they will wait for something nobody is going to do. (2026-09-11, architect)\n *\n * Nothing is imported: the test runner strips types without reading decorators, and one heavy\n * import takes a whole test file down — that happened three times in one day.\n */\n\nexport type MutationOutcome =\n /** It went through. `data` is what the mutation answered, so the caller need not keep the response. */\n | { ok: true; data: any }\n /** The server said this user may not. `requires` is what it said is needed, when it said. */\n | { ok: false; kind: 'forbidden'; said: string; requires?: unknown }\n /** No session reached the server. Signing in again is the answer, not a privilege. */\n | { ok: false; kind: 'signed-out'; said: string }\n /** Something else. `said` is the server's own sentence — this side does not know the cause. */\n | { ok: false; kind: 'failed'; said: string }\n\n/** Reading a resolved response. */\nexport function outcomeOf(response: any): MutationOutcome {\n const errors = response?.errors || []\n\n if (!errors.length && response?.data) {\n return { ok: true, data: response.data }\n }\n\n const forbidden = errors.find((error: any) => error?.extensions?.code == 'FORBIDDEN')\n\n if (forbidden) {\n return {\n ok: false,\n kind: 'forbidden',\n said: String(forbidden.message || ''),\n requires: forbidden.extensions?.requires\n }\n }\n\n const signedOut = errors.find((error: any) => looksSignedOut(error?.message))\n\n if (signedOut) {\n return { ok: false, kind: 'signed-out', said: String(signedOut.message || '') }\n }\n\n return { ok: false, kind: 'failed', said: String(errors[0]?.message || '') }\n}\n\n/** Reading a thrown error — the road a 401 takes. */\nexport function outcomeOfThrow(thrown: any): MutationOutcome {\n const said = String(thrown?.message || thrown || '')\n\n /*\n * Apollo wraps an HTTP failure, so the 401's body travels inside the message. Matching the text\n * is not ideal; it is what the server gives, since the body is plain text rather than a GraphQL\n * error with a code. If the server ever answers 401 as a GraphQL error, outcomeOf catches it on\n * the other road and this one keeps working.\n */\n if (looksSignedOut(said) || thrown?.statusCode == 401 || thrown?.networkError?.statusCode == 401) {\n return { ok: false, kind: 'signed-out', said }\n }\n\n return { ok: false, kind: 'failed', said }\n}\n\n/** The sentence a session failure carries. Matched loosely because the wording is not ours. */\nfunction looksSignedOut(message: any): boolean {\n const text = String(message || '').toLowerCase()\n\n return text.includes('no auth token') || text.includes('jwt expired') || text.includes('unauthenticated')\n}\n\n/** The i18n key for a failure, so every screen says the same thing about the same thing. */\nexport function outcomeKey(outcome: MutationOutcome): string {\n if (outcome.ok) {\n return ''\n }\n\n return {\n forbidden: 'text.not-allowed-to-do-this',\n 'signed-out': 'text.signed-out-sign-in-again',\n failed: 'text.it-did-not-go-through'\n }[outcome.kind]\n}\n"]}
1
+ {"version":3,"file":"mutation-outcome.js","sourceRoot":"","sources":["../../client/components/mutation-outcome.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What came back from a mutation, in the terms a screen has to speak.\n *\n * ── Two failures that arrive by different roads ───────────────────────────\n * A privilege refusal is a GraphQL error. The server marks it itself\n * ([읽었음] auth-base/server/service/privilege/privilege-rejection.ts:61) with\n * `extensions: { code: 'FORBIDDEN', requires }`, and `mutate` is configured with\n * `errorPolicy: 'all'` ([읽었음] operato/webcomponents/graphql/src/graphql-client.ts:18), so it\n * **resolves** with `errors` rather than throwing.\n *\n * A missing or expired session never reaches GraphQL at all:\n *\n * [확인함] curl -X POST http://localhost:4000/graphql -d '{\"query\":\"{ __typename }\"}'\n * HTTP 401 · body: No auth token\n *\n * That is an HTTP failure with a plain-text body, so it arrives as a thrown error, not as `errors`.\n * A handler that only looks at `errors` misses it, and the throw takes the rest of the handler with\n * it. Both roads are handled here so a caller does not have to remember there are two.\n *\n * ── Why they must not share a sentence ────────────────────────────────────\n * Telling someone whose session expired to ask an administrator for a privilege sends them to the\n * wrong place, and they will wait for something nobody is going to do. (2026-09-11, architect)\n *\n * Nothing is imported: the test runner strips types without reading decorators, and one heavy\n * import takes a whole test file down — that happened three times in one day.\n */\n\nexport type MutationOutcome =\n /** It went through. `data` is what the mutation answered, so the caller need not keep the response. */\n | { ok: true; data: any }\n /** The server said this user may not. `requires` is what it said is needed, when it said. */\n | { ok: false; kind: 'forbidden'; said: string; requires?: unknown }\n /** No session reached the server. Signing in again is the answer, not a privilege. */\n | { ok: false; kind: 'signed-out'; said: string }\n /** Something else. `said` is the server's own sentence — this side does not know the cause. */\n | { ok: false; kind: 'failed'; said: string }\n\n/** Reading a resolved response. */\nexport function outcomeOf(response: any): MutationOutcome {\n const errors = response?.errors || []\n\n if (!errors.length && response?.data) {\n return { ok: true, data: response.data }\n }\n\n const forbidden = errors.find((error: any) => error?.extensions?.code == 'FORBIDDEN')\n\n if (forbidden) {\n return {\n ok: false,\n kind: 'forbidden',\n said: String(forbidden.message || ''),\n requires: forbidden.extensions?.requires\n }\n }\n\n const signedOut = errors.find((error: any) => looksSignedOut(error?.message))\n\n if (signedOut) {\n return { ok: false, kind: 'signed-out', said: String(signedOut.message || '') }\n }\n\n return { ok: false, kind: 'failed', said: String(errors[0]?.message || '') }\n}\n\n/** Reading a thrown error — the road a 401 takes. */\nexport function outcomeOfThrow(thrown: any): MutationOutcome {\n const said = String(thrown?.message || thrown || '')\n\n /*\n * Apollo wraps an HTTP failure, so the 401's body travels inside the message. Matching the text\n * is not ideal; it is what the server gives, since the body is plain text rather than a GraphQL\n * error with a code. If the server ever answers 401 as a GraphQL error, outcomeOf catches it on\n * the other road and this one keeps working.\n */\n if (looksSignedOut(said) || thrown?.statusCode == 401 || thrown?.networkError?.statusCode == 401) {\n return { ok: false, kind: 'signed-out', said }\n }\n\n return { ok: false, kind: 'failed', said }\n}\n\n/**\n * Reading a failed save's `error` as a MutationController keeps it: the ApolloError carrying the server's GraphQL\n * errors (the resolved road), or what the request threw (the 401's road). Both roads are read above; this only\n * says which one the error came by.\n */\nexport function mutationOutcome(error: unknown): MutationOutcome {\n const errors = (error as any)?.graphQLErrors\n\n return errors?.length ? outcomeOf({ errors }) : outcomeOfThrow(error)\n}\n\n/** The sentence a session failure carries. Matched loosely because the wording is not ours. */\nfunction looksSignedOut(message: any): boolean {\n const text = String(message || '').toLowerCase()\n\n return text.includes('no auth token') || text.includes('jwt expired') || text.includes('unauthenticated')\n}\n\n/** The i18n key for a failure, so every screen says the same thing about the same thing. */\nexport function outcomeKey(outcome: MutationOutcome): string {\n if (outcome.ok) {\n return ''\n }\n\n return {\n forbidden: 'text.not-allowed-to-do-this',\n 'signed-out': 'text.signed-out-sign-in-again',\n failed: 'text.it-did-not-go-through'\n }[outcome.kind]\n}\n"]}
@@ -13,6 +13,9 @@ import { MutationOutcome } from './mutation-outcome.js';
13
13
  * const outcome = await ranMutation(() => client.mutate({ … }))
14
14
  * if (!outcome.ok) return
15
15
  * … what to do when it worked …
16
+ *
17
+ * A save the screen shows is a MutationController instead (ADR-0190); it keeps its failure as `error`, and the
18
+ * screen says it with `sayFailure(mutationOutcome(save.error))`.
16
19
  */
17
20
  export declare function ranMutation(run: () => Promise<any>): Promise<MutationOutcome>;
18
21
  /**
@@ -14,6 +14,9 @@ import { outcomeKey, outcomeOf, outcomeOfThrow } from './mutation-outcome.js';
14
14
  * const outcome = await ranMutation(() => client.mutate({ … }))
15
15
  * if (!outcome.ok) return
16
16
  * … what to do when it worked …
17
+ *
18
+ * A save the screen shows is a MutationController instead (ADR-0190); it keeps its failure as `error`, and the
19
+ * screen says it with `sayFailure(mutationOutcome(save.error))`.
17
20
  */
18
21
  export async function ranMutation(run) {
19
22
  let outcome;
@@ -1 +1 @@
1
- {"version":3,"file":"say-outcome.js","sourceRoot":"","sources":["../../client/components/say-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAmB,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE9F;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAuB;IACvD,IAAI,OAAwB,CAAA;IAE5B,IAAI,CAAC;QACH,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAClC,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,UAAU,CAAC,OAAO,CAAC,CAAA;IACrB,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,OAAwB;IACjD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;QACf,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IAE/B,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE;QACxB,MAAM,EAAE;YACN,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;SACtD;KACF,CAAC,CACH,CAAA;IAED,OAAO,CAAC,KAAK,CAAC,cAAc,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;AAC/D,CAAC","sourcesContent":["import { i18next } from '@operato/i18n'\n\nimport { MutationOutcome, outcomeKey, outcomeOf, outcomeOfThrow } from './mutation-outcome.js'\n\n/**\n * Run a mutation and say so when it does not go through.\n *\n * ── Why a wrapper and not a check at each call ────────────────────────────\n * A failure arrives by two roads — a privilege refusal resolves with `errors`, a missing session\n * throws an HTTP 401 — and every call site would have to remember both. Six handlers in this package\n * remembered neither: they read `errors` only to skip the success branch, with no `else`, so a\n * failed save changed nothing on screen and said nothing. The worker presses the button again.\n *\n * The caller keeps its success path and stops carrying the failure one:\n *\n * const outcome = await ranMutation(() => client.mutate({ … }))\n * if (!outcome.ok) return\n * … what to do when it worked …\n */\nexport async function ranMutation(run: () => Promise<any>): Promise<MutationOutcome> {\n let outcome: MutationOutcome\n\n try {\n outcome = outcomeOf(await run())\n } catch (thrown) {\n outcome = outcomeOfThrow(thrown)\n }\n\n if (!outcome.ok) {\n sayFailure(outcome)\n }\n\n return outcome\n}\n\n/**\n * One sentence per kind of failure.\n *\n * `said` is the server's own sentence and only the last kind prints it — for the other two this\n * side knows what happened and can say what to do about it. Telling someone whose session expired\n * to ask an administrator for a privilege would send them where nobody can help.\n */\nexport function sayFailure(outcome: MutationOutcome) {\n if (outcome.ok) {\n return\n }\n\n const key = outcomeKey(outcome)\n\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: i18next.t(key, { said: outcome.said || '' })\n }\n })\n )\n\n console.error(`[worklist] ${outcome.kind} — ${outcome.said}`)\n}\n"]}
1
+ {"version":3,"file":"say-outcome.js","sourceRoot":"","sources":["../../client/components/say-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAmB,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE9F;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAuB;IACvD,IAAI,OAAwB,CAAA;IAE5B,IAAI,CAAC;QACH,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAClC,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,UAAU,CAAC,OAAO,CAAC,CAAA;IACrB,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,OAAwB;IACjD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;QACf,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IAE/B,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE;QACxB,MAAM,EAAE;YACN,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;SACtD;KACF,CAAC,CACH,CAAA;IAED,OAAO,CAAC,KAAK,CAAC,cAAc,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;AAC/D,CAAC","sourcesContent":["import { i18next } from '@operato/i18n'\n\nimport { MutationOutcome, outcomeKey, outcomeOf, outcomeOfThrow } from './mutation-outcome.js'\n\n/**\n * Run a mutation and say so when it does not go through.\n *\n * ── Why a wrapper and not a check at each call ────────────────────────────\n * A failure arrives by two roads — a privilege refusal resolves with `errors`, a missing session\n * throws an HTTP 401 — and every call site would have to remember both. Six handlers in this package\n * remembered neither: they read `errors` only to skip the success branch, with no `else`, so a\n * failed save changed nothing on screen and said nothing. The worker presses the button again.\n *\n * The caller keeps its success path and stops carrying the failure one:\n *\n * const outcome = await ranMutation(() => client.mutate({ … }))\n * if (!outcome.ok) return\n * … what to do when it worked …\n *\n * A save the screen shows is a MutationController instead (ADR-0190); it keeps its failure as `error`, and the\n * screen says it with `sayFailure(mutationOutcome(save.error))`.\n */\nexport async function ranMutation(run: () => Promise<any>): Promise<MutationOutcome> {\n let outcome: MutationOutcome\n\n try {\n outcome = outcomeOf(await run())\n } catch (thrown) {\n outcome = outcomeOfThrow(thrown)\n }\n\n if (!outcome.ok) {\n sayFailure(outcome)\n }\n\n return outcome\n}\n\n/**\n * One sentence per kind of failure.\n *\n * `said` is the server's own sentence and only the last kind prints it — for the other two this\n * side knows what happened and can say what to do about it. Telling someone whose session expired\n * to ask an administrator for a privilege would send them where nobody can help.\n */\nexport function sayFailure(outcome: MutationOutcome) {\n if (outcome.ok) {\n return\n }\n\n const key = outcomeKey(outcome)\n\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: i18next.t(key, { said: outcome.said || '' })\n }\n })\n )\n\n console.error(`[worklist] ${outcome.kind} — ${outcome.said}`)\n}\n"]}
@@ -15,9 +15,8 @@ export declare function registerPersonOpenWorkSection(): void;
15
15
  export declare class PersonOpenWorkSection extends LitElement {
16
16
  static styles: import("lit").CSSResult;
17
17
  subject?: Entity360Subject;
18
- answer?: Entity360DoorAnswer<OpenWork | null>;
19
- updated(changed: Map<string, unknown>): void;
20
- private read;
18
+ private openWork;
19
+ get answer(): Entity360DoorAnswer<OpenWork | null> | undefined;
21
20
  render(): import("lit-html").TemplateResult<1>;
22
21
  }
23
22
  export {};
@@ -1,10 +1,10 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import gql from 'graphql-tag';
3
3
  import { css, html, LitElement } from 'lit';
4
- import { customElement, property, state } from 'lit/decorators.js';
5
- import { client } from '@operato/graphql';
4
+ import { customElement, property } from 'lit/decorators.js';
5
+ import { QueryController } from '@operato/graphql';
6
6
  import { i18next } from '@operato/i18n';
7
- import { readEntity360Door, registerEntity360Section } from '@operato/layout';
7
+ import { entity360Answer, registerEntity360Section } from '@operato/layout';
8
8
  export function registerPersonOpenWorkSection() {
9
9
  registerEntity360Section('person', {
10
10
  name: 'open-work',
@@ -13,6 +13,18 @@ export function registerPersonOpenWorkSection() {
13
13
  });
14
14
  }
15
15
  let PersonOpenWorkSection = class PersonOpenWorkSection extends LitElement {
16
+ constructor() {
17
+ super(...arguments);
18
+ /* The counts for the person shown (ADR-0190). */
19
+ this.openWork = new QueryController(this, gql `
20
+ query ($userId: String!) {
21
+ personOpenWork(userId: $userId) {
22
+ toDos
23
+ approvalsPending
24
+ }
25
+ }
26
+ `, { variables: () => (this.subject?.id ? { userId: this.subject.id } : undefined) });
27
+ }
16
28
  static { this.styles = css `
17
29
  p {
18
30
  margin: 0;
@@ -21,30 +33,8 @@ let PersonOpenWorkSection = class PersonOpenWorkSection extends LitElement {
21
33
  font-variant-numeric: tabular-nums;
22
34
  }
23
35
  `; }
24
- updated(changed) {
25
- if (changed.has('subject'))
26
- this.read();
27
- }
28
- async read() {
29
- const id = this.subject?.id;
30
- this.answer = undefined;
31
- if (!id)
32
- return;
33
- const response = await client.query({
34
- query: gql `
35
- query ($userId: String!) {
36
- personOpenWork(userId: $userId) {
37
- toDos
38
- approvalsPending
39
- }
40
- }
41
- `,
42
- variables: { userId: id }
43
- });
44
- /* A later subject may have arrived while this one was being read. */
45
- if (this.subject?.id !== id)
46
- return;
47
- this.answer = readEntity360Door(response, data => data?.personOpenWork ?? null);
36
+ get answer() {
37
+ return entity360Answer(this.openWork, data => data?.personOpenWork ?? null);
48
38
  }
49
39
  render() {
50
40
  const answer = this.answer;
@@ -68,10 +58,6 @@ __decorate([
68
58
  property({ attribute: false }),
69
59
  __metadata("design:type", Object)
70
60
  ], PersonOpenWorkSection.prototype, "subject", void 0);
71
- __decorate([
72
- state(),
73
- __metadata("design:type", Object)
74
- ], PersonOpenWorkSection.prototype, "answer", void 0);
75
61
  PersonOpenWorkSection = __decorate([
76
62
  customElement('person-open-work-section')
77
63
  ], PersonOpenWorkSection);
@@ -1 +1 @@
1
- {"version":3,"file":"person-open-work-section.js","sourceRoot":"","sources":["../../client/entity360/person-open-work-section.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAmD,MAAM,iBAAiB,CAAA;AAY9H,MAAM,UAAU,6BAA6B;IAC3C,wBAAwB,CAAC,QAAQ,EAAE;QACjC,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,CAAA,sCAAsC,OAAO,8BAA8B;KACnG,CAAC,CAAA;AACJ,CAAC;AAGM,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,UAAU;aAC5C,WAAM,GAAG,GAAG,CAAA;;;;;;;GAOlB,AAPY,CAOZ;IAKD,OAAO,CAAC,OAA6B;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,IAAI,CAAC,IAAI,EAAE,CAAA;IACzC,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,CAAA;QAC3B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAA;QACvB,IAAI,CAAC,EAAE;YAAE,OAAM;QAEf,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;OAOT;YACD,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;SAC1B,CAAC,CAAA;QAEF,qEAAqE;QACrE,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE;YAAE,OAAM;QACnC,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,IAAI,IAAI,CAAC,CAAA;IACjF,CAAC;IAED,MAAM;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAA;QAEzB,OAAO,IAAI,CAAA;iBACE,OAAO,CAAC,CAAC,CAAC,wBAAwB,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;eACpE,MAAM,EAAE,KAAK,IAAI,SAAS;iBACxB,MAAM,EAAE,OAAO,IAAI,EAAE;;;UAG5B,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE;YACnC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,EAAE,gBAAgB,IAAI,CAAC;YACtC,YAAY,EAAE,gDAAgD;SAC/D,CAAC;;4BAEkB,CAAA;IAC1B,CAAC;;AA9C+B;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;sDAA2B;AACjD;IAAR,KAAK,EAAE;;qDAA8C;AAX3C,qBAAqB;IADjC,aAAa,CAAC,0BAA0B,CAAC;GAC7B,qBAAqB,CAyDjC","sourcesContent":["import gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { readEntity360Door, registerEntity360Section, type Entity360DoorAnswer, type Entity360Subject } from '@operato/layout'\n\n/**\n * The person 360's open-work section (ADR-0067 person 360 ruling, ADR-0091): how many to-dos are\n * assigned to the person and how many approvals are waiting on them - counts only. The items stay\n * with the person and the site owner; this section never lists them.\n *\n * `personOpenWork` answers null for someone who is not on this site - 「없음」, not zero.\n */\n\ntype OpenWork = { toDos: number; approvalsPending: number }\n\nexport function registerPersonOpenWorkSection() {\n registerEntity360Section('person', {\n name: 'open-work',\n order: 20,\n render: subject => html`<person-open-work-section .subject=${subject}></person-open-work-section>`\n })\n}\n\n@customElement('person-open-work-section')\nexport class PersonOpenWorkSection extends LitElement {\n static styles = css`\n p {\n margin: 0;\n font: 13px/1.5 sans-serif;\n color: var(--md-sys-color-on-surface);\n font-variant-numeric: tabular-nums;\n }\n `\n\n @property({ attribute: false }) subject?: Entity360Subject\n @state() answer?: Entity360DoorAnswer<OpenWork | null>\n\n updated(changed: Map<string, unknown>) {\n if (changed.has('subject')) this.read()\n }\n\n private async read() {\n const id = this.subject?.id\n this.answer = undefined\n if (!id) return\n\n const response = await client.query({\n query: gql`\n query ($userId: String!) {\n personOpenWork(userId: $userId) {\n toDos\n approvalsPending\n }\n }\n `,\n variables: { userId: id }\n })\n\n /* A later subject may have arrived while this one was being read. */\n if (this.subject?.id !== id) return\n this.answer = readEntity360Door(response, data => data?.personOpenWork ?? null)\n }\n\n render() {\n const answer = this.answer\n const work = answer?.data\n\n return html`<ox-entity360-section\n .heading=${i18next.t('title.person-open-work', { defaultValue: 'open work' })}\n .state=${answer?.state ?? 'loading'}\n .message=${answer?.message ?? ''}\n >\n <p>\n ${i18next.t('text.person-open-work', {\n toDos: work?.toDos ?? 0,\n approvals: work?.approvalsPending ?? 0,\n defaultValue: 'to-dos {toDos} · approvals waiting {approvals}'\n })}\n </p>\n </ox-entity360-section>`\n }\n}\n"]}
1
+ {"version":3,"file":"person-open-work-section.js","sourceRoot":"","sources":["../../client/entity360/person-open-work-section.ts"],"names":[],"mappings":";AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAmD,MAAM,iBAAiB,CAAA;AAY5H,MAAM,UAAU,6BAA6B;IAC3C,wBAAwB,CAAC,QAAQ,EAAE;QACjC,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,CAAA,sCAAsC,OAAO,8BAA8B;KACnG,CAAC,CAAA;AACJ,CAAC;AAGM,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,UAAU;IAA9C;;QAYL,iDAAiD;QACzC,aAAQ,GAAG,IAAI,eAAe,CACpC,IAAI,EACJ,GAAG,CAAA;;;;;;;KAOF,EACD,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAClF,CAAA;IAwBH,CAAC;aA/CQ,WAAM,GAAG,GAAG,CAAA;;;;;;;GAOlB,AAPY,CAOZ;IAkBD,IAAI,MAAM;QACR,OAAO,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,IAAI,IAAI,CAAC,CAAA;IAC7E,CAAC;IAED,MAAM;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAA;QAEzB,OAAO,IAAI,CAAA;iBACE,OAAO,CAAC,CAAC,CAAC,wBAAwB,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;eACpE,MAAM,EAAE,KAAK,IAAI,SAAS;iBACxB,MAAM,EAAE,OAAO,IAAI,EAAE;;;UAG5B,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE;YACnC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,EAAE,gBAAgB,IAAI,CAAC;YACtC,YAAY,EAAE,gDAAgD;SAC/D,CAAC;;4BAEkB,CAAA;IAC1B,CAAC;;AArC+B;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;sDAA2B;AAV/C,qBAAqB;IADjC,aAAa,CAAC,0BAA0B,CAAC;GAC7B,qBAAqB,CAgDjC","sourcesContent":["import gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { QueryController } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { entity360Answer, registerEntity360Section, type Entity360DoorAnswer, type Entity360Subject } from '@operato/layout'\n\n/**\n * The person 360's open-work section (ADR-0067 person 360 ruling, ADR-0091): how many to-dos are\n * assigned to the person and how many approvals are waiting on them - counts only. The items stay\n * with the person and the site owner; this section never lists them.\n *\n * `personOpenWork` answers null for someone who is not on this site - 「없음」, not zero.\n */\n\ntype OpenWork = { toDos: number; approvalsPending: number }\n\nexport function registerPersonOpenWorkSection() {\n registerEntity360Section('person', {\n name: 'open-work',\n order: 20,\n render: subject => html`<person-open-work-section .subject=${subject}></person-open-work-section>`\n })\n}\n\n@customElement('person-open-work-section')\nexport class PersonOpenWorkSection extends LitElement {\n static styles = css`\n p {\n margin: 0;\n font: 13px/1.5 sans-serif;\n color: var(--md-sys-color-on-surface);\n font-variant-numeric: tabular-nums;\n }\n `\n\n @property({ attribute: false }) subject?: Entity360Subject\n\n /* The counts for the person shown (ADR-0190). */\n private openWork = new QueryController(\n this,\n gql`\n query ($userId: String!) {\n personOpenWork(userId: $userId) {\n toDos\n approvalsPending\n }\n }\n `,\n { variables: () => (this.subject?.id ? { userId: this.subject.id } : undefined) }\n )\n\n get answer(): Entity360DoorAnswer<OpenWork | null> | undefined {\n return entity360Answer(this.openWork, data => data?.personOpenWork ?? null)\n }\n\n render() {\n const answer = this.answer\n const work = answer?.data\n\n return html`<ox-entity360-section\n .heading=${i18next.t('title.person-open-work', { defaultValue: 'open work' })}\n .state=${answer?.state ?? 'loading'}\n .message=${answer?.message ?? ''}\n >\n <p>\n ${i18next.t('text.person-open-work', {\n toDos: work?.toDos ?? 0,\n approvals: work?.approvalsPending ?? 0,\n defaultValue: 'to-dos {toDos} · approvals waiting {approvals}'\n })}\n </p>\n </ox-entity360-section>`\n }\n}\n"]}
@@ -14,8 +14,6 @@ export declare class ActivityListPage extends ActivityListPage_base {
14
14
  mode: 'CARD' | 'GRID';
15
15
  grist: DataGrist;
16
16
  filters: string[];
17
- /** How many activities each state chip would show under the list's other conditions. */
18
- stateCounts: Map<string, number>;
19
17
  private roleOptions;
20
18
  get context(): {
21
19
  title: string;
@@ -41,6 +39,10 @@ export declare class ActivityListPage extends ActivityListPage_base {
41
39
  };
42
40
  render(): import("lit-html").TemplateResult<1>;
43
41
  pageInitialized(lifecycle: any): Promise<void>;
42
+ /** How many activities each state chip would show under the list's other conditions. */
43
+ countHandler({ filters, signal }: FetchOption): Promise<{
44
+ state: Record<string, number>;
45
+ }>;
44
46
  fetchHandler({ page, limit, sortings, filters }: FetchOption): Promise<{
45
47
  total: any;
46
48
  records: any;
@@ -27,8 +27,6 @@ let ActivityListPage = class ActivityListPage extends localize(i18next)(PageView
27
27
  super(...arguments);
28
28
  this.mode = isMobileDevice() ? 'CARD' : 'GRID';
29
29
  this.filters = ['released'];
30
- /** How many activities each state chip would show under the list's other conditions. */
31
- this.stateCounts = new Map();
32
30
  /* This domain's roles, for the pool column - read once when the page opens. */
33
31
  this.roleOptions = [];
34
32
  }
@@ -68,7 +66,7 @@ let ActivityListPage = class ActivityListPage extends localize(i18next)(PageView
68
66
  render() {
69
67
  const mode = this.mode;
70
68
  return html `
71
- <ox-grist class="page-fill" .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
69
+ <ox-grist class="page-fill" .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)} .countHandler=${this.countHandler.bind(this)} @counts-change=${() => this.requestUpdate()}>
72
70
  <div slot="headroom" class="header">
73
71
  <div class="filters">
74
72
  <ox-input-select-buttons
@@ -83,7 +81,7 @@ let ActivityListPage = class ActivityListPage extends localize(i18next)(PageView
83
81
  { display: i18next.t('label.filter-deprecated'),
84
82
  value: 'deprecated'
85
83
  }
86
- ].map(chip => ({ ...chip, count: this.stateCounts.get(chip.value) ?? 0 }))}
84
+ ].map(chip => ({ ...chip, count: this.grist?.counts?.state?.[chip.value] ?? 0 }))}
87
85
  @change=${(e) => {
88
86
  this.filters = e.currentTarget?.value;
89
87
  this.grist.fetch();
@@ -394,10 +392,11 @@ let ActivityListPage = class ActivityListPage extends localize(i18next)(PageView
394
392
  }
395
393
  ] };
396
394
  }
395
+ /** How many activities each state chip would show under the list's other conditions. */
396
+ async countHandler({ filters = [], signal }) {
397
+ return { state: await activityStateCounts(filters, signal) };
398
+ }
397
399
  async fetchHandler({ page, limit, sortings = [], filters = [] }) {
398
- activityStateCounts(filters)
399
- .then(counts => (this.stateCounts = counts))
400
- .catch(e => console.error(e));
401
400
  const status = ['draft', 'released', 'deprecated'].filter(state => this.filters?.includes(state));
402
401
  if (status.length > 0) {
403
402
  filters = adjustFilters(filters, [{ name: 'state', operator: 'in', value: status }]);
@@ -589,10 +588,6 @@ __decorate([
589
588
  state(),
590
589
  __metadata("design:type", Array)
591
590
  ], ActivityListPage.prototype, "filters", void 0);
592
- __decorate([
593
- state(),
594
- __metadata("design:type", Object)
595
- ], ActivityListPage.prototype, "stateCounts", void 0);
596
591
  ActivityListPage = __decorate([
597
592
  customElement('activity-list-page')
598
593
  ], ActivityListPage);