1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-23 12:50:16 +00:00
bramw_baserow/web-frontend/modules/builder/components/page/PageForm.vue
2023-03-23 16:22:14 +00:00

185 lines
4.5 KiB
Vue

<template>
<form @submit.prevent="submit">
<FormElement :error="fieldHasErrors('name')" class="control">
<label class="control__label">
<i class="fas fa-font"></i>
{{ $t('pageForm.nameLabel') }}
</label>
<input
ref="name"
v-model="values.name"
type="text"
class="input input--large"
:class="{ 'input--error': fieldHasErrors('name') }"
@focus.once="$event.target.select()"
@blur="$v.values.name.$touch()"
/>
<div
v-if="$v.values.name.$dirty && !$v.values.name.required"
class="error"
>
{{ $t('error.requiredField') }}
</div>
<div
v-if="$v.values.name.$dirty && !$v.values.name.maxLength"
class="error"
>
{{ $t('error.maxLength', { max: 255 }) }}
</div>
<div
v-if="$v.values.name.$dirty && !$v.values.name.isUnique"
class="error"
>
{{ $t('pageForm.errorNameNotUnique') }}
</div>
</FormElement>
<FormElement :error="fieldHasErrors('path')" class="control">
<label class="control__label">
<i class="fas fa-font"></i>
{{ $t('pageForm.pathLabel') }}
</label>
<input
ref="path"
v-model="values.path"
type="text"
class="input input--large"
:class="{ 'input--error': fieldHasErrors('path') }"
@input="hasPathBeenEdited = true"
@focus.once="$event.target.select()"
@blur="$v.values.path.$touch()"
/>
<div
v-if="$v.values.path.$dirty && !$v.values.path.required"
class="error"
>
{{ $t('error.requiredField') }}
</div>
<div
v-if="$v.values.path.$dirty && !$v.values.path.isUnique"
class="error"
>
{{ $t('pageForm.errorPathNotUnique') }}
</div>
<div
v-if="$v.values.path.$dirty && !$v.values.path.maxLength"
class="error"
>
{{ $t('error.maxLength', { max: 255 }) }}
</div>
<div
v-if="$v.values.path.$dirty && !$v.values.path.startingSlash"
class="error"
>
{{ $t('pageForm.errorStartingSlash') }}
</div>
<div
v-if="$v.values.path.$dirty && !$v.values.path.validPathCharacters"
class="error"
>
{{ $t('pageForm.errorValidPathCharacters') }}
</div>
</FormElement>
<slot></slot>
</form>
</template>
<script>
import form from '@baserow/modules/core/mixins/form'
import { maxLength, required } from 'vuelidate/lib/validators'
import {
getNextAvailableNameInSequence,
slugify,
} from '@baserow/modules/core/utils/string'
import { VALID_PATH_CHARACTERS } from '@baserow/modules/builder/enums'
export default {
name: 'PageForm',
mixins: [form],
props: {
builder: {
type: Object,
required: true,
},
creation: {
type: Boolean,
default: true,
},
},
data() {
return {
allowedValues: ['name', 'path'],
values: {
name: '',
path: '',
},
hasPathBeenEdited: false,
}
},
computed: {
pageNames() {
return this.builder.pages.map((page) => page.name)
},
pagePaths() {
return this.builder.pages.map((page) => page.path)
},
defaultName() {
const baseName = this.$t('pageForm.defaultName')
return getNextAvailableNameInSequence(baseName, this.pageNames)
},
},
watch: {
'values.name': {
handler(value) {
if (!this.hasPathBeenEdited && this.creation) {
this.values.path = `/${slugify(value)}`
}
},
immediate: true,
},
},
created() {
if (this.creation) {
this.values.name = this.defaultName
}
},
mounted() {
if (this.creation) {
this.$refs.name.focus()
}
},
methods: {
isNameUnique(name) {
return !this.pageNames.includes(name)
},
isPathUnique(path) {
return !this.pagePaths.includes(path)
},
pathStartsWithSlash(path) {
return path[0] === '/'
},
pathHasValidCharacters(path) {
return !path
.split('')
.some((letter) => !VALID_PATH_CHARACTERS.includes(letter))
},
},
validations() {
return {
values: {
name: {
required,
isUnique: this.isNameUnique,
maxLength: maxLength(255),
},
path: {
required,
isUnique: this.isPathUnique,
maxLength: maxLength(255),
startingSlash: this.pathStartsWithSlash,
validPathCharacters: this.pathHasValidCharacters,
},
},
}
},
}
</script>