@visns-studio/visns-components 6.6.3 → 6.15.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 (100) hide show
  1. package/README.md +1658 -18
  2. package/package.json +10 -4
  3. package/src/components/DataGrid.jsx +619 -158
  4. package/src/components/Fetch.jsx +80 -3
  5. package/src/components/Form.jsx +9 -0
  6. package/src/components/Navigation.jsx +109 -50
  7. package/src/components/Notification.jsx +279 -9
  8. package/src/components/TableFilter.jsx +14 -1
  9. package/src/components/auth/AuthBrandPanel.jsx +43 -0
  10. package/src/components/auth/AuthLoading.jsx +78 -0
  11. package/src/components/auth/AuthShell.jsx +59 -0
  12. package/src/components/auth/ClientAuth.jsx +161 -0
  13. package/src/components/auth/ClientAuthFrame.jsx +59 -0
  14. package/src/components/auth/ClientLogin.jsx +266 -55
  15. package/src/components/auth/ClientOTPVerify.jsx +587 -115
  16. package/src/components/auth/ImpersonateGate.jsx +254 -0
  17. package/src/components/auth/Login.jsx +134 -41
  18. package/src/components/auth/LogoutScreen.jsx +112 -0
  19. package/src/components/auth/Reset.jsx +134 -77
  20. package/src/components/auth/TwoFactorAuth.jsx +475 -297
  21. package/src/components/auth/Verify.jsx +237 -126
  22. package/src/components/auth/authEndpoints.js +105 -0
  23. package/src/components/auth/authFont.js +23 -0
  24. package/src/components/auth/authHelpers.js +465 -0
  25. package/src/components/auth/clientAuthProtocols.js +240 -0
  26. package/src/components/auth/useOptionalRouter.js +49 -0
  27. package/src/components/callQueue/CallQueuePop.jsx +1502 -0
  28. package/src/components/callQueue/CallQueueSettings.jsx +508 -0
  29. package/src/components/callQueue/callQueueHelpers.js +280 -0
  30. package/src/components/callQueue/callQueueSettingsHelpers.js +75 -0
  31. package/src/components/columns/AutoGrowCell.jsx +141 -0
  32. package/src/components/columns/ColumnRenderers.jsx +53 -7
  33. package/src/components/generic/GenericAuth.jsx +163 -96
  34. package/src/components/generic/GenericDetail.jsx +215 -90
  35. package/src/components/generic/GenericIndex.jsx +20 -47
  36. package/src/components/generic/GenericMain.jsx +5 -0
  37. package/src/components/generic/GroupedReportRenderer.jsx +1 -5
  38. package/src/components/generic/StandardModal.jsx +17 -5
  39. package/src/components/generic/reportSemanticSteps/SemanticEntityStep.jsx +1 -6
  40. package/src/components/generic/reportSemanticSteps/SemanticFieldsStep.jsx +4 -11
  41. package/src/components/generic/reportSemanticSteps/SemanticFiltersStep.jsx +9 -27
  42. package/src/components/generic/reportSemanticSteps/SemanticGroupingStep.jsx +5 -13
  43. package/src/components/generic/reportSemanticSteps/SemanticParameterPrompt.jsx +5 -13
  44. package/src/components/generic/reportSemanticSteps/SemanticPreviewStep.jsx +14 -31
  45. package/src/components/generic/reportSemanticSteps/SemanticRelationsStep.jsx +3 -9
  46. package/src/components/generic/reportSemanticSteps/SemanticValueInput.jsx +2 -15
  47. package/src/components/navActive.js +60 -0
  48. package/src/components/notify/desktopNotifications.js +256 -0
  49. package/src/components/sketch/SketchField.jsx +12 -2
  50. package/src/components/sms/SmsComposeModal.jsx +495 -0
  51. package/src/components/sms/SmsInbox.jsx +596 -0
  52. package/src/components/sms/SmsInboxBadge.jsx +468 -0
  53. package/src/components/sms/SmsLineSettings.jsx +854 -0
  54. package/src/components/sms/SmsThreadPanel.jsx +1184 -0
  55. package/src/components/sms/smsEndpoints.js +56 -0
  56. package/src/components/sms/smsHelpers.js +1075 -0
  57. package/src/components/sms/smsLiveState.js +132 -0
  58. package/src/components/sms/useSmsLive.js +307 -0
  59. package/src/components/styles/CallQueuePop.module.scss +646 -0
  60. package/src/components/styles/CallQueueSettings.module.scss +460 -0
  61. package/src/components/styles/ClientAuth.module.scss +229 -0
  62. package/src/components/styles/DataGrid.module.scss +10 -0
  63. package/src/components/styles/GenericDetail.module.scss +153 -26
  64. package/src/components/styles/GenericIndex.module.scss +13 -0
  65. package/src/components/styles/GenericMain.module.scss +19 -2
  66. package/src/components/styles/ImpersonateGate.module.scss +85 -0
  67. package/src/components/styles/Login.module.scss +13 -122
  68. package/src/components/styles/LogoutScreen.module.scss +89 -0
  69. package/src/components/styles/Navigation.module.scss +509 -223
  70. package/src/components/styles/Notification.module.scss +103 -0
  71. package/src/components/styles/Reset.module.scss +52 -186
  72. package/src/components/styles/Sms.module.scss +2382 -0
  73. package/src/components/styles/TableFilter.module.scss +118 -98
  74. package/src/components/styles/TwoFactorAuth.module.scss +115 -176
  75. package/src/components/styles/Vault.module.scss +1983 -0
  76. package/src/components/styles/Verify.module.scss +57 -180
  77. package/src/components/styles/_authBrandPanel.scss +163 -0
  78. package/src/components/styles/_authShell.scss +369 -0
  79. package/src/components/styles/global-datagrid.css +29 -0
  80. package/src/components/utils/buildEnv.js +67 -0
  81. package/src/components/utils/displayValue.js +94 -0
  82. package/src/components/utils/useDensity.js +345 -9
  83. package/src/components/vault/OtpChip.jsx +208 -0
  84. package/src/components/vault/PasswordGenerator.jsx +145 -0
  85. package/src/components/vault/QrScanner.jsx +326 -0
  86. package/src/components/vault/VaultAccessLog.jsx +225 -0
  87. package/src/components/vault/VaultConfirmPanel.jsx +113 -0
  88. package/src/components/vault/VaultEntryForm.jsx +740 -0
  89. package/src/components/vault/VaultManager.jsx +1000 -0
  90. package/src/components/vault/VaultQuickSearch.jsx +681 -0
  91. package/src/components/vault/qrDecode.js +257 -0
  92. package/src/components/vault/useDebouncedValue.js +22 -0
  93. package/src/components/vault/useVaultReveal.js +160 -0
  94. package/src/components/vault/vaultClipboard.js +33 -0
  95. package/src/components/vault/vaultEndpoints.js +40 -0
  96. package/src/components/vault/vaultFit.js +116 -0
  97. package/src/components/vault/vaultHelpers.js +547 -0
  98. package/src/components/vault/vaultNavigation.jsx +58 -0
  99. package/src/components/vault/vaultOtp.js +105 -0
  100. package/src/index.js +233 -1
