@visns-studio/visns-components 6.32.3 → 6.34.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 (41) hide show
  1. package/README.md +470 -0
  2. package/package.json +1 -1
  3. package/src/components/DataGrid.jsx +44 -2
  4. package/src/components/Field.jsx +32 -0
  5. package/src/components/Form.jsx +39 -2
  6. package/src/components/Navigation.jsx +274 -15
  7. package/src/components/Notification.jsx +13 -2
  8. package/src/components/TableFilter.jsx +14 -2
  9. package/src/components/auth/Login.jsx +9 -2
  10. package/src/components/auth/PasskeyEnrolPrompt.jsx +269 -0
  11. package/src/components/auth/Profile.jsx +422 -26
  12. package/src/components/auth/authEndpoints.js +43 -0
  13. package/src/components/auth/passkeyClient.js +102 -0
  14. package/src/components/auth/passkeyPrompt.js +408 -0
  15. package/src/components/auth/profileLayout.js +45 -0
  16. package/src/components/controls/DataGridSearch.jsx +16 -2
  17. package/src/components/controls/DataGridSortSheet.jsx +2 -0
  18. package/src/components/generic/ActionButtons.jsx +1 -1
  19. package/src/components/generic/GenericAuth.jsx +197 -21
  20. package/src/components/generic/GenericDetail.jsx +95 -3
  21. package/src/components/generic/GenericMain.jsx +7 -0
  22. package/src/components/generic/StandardModal.jsx +71 -158
  23. package/src/components/sms/SmsCampaigns.jsx +2487 -0
  24. package/src/components/sms/SmsInbox.jsx +18 -0
  25. package/src/components/sms/SmsThreadPanel.jsx +20 -0
  26. package/src/components/sms/smsEndpoints.js +23 -0
  27. package/src/components/styles/DataGrid.module.scss +22 -0
  28. package/src/components/styles/Form.module.scss +100 -2
  29. package/src/components/styles/Navigation.module.scss +322 -5
  30. package/src/components/styles/Notification.module.scss +140 -8
  31. package/src/components/styles/PasskeyEnrolPrompt.module.scss +105 -0
  32. package/src/components/styles/Profile.module.scss +157 -0
  33. package/src/components/styles/Sms.module.scss +451 -0
  34. package/src/components/styles/StandardModal.module.scss +273 -0
  35. package/src/components/styles/global.css +24 -5
  36. package/src/components/utils/navCollapsed.js +201 -0
  37. package/src/components/utils/rowActionSettings.js +76 -0
  38. package/src/components/utils/usePasskeysEnabled.js +84 -0
  39. package/src/components/utils/useShellLayout.js +131 -0
  40. package/src/index.js +103 -1
  41. package/src/utils/rememberTab.js +70 -0
