@sowell/quasar-app-extension-auth 1.11.0 → 1.11.2
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.
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
alt="Background logo"
|
|
12
12
|
/>
|
|
13
13
|
</div>
|
|
14
|
-
<div class="row justify-between items-center full-width q-px-lg
|
|
14
|
+
<div class="row justify-between items-center full-width q-px-lg top-bar">
|
|
15
15
|
<div
|
|
16
16
|
class="row items-center back-link"
|
|
17
17
|
data-testid="restricted-back-btn"
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
|
|
63
63
|
<div
|
|
64
64
|
v-else
|
|
65
|
-
class="row justify-center full-height q-pl-sm q-pr-sm"
|
|
65
|
+
class="row justify-center full-height q-pl-sm q-pr-sm send-email-form"
|
|
66
66
|
style="background: #f4f5f6"
|
|
67
67
|
data-testid="ask-password-change-form"
|
|
68
68
|
>
|
|
@@ -107,6 +107,9 @@
|
|
|
107
107
|
<q-input
|
|
108
108
|
data-testid="email-input"
|
|
109
109
|
v-model="email"
|
|
110
|
+
type="email"
|
|
111
|
+
autocapitalize="off"
|
|
112
|
+
autocorrect="off"
|
|
110
113
|
dense
|
|
111
114
|
borderless
|
|
112
115
|
bg-color="white"
|
|
@@ -119,7 +122,7 @@
|
|
|
119
122
|
</q-input>
|
|
120
123
|
</div>
|
|
121
124
|
</q-card-section>
|
|
122
|
-
<q-space class="mobile" />
|
|
125
|
+
<q-space v-if="!keyboardOpen" class="mobile" />
|
|
123
126
|
<q-card-actions class="q-ml-lg q-mr-lg q-mb-lg row justify-center">
|
|
124
127
|
<q-btn
|
|
125
128
|
data-testid="submit-btn"
|
|
@@ -145,6 +148,7 @@
|
|
|
145
148
|
import { computed, defineComponent, ref } from "vue"
|
|
146
149
|
import { useI18n } from "vue-i18n"
|
|
147
150
|
import prompts from "app/quasar.extensions.json"
|
|
151
|
+
import { useKeyboardOpen } from "../../composables/useKeyboardOpen"
|
|
148
152
|
import {
|
|
149
153
|
ionMailOutline,
|
|
150
154
|
ionPaperPlaneOutline,
|
|
@@ -179,6 +183,7 @@ export default defineComponent({
|
|
|
179
183
|
"@sowell/auth": { USE_SSO },
|
|
180
184
|
} = prompts
|
|
181
185
|
const email = ref("")
|
|
186
|
+
const { keyboardOpen } = useKeyboardOpen()
|
|
182
187
|
const sendEmail = () => {
|
|
183
188
|
emit("resetPassword", email.value)
|
|
184
189
|
}
|
|
@@ -200,6 +205,7 @@ export default defineComponent({
|
|
|
200
205
|
|
|
201
206
|
return {
|
|
202
207
|
email,
|
|
208
|
+
keyboardOpen,
|
|
203
209
|
sendEmail,
|
|
204
210
|
emit,
|
|
205
211
|
USE_SSO,
|
|
@@ -247,9 +253,18 @@ export default defineComponent({
|
|
|
247
253
|
max-height: 100vh;
|
|
248
254
|
}
|
|
249
255
|
|
|
256
|
+
/* Ce composant s'affiche dans un q-dialog. Sur iOS, Quasar (q-ios-padding)
|
|
257
|
+
décale déjà .q-dialog__inner sous la barre d'état : on ne lit donc PAS
|
|
258
|
+
env(), sinon le décalage serait doublé. --safe-area-inset-top n'est
|
|
259
|
+
injectée que par Capacitor SystemBars sur Android (edge-to-edge, 15+). */
|
|
250
260
|
.top-bar {
|
|
251
261
|
z-index: 1;
|
|
252
262
|
max-width: 430px;
|
|
263
|
+
padding-top: calc(24px + var(--safe-area-inset-top, 0px));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.send-email-form {
|
|
267
|
+
padding-top: var(--safe-area-inset-top, 0px);
|
|
253
268
|
}
|
|
254
269
|
|
|
255
270
|
.back-link {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
class="background-logo"
|
|
9
9
|
alt="Background logo" />
|
|
10
10
|
</div>
|
|
11
|
-
<div class="row justify-between items-center full-width q-px-lg
|
|
11
|
+
<div class="row justify-between items-center full-width q-px-lg top-bar">
|
|
12
12
|
<div
|
|
13
13
|
class="row items-center back-link"
|
|
14
14
|
data-testid="back-btn"
|
|
@@ -424,6 +424,11 @@ export default defineComponent({
|
|
|
424
424
|
.top-bar {
|
|
425
425
|
z-index: 1;
|
|
426
426
|
max-width: 430px;
|
|
427
|
+
/* 24px = ancien q-pt-lg. Sur iOS (viewport-fit=cover), la page n'a pas de
|
|
428
|
+
q-header : le padding iOS de Quasar ne s'applique pas, on ajoute donc la
|
|
429
|
+
safe-area ici. --safe-area-inset-top est injectée par SystemBars sur
|
|
430
|
+
Android ; env() vaut 0 sur le web. */
|
|
431
|
+
padding-top: calc(24px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px)));
|
|
427
432
|
}
|
|
428
433
|
|
|
429
434
|
.back-link {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
class="background-logo"
|
|
9
9
|
alt="Background logo" />
|
|
10
10
|
</div>
|
|
11
|
-
<div class="row justify-between items-center full-width q-px-lg
|
|
11
|
+
<div class="row justify-between items-center full-width q-px-lg top-bar">
|
|
12
12
|
<div
|
|
13
13
|
class="row items-center back-link"
|
|
14
14
|
data-testid="back-btn"
|
|
@@ -317,6 +317,11 @@ export default defineComponent({
|
|
|
317
317
|
.top-bar {
|
|
318
318
|
z-index: 1;
|
|
319
319
|
max-width: 430px;
|
|
320
|
+
/* 24px = ancien q-pt-lg. Sur iOS (viewport-fit=cover), la page n'a pas de
|
|
321
|
+
q-header : le padding iOS de Quasar ne s'applique pas, on ajoute donc la
|
|
322
|
+
safe-area ici. --safe-area-inset-top est injectée par SystemBars sur
|
|
323
|
+
Android ; env() vaut 0 sur le web. */
|
|
324
|
+
padding-top: calc(24px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px)));
|
|
320
325
|
}
|
|
321
326
|
|
|
322
327
|
.back-link {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ref, onMounted, onBeforeUnmount } from "vue"
|
|
2
|
+
|
|
3
|
+
// Ecart minimal (px CSS) entre la fenetre de mise en page et la zone visible
|
|
4
|
+
// pour conclure qu'un clavier virtuel est ouvert. Les barres d'URL ou de
|
|
5
|
+
// navigation qui se replient restent largement en dessous.
|
|
6
|
+
export const KEYBOARD_GAP_THRESHOLD = 150
|
|
7
|
+
|
|
8
|
+
interface ViewportHost {
|
|
9
|
+
innerHeight: number
|
|
10
|
+
visualViewport?: {
|
|
11
|
+
height: number
|
|
12
|
+
addEventListener: (type: "resize", listener: () => void) => void
|
|
13
|
+
removeEventListener: (type: "resize", listener: () => void) => void
|
|
14
|
+
} | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Android 15+ edge-to-edge (WebView >= 140) : le clavier ne reduit que
|
|
18
|
+
// visualViewport, innerHeight reste inchange. Sur iOS (Keyboard.resize native)
|
|
19
|
+
// ou Android classique la WebView entiere retrecit : l'ecart reste nul et on
|
|
20
|
+
// ne detecte rien, la mise en page suit deja le clavier.
|
|
21
|
+
export const isKeyboardOpen = (host: ViewportHost): boolean => {
|
|
22
|
+
const viewport = host.visualViewport
|
|
23
|
+
if (!viewport) return false
|
|
24
|
+
return host.innerHeight - viewport.height > KEYBOARD_GAP_THRESHOLD
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Appelle `onChange` a chaque variation de l'etat (et une fois a l'initialisation),
|
|
28
|
+
// rend la fonction de nettoyage. Sans visualViewport : etat false, rien a ecouter.
|
|
29
|
+
export const observeKeyboard = (
|
|
30
|
+
host: ViewportHost,
|
|
31
|
+
onChange: (open: boolean) => void
|
|
32
|
+
): (() => void) => {
|
|
33
|
+
const update = () => onChange(isKeyboardOpen(host))
|
|
34
|
+
update()
|
|
35
|
+
const viewport = host.visualViewport
|
|
36
|
+
if (!viewport) return () => undefined
|
|
37
|
+
viewport.addEventListener("resize", update)
|
|
38
|
+
return () => viewport.removeEventListener("resize", update)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const useKeyboardOpen = () => {
|
|
42
|
+
const keyboardOpen = ref(false)
|
|
43
|
+
let stop: (() => void) | undefined
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
if (typeof window === "undefined") return
|
|
46
|
+
stop = observeKeyboard(window, (open) => {
|
|
47
|
+
keyboardOpen.value = open
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
onBeforeUnmount(() => {
|
|
51
|
+
stop?.()
|
|
52
|
+
stop = undefined
|
|
53
|
+
})
|
|
54
|
+
return { keyboardOpen }
|
|
55
|
+
}
|