@visns-studio/visns-components 6.24.4 → 6.26.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 (51) hide show
  1. package/package.json +4 -2
  2. package/src/components/Autocomplete.jsx +189 -119
  3. package/src/components/DataGrid.jsx +472 -31
  4. package/src/components/Navigation.jsx +475 -51
  5. package/src/components/auth/ClientAuthFrame.jsx +5 -0
  6. package/src/components/auth/ClientAuthScreen.jsx +29 -0
  7. package/src/components/callQueue/CallQueueDiagnostics.jsx +1043 -0
  8. package/src/components/callQueue/CallQueuePop.jsx +713 -90
  9. package/src/components/callQueue/CallQueueSettings.jsx +308 -146
  10. package/src/components/callQueue/callPopStatus.js +236 -0
  11. package/src/components/callQueue/callQueueHelpers.js +284 -2
  12. package/src/components/columns/ColumnRenderers.jsx +3 -46
  13. package/src/components/columns/StackedRow.jsx +186 -0
  14. package/src/components/controls/DataGridSearch.jsx +110 -2
  15. package/src/components/controls/DataGridSortSheet.jsx +155 -0
  16. package/src/components/generic/GenericAuth.jsx +50 -18
  17. package/src/components/generic/GenericDashboard.jsx +20 -1
  18. package/src/components/generic/GenericDetail.jsx +446 -259
  19. package/src/components/mapboxSearchBox.js +640 -0
  20. package/src/components/navBadges.js +63 -1
  21. package/src/components/navDrawer.js +147 -0
  22. package/src/components/sms/SmsThreadPanel.jsx +34 -6
  23. package/src/components/sms/smsHelpers.js +15 -0
  24. package/src/components/styles/CallQueueDiagnostics.module.scss +398 -0
  25. package/src/components/styles/CallQueuePop.module.scss +29 -0
  26. package/src/components/styles/CallQueueSettings.module.scss +93 -0
  27. package/src/components/styles/ClientAuth.module.scss +39 -0
  28. package/src/components/styles/DataGrid.module.scss +158 -5
  29. package/src/components/styles/Field.module.scss +52 -1
  30. package/src/components/styles/Form.module.scss +82 -0
  31. package/src/components/styles/GenericClientPortal.module.scss +72 -20
  32. package/src/components/styles/GenericDashboard.module.scss +50 -0
  33. package/src/components/styles/GenericDetail.module.scss +63 -1
  34. package/src/components/styles/GenericDynamic.module.scss +23 -0
  35. package/src/components/styles/GenericFormBuilder.module.scss +11 -0
  36. package/src/components/styles/GenericIndex.module.scss +6 -1
  37. package/src/components/styles/Navigation.module.scss +460 -7
  38. package/src/components/styles/Sms.module.scss +92 -0
  39. package/src/components/styles/StackedRow.module.scss +182 -0
  40. package/src/components/styles/TicketConversation.module.scss +76 -0
  41. package/src/components/styles/Vault.module.scss +192 -0
  42. package/src/components/styles/density.css +10 -0
  43. package/src/components/styles/global-datagrid.css +163 -0
  44. package/src/components/styles/global.css +20 -0
  45. package/src/components/tickets/TicketConversation.jsx +13 -8
  46. package/src/components/utils/ConfirmDialog.js +22 -3
  47. package/src/components/utils/cardLayout.js +666 -0
  48. package/src/components/utils/contactChannels.js +130 -0
  49. package/src/components/utils/editPlacement.js +95 -0
  50. package/src/components/utils/useDensity.js +303 -7
  51. package/src/index.js +42 -0
@@ -314,6 +314,26 @@ input[type]:not([type='search']):not([type='url']):not([type='hidden']):not(
314
314
  }
315
315
  }
316
316
 
