@nyaruka/temba-components 0.122.0 → 0.124.0

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 (262) hide show
  1. package/.github/copilot-instructions.md +181 -0
  2. package/.github/workflows/build.yml +3 -3
  3. package/.github/workflows/cla.yml +6 -6
  4. package/.github/workflows/copilot-setup-steps.yml +86 -0
  5. package/CHANGELOG.md +44 -0
  6. package/demo/drag-drop-demo.html +141 -0
  7. package/demo/index.html +57 -0
  8. package/demo/test-drag-drop.html +94 -0
  9. package/dist/locales/es.js +1 -0
  10. package/dist/locales/es.js.map +1 -1
  11. package/dist/locales/fr.js +1 -0
  12. package/dist/locales/fr.js.map +1 -1
  13. package/dist/locales/pt.js +1 -0
  14. package/dist/locales/pt.js.map +1 -1
  15. package/dist/temba-components.js +366 -247
  16. package/dist/temba-components.js.map +1 -1
  17. package/out-tsc/src/chart/TembaChart.js +81 -14
  18. package/out-tsc/src/chart/TembaChart.js.map +1 -1
  19. package/out-tsc/src/fields/FieldManager.js +27 -34
  20. package/out-tsc/src/fields/FieldManager.js.map +1 -1
  21. package/out-tsc/src/list/RunList.js +13 -8
  22. package/out-tsc/src/list/RunList.js.map +1 -1
  23. package/out-tsc/src/list/SortableList.js +257 -60
  24. package/out-tsc/src/list/SortableList.js.map +1 -1
  25. package/out-tsc/src/locales/es.js +1 -0
  26. package/out-tsc/src/locales/es.js.map +1 -1
  27. package/out-tsc/src/locales/fr.js +1 -0
  28. package/out-tsc/src/locales/fr.js.map +1 -1
  29. package/out-tsc/src/locales/pt.js +1 -0
  30. package/out-tsc/src/locales/pt.js.map +1 -1
  31. package/out-tsc/src/omnibox/Omnibox.js +1 -1
  32. package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
  33. package/out-tsc/src/options/Options.js +36 -13
  34. package/out-tsc/src/options/Options.js.map +1 -1
  35. package/out-tsc/src/select/Select.js +226 -43
  36. package/out-tsc/src/select/Select.js.map +1 -1
  37. package/out-tsc/src/store/AppState.js +3 -3
  38. package/out-tsc/src/store/AppState.js.map +1 -1
  39. package/out-tsc/src/utils/index.js +6 -1
  40. package/out-tsc/src/utils/index.js.map +1 -1
  41. package/out-tsc/src/vectoricon/VectorIcon.js +2 -1
  42. package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
  43. package/out-tsc/src/webchat/WebChat.js +5 -2
  44. package/out-tsc/src/webchat/WebChat.js.map +1 -1
  45. package/out-tsc/temba-modules.js +0 -2
  46. package/out-tsc/temba-modules.js.map +1 -1
  47. package/out-tsc/test/temba-appstate-language.test.js +176 -0
  48. package/out-tsc/test/temba-appstate-language.test.js.map +1 -0
  49. package/out-tsc/test/temba-chart.test.js +125 -0
  50. package/out-tsc/test/temba-chart.test.js.map +1 -1
  51. package/out-tsc/test/temba-dropdown.test.js +317 -0
  52. package/out-tsc/test/temba-dropdown.test.js.map +1 -0
  53. package/out-tsc/test/temba-flow-editor-node.test.js +273 -0
  54. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -0
  55. package/out-tsc/test/temba-flow-editor.test.js +244 -0
  56. package/out-tsc/test/temba-flow-editor.test.js.map +1 -0
  57. package/out-tsc/test/temba-flow-plumber.test.js +145 -0
  58. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -0
  59. package/out-tsc/test/temba-flow-render.test.js +171 -0
  60. package/out-tsc/test/temba-flow-render.test.js.map +1 -0
  61. package/out-tsc/test/temba-omnibox.test.js +2 -3
  62. package/out-tsc/test/temba-omnibox.test.js.map +1 -1
  63. package/out-tsc/test/temba-run-list.test.js +588 -0
  64. package/out-tsc/test/temba-run-list.test.js.map +1 -0
  65. package/out-tsc/test/temba-select.test.js +149 -52
  66. package/out-tsc/test/temba-select.test.js.map +1 -1
  67. package/out-tsc/test/temba-sortable-list.test.js +91 -15
  68. package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
  69. package/out-tsc/test/temba-toast.test.js +299 -0
  70. package/out-tsc/test/temba-toast.test.js.map +1 -0
  71. package/out-tsc/test/temba-utils-index.test.js +1178 -0
  72. package/out-tsc/test/temba-utils-index.test.js.map +1 -0
  73. package/out-tsc/test/temba-webchat-lightbox-fix.test.js +42 -0
  74. package/out-tsc/test/temba-webchat-lightbox-fix.test.js.map +1 -0
  75. package/out-tsc/test/temba-webchat.test.js +816 -0
  76. package/out-tsc/test/temba-webchat.test.js.map +1 -0
  77. package/out-tsc/test/utils.test.js +33 -1
  78. package/out-tsc/test/utils.test.js.map +1 -1
  79. package/package.json +6 -8
  80. package/screenshots/truth/alert/error.png +0 -0
  81. package/screenshots/truth/alert/info.png +0 -0
  82. package/screenshots/truth/alert/warning.png +0 -0
  83. package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
  84. package/screenshots/truth/checkbox/checked.png +0 -0
  85. package/screenshots/truth/checkbox/default.png +0 -0
  86. package/screenshots/truth/colorpicker/default.png +0 -0
  87. package/screenshots/truth/colorpicker/focused.png +0 -0
  88. package/screenshots/truth/colorpicker/initialized.png +0 -0
  89. package/screenshots/truth/colorpicker/selected.png +0 -0
  90. package/screenshots/truth/compose/attachments-tab.png +0 -0
  91. package/screenshots/truth/compose/attachments-with-files-focused.png +0 -0
  92. package/screenshots/truth/compose/attachments-with-files.png +0 -0
  93. package/screenshots/truth/compose/intial-text.png +0 -0
  94. package/screenshots/truth/compose/no-counter.png +0 -0
  95. package/screenshots/truth/compose/wraps-text-and-spaces.png +0 -0
  96. package/screenshots/truth/compose/wraps-text-and-url.png +0 -0
  97. package/screenshots/truth/compose/wraps-text-no-spaces.png +0 -0
  98. package/screenshots/truth/contacts/badges.png +0 -0
  99. package/screenshots/truth/contacts/chat-failure.png +0 -0
  100. package/screenshots/truth/contacts/chat-for-active-contact.png +0 -0
  101. package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
  102. package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
  103. package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
  104. package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
  105. package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
  106. package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
  107. package/screenshots/truth/content-menu/button-no-items.png +0 -0
  108. package/screenshots/truth/content-menu/items-and-buttons.png +0 -0
  109. package/screenshots/truth/counter/summary.png +0 -0
  110. package/screenshots/truth/counter/text.png +0 -0
  111. package/screenshots/truth/counter/unicode-variables.png +0 -0
  112. package/screenshots/truth/counter/unicode.png +0 -0
  113. package/screenshots/truth/counter/variable.png +0 -0
  114. package/screenshots/truth/date/date-inline.png +0 -0
  115. package/screenshots/truth/date/date.png +0 -0
  116. package/screenshots/truth/date/datetime.png +0 -0
  117. package/screenshots/truth/date/duration.png +0 -0
  118. package/screenshots/truth/date/timedate.png +0 -0
  119. package/screenshots/truth/datepicker/date-truncated-time.png +0 -0
  120. package/screenshots/truth/datepicker/date.png +0 -0
  121. package/screenshots/truth/datepicker/initial-timezone.png +0 -0
  122. package/screenshots/truth/datepicker/updated-keyboard-date.png +0 -0
  123. package/screenshots/truth/dialog/focused.png +0 -0
  124. package/screenshots/truth/dropdown/after-blur.png +0 -0
  125. package/screenshots/truth/dropdown/bottom-edge-collision.png +0 -0
  126. package/screenshots/truth/dropdown/custom-arrow-size.png +0 -0
  127. package/screenshots/truth/dropdown/default.png +0 -0
  128. package/screenshots/truth/dropdown/narrow-toggle.png +0 -0
  129. package/screenshots/truth/dropdown/no-mask.png +0 -0
  130. package/screenshots/truth/dropdown/opened.png +0 -0
  131. package/screenshots/truth/dropdown/positioned.png +0 -0
  132. package/screenshots/truth/dropdown/right-edge-collision.png +0 -0
  133. package/screenshots/truth/dropdown/with-mask.png +0 -0
  134. package/screenshots/truth/flow/editor-basic.png +0 -0
  135. package/screenshots/truth/label/custom.png +0 -0
  136. package/screenshots/truth/label/danger.png +0 -0
  137. package/screenshots/truth/label/dark.png +0 -0
  138. package/screenshots/truth/label/default-icon.png +0 -0
  139. package/screenshots/truth/label/no-icon.png +0 -0
  140. package/screenshots/truth/label/primary.png +0 -0
  141. package/screenshots/truth/label/secondary.png +0 -0
  142. package/screenshots/truth/label/shadow.png +0 -0
  143. package/screenshots/truth/label/tertiary.png +0 -0
  144. package/screenshots/truth/lightbox/img-zoomed.png +0 -0
  145. package/screenshots/truth/list/fields-dragging.png +0 -0
  146. package/screenshots/truth/list/fields-filtered.png +0 -0
  147. package/screenshots/truth/list/fields-hovered.png +0 -0
  148. package/screenshots/truth/list/fields.png +0 -0
  149. package/screenshots/truth/list/items-selected.png +0 -0
  150. package/screenshots/truth/list/items-updated.png +0 -0
  151. package/screenshots/truth/list/items.png +0 -0
  152. package/screenshots/truth/list/sortable-dragging.png +0 -0
  153. package/screenshots/truth/list/sortable-dropped.png +0 -0
  154. package/screenshots/truth/list/sortable.png +0 -0
  155. package/screenshots/truth/menu/menu-focused-with items.png +0 -0
  156. package/screenshots/truth/menu/menu-refresh-1.png +0 -0
  157. package/screenshots/truth/menu/menu-refresh-2.png +0 -0
  158. package/screenshots/truth/menu/menu-root.png +0 -0
  159. package/screenshots/truth/menu/menu-submenu.png +0 -0
  160. package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
  161. package/screenshots/truth/menu/menu-tasks.png +0 -0
  162. package/screenshots/truth/modax/form.png +0 -0
  163. package/screenshots/truth/modax/simple.png +0 -0
  164. package/screenshots/truth/omnibox/selected.png +0 -0
  165. package/screenshots/truth/options/block.png +0 -0
  166. package/screenshots/truth/run-list/basic.png +0 -0
  167. package/screenshots/truth/select/disabled-multi-selection.png +0 -0
  168. package/screenshots/truth/select/disabled-selection.png +0 -0
  169. package/screenshots/truth/select/disabled.png +0 -0
  170. package/screenshots/truth/select/embedded.png +0 -0
  171. package/screenshots/truth/select/empty-options.png +0 -0
  172. package/screenshots/truth/select/expression-selected.png +0 -0
  173. package/screenshots/truth/select/expressions.png +0 -0
  174. package/screenshots/truth/select/functions.png +0 -0
  175. package/screenshots/truth/select/local-options.png +0 -0
  176. package/screenshots/truth/select/multi-reorder-final.png +0 -0
  177. package/screenshots/truth/select/multi-reorder-initial.png +0 -0
  178. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  179. package/screenshots/truth/select/multiple-initial-values.png +0 -0
  180. package/screenshots/truth/select/remote-options.png +0 -0
  181. package/screenshots/truth/select/search-enabled.png +0 -0
  182. package/screenshots/truth/select/search-multi-no-matches.png +0 -0
  183. package/screenshots/truth/select/search-selected-focus.png +0 -0
  184. package/screenshots/truth/select/search-selected.png +0 -0
  185. package/screenshots/truth/select/search-with-selected.png +0 -0
  186. package/screenshots/truth/select/searching.png +0 -0
  187. package/screenshots/truth/select/selected-multi-maxitems-reached.png +0 -0
  188. package/screenshots/truth/select/selected-multi.png +0 -0
  189. package/screenshots/truth/select/selected-single.png +0 -0
  190. package/screenshots/truth/select/selection-clearable.png +0 -0
  191. package/screenshots/truth/select/static-initial-value.png +0 -0
  192. package/screenshots/truth/select/static-initial-via-selected.png +0 -0
  193. package/screenshots/truth/select/truncated-selection.png +0 -0
  194. package/screenshots/truth/select/with-placeholder.png +0 -0
  195. package/screenshots/truth/select/without-placeholder.png +0 -0
  196. package/screenshots/truth/slider/custom-min-custom-max-valid-value.png +0 -0
  197. package/screenshots/truth/slider/custom-min-default-max-no-value.png +0 -0
  198. package/screenshots/truth/slider/default-min-custom-max-no-value.png +0 -0
  199. package/screenshots/truth/slider/default-min-default-max-invalid-value.png +0 -0
  200. package/screenshots/truth/slider/default-min-default-max-valid-value.png +0 -0
  201. package/screenshots/truth/slider/update-slider-on-value-change.png +0 -0
  202. package/screenshots/truth/templates/default.png +0 -0
  203. package/screenshots/truth/templates/unapproved.png +0 -0
  204. package/screenshots/truth/textinput/input-disabled.png +0 -0
  205. package/screenshots/truth/textinput/input-focused.png +0 -0
  206. package/screenshots/truth/textinput/input-form.png +0 -0
  207. package/screenshots/truth/textinput/input-inserted.png +0 -0
  208. package/screenshots/truth/textinput/input-placeholder.png +0 -0
  209. package/screenshots/truth/textinput/input-updated.png +0 -0
  210. package/screenshots/truth/textinput/input.png +0 -0
  211. package/screenshots/truth/textinput/textarea-focused.png +0 -0
  212. package/screenshots/truth/textinput/textarea.png +0 -0
  213. package/screenshots/truth/tip/bottom.png +0 -0
  214. package/screenshots/truth/tip/left.png +0 -0
  215. package/screenshots/truth/tip/right.png +0 -0
  216. package/screenshots/truth/tip/top.png +0 -0
  217. package/screenshots/truth/webchat/closed-widget.png +0 -0
  218. package/screenshots/truth/webchat/connected-state.png +0 -0
  219. package/screenshots/truth/webchat/connecting-state.png +0 -0
  220. package/screenshots/truth/webchat/disconnected-state.png +0 -0
  221. package/screenshots/truth/webchat/opened-widget.png +0 -0
  222. package/src/chart/TembaChart.ts +86 -15
  223. package/src/fields/FieldManager.ts +30 -38
  224. package/src/list/RunList.ts +11 -8
  225. package/src/list/SortableList.ts +291 -67
  226. package/src/locales/es.ts +1 -0
  227. package/src/locales/fr.ts +1 -0
  228. package/src/locales/pt.ts +1 -0
  229. package/src/omnibox/Omnibox.ts +1 -1
  230. package/src/options/Options.ts +38 -13
  231. package/src/select/Select.ts +245 -47
  232. package/src/store/AppState.ts +3 -3
  233. package/src/utils/index.ts +17 -5
  234. package/src/vectoricon/VectorIcon.ts +2 -1
  235. package/src/webchat/WebChat.ts +5 -2
  236. package/temba-modules.ts +0 -2
  237. package/test/temba-appstate-language.test.ts +218 -0
  238. package/test/temba-chart.test.ts +161 -1
  239. package/test/temba-dropdown.test.ts +444 -0
  240. package/test/temba-flow-editor-node.test.ts +344 -0
  241. package/test/temba-flow-editor.test.ts +301 -0
  242. package/test/temba-flow-plumber.test.ts +189 -0
  243. package/test/temba-flow-render.test.ts +220 -0
  244. package/test/temba-omnibox.test.ts +2 -3
  245. package/test/temba-run-list.test.ts +774 -0
  246. package/test/temba-select.test.ts +206 -78
  247. package/test/temba-sortable-list.test.ts +108 -15
  248. package/test/temba-toast.test.ts +386 -0
  249. package/test/temba-utils-index.test.ts +1547 -0
  250. package/test/temba-webchat-lightbox-fix.test.ts +57 -0
  251. package/test/temba-webchat.test.ts +1095 -0
  252. package/test/utils.test.ts +56 -2
  253. package/test-assets/list/flow-results.json +17 -0
  254. package/test-assets/list/runs.json +126 -0
  255. package/test-assets/style.css +23 -0
  256. package/web-test-runner.config.mjs +33 -7
  257. package/xliff/es.xlf +3 -0
  258. package/xliff/fr.xlf +3 -0
  259. package/xliff/pt.xlf +3 -0
  260. package/out-tsc/src/outboxmonitor/OutboxMonitor.js +0 -136
  261. package/out-tsc/src/outboxmonitor/OutboxMonitor.js.map +0 -1
  262. package/src/outboxmonitor/OutboxMonitor.ts +0 -148
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temba-run-list.test.js","sourceRoot":"","sources":["../../test/temba-run-list.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert, expect } from '@open-wc/testing';\nimport * as sinon from 'sinon';\nimport { useFakeTimers } from 'sinon';\nimport { CustomEventType } from '../src/interfaces';\nimport { RunList } from '../src/list/RunList';\nimport {\n assertScreenshot,\n getClip,\n getComponent,\n mockGET,\n mockAPI\n} from './utils.test';\n\nlet clock: any;\n\nconst TAG = 'temba-run-list';\nconst getRunList = async (attrs: any = {}, width = 250, height = 0) => {\n const runList = (await getComponent(\n TAG,\n attrs,\n '',\n width,\n height\n )) as RunList;\n\n if (!runList.endpoint) {\n return runList;\n }\n\n return new Promise<RunList>((resolve) => {\n runList.addEventListener(\n CustomEventType.FetchComplete,\n async () => {\n resolve(runList);\n },\n { once: true }\n );\n });\n};\n\ndescribe('temba-run-list', () => {\n beforeEach(function () {\n clock = useFakeTimers();\n // set up general mocking\n mockAPI();\n // mock the runs API endpoint\n mockGET(/\\/api\\/v2\\/runs\\.json/, '/test-assets/list/runs.json');\n });\n\n afterEach(function () {\n clock.restore();\n });\n\n it('can be created', async () => {\n const runList: RunList = await getRunList();\n assert.instanceOf(runList, RunList);\n expect(runList.responses).to.equal(true);\n expect(runList.allowDelete).to.equal(false);\n expect(runList.valueKey).to.equal('uuid');\n expect(runList.hideShadow).to.equal(true);\n expect(runList.reverseRefresh).to.equal(false);\n });\n\n it('initializes with correct default properties', async () => {\n const runList: RunList = await getRunList();\n expect(runList.responses).to.equal(true);\n expect(runList.allowDelete).to.equal(false);\n expect(runList.resultPreview).to.be.undefined;\n expect(runList.selectedRun).to.be.undefined;\n expect(runList.results).to.be.undefined;\n expect(runList.flow).to.be.undefined;\n });\n\n it('sets endpoint when flow property changes', async () => {\n const runList: RunList = await getRunList();\n\n runList.flow = 'test-flow-uuid';\n await runList.updateComplete;\n\n expect(runList.endpoint).to.equal(\n '/api/v2/runs.json?flow=test-flow-uuid&responded=1'\n );\n });\n\n it('sets endpoint without responded parameter when responses is false', async () => {\n const runList: RunList = await getRunList();\n\n runList.responses = false;\n runList.flow = 'test-flow-uuid';\n await runList.updateComplete;\n\n expect(runList.endpoint).to.equal('/api/v2/runs.json?flow=test-flow-uuid');\n });\n\n it('loads runs with flow endpoint', async () => {\n const runList: RunList = await getRunList(\n {\n flow: 'test-flow-uuid'\n },\n 250,\n 400\n ); // use bigger height to avoid overlap\n\n expect(runList.items.length).to.equal(5);\n await assertScreenshot('run-list/basic', getClip(runList));\n });\n\n it('handles results property change', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n const results = [\n { key: 'name', name: 'Name', categories: ['Text'] },\n { key: 'age', name: 'Age', categories: ['Number'] }\n ];\n\n runList.results = results;\n await runList.updateComplete;\n\n expect(mockSelect.setOptions.calledWith(results)).to.be.true;\n // Since resultKeys is private, we test the observable behavior indirectly\n // by verifying the results were processed correctly via setOptions call.\n });\n\n it('calls createRenderOption when resultPreview changes', async () => {\n const runList: RunList = await getRunList();\n const createRenderOptionSpy = sinon.spy(runList, 'createRenderOption');\n\n runList.resultPreview = { key: 'name', name: 'Name' };\n await runList.updateComplete;\n\n expect(createRenderOptionSpy.called).to.be.true;\n });\n\n it('getIcon returns correct icon for completed run', async () => {\n const runList: RunList = await getRunList();\n const run = { exit_type: 'completed' };\n\n const icon = runList.getIcon(run);\n expect(icon.strings[0]).to.contain('temba-icon');\n expect(icon.strings[0]).to.contain('name=\"check\"');\n });\n\n it('getIcon returns correct icon for interrupted run', async () => {\n const runList: RunList = await getRunList();\n const run = { exit_type: 'interrupted' };\n\n const icon = runList.getIcon(run);\n expect(icon.strings[0]).to.contain('temba-icon');\n expect(icon.strings[0]).to.contain('name=\"x-octagon\"');\n });\n\n it('getIcon returns correct icon for expired run', async () => {\n const runList: RunList = await getRunList();\n const run = { exit_type: 'expired' };\n\n const icon = runList.getIcon(run);\n expect(icon.strings[0]).to.contain('temba-icon');\n expect(icon.strings[0]).to.contain('name=\"clock\"');\n });\n\n it('getIcon returns activity icon for active responded run', async () => {\n const runList: RunList = await getRunList();\n const run = { exit_type: null, responded: true };\n\n const icon = runList.getIcon(run);\n expect(icon.strings[0]).to.contain('temba-icon');\n expect(icon.strings[0]).to.contain('name=\"activity\"');\n });\n\n it('getIcon returns hourglass icon for active non-responded run', async () => {\n const runList: RunList = await getRunList();\n const run = { exit_type: null, responded: false };\n\n const icon = runList.getIcon(run);\n expect(icon.strings[0]).to.contain('temba-icon');\n expect(icon.strings[0]).to.contain('name=\"hourglass\"');\n });\n\n it('renderResultPreview returns category for multi-category result', async () => {\n const runList: RunList = await getRunList();\n\n runList.resultPreview = {\n key: 'gender',\n categories: ['Male', 'Female', 'Other']\n };\n\n const run = {\n values: {\n gender: {\n category: 'Male',\n value: 'Male'\n }\n }\n };\n\n const result = runList.renderResultPreview(run);\n expect(result).to.equal('Male');\n });\n\n it('renderResultPreview returns value for single-category result', async () => {\n const runList: RunList = await getRunList();\n\n runList.resultPreview = { key: 'name', categories: ['Text'] };\n\n const run = {\n values: {\n name: {\n category: 'Text',\n value: 'John Doe'\n }\n }\n };\n\n const result = runList.renderResultPreview(run);\n expect(result).to.equal('John Doe');\n });\n\n it('renderResultPreview returns null when no result preview', async () => {\n const runList: RunList = await getRunList();\n\n const run = { values: {} };\n const result = runList.renderResultPreview(run);\n expect(result).to.be.null;\n });\n\n it('renderResultPreview returns null when no matching value', async () => {\n const runList: RunList = await getRunList();\n\n runList.resultPreview = { key: 'missing', categories: ['Text'] };\n\n const run = { values: {} };\n const result = runList.renderResultPreview(run);\n expect(result).to.be.null;\n });\n\n it('handles results property change when results is null', async () => {\n const runList: RunList = await getRunList();\n\n // set initial results\n runList.results = [{ key: 'name', name: 'Name' }];\n await runList.updateComplete;\n\n // clear results\n runList.results = null;\n await runList.updateComplete;\n\n // should not throw an error\n expect(runList.results).to.be.null;\n });\n\n it('handles responses/flow change when flow is not set', async () => {\n const runList: RunList = await getRunList();\n\n // change responses without setting flow\n runList.responses = false;\n await runList.updateComplete;\n\n // endpoint should not be set\n expect(runList.endpoint).to.be.undefined;\n });\n\n it('renderResultPreview returns null when category is missing in multi-category result', async () => {\n const runList: RunList = await getRunList();\n\n runList.resultPreview = {\n key: 'gender',\n categories: ['Male', 'Female', 'Other']\n };\n\n const run = {\n values: {\n gender: {\n value: 'Male'\n // missing category property\n }\n }\n };\n\n const result = runList.renderResultPreview(run);\n expect(result).to.be.null;\n });\n\n it('removeRun removes item and updates cursor', async () => {\n const runList: RunList = await getRunList({\n flow: 'test-flow-uuid'\n });\n\n const initialCount = runList.items.length;\n expect(initialCount).to.equal(5);\n\n runList.cursorIndex = 2;\n runList.removeRun(2);\n\n expect(runList.items.length).to.equal(4);\n expect(runList.items.find((item) => item.id === 2)).to.be.undefined;\n expect(runList.cursorIndex).to.equal(2);\n });\n\n it('removeRun adjusts cursor when removing last item', async () => {\n const runList: RunList = await getRunList();\n\n // set up items manually\n runList.items = [\n { id: 1, uuid: 'uuid-1' },\n { id: 2, uuid: 'uuid-2' }\n ];\n runList.cursorIndex = 1;\n\n runList.removeRun(2);\n\n expect(runList.items.length).to.equal(1);\n expect(runList.cursorIndex).to.equal(1);\n });\n\n it('getRefreshEndpoint returns endpoint with after parameter when items exist', async () => {\n const runList: RunList = await getRunList({\n flow: 'test-flow-uuid'\n });\n\n const endpoint = runList.getRefreshEndpoint();\n expect(endpoint).to.contain('&after=');\n expect(endpoint).to.contain('2023-12-01T10:30:00.000Z');\n });\n\n it('getRefreshEndpoint returns base endpoint when no items', async () => {\n const runList: RunList = await getRunList();\n runList.endpoint = '/api/v2/runs.json?flow=test';\n\n const endpoint = runList.getRefreshEndpoint();\n expect(endpoint).to.equal('/api/v2/runs.json?flow=test');\n });\n\n it('toggleResponded updates responses property', async () => {\n const runList: RunList = await getRunList();\n\n // mock checkbox element\n const mockCheckbox = document.createElement('input') as any;\n mockCheckbox.checked = false;\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockCheckbox);\n\n runList.toggleResponded();\n\n expect(runList.responses).to.equal(false);\n });\n\n it('handleColumnChanged sets resultPreview from event', async () => {\n const runList: RunList = await getRunList();\n\n const event = {\n target: {\n values: [{ key: 'name', name: 'Name' }]\n }\n };\n\n runList.handleColumnChanged(event);\n\n expect(runList.resultPreview).to.deep.equal({ key: 'name', name: 'Name' });\n });\n\n it('handleColumnChanged clears resultPreview when no values', async () => {\n const runList: RunList = await getRunList();\n\n runList.resultPreview = { key: 'name', name: 'Name' };\n\n const event = {\n target: {\n values: []\n }\n };\n\n runList.handleColumnChanged(event);\n\n expect(runList.resultPreview).to.be.null;\n });\n\n it('handleSelected sets selectedRun', async () => {\n const runList: RunList = await getRunList();\n\n const selectedRun = { id: 1, uuid: 'test-uuid' };\n runList.handleSelected(selectedRun);\n\n expect(runList.selectedRun).to.equal(selectedRun);\n });\n\n it('getListStyle returns empty string', async () => {\n const runList: RunList = await getRunList();\n\n const style = runList.getListStyle();\n expect(style).to.equal('');\n });\n\n it('renderHeader shows checkbox', async () => {\n const runList: RunList = await getRunList();\n\n const header = runList.renderHeader();\n const headerString = header.strings.join('');\n expect(headerString).to.contain('temba-checkbox');\n expect(headerString).to.contain('Responses Only');\n });\n\n it('renderHeader shows select when results exist', async () => {\n const runList: RunList = await getRunList();\n\n runList.results = [{ key: 'name', name: 'Name' }];\n await runList.updateComplete;\n\n const header = runList.renderHeader();\n\n // check if the template includes the results check and nested template\n expect(header.values).to.have.length.greaterThan(0);\n\n // check that results is truthy which will render the select\n expect(runList.results).to.not.be.null;\n });\n\n it('renderHeader without results hides select', async () => {\n const runList: RunList = await getRunList();\n\n const header = runList.renderHeader();\n expect(header.strings.join('')).to.not.contain('temba-select');\n expect(header.strings.join('')).to.contain('temba-checkbox');\n });\n\n it('renderFooter returns null when no selectedRun', async () => {\n const runList: RunList = await getRunList();\n\n const footer = runList.renderFooter();\n expect(footer).to.be.null;\n });\n\n it('renderFooter returns null when no resultKeys', async () => {\n const runList: RunList = await getRunList();\n\n runList.selectedRun = { id: 1, values: {} };\n // Don't set results, so resultKeys will be empty object {} which is truthy.\n // The method only returns null if selectedRun is null/undefined, not for empty resultKeys.\n\n const footer = runList.renderFooter();\n expect(footer).to.not.be.null; // Empty object {} is truthy, so footer should render\n });\n\n it('renderFooter handles selectedRun without values', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [];\n await runList.updateComplete;\n\n runList.selectedRun = {\n id: 1,\n contact: {\n uuid: 'contact-uuid',\n name: 'John Doe',\n urn: 'tel:+1234567890'\n },\n created_on: '2023-12-01T10:00:00.000Z'\n };\n\n // should work now with the safety check\n const footer = runList.renderFooter();\n expect(footer).to.not.be.null;\n });\n\n it('renderFooter displays contact information', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [{ key: 'name', name: 'Name', categories: ['Text'] }];\n await runList.updateComplete;\n\n runList.selectedRun = {\n id: 1,\n contact: {\n uuid: 'contact-uuid',\n name: 'John Doe',\n urn: 'tel:+1234567890'\n },\n exit_type: 'completed',\n exited_on: '2023-12-01T10:30:00.000Z',\n created_on: '2023-12-01T10:00:00.000Z',\n values: {\n name: { name: 'Name', key: 'name', value: 'John Doe', category: 'Text' }\n }\n };\n\n const footer = runList.renderFooter();\n expect(footer).to.not.be.null;\n expect(footer.strings[0]).to.contain('temba-contact-name');\n });\n\n it('renderFooter shows delete icon when allowDelete is true', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [];\n await runList.updateComplete;\n\n runList.allowDelete = true;\n runList.selectedRun = {\n id: 1,\n contact: {\n uuid: 'contact-uuid',\n name: 'John Doe',\n urn: 'tel:+1234567890'\n },\n created_on: '2023-12-01T10:00:00.000Z',\n values: {}\n };\n\n const footer = runList.renderFooter();\n expect(footer).to.not.be.null;\n\n // verify the conditions that would show the delete icon\n expect(runList.allowDelete).to.be.true;\n expect(runList.selectedRun.id).to.equal(1);\n });\n\n it('renderFooter shows active run status', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [];\n await runList.updateComplete;\n\n runList.selectedRun = {\n id: 1,\n contact: {\n uuid: 'contact-uuid',\n name: 'John Doe',\n urn: 'tel:+1234567890'\n },\n exit_type: null,\n created_on: '2023-12-01T10:00:00.000Z',\n values: {}\n };\n\n const footer = runList.renderFooter();\n expect(footer.strings.join('')).to.contain('Started');\n });\n\n it('createRenderOption creates renderOption function', async () => {\n const runList: RunList = await getRunList();\n\n expect(runList.renderOption).to.be.a('function');\n\n const run = {\n contact: {\n name: 'John Doe',\n urn: 'tel:+1234567890',\n anon_display: '1234567890'\n },\n modified_on: '2023-12-01T10:30:00.000Z',\n exited_on: '2023-12-01T10:30:00.000Z',\n responded: true\n };\n\n const result = runList.renderOption(run, false);\n expect(result.strings.join('')).to.contain('temba-contact-name');\n expect(result.strings.join('')).to.contain('temba-date');\n });\n\n it('renderOption handles run without contact name', async () => {\n const runList: RunList = await getRunList();\n\n const run = {\n contact: {\n name: null,\n urn: 'tel:+1234567890',\n anon_display: '1234567890'\n },\n modified_on: '2023-12-01T10:30:00.000Z',\n exited_on: null,\n responded: false\n };\n\n const result = runList.renderOption(run, false);\n expect(result.strings.join('')).to.contain('temba-contact-name');\n });\n\n it('renderOption handles run without contact', async () => {\n const runList: RunList = await getRunList();\n\n const run = {\n modified_on: '2023-12-01T10:30:00.000Z',\n exited_on: null,\n responded: false\n };\n\n const result = runList.renderOption(run, false);\n expect(result.strings.join('')).to.contain('temba-contact-name');\n });\n\n it('handles results without categories in renderResultPreview', async () => {\n const runList: RunList = await getRunList();\n\n runList.resultPreview = { key: 'name', categories: ['Text'] };\n\n const run = {\n values: {\n name: {\n value: 'Test Value'\n // missing category property\n }\n }\n };\n\n const result = runList.renderResultPreview(run);\n expect(result).to.equal('Test Value');\n });\n\n it('firstUpdated calls super', async () => {\n const runList: RunList = await getRunList();\n const superSpy = sinon.spy(\n Object.getPrototypeOf(RunList.prototype),\n 'firstUpdated'\n );\n\n runList.firstUpdated(new Map());\n\n expect(superSpy.called).to.be.true;\n superSpy.restore();\n });\n\n it('renderFooter shows result values', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [{ key: 'name', name: 'Name', categories: ['Text'] }];\n await runList.updateComplete;\n\n runList.selectedRun = {\n id: 1,\n contact: {\n uuid: 'contact-uuid',\n name: 'John Doe',\n urn: 'tel:+1234567890'\n },\n created_on: '2023-12-01T10:00:00.000Z',\n values: {\n name: { name: 'Name', key: 'name', value: 'John Doe', category: 'Text' }\n }\n };\n\n const footer = runList.renderFooter();\n expect(footer).to.not.be.null;\n\n // check that the conditions for showing the table are met\n const resultKeys = Object.keys(runList.selectedRun.values || {});\n expect(resultKeys.length).to.be.greaterThan(0);\n });\n\n it('renderFooter shows multi-category display', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [\n { key: 'gender', name: 'Gender', categories: ['Male', 'Female', 'Other'] }\n ];\n await runList.updateComplete;\n\n runList.selectedRun = {\n id: 1,\n contact: {\n uuid: 'contact-uuid',\n name: 'John Doe',\n urn: 'tel:+1234567890'\n },\n created_on: '2023-12-01T10:00:00.000Z',\n values: {\n gender: {\n name: 'Gender',\n key: 'gender',\n value: 'Male',\n category: 'Male'\n }\n }\n };\n\n const footer = runList.renderFooter();\n expect(footer).to.not.be.null;\n\n // check that we have data setup correctly by verifying the selected run has values\n expect(Object.keys(runList.selectedRun.values).length).to.be.greaterThan(0);\n });\n\n it('renderFooter handles missing contact uuid', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [];\n await runList.updateComplete;\n\n runList.selectedRun = {\n id: 1,\n contact: null, // Missing contact to trigger the fallback\n created_on: '2023-12-01T10:00:00.000Z',\n values: {}\n };\n\n const footer = runList.renderFooter();\n expect(footer).to.not.be.null;\n expect(footer.strings[0]).to.contain('temba-contact-name');\n });\n\n it('renderFooter shows single-category result display', async () => {\n const runList: RunList = await getRunList();\n\n // mock temba-select element for the results\n const mockSelect = document.createElement('div') as any;\n mockSelect.setOptions = sinon.spy();\n sinon.stub(runList.shadowRoot, 'querySelector').returns(mockSelect);\n\n // set results to populate resultKeys\n runList.results = [{ key: 'name', name: 'Name', categories: ['Text'] }];\n await runList.updateComplete;\n\n runList.selectedRun = {\n id: 1,\n contact: {\n uuid: 'contact-uuid',\n name: 'John Doe',\n urn: 'tel:+1234567890'\n },\n created_on: '2023-12-01T10:00:00.000Z',\n values: {\n name: { name: 'Name', key: 'name', value: 'John Doe', category: 'Text' }\n }\n };\n\n const footer = runList.renderFooter();\n const footerString = footer.strings.join('');\n expect(footerString).to.contain('--'); // Single category shows '--' for category\n });\n});\n"]}
@@ -3,8 +3,7 @@ import { fixture, expect, assert } from '@open-wc/testing';
3
3
  import { useFakeTimers } from 'sinon';
4
4
  import { Options } from '../src/options/Options';
5
5
  import { Select } from '../src/select/Select';
6
- import { assertScreenshot, checkTimers, getClip, loadStore, mouseClickElement } from './utils.test';
7
- import { CustomEventType } from '../src/interfaces';
6
+ import { assertScreenshot, getClip, getOptions, loadStore, openAndClick, openSelect } from './utils.test';
8
7
  const colors = [
9
8
  { name: 'Red', value: '0' },
10
9
  { name: 'Green', value: '1' },
@@ -12,48 +11,15 @@ const colors = [
12
11
  ];
13
12
  export const createSelect = async (clock, def) => {
14
13
  const parentNode = document.createElement('div');
15
- parentNode.setAttribute('style', 'width: 250px;');
14
+ parentNode.setAttribute('style', 'width: 400px;');
16
15
  const select = await fixture(def, { parentNode });
17
16
  clock.runAll();
18
17
  await select.updateComplete;
19
18
  return select;
20
19
  };
21
- export const open = async (clock, select) => {
22
- if (!select.endpoint) {
23
- await mouseClickElement(select);
24
- await clock.runAll();
25
- await clock.runAll();
26
- return select;
27
- }
28
- const promise = new Promise((resolve) => {
29
- select.addEventListener(CustomEventType.FetchComplete, async () => {
30
- await clock.runAll();
31
- resolve(select);
32
- }, { once: true });
33
- });
34
- await mouseClickElement(select);
35
- await clock.runAll();
36
- return promise;
37
- };
38
20
  export const clear = (select) => {
39
21
  select.shadowRoot.querySelector('.clear-button').click();
40
22
  };
41
- export const getOptions = (select) => {
42
- return select.shadowRoot.querySelector('temba-options[visible]');
43
- };
44
- export const clickOption = async (clock, select, index) => {
45
- const options = getOptions(select);
46
- const option = options.shadowRoot.querySelector(`[data-option-index="${index}"]`);
47
- await mouseClickElement(option);
48
- await options.updateComplete;
49
- await select.updateComplete;
50
- await clock.runAll();
51
- checkTimers(clock);
52
- };
53
- export const openAndClick = async (clock, select, index) => {
54
- await open(clock, select);
55
- await clickOption(clock, select, index);
56
- };
57
23
  export const getSelectHTML = (options = colors, attrs = { placeholder: 'Select a color', name: 'color' }, selected = null) => {
58
24
  const selectHTML = `
59
25
  <temba-select${Object.keys(attrs)
@@ -121,7 +87,7 @@ describe('temba-select', () => {
121
87
  select.disabled = true;
122
88
  expect(select.disabled).to.equal(true);
123
89
  // make sure we can't select anymore
124
- await open(clock, select);
90
+ await openSelect(clock, select);
125
91
  expect(select.isOpen()).to.equal(false);
126
92
  await assertScreenshot('select/disabled-multi-selection', getClip(select));
127
93
  });
@@ -139,7 +105,7 @@ describe('temba-select', () => {
139
105
  });
140
106
  it('shows options when opened', async () => {
141
107
  const select = await createSelect(clock, getSelectHTML());
142
- await open(clock, select);
108
+ await openSelect(clock, select);
143
109
  const options = getOptions(select);
144
110
  assert.instanceOf(options, Options);
145
111
  // our options should be visible
@@ -156,6 +122,22 @@ describe('temba-select', () => {
156
122
  expect(select.values[0].name).to.equal('Embedded Option');
157
123
  await assertScreenshot('select/embedded', getClipWithOptions(select));
158
124
  });
125
+ it('shows no options message when opening with empty options', async () => {
126
+ const select = await createSelect(clock, getSelectHTML([], { placeholder: 'Select an option' }));
127
+ // attempt to open the select with no options
128
+ await openSelect(clock, select);
129
+ // should show options dropdown even though there are no options
130
+ const options = getOptions(select);
131
+ assert.instanceOf(options, Options);
132
+ // the options dropdown should be visible
133
+ assert.isTrue(options.shadowRoot
134
+ .querySelector('.options-container')
135
+ .classList.contains('show'));
136
+ // should contain a "No options" message
137
+ const noOptionsText = options.shadowRoot.textContent;
138
+ assert.include(noOptionsText.toLowerCase(), 'no options');
139
+ await assertScreenshot('select/empty-options', getClipWithOptions(select));
140
+ });
159
141
  describe('single selection', () => {
160
142
  it('can select a single option', async () => {
161
143
  const select = await createSelect(clock, getSelectHTML());
@@ -179,12 +161,12 @@ describe('temba-select', () => {
179
161
  expect(select.values.length).to.equal(1);
180
162
  expect(select.values[0].name).to.equal('Green');
181
163
  // for single selection our current selection should be in the list and focused
182
- await open(clock, select);
164
+ await openSelect(clock, select);
183
165
  assert.equal(select.cursorIndex, 1);
184
166
  assert.equal(select.visibleOptions.length, 3);
185
167
  // now lets do a search, we should see our selection (green) and one other (red)
186
168
  await typeInto('temba-select', 're', false);
187
- await open(clock, select);
169
+ await openSelect(clock, select);
188
170
  assert.equal(select.visibleOptions.length, 2);
189
171
  await assertScreenshot('select/search-with-selected', getClipWithOptions(select));
190
172
  // but our cursor should be on the first match
@@ -225,7 +207,7 @@ describe('temba-select', () => {
225
207
  await openAndClick(clock, select, 0);
226
208
  assert(changeEvent.called, 'change event not fired');
227
209
  changeEvent.resetHistory();
228
- await open(clock, select);
210
+ await openSelect(clock, select);
229
211
  assert.equal(select.visibleOptions.length, 0);
230
212
  assert(!changeEvent.called, 'change event should not be fired');
231
213
  // but we should have red and green selected only, no blue
@@ -247,6 +229,121 @@ describe('temba-select', () => {
247
229
  expect(select.values.length).to.equal(2);
248
230
  });
249
231
  });
232
+ describe('drag and drop reordering', () => {
233
+ it('handles drag and drop with swap-based logic', async () => {
234
+ const select = await createSelect(clock, getSelectHTML([
235
+ { name: 'Red', value: '0', selected: true },
236
+ { name: 'Green', value: '1', selected: true },
237
+ { name: 'Blue', value: '2', selected: true }
238
+ ], {
239
+ placeholder: 'Select colors',
240
+ multi: true
241
+ }));
242
+ // Verify initial order: Red, Green, Blue
243
+ expect(select.values.length).to.equal(3);
244
+ expect(select.values[0].name).to.equal('Red');
245
+ expect(select.values[1].name).to.equal('Green');
246
+ expect(select.values[2].name).to.equal('Blue');
247
+ const sortableList = select.shadowRoot.querySelector('temba-sortable-list');
248
+ expect(sortableList).to.not.be.null;
249
+ // Example 1: Pick up Blue (index 2), drop between Red and Green
250
+ // Expected result: Red, Blue, Green (swap [1,2])
251
+ const blueItem = sortableList.querySelector('#selected-2');
252
+ const greenItem = sortableList.querySelector('#selected-1');
253
+ expect(blueItem).to.not.be.null;
254
+ expect(greenItem).to.not.be.null;
255
+ const blueBounds = blueItem.getBoundingClientRect();
256
+ const greenBounds = greenItem.getBoundingClientRect();
257
+ // Start drag from Blue item
258
+ await moveMouse(blueBounds.left + 10, blueBounds.top + 10);
259
+ await mouseDown();
260
+ // Drag to position between Red and Green (left side of Green)
261
+ await moveMouse(greenBounds.left - 5, greenBounds.top + 10);
262
+ await waitFor(100);
263
+ await mouseUp();
264
+ clock.runAll();
265
+ // Verify result: Red, Blue, Green (Green and Blue swapped)
266
+ expect(select.values.length).to.equal(3);
267
+ expect(select.values[0].name).to.equal('Red');
268
+ expect(select.values[1].name).to.equal('Blue');
269
+ expect(select.values[2].name).to.equal('Green');
270
+ // Reset for next test
271
+ select.values = [
272
+ { name: 'Red', value: '0', selected: true },
273
+ { name: 'Green', value: '1', selected: true },
274
+ { name: 'Blue', value: '2', selected: true }
275
+ ];
276
+ await select.updateComplete;
277
+ // Example 2: Pick up Red (index 0), drop at end
278
+ // Expected result: Green, Blue, Red (swap [0,2])
279
+ const redItem = sortableList.querySelector('#selected-0');
280
+ const redBounds = redItem.getBoundingClientRect();
281
+ const blueItemBounds = sortableList
282
+ .querySelector('#selected-2')
283
+ .getBoundingClientRect();
284
+ // Start drag from Red item
285
+ await moveMouse(redBounds.left + 10, redBounds.top + 10);
286
+ await mouseDown();
287
+ // Drag to end position (right side of Blue)
288
+ await moveMouse(blueItemBounds.right + 5, blueItemBounds.top + 10);
289
+ await waitFor(100);
290
+ await mouseUp();
291
+ clock.runAll();
292
+ // Verify result: Green, Blue, Red (Red and Blue swapped)
293
+ expect(select.values.length).to.equal(3);
294
+ expect(select.values[0].name).to.equal('Green');
295
+ expect(select.values[1].name).to.equal('Blue');
296
+ expect(select.values[2].name).to.equal('Red');
297
+ // Reset for next test
298
+ select.values = [
299
+ { name: 'Red', value: '0', selected: true },
300
+ { name: 'Green', value: '1', selected: true },
301
+ { name: 'Blue', value: '2', selected: true }
302
+ ];
303
+ await select.updateComplete;
304
+ // Example 3: Pick up Green (index 1), drop at same position
305
+ // Expected result: No change, no event
306
+ const greenItemNew = sortableList.querySelector('#selected-1');
307
+ const greenBoundsNew = greenItemNew.getBoundingClientRect();
308
+ // Start drag from Green item
309
+ await moveMouse(greenBoundsNew.left + 10, greenBoundsNew.top + 10);
310
+ await mouseDown();
311
+ // Drag slightly but return to same position
312
+ await moveMouse(greenBoundsNew.left + 15, greenBoundsNew.top + 10);
313
+ await moveMouse(greenBoundsNew.left + 10, greenBoundsNew.top + 10);
314
+ await waitFor(100);
315
+ await mouseUp();
316
+ clock.runAll();
317
+ // Verify result: No change
318
+ expect(select.values.length).to.equal(3);
319
+ expect(select.values[0].name).to.equal('Red');
320
+ expect(select.values[1].name).to.equal('Green');
321
+ expect(select.values[2].name).to.equal('Blue');
322
+ });
323
+ it('does not show sortable list for single item', async () => {
324
+ const select = await createSelect(clock, getSelectHTML([{ name: 'Red', value: '0', selected: true }], {
325
+ placeholder: 'Select a color',
326
+ multi: true
327
+ }));
328
+ // Should not have a sortable list with only one item
329
+ const sortableList = select.shadowRoot.querySelector('temba-sortable-list');
330
+ expect(sortableList).to.be.null;
331
+ // Should still show the selected item normally
332
+ expect(select.values.length).to.equal(1);
333
+ expect(select.values[0].name).to.equal('Red');
334
+ });
335
+ it('does not show sortable list for non-multi select', async () => {
336
+ const select = await createSelect(clock, getSelectHTML([{ name: 'Red', value: '0', selected: true }], {
337
+ placeholder: 'Select a color',
338
+ multi: false
339
+ }));
340
+ // Should not have a sortable list for single select
341
+ const sortableList = select.shadowRoot.querySelector('temba-sortable-list');
342
+ expect(sortableList).to.be.null;
343
+ expect(select.values.length).to.equal(1);
344
+ expect(select.values[0].name).to.equal('Red');
345
+ });
346
+ });
250
347
  describe('static options', () => {
251
348
  it('accepts an initial value', async () => {
252
349
  const select = await createSelect(clock, getSelectHTML(colors, { value: '1' }));
@@ -265,7 +362,7 @@ describe('temba-select', () => {
265
362
  placeholder: 'Select a color',
266
363
  endpoint: '/test-assets/select/colors.json'
267
364
  }));
268
- await open(clock, select);
365
+ await openSelect(clock, select);
269
366
  await assertScreenshot('select/remote-options', getClipWithOptions(select));
270
367
  assert.equal(select.visibleOptions.length, 3);
271
368
  });
@@ -276,7 +373,7 @@ describe('temba-select', () => {
276
373
  searchable: true
277
374
  }));
278
375
  await typeInto('temba-select', 're', false);
279
- await open(clock, select);
376
+ await openSelect(clock, select);
280
377
  assert.equal(select.visibleOptions.length, 2);
281
378
  await assertScreenshot('select/searching', getClipWithOptions(select));
282
379
  });
@@ -298,7 +395,7 @@ describe('temba-select', () => {
298
395
  endpoint: '/test-assets/select/groups.json',
299
396
  valueKey: 'uuid'
300
397
  }));
301
- await open(clock, select);
398
+ await openSelect(clock, select);
302
399
  // should have all three pages visible right away
303
400
  assert.equal(select.visibleOptions.length, 15);
304
401
  });
@@ -310,12 +407,12 @@ describe('temba-select', () => {
310
407
  searchable: true
311
408
  }));
312
409
  // wait for updates from fetching three pages
313
- await open(clock, select);
410
+ await openSelect(clock, select);
314
411
  assert.equal(select.visibleOptions.length, 15);
315
412
  // close and reopen
316
413
  select.blur();
317
414
  await clock.tick(250);
318
- await open(clock, select);
415
+ await openSelect(clock, select);
319
416
  assert.equal(select.visibleOptions.length, 15);
320
417
  // close and reopen once more (previous bug failed on third opening)
321
418
  // select.blur();
@@ -330,7 +427,7 @@ describe('temba-select', () => {
330
427
  expressions: 'session'
331
428
  }));
332
429
  await typeInto('temba-select', 'Hi there @contact', false);
333
- await open(clock, select);
430
+ await openSelect(clock, select);
334
431
  assert.equal(select.completionOptions.length, 14);
335
432
  await assertScreenshot('select/expressions', getClipWithOptions(select));
336
433
  });
@@ -361,7 +458,7 @@ describe('temba-select', () => {
361
458
  // select the first option
362
459
  await openAndClick(clock, select, 1);
363
460
  // now open and look at focus
364
- await open(clock, select);
461
+ await openSelect(clock, select);
365
462
  await assertScreenshot('select/search-selected-focus', getClipWithOptions(select));
366
463
  });
367
464
  it('should show search with existing multiple selection', async () => {
@@ -373,10 +470,10 @@ describe('temba-select', () => {
373
470
  // select the first option
374
471
  await openAndClick(clock, select, 0);
375
472
  await openAndClick(clock, select, 0);
376
- await open(clock, select);
473
+ await openSelect(clock, select);
377
474
  // now lets do a search, we should see our selection (green) and one other (red)
378
475
  await typeInto('temba-select', 're', false);
379
- await open(clock, select);
476
+ await openSelect(clock, select);
380
477
  // should have two things selected and active query and no matching options
381
478
  await assertScreenshot('select/search-multi-no-matches', getClipWithOptions(select));
382
479
  });
@@ -388,13 +485,13 @@ describe('temba-select', () => {
388
485
  expressions: 'session'
389
486
  }));
390
487
  await typeInto('temba-select', 'look at @(max(m', false);
391
- await open(clock, select);
488
+ await openSelect(clock, select);
392
489
  await assertScreenshot('select/functions', getClipWithOptions(select));
393
490
  });
394
491
  it('should truncate selection if necessesary', async () => {
395
492
  const options = [
396
493
  {
397
- name: 'this_is_a_long_selection_to_make_sure_it_truncates',
494
+ name: 'this_is_a_long_selection_to_make_sure_it_truncates_but_it_needs_to_be_longer',
398
495
  value: '0'
399
496
  }
400
497
  ];