@@ -992,6 +992,8 @@ function Field({
992
992
  {settings.create && (
993
993
  <button
994
994
  className={styles.buttonRight}
995
+ title="Create a new record to choose in this field"
996
+ aria-label="Create a new record to choose in this field"
995
997
  onClick={(e) => {
996
998
  e.preventDefault();
997
999
  let allow = false;
@@ -1285,6 +1287,8 @@ function Field({
1285
1287
  {settings.create && (
1286
1288
  <button
1287
1289
  className={styles.buttonRight}
1290
+ title="Create a new record to choose in this field"
1291
+ aria-label="Create a new record to choose in this field"
1288
1292
  onClick={(e) => {
1289
1293
  e.preventDefault();
1290
1294
  let allow = false;
@@ -1484,6 +1488,8 @@ function Field({
1484
1488
 
1485
1489
  <button
1486
1490
  className={styles['trash-button']}
1491
+ title="Remove this file from the selection"
1492
+ aria-label="Remove this file from the selection"
1487
1493
  onClick={(e) => {
1488
1494
  e.preventDefault();
1489
1495
  e.stopPropagation();
@@ -1580,6 +1586,18 @@ function Field({
1580
1586
  {((inputValue.key && inputValue.uuid) || inputValue.file_url || inputValue.file_path || inputValue.id) && (
1581
1587
  <button
1582
1588
  className={styles['download-button']}
1589
+ // NO NATIVE `title` HERE, unlike every
1590
+ // other button in this file: this one
1591
+ // already draws react-tooltip's card off
1592
+ // `data-tooltip-content`, and a `title`
1593
+ // beside it makes the browser draw a
1594
+ // SECOND tooltip a moment later, in a
1595
+ // different place. The `aria-label` is
1596
+ // the part that was genuinely missing —
1597
+ // the body is a glyph, and a
1598
+ // `data-tooltip-content` is not an
1599
+ // accessible name.
1600
+ aria-label="Download a copy of this file"
1583
1601
  data-tooltip-id="system-tooltip"
1584
1602
  data-tooltip-content={`Download ${inputValue.filename || inputValue.name || inputValue.file_name}`}
1585
1603
  onClick={(e) => {
@@ -2083,6 +2101,7 @@ function Field({
2083
2101
  }
2084
2102
  className={styles.jsonTableDeleteBtn}
2085
2103
  title="Delete row"
2104
+ aria-label="Delete row"
2086
2105
  >
2087
2106
  <Trash2 size={14} />
2088
2107
  </button>
@@ -2102,6 +2121,7 @@ function Field({
2102
2121
  onAddJsonTableRow && onAddJsonTableRow(settings.id, settings.defaultRow || {})
2103
2122
  }
2104
2123
  className={styles.jsonTableAddBtn}
2124
+ title="Add another row to this list"
2105
2125
  >
2106
2126
  <CirclePlus size={16} />
2107
2127
  <span>{settings.addRowButton?.label || 'Add Row'}</span>
@@ -2214,6 +2234,8 @@ function Field({
2214
2234
  {settings.create && (
2215
2235
  <button
2216
2236
  className={styles.buttonRight}
2237
+ title="Create a new record to choose in this field"
2238
+ aria-label="Create a new record to choose in this field"
2217
2239
  onClick={(e) => {
2218
2240
  e.preventDefault();
2219
2241
  let allow = false;
@@ -2502,6 +2524,7 @@ function Field({
2502
2524
  <button
2503
2525
  type="button"
2504
2526
  className={styles.signButton}
2527
+ title="Open the signature pad and sign this document"
2505
2528
  onClick={(e) => {
2506
2529
  e.preventDefault();
2507
2530
 
@@ -3143,6 +3166,7 @@ function Field({
3143
3166
  control). Visibility is CSS-only. */}
3144
3167
  <button
3145
3168
  type="button"
3169
+ title="Empty this date field"
3146
3170
  aria-label="Clear date"
3147
3171
  aria-hidden={value ? undefined : 'true'}
3148
3172
  tabIndex={value ? 0 : -1}
@@ -3672,6 +3696,8 @@ function Field({
3672
3696
  <h1>Edit Canvas</h1>
3673
3697
  <button
3674
3698
  className={styles.modal__close}
3699
+ title="Close this drawing without keeping it"
3700
+ aria-label="Close this drawing without keeping it"
3675
3701
  onClick={() => setCanvasPopupOpen(false)}
3676
3702
  >
3677
3703
  <X size={24} color="#FFF" />
@@ -3684,6 +3710,7 @@ function Field({
3684
3710
  <ul className={styles.drawactions}>
3685
3711
  <li>
3686
3712
  <button
3713
+ title="Keep this drawing on the field and close it"
3687
3714
  onClick={() => {
3688
3715
  handleCanvasSave();
3689
3716
  }}
@@ -3694,6 +3721,7 @@ function Field({
3694
3721
  </li>
3695
3722
  <li>
3696
3723
  <button
3724
+ title="Draw freehand on this drawing"
3697
3725
  onClick={() => {
3698
3726
  setSketchTool(Tools.Pencil);
3699
3727
  setToolClass('pencil');
@@ -3711,6 +3739,7 @@ function Field({
3711
3739
  </li>
3712
3740
  <li>
3713
3741
  <button
3742
+ title="Draw straight lines on this drawing"
3714
3743
  onClick={() => {
3715
3744
  setSketchTool(Tools.Line);
3716
3745
 
@@ -3729,6 +3758,7 @@ function Field({
3729
3758
  </li>
3730
3759
  <li>
3731
3760
  <button
3761
+ title="Draw circles on this drawing"
3732
3762
  onClick={() => {
3733
3763
  setSketchTool(Tools.Circle);
3734
3764
 
@@ -3747,6 +3777,7 @@ function Field({
3747
3777
  </li>
3748
3778
  <li>
3749
3779
  <button
3780
+ title="Take back the last mark you made"
3750
3781
  onClick={() => sketchRef.current.undo()}
3751
3782
  className={styles['drawaction-undo']}
3752
3783
  >
@@ -3755,6 +3786,7 @@ function Field({
3755
3786
  </li>
3756
3787
  <li>
3757
3788
  <button
3789
+ title="Erase every mark on this drawing"
3758
3790
  onClick={() =>
3759
3791
  sketchRef.current.clearCanvas()
3760
3792
  }
@@ -3686,6 +3686,16 @@ function Form({
3686
3686
  >
3687
3687
  <button
3688
3688
  className="group-expand-btn"
3689
+ title={
3690
+ collapsed
3691
+ ? 'Show the rows in this group'
3692
+ : 'Hide the rows in this group'
3693
+ }
3694
+ aria-label={
3695
+ collapsed
3696
+ ? 'Show the rows in this group'
3697
+ : 'Hide the rows in this group'
3698
+ }
3689
3699
  onClick={(e) => {
3690
3700
  e.preventDefault();
3691
3701
  e.stopPropagation();
@@ -3949,6 +3959,7 @@ function Form({
3949
3959
  formSettings.customButton.url ? (
3950
3960
  <button
3951
3961
  className={styles.btn}
3962
+ title="Run this action against the record on this form"
3952
3963
  onClick={(e) => {
3953
3964
  e.preventDefault();
3954
3965
  handleCustom(formSettings);
@@ -3961,14 +3972,22 @@ function Form({
3961
3972
  ) : null}
3962
3973
 
3963
3974
  {formSettings?.download?.button?.label && (
3964
- <button className={styles.btn} onClick={handleDownload}>
3975
+ <button
3976
+ className={styles.btn}
3977
+ title="Download the result of this form as a file"
3978
+ onClick={handleDownload}
3979
+ >
3965
3980
  {formSettings.download.button.label}
3966
3981
  </button>
3967
3982
  )}
3968
3983
 
3969
3984
  {formSettings.hasOwnProperty('sortButton') &&
3970
3985
  formSettings.sortButton.url ? (
3971
- <button className={styles.btn} onClick={handleSort}>
3986
+ <button
3987
+ className={styles.btn}
3988
+ title="Sort this record's files into name order"
3989
+ onClick={handleSort}
3990
+ >
3972
3991
  {formSettings.sortButton.label
3973
3992
  ? formSettings.sortButton.label
3974
3993
  : 'Sort'}
@@ -3977,6 +3996,7 @@ function Form({
3977
3996
 
3978
3997
  <button
3979
3998
  className={styles.saveBtn}
3999
+ title="Submit this form"
3980
4000
  onClick={handleSubmit}
3981
4001
  data-type="save"
3982
4002
  >
@@ -3988,6 +4008,7 @@ function Form({
3988
4008
  {formSettings.hasOwnProperty('saveExit') && (
3989
4009
  <button
3990
4010
  className={styles.btn}
4011
+ title="Save this form and leave this screen"
3991
4012
  onClick={handleSubmit}
3992
4013
  data-type="saveExit"
3993
4014
  >
@@ -4014,6 +4035,8 @@ function Form({
4014
4035
  </h1>
4015
4036
  <button
4016
4037
  className={styles.modal__close}
4038
+ title="Close this form without saving"
4039
+ aria-label="Close this form without saving"
4017
4040
  onClick={closeModal}
4018
4041
  >
4019
4042
  <X strokeWidth={2} size={24} />
@@ -4108,6 +4131,7 @@ function Form({
4108
4131
  >
4109
4132
  <button
4110
4133
  className={styles.btnSecondary}
4134
+ title="Close without saving the changes you have made"
4111
4135
  onClick={(e) => {
4112
4136
  e.preventDefault();
4113
4137
  guardedClose();
@@ -4119,6 +4143,7 @@ function Form({
4119
4143
  </button>
4120
4144
  <button
4121
4145
  className={styles.btn}
4146
+ title="Save this form and close it"
4122
4147
  onClick={handleSubmit}
4123
4148
  data-type="save"
4124
4149
  >
@@ -4129,6 +4154,7 @@ function Form({
4129
4154
  ) && (
4130
4155
  <button
4131
4156
  className={styles.btn}
4157
+ title="Save this record and open a blank form for the next one"
4132
4158
  onClick={handleSubmit}
4133
4159
  data-type="saveAnother"
4134
4160
  >
@@ -4140,6 +4166,7 @@ function Form({
4140
4166
  ) && (
4141
4167
  <button
4142
4168
  className={styles.btn}
4169
+ title="Save this form and leave this screen"
4143
4170
  onClick={handleSubmit}
4144
4171
  data-type="saveExit"
4145
4172
  >
@@ -4183,6 +4210,7 @@ function Form({
4183
4210
  >
4184
4211
  <button
4185
4212
  className={styles.btnSecondary}
4213
+ title="Close without saving the changes you have made"
4186
4214
  onClick={(e) => {
4187
4215
  e.preventDefault();
4188
4216
  guardedClose();
@@ -4194,6 +4222,7 @@ function Form({
4194
4222
  </button>
4195
4223
  <button
4196
4224
  className={styles.btn}
4225
+ title="Save this form and close it"
4197
4226
  onClick={handleSubmit}
4198
4227
  data-type="save"
4199
4228
  >
@@ -4204,6 +4233,12 @@ function Form({
4204
4233
  className={
4205
4234
  styles.btn
4206
4235
  }
4236
+ title={
4237
+ saveAnotherDisabled
4238
+ ? saveAnotherDisableWhen?.message ||
4239
+ 'This action is currently unavailable.'
4240
+ : 'Save this form and move straight on to the next step'
4241
+ }
4207
4242
  onClick={
4208
4243
  handleSubmit
4209
4244
  }
@@ -4234,6 +4269,7 @@ function Form({
4234
4269
  className={
4235
4270
  styles.btn
4236
4271
  }
4272
+ title="Save this form and leave this screen"
4237
4273
  onClick={
4238
4274
  handleSubmit
4239
4275
  }
@@ -4304,6 +4340,7 @@ function Form({
4304
4340
  >
4305
4341
  <button
4306
4342
  className={styles.btn}
4343
+ title="Submit this form"
4307
4344
  onClick={handleSubmit}
4308
4345
  data-type="save"
4309
4346
  >