@globalbrain/sefirot 3.48.0 → 3.50.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.
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import LockKey from '@iconify-icons/ph/lock-key-fill'
|
|
2
3
|
import IconGoogle from '@iconify-icons/ri/google-fill'
|
|
3
|
-
import { computed } from 'vue'
|
|
4
|
+
import { computed, ref } from 'vue'
|
|
5
|
+
import { usePower } from '../composables/Power'
|
|
4
6
|
import SButton from './SButton.vue'
|
|
5
7
|
import SLink from './SLink.vue'
|
|
8
|
+
import SLoginPagePasswordDialog from './SLoginPagePasswordDialog.vue'
|
|
9
|
+
import SModal from './SModal.vue'
|
|
6
10
|
import SIconGbLogoWhite from './icon/SIconGbLogoWhite.vue'
|
|
7
11
|
|
|
8
12
|
export interface CoverTitle {
|
|
@@ -15,11 +19,20 @@ export interface CoverPhotographer {
|
|
|
15
19
|
link: string
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
export
|
|
22
|
+
export type Action = ActionPassword | ActionSocial
|
|
23
|
+
|
|
24
|
+
export interface ActionPassword {
|
|
25
|
+
type: 'password'
|
|
26
|
+
onSubmit(email: string, password: string): Promise<boolean>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ActionSocial {
|
|
19
30
|
type: 'google'
|
|
20
|
-
onClick
|
|
31
|
+
onClick(): Promise<void>
|
|
21
32
|
}
|
|
22
33
|
|
|
34
|
+
export type ActionType = 'password' | 'google'
|
|
35
|
+
|
|
23
36
|
const props = defineProps<{
|
|
24
37
|
cover: string
|
|
25
38
|
coverTitle: CoverTitle
|
|
@@ -27,23 +40,51 @@ const props = defineProps<{
|
|
|
27
40
|
actions: Action[]
|
|
28
41
|
}>()
|
|
29
42
|
|
|
43
|
+
const passwordDialog = usePower()
|
|
44
|
+
|
|
45
|
+
const selectedPasswordAction = ref<ActionPassword | null>(null)
|
|
46
|
+
const actionInProgress = ref(false)
|
|
47
|
+
const actionError = ref(false)
|
|
48
|
+
|
|
30
49
|
const coverBgImageStyle = computed(() => `url(${props.cover})`)
|
|
31
50
|
|
|
32
|
-
function getActionLabel(type:
|
|
51
|
+
function getActionLabel(type: ActionType) {
|
|
33
52
|
switch (type) {
|
|
53
|
+
case 'password':
|
|
54
|
+
return 'Sign in via Password'
|
|
34
55
|
case 'google':
|
|
35
56
|
return 'Sign in via Google'
|
|
36
|
-
default:
|
|
37
|
-
throw new Error('[sefirot] Invalid action type')
|
|
38
57
|
}
|
|
39
58
|
}
|
|
40
59
|
|
|
41
|
-
function getIconComponent(type:
|
|
60
|
+
function getIconComponent(type: ActionType) {
|
|
42
61
|
switch (type) {
|
|
62
|
+
case 'password':
|
|
63
|
+
return LockKey
|
|
43
64
|
case 'google':
|
|
44
65
|
return IconGoogle
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function onAction(action: Action) {
|
|
70
|
+
switch (action.type) {
|
|
71
|
+
case 'password':
|
|
72
|
+
selectedPasswordAction.value = action
|
|
73
|
+
return passwordDialog.on()
|
|
74
|
+
case 'google':
|
|
75
|
+
return action.onClick()
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function onSubmit(email: string, password: string) {
|
|
80
|
+
actionInProgress.value = true
|
|
81
|
+
|
|
82
|
+
actionError.value = !(await selectedPasswordAction.value!.onSubmit(email, password))
|
|
83
|
+
|
|
84
|
+
actionInProgress.value = false
|
|
85
|
+
|
|
86
|
+
if (!actionError.value) {
|
|
87
|
+
passwordDialog.off()
|
|
47
88
|
}
|
|
48
89
|
}
|
|
49
90
|
</script>
|
|
@@ -74,20 +115,30 @@ function getIconComponent(type: Action['type']) {
|
|
|
74
115
|
<p class="form-lead">This is a very closed login form meant for specific audiences only. If you can’t login, well, you know who to ask.</p>
|
|
75
116
|
</div>
|
|
76
117
|
|
|
77
|
-
<div class="form-actions">
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
118
|
+
<div class="form-actions" :class="{ multi: actions.length > 1 }">
|
|
119
|
+
<div v-for="action in actions" :key="action.type" class="form-action">
|
|
120
|
+
<SButton
|
|
121
|
+
size="large"
|
|
122
|
+
mode="white"
|
|
123
|
+
block
|
|
124
|
+
rounded
|
|
125
|
+
:label="getActionLabel(action.type)"
|
|
126
|
+
:icon="getIconComponent(action.type)"
|
|
127
|
+
@click="onAction(action)"
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
88
130
|
</div>
|
|
89
131
|
</div>
|
|
90
132
|
</div>
|
|
133
|
+
|
|
134
|
+
<SModal :open="passwordDialog.state.value" @close="passwordDialog.off">
|
|
135
|
+
<SLoginPagePasswordDialog
|
|
136
|
+
:loading="actionInProgress"
|
|
137
|
+
:error="actionError"
|
|
138
|
+
@cancel="passwordDialog.off"
|
|
139
|
+
@submit="onSubmit"
|
|
140
|
+
/>
|
|
141
|
+
</SModal>
|
|
91
142
|
</div>
|
|
92
143
|
</template>
|
|
93
144
|
|
|
@@ -196,9 +247,15 @@ function getIconComponent(type: Action['type']) {
|
|
|
196
247
|
display: flex;
|
|
197
248
|
flex-direction: column;
|
|
198
249
|
align-items: center;
|
|
199
|
-
gap:
|
|
250
|
+
gap: 16px;
|
|
200
251
|
padding-top: 24px;
|
|
201
252
|
text-align: center;
|
|
202
253
|
margin: 0 auto;
|
|
203
254
|
}
|
|
255
|
+
|
|
256
|
+
.form-actions.multi .form-action {
|
|
257
|
+
display: block;
|
|
258
|
+
width: 100%;
|
|
259
|
+
max-width: 256px;
|
|
260
|
+
}
|
|
204
261
|
</style>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useD } from '../composables/D'
|
|
3
|
+
import { useV } from '../composables/V'
|
|
4
|
+
import { email, maxLength, required } from '../validation/rules'
|
|
5
|
+
import SAlert from './SAlert.vue'
|
|
6
|
+
import SCard from './SCard.vue'
|
|
7
|
+
import SCardBlock from './SCardBlock.vue'
|
|
8
|
+
import SContent from './SContent.vue'
|
|
9
|
+
import SControl from './SControl.vue'
|
|
10
|
+
import SControlButton from './SControlButton.vue'
|
|
11
|
+
import SControlRight from './SControlRight.vue'
|
|
12
|
+
import SDoc from './SDoc.vue'
|
|
13
|
+
import SInputText from './SInputText.vue'
|
|
14
|
+
|
|
15
|
+
defineProps<{
|
|
16
|
+
loading: boolean
|
|
17
|
+
error: boolean
|
|
18
|
+
}>()
|
|
19
|
+
|
|
20
|
+
const emit = defineEmits<{
|
|
21
|
+
cancel: []
|
|
22
|
+
submit: [email: string, password: string]
|
|
23
|
+
}>()
|
|
24
|
+
|
|
25
|
+
const { data } = useD({
|
|
26
|
+
email: null as string | null,
|
|
27
|
+
password: null as string | null
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const { validation, validateAndNotify } = useV(data, {
|
|
31
|
+
email: {
|
|
32
|
+
required: required(),
|
|
33
|
+
maxLength: maxLength(255),
|
|
34
|
+
email: email()
|
|
35
|
+
},
|
|
36
|
+
password: {
|
|
37
|
+
required: required(),
|
|
38
|
+
maxLength: maxLength(255)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
async function onSubmit() {
|
|
43
|
+
if (await validateAndNotify()) {
|
|
44
|
+
emit('submit', data.value.email!, data.value.password!)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<SCard size="small">
|
|
51
|
+
<SCardBlock class="s-p-24">
|
|
52
|
+
<SDoc>
|
|
53
|
+
<SContent>
|
|
54
|
+
<h2>Sign in to account</h2>
|
|
55
|
+
</SContent>
|
|
56
|
+
<SAlert v-if="error" mode="danger">
|
|
57
|
+
<p>Invalid email or password.</p>
|
|
58
|
+
</SAlert>
|
|
59
|
+
<SInputText
|
|
60
|
+
name="email"
|
|
61
|
+
type="email"
|
|
62
|
+
label="Email"
|
|
63
|
+
placeholder="john.doe@example.com"
|
|
64
|
+
v-model="data.email"
|
|
65
|
+
:validation="validation.email"
|
|
66
|
+
/>
|
|
67
|
+
<SInputText
|
|
68
|
+
name="password"
|
|
69
|
+
type="password"
|
|
70
|
+
label="Password"
|
|
71
|
+
placeholder="Password"
|
|
72
|
+
v-model="data.password"
|
|
73
|
+
:validation="validation.password"
|
|
74
|
+
/>
|
|
75
|
+
</SDoc>
|
|
76
|
+
</SCardBlock>
|
|
77
|
+
<SCardBlock size="xlarge" class="s-px-24">
|
|
78
|
+
<SControl>
|
|
79
|
+
<SControlRight>
|
|
80
|
+
<SControlButton
|
|
81
|
+
label="Cancel"
|
|
82
|
+
:disabled="loading"
|
|
83
|
+
@click="$emit('cancel')"
|
|
84
|
+
/>
|
|
85
|
+
<SControlButton
|
|
86
|
+
mode="info"
|
|
87
|
+
label="Sign in"
|
|
88
|
+
:loading="loading"
|
|
89
|
+
@click="onSubmit"
|
|
90
|
+
/>
|
|
91
|
+
</SControlRight>
|
|
92
|
+
</SControl>
|
|
93
|
+
</SCardBlock>
|
|
94
|
+
</SCard>
|
|
95
|
+
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isString } from '../../support/Utils'
|
|
2
2
|
|
|
3
3
|
/* eslint-disable-next-line no-control-regex */
|
|
4
|
-
const regExp = /^(?:[A-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|[\x01-\x09\x0B\x0C\x0E-\x7F])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21-\x5A\x53-\x7F]|\\[\x01-\x09\x0B\x0C\x0E-\x7F])+)\])$/i
|
|
4
|
+
const regExp = /^(?:[A-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|[\x01-\x09\x0B\x0C\x0E-\x7F])*")@(?:(?:[a-z0-9](?:[a-z0-9-_]*[a-z0-9])?\.)+[a-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21-\x5A\x53-\x7F]|\\[\x01-\x09\x0B\x0C\x0E-\x7F])+)\])$/i
|
|
5
5
|
|
|
6
6
|
export function email(value: unknown): boolean {
|
|
7
7
|
if (!isString(value)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@globalbrain/sefirot",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.50.0",
|
|
4
4
|
"packageManager": "pnpm@9.1.1",
|
|
5
5
|
"description": "Vue Components for Global Brain Design System.",
|
|
6
6
|
"author": "Kia Ishii <ka.ishii@globalbrains.com>",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@vuelidate/validators": "^2.0.4",
|
|
53
53
|
"@vueuse/core": "^10.9.0",
|
|
54
54
|
"body-scroll-lock": "4.0.0-beta.0",
|
|
55
|
+
"dayjs": "^1.11.11",
|
|
55
56
|
"fuse.js": "^7.0.0",
|
|
56
57
|
"lodash-es": "^4.17.21",
|
|
57
58
|
"markdown-it": "^14.1.0",
|
|
@@ -70,7 +71,6 @@
|
|
|
70
71
|
"@tinyhttp/cookie": "^2.1.0",
|
|
71
72
|
"@types/file-saver": "^2.0.7",
|
|
72
73
|
"@types/qs": "^6.9.15",
|
|
73
|
-
"dayjs": "^1.11.11",
|
|
74
74
|
"file-saver": "^2.0.5",
|
|
75
75
|
"ofetch": "^1.3.4",
|
|
76
76
|
"qs": "^6.12.1"
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"@vuelidate/validators": "^2.0.4",
|
|
96
96
|
"@vueuse/core": "^10.9.0",
|
|
97
97
|
"body-scroll-lock": "4.0.0-beta.0",
|
|
98
|
+
"dayjs": "^1.11.11",
|
|
98
99
|
"eslint": "^8.57.0",
|
|
99
100
|
"fuse.js": "^7.0.0",
|
|
100
101
|
"happy-dom": "^14.10.2",
|