317
+ /* THE DROPDOWN ARROW, restored. The rule further up gives `select` its
318
+ chevron and strips the native chrome (`appearance: none`), and then the
319
+ chained rule above this comment writes `background: white` — a SHORTHAND,
320
+ which resets background-image along with the colour. Net result shipped
321
+ for months: every native select rendered as a plain box visually identical
322
+ to a text input, with nothing saying "this opens".
323
+
324
+ This sits AFTER the chained rule so source order wins at equal
325
+ specificity, states only the longhands the shorthand clobbered, and
326
+ positions the chevron inside the field (the original hugged the raw right
327
+ edge) with the padding to keep long option text from running under it. */
328
+ select {
329
+ background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0Ljk1IDEwIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6IzQ0NDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPmFycm93czwvdGl0bGU+PHJlY3QgY2xhc3M9ImNscy0xIiB3aWR0aD0iNC45NSIgaGVpZ2h0PSIxMCIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxLjQxIDQuNjcgMi40OCAzLjE4IDMuNTQgNC42NyAxLjQxIDQuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iMy41NCA1LjMzIDIuNDggNi44MiAxLjQxIDUuMzMgMy41NCA1LjMzIi8+PC9zdmc+);
330
+ background-repeat: no-repeat;
331
+ background-position: right 0.65rem center;
332
+ background-size: 7px 14px;
333
+ padding-right: 2rem;
334
+ cursor: pointer;
335
+ }
336
+
317
337
  /* A textarea is multi-line by definition, so it is the one control that opts
318
338
  out of the fixed height — it keeps the font and the horizontal padding, and
319
339
  takes the vertical padding that puts its FIRST row on the same line as the
@@ -119,6 +119,19 @@ const TicketConversation = ({
119
119
  <div className={styles.wrap}>
120
120
  {ticket && <TicketHeader ticket={ticket} counts={counts} />}
121
121
 
122
+ {/* The composer sits ABOVE the thread, and a posted reply is
123
+ PREPENDED: the server answers newest-first now, so the top of
124
+ the list is where the conversation currently is — writing
125
+ happens beside the message being answered, not three scrolls
126
+ below it under the original request. */}
127
+ {canReply && (
128
+ <Composer
129
+ base={base}
130
+ ticketId={ticketId}
131
+ onPosted={(entry) => setEntries((prev) => [entry, ...prev])}
132
+ />
133
+ )}
134
+
122
135
  {entries.length === 0 ? (
123
136
  <p className={styles.state}>
124
137
  Nothing has been said on this ticket yet.
@@ -130,14 +143,6 @@ const TicketConversation = ({
130
143
  ))}
131
144
  </ol>
132
145
  )}
133
-
134
- {canReply && (
135
- <Composer
136
- base={base}
137
- ticketId={ticketId}
138
- onPosted={(entry) => setEntries((prev) => [...prev, entry])}
139
- />
140
- )}
141
146
  </div>
142
147
  );
143
148
  };
@@ -42,9 +42,28 @@ export const confirmDialog = (options) => {
42
42
  data = null, // Optional data object from the selected row
43
43
  } = options;
44
44
 
45
- // Find Yes and No buttons if they exist
46
- const yesButton = buttons.find((btn) => btn.label === 'Yes');
47
- const noButton = buttons.find((btn) => btn.label === 'No');
45
+ /*
46
+ * WHICH BUTTON CONFIRMS IS NOT A LABEL LOOKUP ANY MORE.
47
+ *
48
+ * This used to find the confirm handler with `label === 'Yes'` and
49
+ * nothing else — so a dialog whose button said "Delete" rendered
50
+ * perfectly, showed a default "Yes" button, and ran NOTHING when it was
51
+ * pressed. Two real screens shipped in that state (ticket delete,
52
+ * customer delete): the reader confirmed a deletion and the app silently
53
+ * did not delete, which is the worst available failure — no error, no
54
+ * effect, no clue. App code even grew comments warning that every
55
+ * confirm button must be labelled "Yes".
56
+ *
57
+ * Now: "No" or "Cancel" (either case) is the cancel button; the FIRST
58
+ * button that is neither is the confirm, whatever it says — "Yes",
59
+ * "Delete", "Remove from this project". Its label is what the reader
60
+ * sees, which is how a destructive dialog should read anyway.
61
+ */
62
+ const isCancelLabel = (label) =>
63
+ typeof label === 'string' && ['no', 'cancel'].includes(label.toLowerCase());
64
+
65
+ const yesButton = buttons.find((btn) => !isCancelLabel(btn.label));
66
+ const noButton = buttons.find((btn) => isCancelLabel(btn.label));
48
67
 
49
68
  // Default button text
50
69
  const confirmButtonText = yesButton ? yesButton.label : 'Yes';