@fy-/fws-vue 2.1.6 → 2.1.8
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/components/fws/CmsArticleBoxed.vue +23 -20
- package/components/fws/CmsArticleSingle.vue +74 -68
- package/components/fws/DataTable.vue +132 -125
- package/components/fws/FilterData.vue +99 -101
- package/components/fws/UserData.vue +33 -32
- package/components/fws/UserFlow.vue +163 -155
- package/components/fws/UserOAuth2.vue +73 -72
- package/components/fws/UserProfile.vue +98 -101
- package/components/fws/UserProfileStrict.vue +65 -64
- package/components/ssr/ClientOnly.ts +7 -7
- package/components/ui/DefaultBreadcrumb.vue +13 -13
- package/components/ui/DefaultConfirm.vue +35 -34
- package/components/ui/DefaultDateSelection.vue +19 -17
- package/components/ui/DefaultDropdown.vue +25 -25
- package/components/ui/DefaultDropdownLink.vue +15 -14
- package/components/ui/DefaultGallery.vue +179 -168
- package/components/ui/DefaultInput.vue +121 -126
- package/components/ui/DefaultLoader.vue +17 -17
- package/components/ui/DefaultModal.vue +35 -33
- package/components/ui/DefaultNotif.vue +50 -52
- package/components/ui/DefaultPaging.vue +92 -95
- package/components/ui/DefaultSidebar.vue +29 -25
- package/components/ui/DefaultTagInput.vue +121 -119
- package/components/ui/transitions/CollapseTransition.vue +1 -1
- package/components/ui/transitions/ExpandTransition.vue +1 -1
- package/components/ui/transitions/FadeTransition.vue +1 -1
- package/components/ui/transitions/ScaleTransition.vue +1 -1
- package/components/ui/transitions/SlideTransition.vue +3 -3
- package/composables/event-bus.ts +10 -8
- package/composables/rest.ts +59 -56
- package/composables/seo.ts +111 -95
- package/composables/ssr.ts +64 -62
- package/composables/templating.ts +57 -57
- package/composables/translations.ts +13 -13
- package/env.d.ts +6 -4
- package/index.ts +101 -98
- package/package.json +7 -7
- package/stores/serverRouter.ts +25 -25
- package/stores/user.ts +79 -72
- package/types.d.ts +65 -65
|
@@ -1,46 +1,47 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import useVuelidate from
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { useRest } from
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
2
|
+
import useVuelidate from '@vuelidate/core'
|
|
3
|
+
import { computed, reactive, watchEffect } from 'vue'
|
|
4
|
+
import { useEventBus } from '../../composables/event-bus'
|
|
5
|
+
import { useRest } from '../../composables/rest'
|
|
6
|
+
import { useUserStore } from '../../stores/user'
|
|
7
|
+
import DefaultInput from '../ui/DefaultInput.vue'
|
|
8
|
+
|
|
9
|
+
const rest = useRest()
|
|
10
|
+
const userStore = useUserStore()
|
|
11
|
+
const userData = computed(() => userStore.user)
|
|
12
|
+
const eventBus = useEventBus()
|
|
12
13
|
const props = withDefaults(
|
|
13
14
|
defineProps<{
|
|
14
|
-
onCompleted?: (data: any) => void
|
|
15
|
+
onCompleted?: (data: any) => void
|
|
15
16
|
}>(),
|
|
16
17
|
{
|
|
17
18
|
onCompleted: () => {},
|
|
18
19
|
},
|
|
19
|
-
)
|
|
20
|
+
)
|
|
20
21
|
const state = reactive({
|
|
21
22
|
userData: {
|
|
22
|
-
Firstname: userData.value?.Firstname ||
|
|
23
|
-
Lastname: userData.value?.Lastname ||
|
|
24
|
-
Phone: userData.value?.Phone ||
|
|
23
|
+
Firstname: userData.value?.Firstname || '',
|
|
24
|
+
Lastname: userData.value?.Lastname || '',
|
|
25
|
+
Phone: userData.value?.Phone || '',
|
|
25
26
|
AcceptedTerms: userData.value?.AcceptedTerms || false,
|
|
26
27
|
EnabledNotifications: userData.value?.EnabledNotifications || false,
|
|
27
28
|
EnabledEmails: userData.value?.EnabledEmails || false,
|
|
28
29
|
EnabledTrainingFromMyData:
|
|
29
30
|
userData.value?.EnabledTrainingFromMyData || false,
|
|
30
31
|
},
|
|
31
|
-
})
|
|
32
|
+
})
|
|
32
33
|
watchEffect(() => {
|
|
33
34
|
state.userData = {
|
|
34
|
-
Firstname: userData.value?.Firstname ||
|
|
35
|
-
Lastname: userData.value?.Lastname ||
|
|
36
|
-
Phone: userData.value?.Phone ||
|
|
35
|
+
Firstname: userData.value?.Firstname || '',
|
|
36
|
+
Lastname: userData.value?.Lastname || '',
|
|
37
|
+
Phone: userData.value?.Phone || '',
|
|
37
38
|
AcceptedTerms: userData.value?.AcceptedTerms || false,
|
|
38
39
|
EnabledNotifications: userData.value?.EnabledNotifications || false,
|
|
39
40
|
EnabledEmails: userData.value?.EnabledEmails || false,
|
|
40
41
|
EnabledTrainingFromMyData:
|
|
41
42
|
userData.value?.EnabledTrainingFromMyData || false,
|
|
42
|
-
}
|
|
43
|
-
})
|
|
43
|
+
}
|
|
44
|
+
})
|
|
44
45
|
const rules = {
|
|
45
46
|
userData: {
|
|
46
47
|
Firstname: {},
|
|
@@ -52,22 +53,22 @@ const rules = {
|
|
|
52
53
|
EnabledEmails: {},
|
|
53
54
|
EnabledTrainingFromMyData: {},
|
|
54
55
|
},
|
|
55
|
-
}
|
|
56
|
-
const v$ = useVuelidate(rules, state)
|
|
56
|
+
}
|
|
57
|
+
const v$ = useVuelidate(rules, state)
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
eventBus.emit(
|
|
59
|
+
async function patchUser() {
|
|
60
|
+
eventBus.emit('main-loading', true)
|
|
60
61
|
if (await v$.value.userData.$validate()) {
|
|
61
|
-
const response = await rest(
|
|
62
|
-
if (response && response.result
|
|
63
|
-
eventBus.emit(
|
|
62
|
+
const response = await rest('User', 'PATCH', state.userData)
|
|
63
|
+
if (response && response.result === 'success') {
|
|
64
|
+
eventBus.emit('user:refresh', true)
|
|
64
65
|
if (props.onCompleted) {
|
|
65
|
-
props.onCompleted(response)
|
|
66
|
+
props.onCompleted(response)
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
|
-
eventBus.emit(
|
|
70
|
-
}
|
|
70
|
+
eventBus.emit('main-loading', false)
|
|
71
|
+
}
|
|
71
72
|
</script>
|
|
72
73
|
|
|
73
74
|
<template>
|
|
@@ -100,8 +101,8 @@ const patchUser = async () => {
|
|
|
100
101
|
:error-vuelidate="v$.userData.Phone.$errors"
|
|
101
102
|
/>
|
|
102
103
|
<DefaultInput
|
|
103
|
-
id="acceptedTermsFWS"
|
|
104
104
|
v-if="!userData?.AcceptedTerms"
|
|
105
|
+
id="acceptedTermsFWS"
|
|
105
106
|
v-model:checkbox-value="state.userData.AcceptedTerms"
|
|
106
107
|
type="toggle"
|
|
107
108
|
:label="$t('fws_accepted_terms_label')"
|
|
@@ -1,202 +1,210 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
2
|
+
import type { KlbFlowData, KlbUserFlowField } from '@fy-/fws-types'
|
|
3
|
+
import type { APIResult } from '../../composables/rest'
|
|
4
|
+
import { EnvelopeIcon } from '@heroicons/vue/24/solid'
|
|
5
|
+
import { useSessionStorage } from '@vueuse/core'
|
|
6
|
+
import { onMounted, ref } from 'vue'
|
|
7
|
+
import { useRoute, useRouter } from 'vue-router'
|
|
8
|
+
import { useEventBus } from '../../composables/event-bus'
|
|
9
|
+
import { useRest } from '../../composables/rest'
|
|
10
|
+
import { useTranslation } from '../../composables/translations'
|
|
11
|
+
import { useUserStore } from '../../stores/user'
|
|
12
|
+
import { ClientOnly } from '../ssr/ClientOnly'
|
|
13
|
+
import DefaultInput from '../ui/DefaultInput.vue'
|
|
14
|
+
|
|
15
|
+
const rest = useRest()
|
|
14
16
|
interface UserFlow extends APIResult {
|
|
15
|
-
data: KlbFlowData
|
|
17
|
+
data: KlbFlowData
|
|
16
18
|
}
|
|
17
|
-
const showEmail = ref<boolean>(false)
|
|
19
|
+
const showEmail = ref<boolean>(false)
|
|
18
20
|
const props = withDefaults(
|
|
19
21
|
defineProps<{
|
|
20
|
-
returnDefault?: string
|
|
21
|
-
forceAction?: string
|
|
22
|
-
onSuccess?: Function
|
|
22
|
+
returnDefault?: string
|
|
23
|
+
forceAction?: string
|
|
24
|
+
onSuccess?: Function
|
|
23
25
|
}>(),
|
|
24
26
|
{
|
|
25
|
-
mode:
|
|
26
|
-
returnDefault:
|
|
27
|
+
mode: 'klb',
|
|
28
|
+
returnDefault: '/',
|
|
27
29
|
},
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
return url.startsWith(
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
initial: boolean
|
|
34
|
-
oauth?: string
|
|
35
|
-
}
|
|
36
|
-
const initial = ref<boolean>(true)
|
|
37
|
-
const store = useUserStore()
|
|
38
|
-
const route = useRoute()
|
|
39
|
-
const router = useRouter()
|
|
40
|
-
const eventBus = useEventBus()
|
|
41
|
-
const returnTo = ref<string>(props.returnDefault)
|
|
42
|
-
const responseMessage = ref<string | null>(null)
|
|
43
|
-
const responseError = ref<APIResult>()
|
|
44
|
-
const responseReq = ref<string[]>([])
|
|
45
|
-
const responseFields = ref<Array<KlbUserFlowField>>([])
|
|
46
|
-
const response = ref<UserFlow>()
|
|
47
|
-
const hasOauth = ref<boolean>(false)
|
|
48
|
-
const fieldsError = ref<Record<string, any>>({})
|
|
49
|
-
const pwdRecoverMailSent = ref<boolean>(false)
|
|
50
|
-
const inputs = ref<InstanceType<typeof DefaultInput>[]>([])
|
|
51
|
-
const translate = useTranslation()
|
|
30
|
+
)
|
|
31
|
+
function isExternalUrl(url: string) {
|
|
32
|
+
return url.startsWith('http://') || url.startsWith('https://')
|
|
33
|
+
}
|
|
34
|
+
interface paramsType {
|
|
35
|
+
initial: boolean
|
|
36
|
+
oauth?: string
|
|
37
|
+
}
|
|
38
|
+
const initial = ref<boolean>(true)
|
|
39
|
+
const store = useUserStore()
|
|
40
|
+
const route = useRoute()
|
|
41
|
+
const router = useRouter()
|
|
42
|
+
const eventBus = useEventBus()
|
|
43
|
+
const returnTo = ref<string>(props.returnDefault)
|
|
44
|
+
const responseMessage = ref<string | null>(null)
|
|
45
|
+
const responseError = ref<APIResult>()
|
|
46
|
+
const responseReq = ref<string[]>([])
|
|
47
|
+
const responseFields = ref<Array<KlbUserFlowField>>([])
|
|
48
|
+
const response = ref<UserFlow>()
|
|
49
|
+
const hasOauth = ref<boolean>(false)
|
|
50
|
+
const fieldsError = ref<Record<string, any>>({})
|
|
51
|
+
const pwdRecoverMailSent = ref<boolean>(false)
|
|
52
|
+
const inputs = ref<InstanceType<typeof DefaultInput>[]>([])
|
|
53
|
+
const translate = useTranslation()
|
|
52
54
|
const session = useSessionStorage<string | null>(
|
|
53
|
-
|
|
55
|
+
'session',
|
|
54
56
|
route.query.session ? route.query.session.toString() : null,
|
|
55
|
-
)
|
|
57
|
+
)
|
|
56
58
|
const formData = ref<Record<string, any>>({
|
|
57
59
|
return_to: props.returnDefault,
|
|
58
60
|
session: session.value,
|
|
59
61
|
action: props.forceAction ? props.forceAction : undefined,
|
|
60
|
-
})
|
|
61
|
-
const completed = ref(false)
|
|
62
|
-
|
|
63
|
-
const doTrigger = async (field: any) => {
|
|
64
|
-
// eslint-disable-next-line
|
|
62
|
+
})
|
|
63
|
+
const completed = ref(false)
|
|
65
64
|
|
|
65
|
+
async function doTrigger(field: any) {
|
|
66
|
+
// eslint-disable-next-line no-eval
|
|
66
67
|
const _res = await eval(
|
|
67
68
|
`const _rest = rest; ${field.info.Button_Extra.trigger}`,
|
|
68
|
-
)
|
|
69
|
+
)
|
|
69
70
|
if (_res.ethereum) {
|
|
70
|
-
formData.value.ethereum = _res.ethereum
|
|
71
|
-
responseReq.value = []
|
|
72
|
-
await userFlow()
|
|
71
|
+
formData.value.ethereum = _res.ethereum
|
|
72
|
+
responseReq.value = []
|
|
73
|
+
await userFlow()
|
|
73
74
|
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
eventBus.emit(
|
|
77
|
-
fieldsError.value = {}
|
|
78
|
-
responseError.value = undefined
|
|
79
|
-
initial.value = params.initial
|
|
75
|
+
}
|
|
76
|
+
async function userFlow(params: paramsType = { initial: false }) {
|
|
77
|
+
eventBus.emit('login-loading', true)
|
|
78
|
+
fieldsError.value = {}
|
|
79
|
+
responseError.value = undefined
|
|
80
|
+
initial.value = params.initial
|
|
80
81
|
if (params.initial === false) {
|
|
81
|
-
let hasError = false
|
|
82
|
+
let hasError = false
|
|
82
83
|
responseReq.value.forEach((field) => {
|
|
83
|
-
if (!formData.value[field] || formData.value[field]
|
|
84
|
-
fieldsError.value[field] = translate(
|
|
85
|
-
hasError = true
|
|
84
|
+
if (!formData.value[field] || formData.value[field] === '') {
|
|
85
|
+
fieldsError.value[field] = translate('vuelidate_validator_req')
|
|
86
|
+
hasError = true
|
|
86
87
|
}
|
|
87
|
-
})
|
|
88
|
+
})
|
|
88
89
|
if (hasError) {
|
|
89
|
-
eventBus.emit(
|
|
90
|
-
return
|
|
90
|
+
eventBus.emit('login-loading', false)
|
|
91
|
+
return
|
|
91
92
|
}
|
|
92
|
-
} else {
|
|
93
|
-
formData.value.initial = true;
|
|
94
93
|
}
|
|
95
|
-
|
|
94
|
+
else {
|
|
95
|
+
formData.value.initial = true
|
|
96
|
+
}
|
|
97
|
+
hasOauth.value = false
|
|
96
98
|
|
|
97
99
|
if (params.oauth) {
|
|
98
|
-
formData.value.oauth2 = params.oauth
|
|
100
|
+
formData.value.oauth2 = params.oauth
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
if (route.query.return_to && typeof route.query.return_to ==
|
|
103
|
+
if (route.query.return_to && typeof route.query.return_to == 'string') {
|
|
102
104
|
returnTo.value = route.query.return_to
|
|
103
105
|
? route.query.return_to
|
|
104
|
-
: props.returnDefault
|
|
106
|
+
: props.returnDefault
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
formData.value.return_to = returnTo.value
|
|
108
|
-
response.value = (await rest(
|
|
109
|
+
formData.value.return_to = returnTo.value
|
|
110
|
+
response.value = (await rest('User:flow', 'POST', formData.value).catch(
|
|
109
111
|
(err: APIResult) => {
|
|
110
|
-
if (err.token && err.token
|
|
111
|
-
window.location.reload()
|
|
112
|
+
if (err.token && err.token === 'invalid_request_token') {
|
|
113
|
+
window.location.reload()
|
|
112
114
|
}
|
|
113
|
-
responseError.value = err
|
|
115
|
+
responseError.value = err
|
|
114
116
|
if (responseError.value.param) {
|
|
115
|
-
fieldsError.value[responseError.value.param]
|
|
116
|
-
responseError.value.token
|
|
117
|
+
fieldsError.value[responseError.value.param]
|
|
118
|
+
= responseError.value.token
|
|
117
119
|
}
|
|
118
|
-
eventBus.emit(
|
|
119
|
-
return;
|
|
120
|
+
eventBus.emit('login-loading', false)
|
|
120
121
|
},
|
|
121
|
-
)) as UserFlow
|
|
122
|
-
if (response.value?.result
|
|
123
|
-
if (response.value.data.complete
|
|
124
|
-
store.setUser(response.value.data.user)
|
|
122
|
+
)) as UserFlow
|
|
123
|
+
if (response.value?.result === 'success') {
|
|
124
|
+
if (response.value.data.complete === true && response.value.data.user) {
|
|
125
|
+
store.setUser(response.value.data.user)
|
|
125
126
|
const actualReturnTo = response.value.data.redirect
|
|
126
127
|
? response.value.data.redirect
|
|
127
|
-
: returnTo.value
|
|
128
|
-
session.value = null
|
|
128
|
+
: returnTo.value
|
|
129
|
+
session.value = null
|
|
129
130
|
if (isExternalUrl(actualReturnTo)) {
|
|
130
131
|
if (props.onSuccess) {
|
|
131
|
-
await props.onSuccess()
|
|
132
|
-
} else {
|
|
133
|
-
window.location.href = actualReturnTo;
|
|
132
|
+
await props.onSuccess()
|
|
134
133
|
}
|
|
135
|
-
|
|
134
|
+
else {
|
|
135
|
+
window.location.href = actualReturnTo
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
136
139
|
if (props.onSuccess) {
|
|
137
|
-
await props.onSuccess(actualReturnTo)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
await props.onSuccess(actualReturnTo)
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const routeExists = router.resolve(actualReturnTo)
|
|
144
|
+
if (routeExists.matched.length !== 0) router.push(actualReturnTo)
|
|
145
|
+
else window.location.href = actualReturnTo
|
|
142
146
|
}
|
|
143
147
|
}
|
|
144
|
-
return
|
|
148
|
+
return
|
|
145
149
|
}
|
|
146
150
|
if (response.value.data.url) {
|
|
147
|
-
window.location.href = response.value.data.url
|
|
148
|
-
return
|
|
151
|
+
window.location.href = response.value.data.url
|
|
152
|
+
return
|
|
149
153
|
}
|
|
150
154
|
if (response.value.data.redirect && response.value.data.complete) {
|
|
151
155
|
router.push(
|
|
152
|
-
response.value.data.redirect ? response.value.data.redirect :
|
|
153
|
-
)
|
|
154
|
-
return
|
|
156
|
+
response.value.data.redirect ? response.value.data.redirect : '/',
|
|
157
|
+
)
|
|
158
|
+
return
|
|
155
159
|
}
|
|
156
160
|
formData.value = {
|
|
157
161
|
session: response.value.data.session,
|
|
158
|
-
}
|
|
159
|
-
session.value = response.value.data.session
|
|
160
|
-
inputs.value = []
|
|
161
|
-
responseFields.value = response.value.data.fields
|
|
162
|
-
if (response.value.data.message)
|
|
163
|
-
responseMessage.value = response.value.data.message
|
|
164
|
-
|
|
162
|
+
}
|
|
163
|
+
session.value = response.value.data.session
|
|
164
|
+
inputs.value = []
|
|
165
|
+
responseFields.value = response.value.data.fields
|
|
166
|
+
if (response.value.data.message) {
|
|
167
|
+
responseMessage.value = response.value.data.message
|
|
168
|
+
}
|
|
169
|
+
responseReq.value = response.value.data.req
|
|
165
170
|
responseFields.value.forEach((field) => {
|
|
166
|
-
if (field.type
|
|
167
|
-
hasOauth.value = true
|
|
171
|
+
if (field.type === 'oauth2') {
|
|
172
|
+
hasOauth.value = true
|
|
168
173
|
}
|
|
169
|
-
})
|
|
174
|
+
})
|
|
170
175
|
if (!hasOauth.value && responseFields.value.length > 0) {
|
|
171
|
-
showEmail.value = true
|
|
176
|
+
showEmail.value = true
|
|
172
177
|
}
|
|
173
178
|
setTimeout(() => {
|
|
174
|
-
if (inputs.value.length > 0 && inputs.value[inputs.value.length - 1])
|
|
175
|
-
inputs.value[inputs.value.length - 1].focus()
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
if (inputs.value.length > 0 && inputs.value[inputs.value.length - 1]) {
|
|
180
|
+
inputs.value[inputs.value.length - 1].focus()
|
|
181
|
+
}
|
|
182
|
+
}, 300)
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
178
185
|
//
|
|
179
186
|
}
|
|
180
187
|
|
|
181
|
-
eventBus.emit(
|
|
182
|
-
}
|
|
188
|
+
eventBus.emit('login-loading', false)
|
|
189
|
+
}
|
|
183
190
|
|
|
184
191
|
onMounted(async () => {
|
|
185
|
-
await userFlow({ initial: true })
|
|
186
|
-
})
|
|
192
|
+
await userFlow({ initial: true })
|
|
193
|
+
})
|
|
187
194
|
</script>
|
|
195
|
+
|
|
188
196
|
<template>
|
|
189
197
|
<ClientOnly>
|
|
190
198
|
<form
|
|
191
|
-
@submit.prevent="userFlow()"
|
|
192
199
|
v-if="!completed"
|
|
193
200
|
class="fws-login w-full"
|
|
201
|
+
@submit.prevent="userFlow()"
|
|
194
202
|
>
|
|
195
|
-
|
|
203
|
+
<!-- <FyLoader id="klblogin" /> -->
|
|
196
204
|
<div class="w-full">
|
|
197
205
|
<h2
|
|
198
|
-
class="text-lg text-fv-neutral-700 dark:text-fv-neutral-300 px-2"
|
|
199
206
|
v-if="responseMessage"
|
|
207
|
+
class="text-lg text-fv-neutral-700 dark:text-fv-neutral-300 px-2"
|
|
200
208
|
>
|
|
201
209
|
{{ responseMessage }}
|
|
202
210
|
</h2>
|
|
@@ -204,30 +212,31 @@ onMounted(async () => {
|
|
|
204
212
|
<div class="flex flex-col gap-2 px-2 justify-center py-2">
|
|
205
213
|
<template v-for="field of responseFields" :key="field.id">
|
|
206
214
|
<a
|
|
215
|
+
v-if="field.type && field.type === 'oauth2' && field.button"
|
|
216
|
+
href="javascript:void(0);"
|
|
217
|
+
class="flex border border-fv-neutral-300 dark:border-fv-neutral-700 shadow items-center gap-2 justify-start btn neutral defaults w-full mx-auto !font-semibold"
|
|
218
|
+
:style="`background: ${
|
|
219
|
+
field.button['background-color']
|
|
220
|
+
}; color: ${$getContrastingTextColor(
|
|
221
|
+
field.button['background-color'],
|
|
222
|
+
)}`"
|
|
207
223
|
@click="
|
|
208
224
|
() => {
|
|
209
225
|
if (field.info.Button_Extra?.trigger) {
|
|
210
226
|
doTrigger(field);
|
|
211
|
-
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
212
229
|
userFlow({ initial: true, oauth: field.id });
|
|
213
230
|
}
|
|
214
231
|
}
|
|
215
232
|
"
|
|
216
|
-
v-if="field.type && field.type == 'oauth2' && field.button"
|
|
217
|
-
href="javascript:void(0);"
|
|
218
|
-
class="flex border border-fv-neutral-300 dark:border-fv-neutral-700 shadow items-center gap-2 justify-start btn neutral defaults w-full mx-auto !font-semibold"
|
|
219
|
-
:style="`background: ${
|
|
220
|
-
field.button['background-color']
|
|
221
|
-
}; color: ${$getContrastingTextColor(
|
|
222
|
-
field.button['background-color'],
|
|
223
|
-
)}`"
|
|
224
233
|
>
|
|
225
234
|
<img
|
|
226
235
|
:key="`${field.label}oauth`"
|
|
227
236
|
class="h-12 w-12 block p-2 mr-3"
|
|
228
237
|
:alt="field.info.Name"
|
|
229
238
|
:src="field.button.logo"
|
|
230
|
-
|
|
239
|
+
>
|
|
231
240
|
<div>
|
|
232
241
|
{{
|
|
233
242
|
$t("user_flow_signin_with", {
|
|
@@ -255,72 +264,72 @@ onMounted(async () => {
|
|
|
255
264
|
}}
|
|
256
265
|
</div>
|
|
257
266
|
</button>
|
|
258
|
-
</div
|
|
259
|
-
>
|
|
267
|
+
</div>
|
|
268
|
+
</template>
|
|
260
269
|
<div
|
|
261
|
-
class="px-2 py-2"
|
|
262
270
|
v-if="forceAction || (showEmail && initial) || !initial"
|
|
271
|
+
class="px-2 py-2"
|
|
263
272
|
>
|
|
264
273
|
<template v-if="responseFields && responseFields.length > 0">
|
|
265
274
|
<template v-for="field of responseFields" :key="field.label">
|
|
266
275
|
<h3
|
|
267
|
-
v-if="field.type
|
|
276
|
+
v-if="field.type === 'label'"
|
|
268
277
|
class="pt-2 pb-1 text-sm text-fv-neutral-500 dark:text-fv-neutral-400"
|
|
269
278
|
:class="
|
|
270
|
-
field.style
|
|
279
|
+
field.style === 'error'
|
|
271
280
|
? 'text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300'
|
|
272
281
|
: ''
|
|
273
282
|
"
|
|
274
283
|
>
|
|
275
|
-
<a
|
|
284
|
+
<a v-if="field.link" :href="field.link" class="fws-link mb-3">{{
|
|
276
285
|
field.label
|
|
277
286
|
}}</a>
|
|
278
|
-
<span class="mb-2"
|
|
287
|
+
<span v-else class="mb-2">{{ field.label }}</span>
|
|
279
288
|
</h3>
|
|
280
289
|
|
|
281
|
-
<template v-if="field.cat
|
|
290
|
+
<template v-if="field.cat === 'input'">
|
|
282
291
|
<template
|
|
283
292
|
v-if="
|
|
284
|
-
field.type
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
293
|
+
field.type === 'text'
|
|
294
|
+
|| field.type === 'password'
|
|
295
|
+
|| field.type === 'email'
|
|
296
|
+
|| field.type === 'mask'
|
|
288
297
|
"
|
|
289
298
|
>
|
|
290
299
|
<DefaultInput
|
|
291
300
|
v-if="field.name"
|
|
292
301
|
:id="field.name"
|
|
302
|
+
ref="inputs"
|
|
303
|
+
v-model="formData[field.name]"
|
|
293
304
|
:label="field.label"
|
|
294
305
|
:mask="field.mask"
|
|
295
306
|
class="mt-3"
|
|
296
307
|
:placeholder="
|
|
297
|
-
field.name
|
|
308
|
+
field.name === 'name' ? 'John Doe' : field.label
|
|
298
309
|
"
|
|
299
310
|
:error="fieldsError[field.name]"
|
|
300
311
|
:type="field.type"
|
|
301
|
-
ref="inputs"
|
|
302
|
-
v-model="formData[field.name]"
|
|
303
312
|
:req="responseReq.includes(field.name)"
|
|
304
313
|
/>
|
|
305
314
|
</template>
|
|
306
315
|
</template>
|
|
307
|
-
<template v-if="field.type
|
|
316
|
+
<template v-if="field.type === 'checkbox'">
|
|
308
317
|
<DefaultInput
|
|
309
318
|
v-if="field.name"
|
|
310
319
|
:id="field.name"
|
|
320
|
+
v-model:checkbox-value="formData[field.name]"
|
|
311
321
|
class="mt-3"
|
|
312
322
|
:label="field.label"
|
|
313
323
|
:error="fieldsError[field.name]"
|
|
314
324
|
:type="field.type"
|
|
315
|
-
v-model:checkbox-value="formData[field.name]"
|
|
316
325
|
:req="responseReq.includes(field.name)"
|
|
317
326
|
:link-icon="field.link"
|
|
318
327
|
/>
|
|
319
328
|
</template>
|
|
320
329
|
</template>
|
|
321
330
|
<div
|
|
322
|
-
class="text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300"
|
|
323
331
|
v-if="responseError && responseError.token"
|
|
332
|
+
class="text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300"
|
|
324
333
|
>
|
|
325
334
|
{{ $t(responseError.token) }}
|
|
326
335
|
</div>
|
|
@@ -333,8 +342,7 @@ onMounted(async () => {
|
|
|
333
342
|
pwdRecoverMailSent = false;
|
|
334
343
|
}
|
|
335
344
|
"
|
|
336
|
-
|
|
337
|
-
>
|
|
345
|
+
>{{ $t("recover_pwd_link") }}</a>
|
|
338
346
|
</div>
|
|
339
347
|
<button class="btn primary medium mt-4">
|
|
340
348
|
{{ $t("cta_login_next") }}
|