terrier-engine 4.74.0 → 4.75.1

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 (288) hide show
  1. package/package.json +1 -1
  2. package/terrier/api-subscriber.ts +1 -1
  3. package/terrier/gen/hub-icons.ts +50 -2
  4. package/terrier/images/icons/active.svg +1 -1
  5. package/terrier/images/icons/admin.svg +1 -1
  6. package/terrier/images/icons/archive.svg +1 -1
  7. package/terrier/images/icons/arrow_down.svg +1 -1
  8. package/terrier/images/icons/arrow_left.svg +1 -1
  9. package/terrier/images/icons/arrow_right.svg +1 -1
  10. package/terrier/images/icons/arrow_up.svg +1 -1
  11. package/terrier/images/icons/assign.svg +1 -1
  12. package/terrier/images/icons/attachment.svg +1 -1
  13. package/terrier/images/icons/back.svg +1 -1
  14. package/terrier/images/icons/badge.svg +1 -1
  15. package/terrier/images/icons/board.svg +1 -1
  16. package/terrier/images/icons/bookmark.svg +1 -1
  17. package/terrier/images/icons/bookmark_add.svg +1 -1
  18. package/terrier/images/icons/bookmark_remove.svg +1 -1
  19. package/terrier/images/icons/bookmarked.svg +1 -1
  20. package/terrier/images/icons/bookmarks.svg +1 -1
  21. package/terrier/images/icons/branch.svg +1 -1
  22. package/terrier/images/icons/bug.svg +1 -1
  23. package/terrier/images/icons/calculator.svg +1 -1
  24. package/terrier/images/icons/checkmark.svg +1 -1
  25. package/terrier/images/icons/close.svg +1 -1
  26. package/terrier/images/icons/clypboard.svg +1 -1
  27. package/terrier/images/icons/comment.svg +1 -1
  28. package/terrier/images/icons/complete.svg +1 -1
  29. package/terrier/images/icons/cool.svg +1 -0
  30. package/terrier/images/icons/dashboard.svg +1 -1
  31. package/terrier/images/icons/data_pull.svg +1 -1
  32. package/terrier/images/icons/data_update.svg +1 -1
  33. package/terrier/images/icons/database.svg +1 -1
  34. package/terrier/images/icons/day.svg +1 -1
  35. package/terrier/images/icons/delete.svg +1 -1
  36. package/terrier/images/icons/documentation.svg +1 -1
  37. package/terrier/images/icons/edit.svg +1 -1
  38. package/terrier/images/icons/existing_child.svg +1 -1
  39. package/terrier/images/icons/existing_parent.svg +1 -1
  40. package/terrier/images/icons/feature.svg +1 -1
  41. package/terrier/images/icons/flex.svg +1 -1
  42. package/terrier/images/icons/forward.svg +1 -1
  43. package/terrier/images/icons/github.svg +1 -1
  44. package/terrier/images/icons/heart.svg +1 -0
  45. package/terrier/images/icons/history.svg +1 -1
  46. package/terrier/images/icons/home.svg +1 -1
  47. package/terrier/images/icons/hundred.svg +1 -1
  48. package/terrier/images/icons/image.svg +1 -1
  49. package/terrier/images/icons/inbox.svg +1 -1
  50. package/terrier/images/icons/info.svg +1 -1
  51. package/terrier/images/icons/internal.svg +1 -1
  52. package/terrier/images/icons/issue.svg +1 -1
  53. package/terrier/images/icons/lane.svg +1 -1
  54. package/terrier/images/icons/lane_asap.svg +1 -1
  55. package/terrier/images/icons/lane_days.svg +1 -1
  56. package/terrier/images/icons/lane_hours.svg +1 -1
  57. package/terrier/images/icons/lane_weeks.svg +1 -1
  58. package/terrier/images/icons/lanes_board.svg +1 -1
  59. package/terrier/images/icons/level_complete.svg +1 -1
  60. package/terrier/images/icons/level_highway.svg +1 -1
  61. package/terrier/images/icons/level_on_ramp.svg +1 -1
  62. package/terrier/images/icons/level_parking.svg +1 -1
  63. package/terrier/images/icons/link.svg +1 -1
  64. package/terrier/images/icons/list_view.svg +1 -1
  65. package/terrier/images/icons/lol.svg +1 -1
  66. package/terrier/images/icons/metrics.svg +1 -1
  67. package/terrier/images/icons/minus.svg +1 -1
  68. package/terrier/images/icons/new_child.svg +1 -1
  69. package/terrier/images/icons/new_parent.svg +1 -1
  70. package/terrier/images/icons/night.svg +1 -1
  71. package/terrier/images/icons/origin.svg +1 -1
  72. package/terrier/images/icons/owner.svg +1 -0
  73. package/terrier/images/icons/pending.svg +1 -1
  74. package/terrier/images/icons/plot.svg +1 -1
  75. package/terrier/images/icons/plus.svg +1 -1
  76. package/terrier/images/icons/post.svg +1 -1
  77. package/terrier/images/icons/posts.svg +1 -1
  78. package/terrier/images/icons/pr_closed.svg +1 -1
  79. package/terrier/images/icons/pr_merged.svg +1 -1
  80. package/terrier/images/icons/pr_open.svg +1 -1
  81. package/terrier/images/icons/prioritized.svg +1 -1
  82. package/terrier/images/icons/private.svg +1 -1
  83. package/terrier/images/icons/project.svg +1 -1
  84. package/terrier/images/icons/public.svg +1 -1
  85. package/terrier/images/icons/question.svg +1 -1
  86. package/terrier/images/icons/recent.svg +1 -1
  87. package/terrier/images/icons/refresh.svg +1 -1
  88. package/terrier/images/icons/related_posts.svg +1 -1
  89. package/terrier/images/icons/releases.svg +1 -1
  90. package/terrier/images/icons/request.svg +1 -1
  91. package/terrier/images/icons/sad.svg +1 -0
  92. package/terrier/images/icons/settings.svg +1 -1
  93. package/terrier/images/icons/smile.svg +1 -0
  94. package/terrier/images/icons/split_view.svg +1 -1
  95. package/terrier/images/icons/status.svg +1 -1
  96. package/terrier/images/icons/step_demo.svg +1 -1
  97. package/terrier/images/icons/step_deploy.svg +1 -1
  98. package/terrier/images/icons/step_develop.svg +1 -1
  99. package/terrier/images/icons/step_investigate.svg +1 -1
  100. package/terrier/images/icons/step_none.svg +1 -1
  101. package/terrier/images/icons/step_required.svg +1 -1
  102. package/terrier/images/icons/step_review.svg +1 -1
  103. package/terrier/images/icons/step_test.svg +1 -1
  104. package/terrier/images/icons/steps.svg +1 -1
  105. package/terrier/images/icons/steps_board.svg +1 -1
  106. package/terrier/images/icons/subscribe.svg +1 -1
  107. package/terrier/images/icons/support.svg +1 -1
  108. package/terrier/images/icons/surprised.svg +1 -0
  109. package/terrier/images/icons/team.svg +1 -1
  110. package/terrier/images/icons/terrier.svg +1 -1
  111. package/terrier/images/icons/type.svg +1 -1
  112. package/terrier/images/icons/unprioritized.svg +1 -1
  113. package/terrier/images/icons/upload.svg +1 -1
  114. package/terrier/images/icons/upvote.svg +1 -1
  115. package/terrier/images/icons/user.svg +1 -1
  116. package/terrier/images/icons/users.svg +1 -1
  117. package/terrier/images/icons/website.svg +1 -1
  118. package/terrier/images/icons/week.svg +1 -1
  119. package/terrier/images/optimized/badge-accounts_payable.svg +1 -1
  120. package/terrier/images/optimized/badge-accounts_receivable.svg +1 -1
  121. package/terrier/images/optimized/badge-applicator_license.svg +1 -1
  122. package/terrier/images/optimized/badge-autopay.svg +1 -1
  123. package/terrier/images/optimized/badge-bats.svg +1 -1
  124. package/terrier/images/optimized/badge-clypboard_hardware.svg +1 -1
  125. package/terrier/images/optimized/badge-clypboard_project.svg +1 -1
  126. package/terrier/images/optimized/badge-clypmart.svg +1 -1
  127. package/terrier/images/optimized/badge-commercial.svg +1 -1
  128. package/terrier/images/optimized/badge-compliance.svg +1 -1
  129. package/terrier/images/optimized/badge-contracts.svg +1 -1
  130. package/terrier/images/optimized/badge-copesan.svg +1 -1
  131. package/terrier/images/optimized/badge-credit_card.svg +1 -1
  132. package/terrier/images/optimized/badge-customer_call.svg +1 -1
  133. package/terrier/images/optimized/badge-customer_text.svg +1 -1
  134. package/terrier/images/optimized/badge-employee_data.svg +1 -1
  135. package/terrier/images/optimized/badge-finance.svg +1 -1
  136. package/terrier/images/optimized/badge-fleet.svg +1 -1
  137. package/terrier/images/optimized/badge-fumigation.svg +1 -1
  138. package/terrier/images/optimized/badge-information_technology.svg +1 -1
  139. package/terrier/images/optimized/badge-irrigation.svg +1 -1
  140. package/terrier/images/optimized/badge-landscape.svg +1 -1
  141. package/terrier/images/optimized/badge-marketing.svg +1 -1
  142. package/terrier/images/optimized/badge-mergers_and_acquisitions.svg +1 -1
  143. package/terrier/images/optimized/badge-multi_housing.svg +1 -1
  144. package/terrier/images/optimized/badge-payroll.svg +1 -1
  145. package/terrier/images/optimized/badge-pest.svg +1 -1
  146. package/terrier/images/optimized/badge-pro.svg +1 -1
  147. package/terrier/images/optimized/badge-program.svg +1 -1
  148. package/terrier/images/optimized/badge-proposals.svg +1 -1
  149. package/terrier/images/optimized/badge-residential.svg +1 -1
  150. package/terrier/images/optimized/badge-sales.svg +1 -1
  151. package/terrier/images/optimized/badge-scripts.svg +1 -1
  152. package/terrier/images/optimized/badge-termite.svg +1 -1
  153. package/terrier/images/optimized/badge-wildlife.svg +1 -1
  154. package/terrier/images/optimized/badge_role-admin.svg +1 -1
  155. package/terrier/images/optimized/badge_role-handling.svg +1 -1
  156. package/terrier/images/optimized/badge_role-management.svg +1 -1
  157. package/terrier/images/optimized/badge_role-ops.svg +1 -1
  158. package/terrier/images/optimized/badge_role-reporting.svg +1 -1
  159. package/terrier/images/optimized/badge_role-sales.svg +1 -1
  160. package/terrier/images/optimized/icon-active.svg +1 -1
  161. package/terrier/images/optimized/icon-admin.svg +1 -1
  162. package/terrier/images/optimized/icon-archive.svg +1 -1
  163. package/terrier/images/optimized/icon-arrow_down.svg +1 -1
  164. package/terrier/images/optimized/icon-arrow_left.svg +1 -1
  165. package/terrier/images/optimized/icon-arrow_right.svg +1 -1
  166. package/terrier/images/optimized/icon-arrow_up.svg +1 -1
  167. package/terrier/images/optimized/icon-assign.svg +1 -1
  168. package/terrier/images/optimized/icon-attachment.svg +1 -1
  169. package/terrier/images/optimized/icon-back.svg +1 -1
  170. package/terrier/images/optimized/icon-badge.svg +1 -1
  171. package/terrier/images/optimized/icon-board.svg +1 -1
  172. package/terrier/images/optimized/icon-bookmark.svg +1 -1
  173. package/terrier/images/optimized/icon-bookmark_add.svg +1 -1
  174. package/terrier/images/optimized/icon-bookmark_remove.svg +1 -1
  175. package/terrier/images/optimized/icon-bookmarked.svg +1 -1
  176. package/terrier/images/optimized/icon-bookmarks.svg +1 -1
  177. package/terrier/images/optimized/icon-branch.svg +1 -1
  178. package/terrier/images/optimized/icon-bug.svg +1 -1
  179. package/terrier/images/optimized/icon-calculator.svg +1 -1
  180. package/terrier/images/optimized/icon-checkmark.svg +1 -1
  181. package/terrier/images/optimized/icon-close.svg +1 -1
  182. package/terrier/images/optimized/icon-clypboard.svg +1 -1
  183. package/terrier/images/optimized/icon-comment.svg +1 -1
  184. package/terrier/images/optimized/icon-complete.svg +1 -1
  185. package/terrier/images/optimized/icon-cool.svg +1 -0
  186. package/terrier/images/optimized/icon-dashboard.svg +1 -1
  187. package/terrier/images/optimized/icon-data_pull.svg +1 -1
  188. package/terrier/images/optimized/icon-data_update.svg +1 -1
  189. package/terrier/images/optimized/icon-database.svg +1 -1
  190. package/terrier/images/optimized/icon-day.svg +1 -1
  191. package/terrier/images/optimized/icon-delete.svg +1 -1
  192. package/terrier/images/optimized/icon-documentation.svg +1 -1
  193. package/terrier/images/optimized/icon-edit.svg +1 -1
  194. package/terrier/images/optimized/icon-existing_child.svg +1 -1
  195. package/terrier/images/optimized/icon-existing_parent.svg +1 -1
  196. package/terrier/images/optimized/icon-feature.svg +1 -1
  197. package/terrier/images/optimized/icon-flex.svg +1 -1
  198. package/terrier/images/optimized/icon-forward.svg +1 -1
  199. package/terrier/images/optimized/icon-github.svg +1 -1
  200. package/terrier/images/optimized/icon-heart.svg +1 -0
  201. package/terrier/images/optimized/icon-history.svg +1 -1
  202. package/terrier/images/optimized/icon-home.svg +1 -1
  203. package/terrier/images/optimized/icon-hundred.svg +1 -1
  204. package/terrier/images/optimized/icon-image.svg +1 -1
  205. package/terrier/images/optimized/icon-inbox.svg +1 -1
  206. package/terrier/images/optimized/icon-info.svg +1 -1
  207. package/terrier/images/optimized/icon-internal.svg +1 -1
  208. package/terrier/images/optimized/icon-issue.svg +1 -1
  209. package/terrier/images/optimized/icon-lane.svg +1 -1
  210. package/terrier/images/optimized/icon-lane_asap.svg +1 -1
  211. package/terrier/images/optimized/icon-lane_days.svg +1 -1
  212. package/terrier/images/optimized/icon-lane_hours.svg +1 -1
  213. package/terrier/images/optimized/icon-lane_weeks.svg +1 -1
  214. package/terrier/images/optimized/icon-lanes_board.svg +1 -1
  215. package/terrier/images/optimized/icon-level_complete.svg +1 -1
  216. package/terrier/images/optimized/icon-level_highway.svg +1 -1
  217. package/terrier/images/optimized/icon-level_on_ramp.svg +1 -1
  218. package/terrier/images/optimized/icon-level_parking.svg +1 -1
  219. package/terrier/images/optimized/icon-link.svg +1 -1
  220. package/terrier/images/optimized/icon-list_view.svg +1 -1
  221. package/terrier/images/optimized/icon-lol.svg +1 -1
  222. package/terrier/images/optimized/icon-metrics.svg +1 -1
  223. package/terrier/images/optimized/icon-minus.svg +1 -1
  224. package/terrier/images/optimized/icon-new_child.svg +1 -1
  225. package/terrier/images/optimized/icon-new_parent.svg +1 -1
  226. package/terrier/images/optimized/icon-night.svg +1 -1
  227. package/terrier/images/optimized/icon-origin.svg +1 -1
  228. package/terrier/images/optimized/icon-owner.svg +1 -0
  229. package/terrier/images/optimized/icon-pending.svg +1 -1
  230. package/terrier/images/optimized/icon-plot.svg +1 -1
  231. package/terrier/images/optimized/icon-plus.svg +1 -1
  232. package/terrier/images/optimized/icon-post.svg +1 -1
  233. package/terrier/images/optimized/icon-posts.svg +1 -1
  234. package/terrier/images/optimized/icon-pr_closed.svg +1 -1
  235. package/terrier/images/optimized/icon-pr_merged.svg +1 -1
  236. package/terrier/images/optimized/icon-pr_open.svg +1 -1
  237. package/terrier/images/optimized/icon-prioritized.svg +1 -1
  238. package/terrier/images/optimized/icon-private.svg +1 -1
  239. package/terrier/images/optimized/icon-project.svg +1 -1
  240. package/terrier/images/optimized/icon-public.svg +1 -1
  241. package/terrier/images/optimized/icon-question.svg +1 -1
  242. package/terrier/images/optimized/icon-recent.svg +1 -1
  243. package/terrier/images/optimized/icon-refresh.svg +1 -1
  244. package/terrier/images/optimized/icon-related_posts.svg +1 -1
  245. package/terrier/images/optimized/icon-releases.svg +1 -1
  246. package/terrier/images/optimized/icon-request.svg +1 -1
  247. package/terrier/images/optimized/icon-sad.svg +1 -0
  248. package/terrier/images/optimized/icon-settings.svg +1 -1
  249. package/terrier/images/optimized/icon-smile.svg +1 -0
  250. package/terrier/images/optimized/icon-split_view.svg +1 -1
  251. package/terrier/images/optimized/icon-status.svg +1 -1
  252. package/terrier/images/optimized/icon-step_demo.svg +1 -1
  253. package/terrier/images/optimized/icon-step_deploy.svg +1 -1
  254. package/terrier/images/optimized/icon-step_develop.svg +1 -1
  255. package/terrier/images/optimized/icon-step_investigate.svg +1 -1
  256. package/terrier/images/optimized/icon-step_none.svg +1 -1
  257. package/terrier/images/optimized/icon-step_required.svg +1 -1
  258. package/terrier/images/optimized/icon-step_review.svg +1 -1
  259. package/terrier/images/optimized/icon-step_test.svg +1 -1
  260. package/terrier/images/optimized/icon-steps.svg +1 -1
  261. package/terrier/images/optimized/icon-steps_board.svg +1 -1
  262. package/terrier/images/optimized/icon-subscribe.svg +1 -1
  263. package/terrier/images/optimized/icon-support.svg +1 -1
  264. package/terrier/images/optimized/icon-surprised.svg +1 -0
  265. package/terrier/images/optimized/icon-team.svg +1 -1
  266. package/terrier/images/optimized/icon-terrier.svg +1 -1
  267. package/terrier/images/optimized/icon-type.svg +1 -1
  268. package/terrier/images/optimized/icon-unprioritized.svg +1 -1
  269. package/terrier/images/optimized/icon-upload.svg +1 -1
  270. package/terrier/images/optimized/icon-upvote.svg +1 -1
  271. package/terrier/images/optimized/icon-user.svg +1 -1
  272. package/terrier/images/optimized/icon-users.svg +1 -1
  273. package/terrier/images/optimized/icon-website.svg +1 -1
  274. package/terrier/images/optimized/icon-week.svg +1 -1
  275. package/terrier/images/optimized/terrier-hub-favicon.svg +1 -1
  276. package/terrier/images/optimized/terrier-hub-icon-dark.svg +1 -1
  277. package/terrier/images/optimized/terrier-hub-icon-light.svg +1 -1
  278. package/terrier/images/optimized/terrier-hub-loader.svg +1 -1
  279. package/terrier/images/optimized/terrier-hub-logo-dark.svg +1 -1
  280. package/terrier/images/optimized/terrier-hub-logo-light.svg +1 -1
  281. package/terrier/images/raw/icon-cool.svg +10 -0
  282. package/terrier/images/raw/icon-heart.svg +7 -0
  283. package/terrier/images/raw/icon-lol.svg +4 -4
  284. package/terrier/images/raw/icon-owner.svg +12 -0
  285. package/terrier/images/raw/icon-sad.svg +11 -0
  286. package/terrier/images/raw/icon-smile.svg +11 -0
  287. package/terrier/images/raw/icon-surprised.svg +13 -0
  288. package/terrier/parts/multi-select-field-part.ts +138 -0
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>icon-surprised</title>
4
+ <g id="icon-surprised" stroke="none" fill="none">
5
+ <circle id="Oval-3" fill-opacity="0.25" fill="#000000" fill-rule="nonzero" cx="16" cy="16" r="11"></circle>
6
+ <ellipse id="Oval-6" fill="#000000" fill-rule="evenodd" cx="16" cy="21" rx="3" ry="4"></ellipse>
7
+ <circle id="Oval" stroke="#000000" stroke-width="2" cx="16" cy="16" r="11"></circle>
8
+ <ellipse id="Oval-4" fill="#000000" fill-rule="evenodd" cx="12" cy="14" rx="1.5" ry="2"></ellipse>
9
+ <ellipse id="Oval-5" fill="#000000" fill-rule="evenodd" cx="20" cy="14" rx="1.5" ry="2"></ellipse>
10
+ <path d="M10,9 C10.5333333,9.33333333 11.2,9.5 12,9.5 C12.8,9.5 13.4666667,9.33333333 14,9" id="Path" stroke="#000000" stroke-width="2" stroke-linecap="round" transform="translate(12, 9.25) scale(1, -1) rotate(15) translate(-12, -9.25)"></path>
11
+ <path d="M18,9 C18.5333333,9.33333333 19.2,9.5 20,9.5 C20.8,9.5 21.4666667,9.33333333 22,9" id="Path-2" stroke="#000000" stroke-width="2" stroke-linecap="round" transform="translate(20, 9.25) scale(1, -1) rotate(-15) translate(-20, -9.25)"></path>
12
+ </g>
13
+ </svg>
@@ -0,0 +1,138 @@
1
+ import Messages from "tuff-core/messages"
2
+ import { PartTag } from "tuff-core/parts"
3
+ import { SelectOption, SelectOptions } from "tuff-core/forms"
4
+ import TerrierPart from "./terrier-part"
5
+
6
+ export type MultiSelectFieldState = {
7
+ options: SelectOptions
8
+ selected_values: string[]
9
+ placeholder?: string
10
+ name?: string
11
+ disabled?: boolean
12
+ }
13
+
14
+ export class MultiSelectFieldPart extends TerrierPart<MultiSelectFieldState> {
15
+ selectionChangedKey = Messages.typedKey<{ selected_values: string[] }>()
16
+ protected addOptionKey = Messages.untypedKey()
17
+ protected removeValueKey = Messages.typedKey<{ value: string }>()
18
+
19
+ async init() {
20
+ await super.init()
21
+
22
+ this.onChange(this.addOptionKey, m => {
23
+ if (m.value?.length) this.addValue(m.value)
24
+ })
25
+
26
+ this.onClick(this.removeValueKey, m => {
27
+ this.removeValue(m.data.value)
28
+ })
29
+ }
30
+
31
+ get parentClasses(): Array<string> {
32
+ const classes = ['tt-multi-select-field', ...super.parentClasses]
33
+ if (this.state.disabled) classes.push('disabled')
34
+ return classes
35
+ }
36
+
37
+
38
+ /// Selection
39
+
40
+ get selectedValues(): string[] {
41
+ return this.state.selected_values
42
+ }
43
+
44
+ setSelectedValues(values: string[]) {
45
+ this.state.selected_values = [...values]
46
+ this.onSelectionChanged()
47
+ }
48
+
49
+ addValue(value: string) {
50
+ if (this.state.selected_values.includes(value)) return
51
+ this.state.selected_values = [...this.state.selected_values, value]
52
+ this.onSelectionChanged()
53
+ }
54
+
55
+ removeValue(value: string) {
56
+ if (!this.state.selected_values.includes(value)) return
57
+ this.state.selected_values = this.state.selected_values.filter(v => v != value)
58
+ this.onSelectionChanged()
59
+ }
60
+
61
+ protected onSelectionChanged() {
62
+ this.dirty()
63
+ this.emitMessage(this.selectionChangedKey, { selected_values: this.state.selected_values })
64
+ }
65
+
66
+
67
+ /// Options
68
+
69
+ protected get flatOptions(): SelectOption[] {
70
+ return this.state.options.flatMap(opt => 'group' in opt ? opt.options : [opt])
71
+ }
72
+
73
+ titleForValue(value: string): string {
74
+ return this.flatOptions.find(opt => `${opt.value}` == value)?.title ?? value
75
+ }
76
+
77
+ protected isSelectable(opt: SelectOption): boolean {
78
+ return opt.value != null && `${opt.value}`.length > 0
79
+ }
80
+
81
+ protected isSelected(value: string | null): boolean {
82
+ return value != null && this.state.selected_values.includes(`${value}`)
83
+ }
84
+
85
+
86
+ /// Rendering
87
+
88
+ render(parent: PartTag) {
89
+ parent.div('.tt-multi-select-field-container', container => {
90
+ this.renderAddSelect(container)
91
+ this.renderChips(container)
92
+ if (this.state.name) {
93
+ container.input('.tt-multi-select-values', {
94
+ type: 'hidden',
95
+ name: this.state.name,
96
+ value: this.state.selected_values.join(',')
97
+ })
98
+ }
99
+ })
100
+ }
101
+ protected renderAddSelect(parent: PartTag) {
102
+ const blankText = this.state.selected_values.length ? '' : (this.state.placeholder ?? 'Select…')
103
+ parent.select('.tt-multi-select-add', this.state.disabled ? { disabled: true } : {}, select => {
104
+ select.option({ value: '', text: blankText })
105
+ for (const opt of this.state.options) {
106
+ if ('group' in opt) {
107
+ const available = opt.options.filter(o => this.isSelectable(o) && !this.isSelected(o.value))
108
+ if (!available.length) continue
109
+ select.optgroup({ label: opt.group }, group => {
110
+ for (const o of available) this.renderAddOption(group, o)
111
+ })
112
+ } else if (this.isSelectable(opt) && !this.isSelected(opt.value)) {
113
+ this.renderAddOption(select, opt)
114
+ }
115
+ }
116
+ }).emitChange(this.addOptionKey)
117
+ }
118
+
119
+ protected renderAddOption(parent: PartTag, opt: SelectOption) {
120
+ parent.option({ value: `${opt.value}`, text: opt.title })
121
+ }
122
+ protected renderChips(parent: PartTag) {
123
+ parent.div('.tt-multi-select-chips', container => {
124
+ for (const value of this.state.selected_values) {
125
+ container.div('.tt-multi-select-chip', chip => {
126
+ chip.div('.tt-multi-select-chip-label', { text: this.titleForValue(value) })
127
+ if (!this.state.disabled) {
128
+ chip.a('.tt-multi-select-chip-remove')
129
+ .emitClick(this.removeValueKey, { value })
130
+ }
131
+ })
132
+ }
133
+ })
134
+ }
135
+
136
+ }
137
+
138
+ export default MultiSelectFieldPart