@verdocs/web-sdk 2.3.23 → 2.3.24

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 (64) hide show
  1. package/dist/cjs/{TemplateStore-6a75cdac.js → TemplateStore-079a1f85.js} +22 -0
  2. package/dist/cjs/ipc-test.cjs.entry.js +1 -1
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/verdocs-build.cjs.entry.js +7 -3
  5. package/dist/cjs/verdocs-portal_2.cjs.entry.js +1 -1
  6. package/dist/cjs/verdocs-preview_8.cjs.entry.js +1 -1
  7. package/dist/cjs/verdocs-template-fields_4.cjs.entry.js +132 -153
  8. package/dist/cjs/verdocs-web-sdk.cjs.js +1 -1
  9. package/dist/collection/components/embeds/verdocs-build/verdocs-build.js +29 -2
  10. package/dist/collection/components/templates/verdocs-template-fields/verdocs-template-fields.js +18 -11
  11. package/dist/collection/components/templates/verdocs-template-role-properties/verdocs-template-role-properties.js +46 -44
  12. package/dist/collection/components/templates/verdocs-template-roles/verdocs-template-roles.js +78 -104
  13. package/dist/collection/utils/TemplateRoleStore.js +19 -0
  14. package/dist/collection/utils/TemplateStore.js +4 -1
  15. package/dist/components/TemplateStore.js +21 -1
  16. package/dist/components/verdocs-build.js +6 -2
  17. package/dist/components/verdocs-template-fields2.js +18 -12
  18. package/dist/components/verdocs-template-role-properties2.js +46 -45
  19. package/dist/components/verdocs-template-roles2.js +74 -101
  20. package/dist/docs.json +16 -7
  21. package/dist/esm/{TemplateStore-3994341c.js → TemplateStore-1ee18675.js} +21 -1
  22. package/dist/esm/ipc-test.entry.js +1 -1
  23. package/dist/esm/loader.js +1 -1
  24. package/dist/esm/verdocs-build.entry.js +7 -3
  25. package/dist/esm/verdocs-portal_2.entry.js +1 -1
  26. package/dist/esm/verdocs-preview_8.entry.js +1 -1
  27. package/dist/esm/verdocs-template-fields_4.entry.js +133 -154
  28. package/dist/esm/verdocs-web-sdk.js +1 -1
  29. package/dist/esm-es5/TemplateStore-1ee18675.js +1 -0
  30. package/dist/esm-es5/ipc-test.entry.js +1 -1
  31. package/dist/esm-es5/loader.js +1 -1
  32. package/dist/esm-es5/verdocs-build.entry.js +1 -1
  33. package/dist/esm-es5/verdocs-portal_2.entry.js +1 -1
  34. package/dist/esm-es5/verdocs-preview_8.entry.js +1 -1
  35. package/dist/esm-es5/verdocs-template-fields_4.entry.js +1 -1
  36. package/dist/esm-es5/verdocs-web-sdk.js +1 -1
  37. package/dist/types/components/embeds/verdocs-build/verdocs-build.d.ts +11 -1
  38. package/dist/types/components/templates/verdocs-template-fields/verdocs-template-fields.d.ts +3 -1
  39. package/dist/types/components/templates/verdocs-template-role-properties/verdocs-template-role-properties.d.ts +7 -3
  40. package/dist/types/components/templates/verdocs-template-roles/verdocs-template-roles.d.ts +13 -10
  41. package/dist/types/components.d.ts +8 -4
  42. package/dist/types/utils/TemplateRoleStore.d.ts +6 -0
  43. package/dist/verdocs-web-sdk/{p-e7ea9726.entry.js → p-00e49c36.entry.js} +1 -1
  44. package/dist/verdocs-web-sdk/p-0bfc239a.system.js +1 -0
  45. package/dist/verdocs-web-sdk/p-2720068f.system.entry.js +1 -0
  46. package/dist/verdocs-web-sdk/p-4fc74ab1.js +1 -0
  47. package/dist/verdocs-web-sdk/{p-07f0bcae.entry.js → p-5361ee8f.entry.js} +1 -1
  48. package/dist/verdocs-web-sdk/p-6ada9427.entry.js +1 -0
  49. package/dist/verdocs-web-sdk/p-7f2f79fa.entry.js +1 -0
  50. package/dist/verdocs-web-sdk/{p-929760fd.system.entry.js → p-9f46a6a9.system.entry.js} +1 -1
  51. package/dist/verdocs-web-sdk/{p-040620ca.system.entry.js → p-b54467df.system.entry.js} +1 -1
  52. package/dist/verdocs-web-sdk/{p-5a05140d.system.entry.js → p-b86c345f.system.entry.js} +1 -1
  53. package/dist/verdocs-web-sdk/{p-8f8db3aa.entry.js → p-cb429454.entry.js} +1 -1
  54. package/dist/verdocs-web-sdk/p-e080e371.system.entry.js +1 -0
  55. package/dist/verdocs-web-sdk/p-f04bf956.system.js +1 -1
  56. package/dist/verdocs-web-sdk/verdocs-web-sdk.esm.js +1 -1
  57. package/package.json +1 -1
  58. package/dist/esm-es5/TemplateStore-3994341c.js +0 -1
  59. package/dist/verdocs-web-sdk/p-0cf7f778.system.entry.js +0 -1
  60. package/dist/verdocs-web-sdk/p-79fcaf1e.system.entry.js +0 -1
  61. package/dist/verdocs-web-sdk/p-a98b0097.system.js +0 -1
  62. package/dist/verdocs-web-sdk/p-cee90f53.entry.js +0 -1
  63. package/dist/verdocs-web-sdk/p-d1837af9.entry.js +0 -1
  64. package/dist/verdocs-web-sdk/p-fc2454b0.js +0 -1
@@ -4,6 +4,7 @@ import { getRGBA } from '@verdocs/js-sdk/Utils/Colors';
4
4
  import { createRole, updateRole } from '@verdocs/js-sdk/Templates/Roles';
5
5
  import { TemplateSenderTypes } from '@verdocs/js-sdk/Templates/Types';
6
6
  import { h, Fragment, Host } from '@stencil/core';
7
+ import { getTemplateRoleStore } from '../../../utils/TemplateRoleStore';
7
8
  import { getTemplateStore } from '../../../utils/TemplateStore';
8
9
  import { getRoleIndex } from '../../../utils/utils';
9
10
  import { SDKError } from '../../../utils/errors';
@@ -27,8 +28,8 @@ const iconCC = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill
27
28
  */