@@ -1,199 +1,76 @@
1
- .formItem {
2
- width: 100%;
3
- position: relative;
4
- box-sizing: border-box;
5
- margin-bottom: 1rem;
6
-
7
- h1 {
8
- text-align: center;
9
- font-size: 1.5rem;
10
- font-weight: 600;
11
- color: #111827;
12
- margin-bottom: 1.5rem;
13
- }
1
+ /**
2
+ * Set a new password (the link out of the reset email).
3
+ *
4
+ * Replaces the pre-6.1 centred card with the two-pane sign-in language, so the
5
+ * last screen of the reset journey matches the first.
6
+ *
7
+ * Everything shared comes from _authShell.scss; only the password-rules list is
8
+ * particular to this screen.
9
+ */
10
+
11
+ @use './authShell' as *;
12
+
13
+ @include auth-shell;
14
+
15
+ /* The rules used to arrive as a five-line toast AFTER a rejected submit, built
16
+ out of `<br />`s. Stating them up front is both kinder and shorter. */
17
+ .rules {
18
+ margin: 0.2rem 0 0;
19
+ padding: 0;
20
+ list-style: none;
21
+ font-size: 0.8rem;
22
+ line-height: 1.6;
23
+ color: var(--muted);
14
24
 
15
- .fi__label {
16
- position: relative;
25
+ li {
17
26
  display: flex;
18
- align-items: center;
19
- }
20
-
21
- .fi__span {
22
- position: absolute;
23
- transition: all 200ms;
24
- opacity: 0.7;
25
- left: 0;
26
- transform-origin: top left;
27
- cursor: text;
28
- padding: 0 1rem;
29
- font-size: 0.9rem;
30
- color: #6b7280;
27
+ align-items: baseline;
28
+ gap: 0.5rem;
31
29
  }
32
30
 
33
- .fi__div {
34
- transition: all 200ms;
35
- opacity: 0.8;
36
- left: 0;
37
- padding: 19px 13px;
38
- border-radius: 0.5rem;
39
- border: 1px solid #e5e7eb;
40
- box-shadow: none;
41
- }
42
-
43
- .fi__toggle {
44
- width: max-content;
45
- padding: 0 10px 0 0;
46
- box-sizing: border-box;
47
- display: inline;
48
- }
49
-
50
- .fi__toggletxt {
51
- position: relative;
52
- left: 5px;
53
- font-size: 0.95em;
54
- top: -5px;
31
+ /* A dot per rule rather than a bullet glyph, so the list reads as a
32
+ checklist and not as prose. */
33
+ li::before {
34
+ content: '';
35
+ flex: none;
36
+ width: 0.3rem;
37
+ height: 0.3rem;
38
+ border-radius: 50%;
39
+ background: var(--line);
40
+ transition: background 0.15s ease;
55
41
  }
56
42
  }
57
43
 
58
- .fwItem,
59
- .fwBuilderItem {
60
- grid-column: 1 / -1;
61
- width: 100%;
62
- }
44
+ /* Satisfied rules mark themselves as the user types — the point of showing the
45
+ list is that it can answer "what is still missing?". */
46
+ .ruleMet {
47
+ color: var(--ink);
63
48
 
64
- .lastItem {
65
- .btn {
66
- width: 100%;
49
+ &::before {
50
+ background: var(--navy) !important;
67
51
  }
68
52
  }
69
53
 
70
- .loginlogo {
71
- display: block;
72
- width: 100%;
73
- max-width: 150px;
74
- height: auto;
75
- margin: 0 auto;
76
- padding-bottom: 1.5rem;
77
- }
78
-
79
- .logincontainer {
80
- width: 100%;
81
- min-height: 100vh;
82
- display: grid;
83
- place-items: center;
84
- padding: 1rem;
85
- background-color: #f9fafb;
86
- }
87
-
88
- .login {
89
- width: 28rem;
90
- padding: 2rem;
91
- margin: 0;
92
- display: grid;
93
- grid-template-columns: 1fr;
94
- gap: 1rem;
95
- background-color: white;
96
- border-radius: 0.75rem;
97
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
98
- 0 2px 4px -1px rgba(0, 0, 0, 0.06);
99
-
100
- > .formItem {
101
- padding: 0;
102
-
103
- small {
104
- position: absolute;
105
- width: 18px;
106
- height: 18px;
107
- right: 14px;
108
- top: 14px;
109
- opacity: 0.4;
110
- color: #6b7280;
111
- }
112
- }
113
-
114
- > .loginitem {
115
- grid-column: 1 / -1;
116
- padding: 0.25em 0;
117
-
118
- label {
119
- width: 100%;
120
- }
121
-
122
- button {
123
- width: 100%;
124
- }
125
- }
126
- }
127
-
128
- .forgotten span {
129
- display: block;
130
- text-align: center;
131
- color: var(--paragraph-color);
132
- padding: 1rem 0;
133
-
134
- a {
135
- color: var(--secondary-color);
136
- text-decoration: none;
137
- }
138
- }
139
-
140
- .lcontainer {
141
- min-height: 100vh;
142
- display: flex;
54
+ .back {
55
+ display: inline-flex;
143
56
  align-items: center;
144
- justify-content: center;
145
- background-color: #f9fafb;
146
- }
147
-
148
- .lwrap {
149
- display: grid;
150
- grid-template-columns: 1fr;
151
- }
152
-
153
- .aside {
154
- opacity: 1;
155
- position: fixed;
156
- overflow: hidden;
157
- height: 101%;
158
- width: var(--sidebar-width);
159
- }
160
-
161
- .btn {
162
- width: max-content;
163
- display: inline-block;
164
- position: relative;
165
- padding: 0.75rem 1rem;
166
- cursor: pointer;
167
- font-size: 0.875rem;
168
- font-weight: 500;
169
- color: white;
57
+ gap: 0.35rem;
58
+ margin-top: 1.4rem;
59
+ padding: 0;
60
+ border: none;
61
+ background: none;
62
+ font-family: inherit;
63
+ font-size: 0.85rem;
64
+ font-weight: 600;
65
+ color: var(--navy);
170
66
  text-decoration: none;
171
- overflow: hidden;
172
- background: var(--primary-color, #4f46e5);
173
- border: 1px solid var(--primary-color, #4f46e5);
174
- border-radius: 0.5rem;
175
- outline: none;
176
- transition: all 0.2s ease;
177
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
67
+ cursor: pointer;
178
68
 
179
69
  &:hover {
180
- background: var(--secondary-color, #3cbf7d);
181
- border-color: var(--secondary-color, #3cbf7d);
70
+ text-decoration: underline;
182
71
  }
183
72
 
184
- &:focus {
185
- box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.25);
73
+ svg {
74
+ flex: none;
186
75
  }
187
76
  }
188
-
189
- input:not(:placeholder-shown) + .fi__span,
190
- textarea:not(:placeholder-shown) + .fi__span,
191
- select:not(:placeholder-shown) + .fi__span {
192
- transform: translateY(-135%) translateX(10px) scale(0.85);
193
- opacity: 1;
194
- padding: 0;
195
- background: white;
196
- font-weight: 500;
197
- transition: all 0.3s ease;
198
- color: var(--primary-color, #4f46e5) !important;
199
- }
@@ -0,0 +1,163 @@
1
+ //
2
+ // The brand panel.
3
+ //
4
+ // The company's own work, not decoration: it is the reason the rest of the
5
+ // system exists, so it carries one side of the sign-in screen and the form is
6
+ // left to be a form.
7
+ //
8
+ // Written once here because three screens now render it — the staff Login, the
9
+ // shared AuthShell behind TwoFactorAuth/Reset/Verify, and the client portal's
10
+ // split layout. It had been copied twice before that, which is the arrangement
11
+ // where one copy quietly stops matching the others.
12
+ //
13
+ // REQUIRES the local token aliases to be declared on an ancestor: `--navy-deep`
14
+ // (the ground behind the photograph), `--flag` (the eyebrow's rule). See the
15
+ // block at the top of `.auth` in Login.module.scss for the canonical set.
16
+ //
17
+ // The `$collapse` argument is the one thing that genuinely differs between the
18
+ // consumers, and it is a layout decision rather than an identity one:
19
+ //
20
+ // `hide` — the staff screens. Under 900px the photograph goes entirely; on a
21
+ // phone the form is the whole job and a cropped hero is in the way.
22
+ // `band` — the client split. The panel becomes a compact header strip
23
+ // instead, because the portal is a public-facing front door and the
24
+ // brand still has to be present on a phone. The consumer supplies
25
+ // the rest of the band's treatment after the include.
26
+
27
+ @mixin auth-brand-panel($collapse: hide) {
28
+ .brand {
29
+ position: relative;
30
+ background-color: var(--navy-deep);
31
+ background-size: cover;
32
+ background-position: center 62%;
33
+ overflow: hidden;
34
+
35
+ // A scrim anchored to the bottom-left, where the copy sits — not a flat
36
+ // wash over the whole image, which would dull the dusk light that makes
37
+ // the photograph worth using.
38
+ //
39
+ // The foot is a near-solid plate rather than a fade. The brand line has
40
+ // to hold against whatever the photograph is doing behind it, and a
41
+ // bright patch exactly where the type sits washed it out. Held high —
42
+ // 0.88 still at 18%, which is where the ink block ends — so the whole
43
+ // block reads on one ground, then released quickly to 0.06 at the top,
44
+ // so the sky above is still a photograph and not a tint.
45
+ &::after {
46
+ content: '';
47
+ position: absolute;
48
+ inset: 0;
49
+ background:
50
+ linear-gradient(
51
+ to top,
52
+ rgba(16, 25, 42, 0.94) 0%,
53
+ rgba(16, 25, 42, 0.88) 18%,
54
+ rgba(16, 25, 42, 0.62) 42%,
55
+ rgba(16, 25, 42, 0.22) 70%,
56
+ rgba(16, 25, 42, 0.06) 100%
57
+ ),
58
+ linear-gradient(
59
+ to right,
60
+ rgba(16, 25, 42, 0.5) 0%,
61
+ rgba(16, 25, 42, 0) 55%
62
+ );
63
+ }
64
+
65
+ @if $collapse == hide {
66
+ @media (max-width: 900px) {
67
+ display: none;
68
+ }
69
+ } @else if $collapse == band {
70
+ @media (max-width: 900px) {
71
+ // Tall enough to read as a band rather than a stripe, short
72
+ // enough that the form is still the first thing on screen.
73
+ min-height: 8.5rem;
74
+ // The crop that worked for a full-height column puts the
75
+ // horizon in the wrong place in a short one.
76
+ background-position: center 45%;
77
+ }
78
+ }
79
+ }
80
+
81
+ .brandInk {
82
+ position: absolute;
83
+ left: clamp(2rem, 4vw, 3.5rem);
84
+ right: clamp(2rem, 4vw, 3.5rem);
85
+ bottom: clamp(2rem, 5vh, 3.5rem);
86
+ z-index: 1;
87
+ color: #fff;
88
+ animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) both;
89
+ }
90
+
91
+ .eyebrow {
92
+ margin: 0 0 0.75rem;
93
+ font-size: 0.72rem;
94
+ font-weight: 700;
95
+ letter-spacing: 0.22em;
96
+ // Stated, not left to the cascade: global.css sets
97
+ // `p { line-height: var(--para-height) }`, which is 1.6 here. That put
98
+ // the kicker on a taller line, so the red dash sat at a different
99
+ // height and the gap beneath it read as wider.
100
+ line-height: 1.4;
101
+ text-transform: uppercase;
102
+ color: rgba(255, 255, 255, 0.75);
103
+ // The single use of the accent colour in the whole screen.
104
+ padding-left: 2.1rem;
105
+ position: relative;
106
+
107
+ &::before {
108
+ content: '';
109
+ position: absolute;
110
+ left: 0;
111
+ top: 50%;
112
+ width: 1.5rem;
113
+ height: 2px;
114
+ background: var(--flag);
115
+ }
116
+ }
117
+
118
+ .brandLine {
119
+ margin: 0 0 0.6rem;
120
+ font-size: clamp(2.4rem, 4.2vw, 3.6rem);
121
+ font-weight: 700;
122
+ line-height: 1;
123
+ // Tight tracking at display size — Barlow opens up as it scales.
124
+ letter-spacing: -0.02em;
125
+ // Stated rather than inherited from .brandInk: this is the one line on
126
+ // the screen that has to be white, and finding that out should not mean
127
+ // reading the parent.
128
+ color: #fff;
129
+ text-wrap: balance;
130
+ }
131
+
132
+ .brandSub {
133
+ margin: 0;
134
+ max-width: 34ch;
135
+ font-size: 1rem;
136
+ font-weight: 300;
137
+ line-height: 1.5;
138
+ // No-op against this app's globals, but a consuming app's own `p` rule
139
+ // may track body copy, so the value is pinned rather than left to
140
+ // whichever global layer the screen happens to render under.
141
+ letter-spacing: 0;
142
+ color: rgba(255, 255, 255, 0.82);
143
+ }
144
+ }
145
+
146
+ //
147
+ // One entrance, staggered between the two panels. Anything more would be
148
+ // decoration on a screen people pass through several times a day.
149
+ //
150
+ // Separate from the panel mixin because a module that includes both the shell
151
+ // and the panel must not emit the keyframes twice.
152
+ @mixin auth-rise-keyframes {
153
+ @keyframes rise {
154
+ from {
155
+ opacity: 0;
156
+ transform: translateY(0.75rem);
157
+ }
158
+ to {
159
+ opacity: 1;
160
+ transform: none;
161
+ }
162
+ }
163
+ }