1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-02-11 23:59:00 +00:00
bramw_baserow/web-frontend/modules/builder/components/userSource/UpdateUserSourceForm.vue
2024-12-10 14:27:16 +00:00

260 lines
7.3 KiB
Vue

<template>
<form @submit.prevent="submit">
<FormRow>
<FormGroup
:label="$t('updateUserSourceForm.nameFieldLabel')"
required
small-label
:error-message="getError('name')"
>
<FormInput
v-model="$v.values.name.$model"
size="large"
class="update-user-source-form__name-input"
:placeholder="$t('updateUserSourceForm.nameFieldPlaceholder')"
/>
</FormGroup>
<FormGroup
:label="$t('updateUserSourceForm.integrationFieldLabel')"
:error-message="getError('integration_id')"
required
small-label
>
<IntegrationDropdown
v-model="$v.values.integration_id.$model"
:application="builder"
:integrations="integrations"
:integration-type="userSourceType.integrationType"
size="large"
/>
</FormGroup>
</FormRow>
<component
:is="userSourceType.formComponent"
v-if="integration"
:default-values="defaultValues"
:application="builder"
:integration="integration"
@values-changed="emitChange"
/>
<div v-if="integration">
<FormGroup
:label="$t('updateUserSourceForm.authTitle')"
small-label
required
>
<div
v-for="appAuthType in appAuthProviderTypes"
:key="appAuthType.type"
class="update-user-source-form__auth-provider"
>
<div class="update-user-source-form__auth-provider-header">
<Checkbox
:checked="hasAtLeastOneOfThisType(appAuthType)"
@input="onSelect(appAuthType)"
>
{{ appAuthType.name }}
</Checkbox>
<ButtonText
v-if="
hasAtLeastOneOfThisType(appAuthType) &&
appAuthType.canCreateNew(appAuthProviderPerTypes)
"
icon="iconoir-plus"
type="secondary"
@click.prevent="addNew(appAuthType)"
>
{{ $t('updateUserSourceForm.addProvider') }}
</ButtonText>
</div>
<div
v-for="appAuthProvider in appAuthProviderPerTypes[appAuthType.type]"
:key="appAuthProvider.id"
class="update-user-source-form__auth-provider-form"
>
<component
:is="appAuthType.formComponent"
v-if="hasAtLeastOneOfThisType(appAuthType)"
:ref="`authProviderForm`"
excluded-form
:integration="integration"
:user-source="fullValues"
:auth-providers="appAuthProviderPerTypes"
:auth-provider="appAuthProvider"
:default-values="appAuthProvider"
:auth-provider-type="appAuthType"
@values-changed="updateAuthProvider(appAuthProvider, $event)"
@delete="remove(appAuthProvider)"
/>
</div>
</div>
</FormGroup>
<input type="submit" hidden />
</div>
</form>
</template>
<script>
import form from '@baserow/modules/core/mixins/form'
import IntegrationDropdown from '@baserow/modules/core/components/integrations/IntegrationDropdown'
import { required, maxLength } from 'vuelidate/lib/validators'
export default {
components: { IntegrationDropdown },
mixins: [form],
props: {
builder: {
type: Object,
required: true,
},
userSourceType: {
type: Object,
required: false,
default: null,
},
},
data() {
return {
values: {
integration_id: null,
name: '',
auth_providers: [],
},
fullValues: this.getFormValues(),
}
},
computed: {
integrations() {
return this.$store.getters['integration/getIntegrations'](this.builder)
},
integration() {
if (!this.values.integration_id) {
return null
}
return this.integrations.find(
({ id }) => id === this.values.integration_id
)
},
appAuthProviderTypes() {
return this.$registry.getOrderedList('appAuthProvider')
},
appAuthProviderPerTypes() {
return Object.fromEntries(
this.appAuthProviderTypes.map((authType) => {
return [
authType.type,
this.values.auth_providers.filter(
({ type }) => type === authType.type
),
]
})
)
},
},
methods: {
// Override the default getChildFormValues to exclude the provider forms from
// final values as they are handled directly by this component
// The problem is that the child provider forms are not handled as a sub array
// so they override the userSource configuration
getChildFormsValues() {
return Object.assign(
{},
...this.$children
.filter(
(child) =>
'getChildFormsValues' in child &&
child.$attrs['excluded-form'] === undefined
)
.map((child) => {
return child.getFormValues()
})
)
},
hasAtLeastOneOfThisType(appAuthProviderType) {
return this.appAuthProviderPerTypes[appAuthProviderType.type]?.length > 0
},
/** Return an integer bigger than any of the current auth_provider id to
* keep the right order when we want to map the error coming back from the server.
*/
nextID() {
return (
Math.max(1, ...this.values.auth_providers.map(({ id }) => id)) + 100
)
},
onSelect(appAuthProviderType) {
if (this.hasAtLeastOneOfThisType(appAuthProviderType)) {
this.values.auth_providers = this.values.auth_providers.filter(
({ type }) => type !== appAuthProviderType.type
)
} else {
this.values.auth_providers.push({
type: appAuthProviderType.type,
id: this.nextID(),
})
}
},
addNew(appAuthProviderType) {
this.values.auth_providers.push({
type: appAuthProviderType.type,
id: this.nextID(),
})
},
remove(appAuthProvider) {
this.values.auth_providers = this.values.auth_providers.filter(
({ id }) => id !== appAuthProvider.id
)
},
updateAuthProvider(authProviderToChange, values) {
this.values.auth_providers = this.values.auth_providers.map(
(authProvider) => {
if (authProvider.id === authProviderToChange.id) {
return { ...authProvider, ...values }
}
return authProvider
}
)
},
emitChange() {
this.fullValues = this.getFormValues()
},
handleServerError(error) {
if (
this.$refs.authProviderForm
.map((form) => form.handleServerError(error))
.some((result) => result)
) {
return true
}
return false
},
getError(fieldName) {
if (!this.$v.values[fieldName].$dirty) {
return ''
}
const fieldState = this.$v.values[fieldName]
if (!fieldState.required) {
return this.$t('error.requiredField')
}
if (fieldName === 'name' && !fieldState.maxLength) {
return this.$t('error.maxLength', { max: 255 })
}
return ''
},
},
validations: {
values: {
integration_id: {
required,
},
name: {
required,
maxLength: maxLength(255),
},
},
},
}
</script>