28
29
  export class VerdocsTemplateRoles {
29
30
  constructor() {
30
- this.sequences = [];
31
- this.store = null;
31
+ this.templateStore = null;
32
+ this.roleStore = null;
32
33
  this.endpoint = VerdocsEndpoint.getDefault();
33
34
  this.templateId = '';
34
35
  this.showingRoleDialog = null;
@@ -47,18 +48,14 @@ export class VerdocsTemplateRoles {
47
48
  console.log('[ROLES] Unable to start builder session, must be authenticated');
48
49
  return;
49
50
  }
50
- await this.reloadStore();
51
+ this.templateStore = await getTemplateStore(this.endpoint, this.templateId, false);
52
+ this.roleStore = getTemplateRoleStore(this.templateId);
51
53
  }
52
54
  catch (e) {
53
55
  console.log('[FIELDS] Error with preview session', e);
54
56
  (_a = this.sdkError) === null || _a === void 0 ? void 0 : _a.emit(new SDKError(e.message, (_b = e.response) === null || _b === void 0 ? void 0 : _b.status, (_c = e.response) === null || _c === void 0 ? void 0 : _c.data));
55
57
  }
56
58
  }
57
- async reloadStore() {
58
- this.store = await getTemplateStore(this.endpoint, this.templateId, false);
59
- this.sortTemplateRoles();
60
- this.renumberTemplateRoles();
61
- }
62
59
  componentDidRender() {
63
60
  interact.dynamicDrop(true);
64
61
  interact('.recipient').draggable({
@@ -68,64 +65,45 @@ export class VerdocsTemplateRoles {
68
65
  this.el.classList.add('dragging');
69
66
  }.bind(this),
70
67
  move: function handleMove(e) {
71
- const oldX = +(e.target.getAttribute('posX') || 0);
72
- const oldY = +(e.target.getAttribute('posY') || 0);
68
+ const oldX = +(e.target.getAttribute('dX') || 0);
69
+ const oldY = +(e.target.getAttribute('dY') || 0);
70
+ const sequence = +(e.target.dataset['sequence'] || 0);
73
71
  const newX = e.dx + oldX;
74
72
  const newY = e.dy + oldY;
75
- e.target.setAttribute('posX', newX);
76
- e.target.setAttribute('posy', newY);
77
- e.target.style.transform = `translate(${newX + 100}px, ${newY - 40}px)`;
73
+ e.target.setAttribute('dX', newX);
74
+ e.target.setAttribute('dY', newY);
75
+ const rect = e.target.getBoundingClientRect();
76
+ // Note: I never did figure out exactly why this is, but if we don't offset the transform
77
+ // the dragged item is offset from the mouse cursor quite a bit.
78
+ e.target.style.transform = `translate(${newX + 80}px, ${newY - rect.height * sequence}px)`;
78
79
  }.bind(this),
79
80
  end: function handleEnd(e) {
80
81
  e.target.classList.remove('dragging');
81
82
  this.el.classList.remove('dragging');
82
83
  // console.log('end', event);
83
- e.target.setAttribute('posX', 0);
84
- e.target.setAttribute('posy', 0);
85
- e.target.style.transform = `translate(0px, 0px)`;
84
+ e.target.removeAttribute('dX');
85
+ e.target.removeAttribute('dY');
86
+ e.target.style.transform = null;
86
87
  }.bind(this),
87
88
  },
88
89
  });
89
90
  interact('.dropzone').dropzone({
90
91
  overlap: 0.05,
91
- ondrop: function handleDrop(event) {
92
- var _a, _b, _c, _d, _e;
92
+ ondrop: async function handleDrop(event) {
93
+ var _a;
93
94
  event.target.classList.remove('active');
94
- // target will be the recipient e.g. <div class="recipient" data-rolename="Buyer" />
95
- // relatedTarget will be the drop zone, e.g. <div class="dropzone" data-order="2" data-sequence="1" />
96
- // console.log(event.relatedTarget, ' was dropped into ', event.target);
97
- // We don't use the role's own order, we rely on the fact that we sorted earlier on the order field. Many legacy
98
- // records don't have order fields yet - they're all 1. That doesn't hurt the sort but it would hurt us here if it
99
- // went 1..1..1 instead of 1..2..3. By using half values here it's easier to handle the drop event later. We don't
100
- // need to do a fancy find/arraymove dance. We just set the dropped element to the half value, sort the result,
101
- // then do a final renumber. It's not expensive to do because most flows are typically a small handful (e.g. 1-4)
102
- // recipients. They never have hundreds.
103
95
  const roleName = event.relatedTarget.dataset.rolename;
104
96
  const targetSequence = +event.target.dataset.sequence;
105
97
  const targetOrder = +event.target.dataset.order;
106
- const changingRole = (_c = (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles) === null || _c === void 0 ? void 0 : _c.find(role => role.name === roleName);
98
+ const changingRole = this.roleStore.get(roleName);
107
99
  if (changingRole) {
108
100
  // To handle the renumbering, we update the role being moved to the new values, which will be some half-interval e.g.
109
- // sequence 1.5 order 1. Then we
110
- changingRole.sequence = targetSequence;
111
- changingRole.order = targetOrder;
112
- this.sortTemplateRoles();
113
- this.renumberTemplateRoles();
114
- this.forceRerender++;
115
- // We have to update ALL the roles to be sure each gets new proper sequence/order numbers assigned.
116
- // TODO: We could optimize this by tracking "dirty" states and only update the roles that have changed. But it's a LOT more
117
- // code to do right, and since most workflows will typically only have 2-4 recipients max, it may not be worth it.
118
- Promise.all((_e = (_d = this.store) === null || _d === void 0 ? void 0 : _d.state) === null || _e === void 0 ? void 0 : _e.roles.map(role => updateRole(this.endpoint, this.templateId, role.name, {
119
- sequence: role.sequence,
120
- order: role.order,
121
- })))
122
- .then(() => {
123
- var _a, _b;
124
- console.log('[ROLES] Updated roles');
125
- (_a = this.templateUpdated) === null || _a === void 0 ? void 0 : _a.emit({ event: 'updated-role', endpoint: this.endpoint, template: (_b = this.store) === null || _b === void 0 ? void 0 : _b.state });
126
- this.reloadStore().catch(e => console.log('Unknown error', e));
127
- })
128
- .catch(e => console.log('[ROLES] Role updates failed', e));
101
+ // sequence 1.5 order 1. Then we sort/renumber the roles at each level to determine their final ordering values.
102
+ const newRole = { ...changingRole, sequence: targetSequence, order: targetOrder };
103
+ this.roleStore.set(changingRole.name, newRole);
104
+ await this.renumberTemplateRoles();
105
+ (_a = this.rolesUpdated) === null || _a === void 0 ? void 0 : _a.emit({ event: 'updated', endpoint: this.endpoint, templateId: this.templateId, roles: this.getSortedRoles() });
106
+ console.log('[ROLES] Updated roles', this.getSortedRoles());
129
107
  }
130
108
  }.bind(this),
131
109
  ondropactivate: e => {
@@ -150,50 +128,60 @@ export class VerdocsTemplateRoles {
150
128
  var _a;
151
129
  (_a = this.next) === null || _a === void 0 ? void 0 : _a.emit();
152
130
  }
153
- sortTemplateRoles() {
154
- var _a, _b;
155
- (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles.sort((a, b) => {
131
+ getSortedRoles() {
132
+ return Object.values(this.roleStore.state)
133
+ .filter(role => role !== undefined)
134
+ .sort((a, b) => {
156
135
  return a.sequence === b.sequence ? a.order - b.order : a.sequence - b.sequence;
157
136
  });
158
137
  }
159
- extractSequenceNumbers() {
160
- var _a, _b;
161
- this.sequences = [];
162
- (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles.forEach(role => {
163
- if (!this.sequences.includes(role.sequence)) {
164
- this.sequences.push(role.sequence);
138
+ getSequenceNumbers() {
139
+ const sequences = [];
140
+ this.getSortedRoles().forEach(role => {
141
+ if (!sequences.includes(role.sequence)) {
142
+ sequences.push(role.sequence);
165
143
  }
166
144
  });
145
+ return sequences.sort((a, b) => a - b);
146
+ }
147
+ getRoleNames() {
148
+ const roles = this.getSortedRoles();
149
+ return roles.map(role => role.name);
150
+ }
151
+ getRolesAtSequence(sequence) {
152
+ // Entries can be undefined when deleted because Stencil has no remove() operator yet for stores.
153
+ // See https://github.com/ionic-team/stencil-store/issues/23
154
+ return Object.values(this.roleStore.state).filter(role => role && role.sequence === sequence);
167
155
  }
156
+ // When the user drags a role around, we handle placement "between" items by assigning it a half-order number
157
+ // e.g. 1.5 to place it between items 1 and 2, 0.5 to place it at the beginning, or last+0.5 to place it at the end.
158
+ // Then we re-sort the list of roles and renumber them.
168
159
  renumberTemplateRoles() {
169
- // Extract the sequence numbers because they may now be something like [2.5, 1, 2]
170
- this.extractSequenceNumbers();
171
- // We need to renumber each role only ONE TIME
160
+ // Avoid dupe renumber attempts
172
161
  const renumbered = [];
173
162
  // If the user dragged an entry from below a row to above it, we end up here like [1,0]. Make sure it's [0,1] for the next operation.
174
- this.sequences.sort((a, b) => a - b);
175
- this.sequences.forEach((originalSequence, newSequenceIndex) => {
176
- var _a, _b;
177
- (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles.filter(role => role.sequence === originalSequence).forEach((role, newOrderIndex) => {
163
+ const renumberRequests = [];
164
+ this.getSequenceNumbers().forEach((originalSequence, newSequenceIndex) => {
165
+ this.getRolesAtSequence(originalSequence).forEach((role, newOrderIndex) => {
178
166
  if (!renumbered.includes(role.name)) {
179
167
  role.sequence = newSequenceIndex + 1;
180
168
  role.order = newOrderIndex + 1;
181
169
  renumbered.push(role.name);
170
+ renumberRequests.push(updateRole(this.endpoint, this.templateId, role.name, { sequence: role.sequence, order: role.order }));
182
171
  }
183
172
  });
184
173
  });
185
- // Now re-extract them to get our final result e.g. [1, 2, 3]
186
- this.extractSequenceNumbers();
174
+ return Promise.all(renumberRequests);
187
175
  }
188
176
  // Look for name conflicts, because they're UGC and can be anything, regardless of order.
189
177
  getNextRoleName() {
190
- var _a, _b, _c, _d;
178
+ var _a;
191
179
  let name = '';
192
- let nextNumber = (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles.length;
180
+ let nextNumber = Object.keys(this.roleStore).length;
193
181
  do {
194
182
  nextNumber++;
195
183
  name = `Recipient ${nextNumber}`;
196
- } while (!name || ((_d = (_c = this.store) === null || _c === void 0 ? void 0 : _c.state) === null || _d === void 0 ? void 0 : _d.roles.some(role => role.name === name)));
184
+ } while (!name || Object.values((_a = this.roleStore) === null || _a === void 0 ? void 0 : _a.state).some(role => role && role.name === name));
197
185
  return name;
198
186
  }
199
187
  callCreateRole(name, sequence, order) {
@@ -210,25 +198,19 @@ export class VerdocsTemplateRoles {
210
198
  delegator: false,
211
199
  })
212
200
  .then(async (r) => {
213
- var _a, _b;
201
+ var _a;
214
202
  console.log('[ROLES] Created role', r);
215
- this.store = await getTemplateStore(this.endpoint, this.templateId, false);
216
- this.sortTemplateRoles();
217
- this.renumberTemplateRoles();
218
- // this.store.state.roles = [...this.store?.state.roles, r];
219
- // this.renumberTemplateRoles();
220
- (_a = this.templateUpdated) === null || _a === void 0 ? void 0 : _a.emit({ event: 'created-role', endpoint: this.endpoint, template: (_b = this.store) === null || _b === void 0 ? void 0 : _b.state });
221
- this.reloadStore().catch(e => console.log('Unknown error', e));
203
+ this.roleStore.set(r.name, r);
204
+ await this.renumberTemplateRoles();
205
+ (_a = this.rolesUpdated) === null || _a === void 0 ? void 0 : _a.emit({ event: 'added', endpoint: this.endpoint, templateId: this.templateId, roles: this.getSortedRoles() });
222
206
  })
223
207
  .catch(e => {
224
208
  console.log('[ROLES] Error creating role', e);
225
209
  });
226
210
  }
227
211
  handleAddRole(e, sequence) {
228
- var _a;
229
212
  e.stopPropagation();
230
- // We don't need to look for a unique order number because we're already working with a sorted/renumbered set by now.
231
- const order = ((_a = this.store) === null || _a === void 0 ? void 0 : _a.state.roles.filter(role => role.sequence === sequence).length) + 1;
213
+ const order = this.getRolesAtSequence(sequence).length + 1;
232
214
  const name = this.getNextRoleName();
233
215
  this.callCreateRole(name, sequence, order);
234
216
  }
@@ -239,33 +221,25 @@ export class VerdocsTemplateRoles {
239
221
  this.callCreateRole(name, sequence, order);
240
222
  }
241
223
  render() {
242
- var _a, _b, _c, _d, _e, _f;
243
- console.log('[ROLES] Rendering');
224
+ var _a, _b, _c;
244
225
  if (!this.endpoint.session) {
245
226
  return (h(Host, null, h("verdocs-component-error", { message: "You must be authenticated to use this module." })));
246
227
  }
247
- if (!((_a = this.store) === null || _a === void 0 ? void 0 : _a.state.isLoaded)) {
228
+ if (!((_a = this.templateStore) === null || _a === void 0 ? void 0 : _a.state.isLoaded)) {
248
229
  return (h(Host, { class: "loading" }, h("verdocs-loader", null)));
249
230
  }
250
- const roleNames = (((_c = (_b = this.store) === null || _b === void 0 ? void 0 : _b.state) === null || _c === void 0 ? void 0 : _c.roles) || []).map(role => role.name);
251
- return (h(Host, null, h("form", { onSubmit: e => e.preventDefault(), onClick: e => e.stopPropagation(), autocomplete: "off", "data-r": (_d = this.store.state) === null || _d === void 0 ? void 0 : _d.updateCount }, h("h5", null, "Roles and Workflow"), h("div", { class: "participants" }, h("div", { class: "left-line" }), h("div", { class: "row" }, h("div", { class: "icon", innerHTML: startIcon }), h("div", { class: "row-roles" }, h("div", { class: "sender" }, h("span", { class: "label" }, "Sender:"), " ", senderLabels[(_f = (_e = this.store) === null || _e === void 0 ? void 0 : _e.state) === null || _f === void 0 ? void 0 : _f.sender], ' ', h("div", { class: "settings-button", innerHTML: settingsIcon, onClick: () => (this.showingSenderDialog = true), "aria-role": "button" })))), h("div", { class: "row add-sequence", "data-sequence": 0 }, h("div", { class: "icon", innerHTML: plusIcon }), h("div", { class: "row-roles" }, h("div", { class: "dropzone", "data-sequence": 0, "data-order": 1 }, "Add Step"))), this.sequences.map(sequence => {
252
- var _a, _b;
253
- return (h(Fragment, null, h("div", { class: "row" }, h("div", { class: "icon", innerHTML: stepIcon }), h("div", { class: "row-roles" }, h("div", { class: "dropzone", "data-order": 0.5, "data-sequence": sequence }), (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 :
254
- _b.roles.filter(role => role.sequence === sequence).map(role => {
255
- const unknown = !role.email;
256
- return unknown ? (h(Fragment, null, h("div", { class: "recipient", style: { backgroundColor: getRGBA(getRoleIndex(roleNames, role.name)) }, "data-rolename": role.name }, h("span", { class: "type-icon", innerHTML: role.type === 'signer' ? iconSigner : role.type === 'cc' ? iconCC : iconApprover }), role.name, " ", h("div", { class: "settings-button", innerHTML: settingsIcon, onClick: () => (this.showingRoleDialog = role.name), "aria-role": "button" })), h("div", { class: "dropzone", "data-order": role.order + 0.5, "data-sequence": sequence }))) : (h(Fragment, null, h("div", { class: "recipient", style: { borderColor: getRGBA(getRoleIndex(roleNames, role.name)) }, "data-rolename": role.name }, h("span", { class: "type-icon", innerHTML: role.type === 'signer' ? iconSigner : role.type === 'cc' ? iconCC : iconApprover }), role.full_name, " ", h("div", { class: "settings-button", innerHTML: settingsIcon, onClick: () => (this.showingRoleDialog = role.name), "aria-role": "button" })), h("div", { class: "dropzone", "data-order": role.order + 0.5, "data-sequence": sequence })));
257
- }), h("button", { class: "add-role", innerHTML: plusIcon, onClick: e => this.handleAddRole(e, sequence) }))), this.sequences.length > 0 && (h("div", { class: "row add-sequence", "data-sequence": sequence }, h("div", { class: "row-roles" }, h("div", { class: "icon", innerHTML: plusIcon }), h("div", { class: "dropzone", "data-sequence": sequence + 1, "data-order": 1 }, "Add Step"))))));
258
- }), h("div", { class: "row", "data-sequence": this.sequences.length + 1 }, h("div", { class: "row-roles" }, h("div", { class: "icon", innerHTML: plusIcon }), h("button", { class: "add-step", innerHTML: plusIcon, onClick: e => this.handleAddStep(e, this.sequences.length + 1) }))), h("div", { class: "row" }, h("div", { class: "icon", innerHTML: doneIcon }), h("div", { class: "row-roles" }, h("div", { class: "complete" }, "Document Complete")))), roleNames.length < 1 && (h("div", { class: "empty" }, "You must add at least one Role before proceeding.", h("br", null), " Click the ", h("span", { innerHTML: plusIcon }), " Add button above to get started.")), h("div", { class: "buttons" }, h("div", { class: "flex-fill" }), h("verdocs-button", { variant: "outline", label: "Cancel", size: "small", onClick: () => this.handleCancel() }), h("verdocs-button", { label: "OK", size: "small", onClick: () => this.handleSubmit(), disabled: roleNames.length < 1 }))), this.showingRoleDialog && (h("verdocs-template-role-properties", { endpoint: this.endpoint, templateId: this.templateId, roleName: this.showingRoleDialog, onClose: () => {
231
+ const roleNames = this.getRoleNames();
232
+ const sequences = this.getSequenceNumbers();
233
+ return (h(Host, null, h("form", { onSubmit: e => e.preventDefault(), onClick: e => e.stopPropagation(), autocomplete: "off" }, h("h5", null, "Roles and Workflow"), h("div", { class: "participants" }, h("div", { class: "left-line" }), h("div", { class: "row" }, h("div", { class: "icon", innerHTML: startIcon }), h("div", { class: "row-roles" }, h("div", { class: "sender" }, h("span", { class: "label" }, "Sender:"), " ", senderLabels[(_c = (_b = this.templateStore) === null || _b === void 0 ? void 0 : _b.state) === null || _c === void 0 ? void 0 : _c.sender], ' ', h("div", { class: "settings-button", innerHTML: settingsIcon, onClick: () => (this.showingSenderDialog = true), "aria-role": "button" })))), h("div", { class: "row add-sequence", "data-sequence": 0 }, h("div", { class: "icon", innerHTML: plusIcon }), h("div", { class: "row-roles" }, h("div", { class: "dropzone", "data-sequence": 0, "data-order": 1 }, "Add Step"))), sequences.map(sequence => (h(Fragment, null, h("div", { class: "row" }, h("div", { class: "icon", innerHTML: stepIcon }), h("div", { class: "row-roles" }, h("div", { class: "dropzone", "data-order": 0.5, "data-sequence": sequence }), this.getRolesAtSequence(sequence).map(role => {
234
+ const unknown = !role.email;
235
+ return unknown ? (h(Fragment, null, h("div", { class: "recipient", style: { backgroundColor: getRGBA(getRoleIndex(roleNames, role.name)) }, "data-rolename": role.name, "data-sequence": sequence }, h("span", { class: "type-icon", innerHTML: role.type === 'signer' ? iconSigner : role.type === 'cc' ? iconCC : iconApprover }), role.name, " ", h("div", { class: "settings-button", innerHTML: settingsIcon, onClick: () => (this.showingRoleDialog = role.name), "aria-role": "button" })), h("div", { class: "dropzone", "data-order": role.order + 0.5, "data-sequence": sequence }))) : (h(Fragment, null, h("div", { class: "recipient", style: { borderColor: getRGBA(getRoleIndex(roleNames, role.name)) }, "data-rolename": role.name, "data-sequence": sequence }, h("span", { class: "type-icon", innerHTML: role.type === 'signer' ? iconSigner : role.type === 'cc' ? iconCC : iconApprover }), role.full_name, " ", h("div", { class: "settings-button", innerHTML: settingsIcon, onClick: () => (this.showingRoleDialog = role.name), "aria-role": "button" })), h("div", { class: "dropzone", "data-order": role.order + 0.5, "data-sequence": sequence })));
236
+ }), h("button", { class: "add-role", innerHTML: plusIcon, onClick: e => this.handleAddRole(e, sequence) }))), sequences.length > 0 && (h("div", { class: "row add-sequence", "data-sequence": sequence }, h("div", { class: "row-roles" }, h("div", { class: "icon", innerHTML: plusIcon }), h("div", { class: "dropzone", "data-sequence": sequence + 1, "data-order": 1 }, "Add Step"))))))), h("div", { class: "row", "data-sequence": sequences.length + 1 }, h("div", { class: "row-roles" }, h("div", { class: "icon", innerHTML: plusIcon }), h("button", { class: "add-step", innerHTML: plusIcon, onClick: e => this.handleAddStep(e, sequences.length + 1) }))), h("div", { class: "row" }, h("div", { class: "icon", innerHTML: doneIcon }), h("div", { class: "row-roles" }, h("div", { class: "complete" }, "Document Complete")))), roleNames.length < 1 && (h("div", { class: "empty" }, "You must add at least one Role before proceeding.", h("br", null), " Click the ", h("span", { innerHTML: plusIcon }), " Add button above to get started.")), h("div", { class: "buttons" }, h("div", { class: "flex-fill" }), h("verdocs-button", { variant: "outline", label: "Cancel", size: "small", onClick: () => this.handleCancel() }), h("verdocs-button", { label: "OK", size: "small", onClick: () => this.handleSubmit(), disabled: roleNames.length < 1 }))), this.showingRoleDialog && (h("verdocs-template-role-properties", { endpoint: this.endpoint, templateId: this.templateId, roleName: this.showingRoleDialog, onClose: () => {
259
237
  this.showingRoleDialog = null;
260
- // this.forceRerender++;
261
238
  }, onDelete: async () => {
262
- var _a, _b;
263
- await getTemplateStore(this.endpoint, this.templateId, false);
264
- this.renumberTemplateRoles();
239
+ var _a;
265
240
  this.showingRoleDialog = null;
266
- // this.forceRerender++;
267
- (_a = this.templateUpdated) === null || _a === void 0 ? void 0 : _a.emit({ event: 'deleted-role', endpoint: this.endpoint, template: (_b = this.store) === null || _b === void 0 ? void 0 : _b.state });
268
- this.reloadStore().catch(e => console.log('Unknown error', e));
241
+ await this.renumberTemplateRoles();
242
+ (_a = this.rolesUpdated) === null || _a === void 0 ? void 0 : _a.emit({ event: 'deleted', endpoint: this.endpoint, templateId: this.templateId, roles: this.getSortedRoles() });
269
243
  } })), this.showingSenderDialog && h("verdocs-template-sender", { endpoint: this.endpoint, templateId: this.templateId, onClose: () => (this.showingSenderDialog = false) })));
270
244
  }
271
245
  static get is() { return "verdocs-template-roles"; }
@@ -381,8 +355,8 @@ export class VerdocsTemplateRoles {
381
355
  }
382
356
  }
383
357
  }, {
384
- "method": "templateUpdated",
385
- "name": "templateUpdated",
358
+ "method": "rolesUpdated",
359
+ "name": "rolesUpdated",
386
360
  "bubbles": true,
387
361
  "cancelable": true,
388
362
  "composed": true,
@@ -391,14 +365,14 @@ export class VerdocsTemplateRoles {
391
365
  "text": "Event fired when the template is updated in any way. May be used for tasks such as cache invalidation or reporting to other systems."
392
366
  },
393
367
  "complexType": {
394
- "original": "{endpoint: VerdocsEndpoint; template: ITemplate; event: string}",
395
- "resolved": "{ endpoint: VerdocsEndpoint; template: ITemplate; event: string; }",
368
+ "original": "{endpoint: VerdocsEndpoint; templateId: string; event: 'added' | 'deleted' | 'updated'; roles: IRole[]}",
369
+ "resolved": "{ endpoint: VerdocsEndpoint; templateId: string; event: \"added\" | \"deleted\" | \"updated\"; roles: IRole[]; }",
396
370
  "references": {
397
371
  "VerdocsEndpoint": {
398
372
  "location": "import",
399
373
  "path": "@verdocs/js-sdk"
400
374
  },
401
- "ITemplate": {
375
+ "IRole": {
402
376
  "location": "import",
403
377
  "path": "@verdocs/js-sdk/Templates/Types"
404
378
  }
@@ -0,0 +1,19 @@
1
+ import { createStore } from '@stencil/store';
2
+ const templateRoleStores = {};
3
+ export const getTemplateRoleStore = (templateId) => templateRoleStores[templateId];
4
+ export const createTemplateRoleStore = (template) => {
5
+ let store = getTemplateRoleStore(template.id);
6
+ if (!store) {
7
+ console.log('Creating template role store for template', template.id);
8
+ store = createStore({});
9
+ templateRoleStores[template.id] = store;
10
+ }
11
+ else {
12
+ console.log('Resetting template role store for template', template.id);
13
+ store.reset();
14
+ }
15
+ template.roles.forEach(role => {
16
+ store.set(role.name, role);
17
+ });
18
+ return store;
19
+ };
@@ -2,6 +2,7 @@ import { createStore } from '@stencil/store';
2
2
  import { getTemplate } from '@verdocs/js-sdk/Templates/Templates';
3
3
  import { TemplateSenderTypes } from '@verdocs/js-sdk/Templates/Types';
4
4
  import { createTemplateFieldStore, getTemplateFieldStore } from './TemplateFieldStore';
5
+ import { createTemplateRoleStore, getTemplateRoleStore } from './TemplateRoleStore';
5
6
  const createTemplateStore = (templateId) => {
6
7
  const now = new Date().toISOString();
7
8
  return createStore({
@@ -69,6 +70,7 @@ export const getTemplateStore = async (endpoint, templateId, forceReload = false
69
70
  store.state.isLoaded = true;
70
71
  store.state.isError = false;
71
72
  store.state.error = undefined;
73
+ createTemplateRoleStore(template);
72
74
  createTemplateFieldStore(template);
73
75
  }
74
76
  catch (e) {
@@ -82,7 +84,8 @@ export const getTemplateStore = async (endpoint, templateId, forceReload = false
82
84
  store.state.updateCount++;
83
85
  }
84
86
  else {
85
- // Just make sure it exists
87
+ // Just make sure they exist
88
+ getTemplateRoleStore(templateId);
86
89
  getTemplateFieldStore(templateId);
87
90
  }
88
91
  return store;
@@ -2,6 +2,25 @@ import { c as createStore } from './index4.js';
2
2
  import { g as getTemplate, b as TemplateSenderTypes } from './VerdocsEndpoint.js';
3
3
  import { a as createTemplateFieldStore } from './TemplateFieldStore.js';
4
4
 
5
+ const templateRoleStores = {};
6
+ const getTemplateRoleStore = (templateId) => templateRoleStores[templateId];
7
+ const createTemplateRoleStore = (template) => {
8
+ let store = getTemplateRoleStore(template.id);
9
+ if (!store) {
10
+ console.log('Creating template role store for template', template.id);
11
+ store = createStore({});
12
+ templateRoleStores[template.id] = store;
13
+ }
14
+ else {
15
+ console.log('Resetting template role store for template', template.id);
16
+ store.reset();
17
+ }
18
+ template.roles.forEach(role => {
19
+ store.set(role.name, role);
20
+ });
21
+ return store;
22
+ };
23
+
5
24
  const createTemplateStore = (templateId) => {
6
25
  const now = new Date().toISOString();
7
26
  return createStore({
@@ -69,6 +88,7 @@ const getTemplateStore = async (endpoint, templateId, forceReload = false) => {
69
88
  store.state.isLoaded = true;
70
89
  store.state.isError = false;
71
90
  store.state.error = undefined;
91
+ createTemplateRoleStore(template);
72
92
  createTemplateFieldStore(template);
73
93
  }
74
94
  catch (e) {
@@ -85,4 +105,4 @@ const getTemplateStore = async (endpoint, templateId, forceReload = false) => {
85
105
  };
86
106
  const getRoleNames = (store) => { var _a; return (((_a = store === null || store === void 0 ? void 0 : store.state) === null || _a === void 0 ? void 0 : _a.roles) || []).map(role => role.name); };
87
107
 
88
- export { getRoleNames as a, getTemplateStore as g };
108
+ export { getRoleNames as a, getTemplateRoleStore as b, createTemplateRoleStore as c, getTemplateStore as g };
@@ -45,6 +45,7 @@ const VerdocsBuild$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
45
45
  this.send = createEvent(this, "send", 7);
46
46
  this.templateUpdated = createEvent(this, "templateUpdated", 7);
47
47
  this.templateCreated = createEvent(this, "templateCreated", 7);
48
+ this.rolesUpdated = createEvent(this, "rolesUpdated", 7);
48
49
  this.endpoint = VerdocsEndpoint.getDefault();
49
50
  this.templateId = null;
50
51
  this.step = 'preview';
@@ -96,9 +97,12 @@ const VerdocsBuild$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
96
97
  this.step = 'roles';
97
98
  (_a = this.stepChanged) === null || _a === void 0 ? void 0 : _a.emit('roles');
98
99
  }
100
+ async handleRolesUpdated(e) {
101
+ var _a;
102
+ (_a = this.templateUpdated) === null || _a === void 0 ? void 0 : _a.emit(e.detail);
103
+ }
99
104
  async handleTemplateUpdated(e) {
100
105
  var _a;
101
- console.log('tup');
102
106
  (_a = this.templateUpdated) === null || _a === void 0 ? void 0 : _a.emit(e.detail);
103
107
  }
104
108
  handleAttachmentsNext() {
@@ -126,7 +130,7 @@ const VerdocsBuild$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
126
130
  return (h(Host, null, h("div", { class: "content" }, h("verdocs-template-build-tabs", { endpoint: this.endpoint, templateId: this.templateId, step: "attachments", onSdkError: e => { var _a; return (_a = this.sdkError) === null || _a === void 0 ? void 0 : _a.emit(e.detail); }, onStepChanged: e => this.handleStepChanged(e.detail) }), h("verdocs-template-create", { endpoint: this.endpoint, onExit: e => this.handleCancel(e), onNext: () => this.handleAttachmentsNext(), onTemplateCreated: e => this.handleTemplateCreated(e.detail.templateId) }))));
127
131
  }
128
132
  console.log('[BUILD] Rendering build view', this.templateId, this.step, ['attachments', 'roles', 'settings', 'fields', 'preview'].indexOf(this.step));
129
- return (h(Host, null, h("div", { class: "content" }, h("verdocs-template-build-tabs", { endpoint: this.endpoint, templateId: this.templateId, step: this.step, onSdkError: e => { var _a; return (_a = this.sdkError) === null || _a === void 0 ? void 0 : _a.emit(e.detail); }, onStepChanged: e => this.handleStepChanged(e.detail) }), this.step === 'attachments' && (h("verdocs-template-attachments", { templateId: this.templateId, endpoint: this.endpoint, onExit: e => this.handleCancel(e), onNext: () => this.handleAttachmentsNext(), onTemplateUpdated: e => this.handleTemplateUpdated(e) })), this.step === 'roles' && (h("verdocs-template-roles", { templateId: this.templateId, endpoint: this.endpoint, onExit: e => this.handleCancel(e), onNext: () => this.handleRolesNext(), onTemplateUpdated: e => this.handleTemplateUpdated(e) })), this.step === 'settings' && (h("div", { style: { flexDirection: 'column', gap: '20px', display: 'flex', maxWidth: '400px', margin: '20px' } }, h("verdocs-template-name", { templateId: this.templateId, endpoint: this.endpoint, style: { backgroundColor: '#ffffff', padding: '20px' }, onTemplateUpdated: e => this.handleTemplateUpdated(e) }), h("verdocs-template-reminders", { templateId: this.templateId, endpoint: this.endpoint, style: { backgroundColor: '#ffffff', padding: '20px' }, onTemplateUpdated: e => this.handleTemplateUpdated(e) }), h("verdocs-template-visibility", { templateId: this.templateId, endpoint: this.endpoint, style: { backgroundColor: '#ffffff', padding: '20px' }, onTemplateUpdated: e => this.handleTemplateUpdated(e) }))), this.step === 'fields' && h("verdocs-template-fields", { templateId: this.templateId, endpoint: this.endpoint, onTemplateUpdated: e => this.handleTemplateUpdated(e) }), this.step === 'preview' && (h("div", { class: "preview-container" }, h("div", { class: "preview-send-wrapper" }, h("verdocs-send", { templateId: this.templateId, endpoint: this.endpoint, onSend: e => { var _a; return (_a = this.send) === null || _a === void 0 ? void 0 : _a.emit(e.detail); }, style: { width: '100%' } })), h("div", { class: "preview-preview-wrapper" }, h("verdocs-preview", { templateId: this.templateId, endpoint: this.endpoint, style: { display: 'flex', flex: '1', maxWidth: '1000px' } })))))));
133
+ return (h(Host, null, h("div", { class: "content" }, h("verdocs-template-build-tabs", { endpoint: this.endpoint, templateId: this.templateId, step: this.step, onSdkError: e => { var _a; return (_a = this.sdkError) === null || _a === void 0 ? void 0 : _a.emit(e.detail); }, onStepChanged: e => this.handleStepChanged(e.detail) }), this.step === 'attachments' && (h("verdocs-template-attachments", { templateId: this.templateId, endpoint: this.endpoint, onExit: e => this.handleCancel(e), onNext: () => this.handleAttachmentsNext(), onTemplateUpdated: e => this.handleTemplateUpdated(e) })), this.step === 'roles' && (h("verdocs-template-roles", { templateId: this.templateId, endpoint: this.endpoint, onExit: e => this.handleCancel(e), onNext: () => this.handleRolesNext(), onRolesUpdated: e => this.handleRolesUpdated(e) })), this.step === 'settings' && (h("div", { style: { flexDirection: 'column', gap: '20px', display: 'flex', maxWidth: '400px', margin: '20px' } }, h("verdocs-template-name", { templateId: this.templateId, endpoint: this.endpoint, style: { backgroundColor: '#ffffff', padding: '20px' }, onTemplateUpdated: e => this.handleTemplateUpdated(e) }), h("verdocs-template-reminders", { templateId: this.templateId, endpoint: this.endpoint, style: { backgroundColor: '#ffffff', padding: '20px' }, onTemplateUpdated: e => this.handleTemplateUpdated(e) }), h("verdocs-template-visibility", { templateId: this.templateId, endpoint: this.endpoint, style: { backgroundColor: '#ffffff', padding: '20px' }, onTemplateUpdated: e => this.handleTemplateUpdated(e) }))), this.step === 'fields' && h("verdocs-template-fields", { templateId: this.templateId, endpoint: this.endpoint, onTemplateUpdated: e => this.handleTemplateUpdated(e) }), this.step === 'preview' && (h("div", { class: "preview-container" }, h("div", { class: "preview-send-wrapper" }, h("verdocs-send", { templateId: this.templateId, endpoint: this.endpoint, onSend: e => { var _a; return (_a = this.send) === null || _a === void 0 ? void 0 : _a.emit(e.detail); }, style: { width: '100%' } })), h("div", { class: "preview-preview-wrapper" }, h("verdocs-preview", { templateId: this.templateId, endpoint: this.endpoint, style: { display: 'flex', flex: '1', maxWidth: '1000px' } })))))));
130
134
  }
131
135
  get el() { return this; }
132
136
  static get watchers() { return {
@@ -5,8 +5,8 @@ import { V as VerdocsEndpoint } from './VerdocsEndpoint.js';
5
5
  import { u as updateField, c as createField } from './Fields.js';
6
6
  import { i as integerSequence } from './Primitives.js';
7
7
  import { b as getRoleIndex, r as renderDocumentField, f as updateCssTransform, h as defaultWidth, i as defaultHeight } from './utils.js';
8
- import { a as createTemplateFieldStore } from './TemplateFieldStore.js';
9
- import { g as getTemplateStore, a as getRoleNames } from './TemplateStore.js';
8
+ import { g as getTemplateStore, b as getTemplateRoleStore, a as getRoleNames } from './TemplateStore.js';
9
+ import { g as getTemplateFieldStore } from './TemplateFieldStore.js';
10
10
  import { S as SDKError } from './errors.js';
11
11
  import { d as defineCustomElement$7 } from './verdocs-button2.js';
12
12
  import { d as defineCustomElement$6 } from './verdocs-component-error2.js';
@@ -53,6 +53,7 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
53
53
  this.pageHeights = {};
54
54
  this.templateStore = null;
55
55
  this.fieldStore = null;
56
+ this.roleStore = null;
56
57
  this.cachedPageInfo = {};
57
58
  this.endpoint = VerdocsEndpoint.getDefault();
58
59
  this.templateId = null;
@@ -74,7 +75,8 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
74
75
  return;
75
76
  }
76
77
  this.templateStore = await getTemplateStore(this.endpoint, this.templateId, false);
77
- this.fieldStore = createTemplateFieldStore(this.templateStore.state);
78
+ this.fieldStore = getTemplateFieldStore(this.templateId);
79
+ this.roleStore = getTemplateRoleStore(this.templateId);
78
80
  this.selectedRoleName = ((_d = (_c = (_b = (_a = this.templateStore) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.name) || '';
79
81
  }
80
82
  catch (e) {
@@ -93,10 +95,10 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
93
95
  }
94
96
  }
95
97
  componentWillUpdate() {
96
- var _a, _b, _c, _d, _e, _f;
98
+ var _a, _b, _c, _d;
97
99
  // If a new role was added and there were none yet so far, or the "selected" role was deleted, reset our selection
98
- if (!this.selectedRoleName || !(((_b = (_a = this.templateStore) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles) || []).find(role => role.name === this.selectedRoleName)) {
99
- this.selectedRoleName = ((_f = (_e = (_d = (_c = this.templateStore) === null || _c === void 0 ? void 0 : _c.state) === null || _d === void 0 ? void 0 : _d.roles) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.name) || '';
100
+ if (!this.selectedRoleName || !Object.values(this.roleStore).find(role => role && role.name === this.selectedRoleName)) {
101
+ this.selectedRoleName = ((_d = (_c = (_b = (_a = this.templateStore) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.roles) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.name) || '';
100
102
  console.log('[FIELDS] Selected new role', this.selectedRoleName);
101
103
  }
102
104
  }
@@ -155,7 +157,9 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
155
157
  // console.log('[FIELDS] Page rendered', pageInfo.pageNumber, pageInfo);
156
158
  this.cachedPageInfo[pageInfo.pageNumber] = pageInfo;
157
159
  this.pageHeights[pageInfo.pageNumber] = pageInfo.naturalHeight;
158
- const fields = Object.values(this.fieldStore.state).filter((field) => field.page_sequence === pageInfo.pageNumber);
160
+ // Entries can be undefined when deleted because Stencil has no remove() operator yet for stores.
161
+ // See https://github.com/ionic-team/stencil-store/issues/23
162
+ const fields = Object.values(this.fieldStore.state).filter((field) => field && field.page_sequence === pageInfo.pageNumber);
159
163
  console.log('[FIELDS] Page rendered', pageInfo, fields);
160
164
  fields.forEach((field) => this.reRenderField(field, pageInfo.pageNumber));
161
165
  }
@@ -253,7 +257,7 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
253
257
  do {
254
258
  fieldName = `${type}P${pageNumber}-${i}`;
255
259
  i++;
256
- } while (Object.values(this.fieldStore.state).some(field => field.name === fieldName));
260
+ } while (Object.values(this.fieldStore.state).some(field => field && field.name === fieldName));
257
261
  return fieldName;
258
262
  }
259
263
  // Scale the X,Y clicks to the virtual page dimensions. Also ensure the field doesn't go off the page.
@@ -365,7 +369,7 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
365
369
  }
366
370
  }
367
371
  render() {
368
- var _a, _b, _c, _d, _e, _f, _g, _h;
372
+ var _a, _b, _c;
369
373
  if (!this.endpoint.session) {
370
374
  return (h(Host, null, h("verdocs-component-error", { message: "You must be authenticated to use this module." })));
371
375
  }
@@ -373,7 +377,9 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
373
377
  if (!((_a = this.templateStore) === null || _a === void 0 ? void 0 : _a.state.isLoaded)) {
374
378
  return (h(Host, null, h("verdocs-loader", null)));
375
379
  }
376
- const selectableRoles = (_c = (_b = this.templateStore) === null || _b === void 0 ? void 0 : _b.state) === null || _c === void 0 ? void 0 : _c.roles.map(role => ({ value: role.name, label: role.name }));
380
+ const selectableRoles = Object.values(this.roleStore)
381
+ .filter(role => role !== undefined)
382
+ .map(role => ({ value: role.name, label: role.name }));
377
383
  return (h(Host, { class: this.placing ? { [`placing-${this.placing}`]: true } : {}, onSubmit: () => { } }, h("div", { id: "verdocs-template-fields-toolbar" }, h("div", { class: "add-for" }, "Add field:"), h("verdocs-select-input", { value: this.selectedRoleName, options: selectableRoles, onInput: (e) => (this.selectedRoleName = e.target.value) }), menuOptions.map(option => (h("verdocs-toolbar-icon", { text: option.tooltip, icon: option.icon, onClick: () => {
378
384
  // We ignore empty-tooltip entries because they're separators
379
385
  if (option.tooltip) {
@@ -385,13 +391,13 @@ const VerdocsTemplateFields = /*@__PURE__*/ proxyCustomElement(class extends HTM
385
391
  this.showMustSelectRole = true;
386
392
  }
387
393
  }
388
- } })))), h("div", { class: "pages" }, (((_e = (_d = this.templateStore) === null || _d === void 0 ? void 0 : _d.state) === null || _e === void 0 ? void 0 : _e.template_documents) || []).map(document => {
394
+ } })))), h("div", { class: "pages" }, (((_c = (_b = this.templateStore) === null || _b === void 0 ? void 0 : _b.state) === null || _c === void 0 ? void 0 : _c.template_documents) || []).map(document => {
389
395
  const pageNumbers = integerSequence(1, document.page_numbers);
390
396
  return pageNumbers.map(page => (h("verdocs-template-document-page", { templateId: this.templateId, documentId: document.id, pageNumber: page, virtualWidth: 612, virtualHeight: 792, onClick: (e) => this.handleClickPage(e, page), onPageRendered: e => this.handlePageRendered(e), layers: [
391
397
  { name: 'page', type: 'canvas' },
392
398
  { name: 'controls', type: 'div' },
393
399
  ] })));
394
- })), this.showMustSelectRole && (h("verdocs-ok-dialog", { heading: "Unable to add field", message: ((_h = (_g = (_f = this.templateStore) === null || _f === void 0 ? void 0 : _f.state) === null || _g === void 0 ? void 0 : _g.roles) === null || _h === void 0 ? void 0 : _h.length) > 0 ? 'Please select a role before adding fields.' : 'Please add at least one role before adding fields.', onNext: () => (this.showMustSelectRole = false) }))));
400
+ })), this.showMustSelectRole && (h("verdocs-ok-dialog", { heading: "Unable to add field", message: Object.keys(this.roleStore).length > 0 ? 'Please select a role before adding fields.' : 'Please add at least one role before adding fields.', onNext: () => (this.showMustSelectRole = false) }))));
395
401
  }
396
402
  static get style() { return verdocsTemplateFieldsCss; }
397
403
  }, [0, "verdocs-template-fields", {