mirror of
https://gitlab.com/bramw/baserow.git
synced 2024-11-24 16:36:46 +00:00
245 lines
7.0 KiB
Vue
245 lines
7.0 KiB
Vue
<template>
|
|
<div>
|
|
<h1>{{ $t('databaseScratchTrackFieldsStep.title') }}</h1>
|
|
<p>
|
|
{{
|
|
$t('databaseScratchTrackFieldsStep.description', {
|
|
selectedFieldsLimitCount,
|
|
})
|
|
}}
|
|
</p>
|
|
<div class="flex flex-wrap margin-bottom-3" style="--gap: 8px">
|
|
<Chips
|
|
v-for="(whatItem, whatKey) in whatItems"
|
|
:key="whatKey"
|
|
:active="isChipActive(whatKey)"
|
|
:disabled="isChipDisabled(whatKey)"
|
|
:icon="whatItem.icon"
|
|
@click="toggleSelection(whatKey)"
|
|
>{{ whatItem.name }}
|
|
</Chips>
|
|
<Chips
|
|
icon="iconoir-plus"
|
|
:disabled="isChipDisabled('own')"
|
|
:active="isChipActive('own')"
|
|
@click="toggleSelection('own')"
|
|
>
|
|
{{ $t('databaseScratchTrackStep.addYourOwn') }}
|
|
</Chips>
|
|
</div>
|
|
|
|
<FormGroup
|
|
v-if="isChipActive('own')"
|
|
required
|
|
small-label
|
|
class="margin-bottom-2 onboarding__form-group"
|
|
>
|
|
<div class="onboarding__form-group-row">
|
|
<div class="onboarding__form-group-column">
|
|
<div class="onboarding__form-group-label">
|
|
{{ $t('databaseScratchTrackFieldsStep.fieldType') }}
|
|
</div>
|
|
<Dropdown v-model="ownField" :show-search="false">
|
|
<DropdownItem
|
|
v-for="field in ownFields"
|
|
:key="field.props.type"
|
|
:name="field.name"
|
|
:value="field"
|
|
:icon="field.icon"
|
|
>
|
|
</DropdownItem>
|
|
</Dropdown>
|
|
</div>
|
|
<div class="onboarding__form-group-column">
|
|
<div class="onboarding__form-group-label">
|
|
{{ $t('databaseScratchTrackFieldsStep.fieldName') }}
|
|
</div>
|
|
<FormInput
|
|
v-model="ownField.props.name"
|
|
:placeholder="$t('databaseScratchTrackFieldsStep.fieldName')"
|
|
size="large"
|
|
:error="
|
|
$v.ownField.props.name.$dirty && $v.ownField.props.name.$invalid
|
|
"
|
|
@blur="$v.ownField.props.name.$touch()"
|
|
/>
|
|
<p
|
|
v-if="
|
|
$v.ownField.props.name.$dirty && $v.ownField.props.name.$invalid
|
|
"
|
|
class="control__messages--error"
|
|
>
|
|
<template v-if="!$v.ownField.props.name.required">
|
|
{{ $t('error.requiredField') }}
|
|
</template>
|
|
<template v-if="!$v.ownField.props.name.uniqueNameValidator">
|
|
{{ $t('error.alreadyInUse') }}
|
|
</template>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</FormGroup>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { requiredIf } from 'vuelidate/lib/validators'
|
|
import { DatabaseScratchTrackOnboardingType } from '@baserow/modules/database/onboardingTypes'
|
|
|
|
export default {
|
|
name: 'DatabaseScratchTrackFieldsStep',
|
|
props: {
|
|
data: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
what: '',
|
|
selectedFieldsLimitCount: 4,
|
|
selectedFieldsCount: 0,
|
|
selectedFields: {},
|
|
ownField: {
|
|
props: {
|
|
name: '',
|
|
},
|
|
},
|
|
isOwnFieldValidationEnabled: false,
|
|
whatItems: [],
|
|
ownFields: [],
|
|
}
|
|
},
|
|
watch: {
|
|
ownField: {
|
|
handler(field) {
|
|
this.selectedFields.own = field
|
|
this.updateValue()
|
|
},
|
|
deep: true,
|
|
},
|
|
},
|
|
mounted() {
|
|
this.what =
|
|
this.data[
|
|
DatabaseScratchTrackOnboardingType.getType()
|
|
].tableName.toLowerCase()
|
|
let onboardingTrackFieldsType
|
|
|
|
try {
|
|
onboardingTrackFieldsType = this.$registry.get(
|
|
'onboardingTrackFields',
|
|
`database_scratch_track_fields_${this.what}`
|
|
)
|
|
} catch {
|
|
onboardingTrackFieldsType = this.$registry.get(
|
|
'onboardingTrackFields',
|
|
`database_scratch_track_fields_custom`
|
|
)
|
|
}
|
|
this.whatItems = onboardingTrackFieldsType.getFields()
|
|
this.ownFields = onboardingTrackFieldsType.getOwnFields()
|
|
this.updateValue()
|
|
},
|
|
methods: {
|
|
isChipDisabled(name) {
|
|
return (
|
|
this.selectedFieldsCount >= this.selectedFieldsLimitCount &&
|
|
!Object.keys(this.selectedFields).includes(name)
|
|
)
|
|
},
|
|
isChipActive(name) {
|
|
const isActive = Object.keys(this.selectedFields).includes(name)
|
|
if (name === 'own') {
|
|
this.isOwnFieldValidationEnabled = isActive
|
|
}
|
|
return isActive
|
|
},
|
|
isValid() {
|
|
return !this.$v.$invalid
|
|
},
|
|
toggleSelection(value) {
|
|
const isAlreadySelected = this.isChipActive(value)
|
|
if (
|
|
this.selectedFieldsCount >= this.selectedFieldsLimitCount &&
|
|
!isAlreadySelected
|
|
) {
|
|
return
|
|
}
|
|
|
|
if (isAlreadySelected) {
|
|
this.selectedFieldsCount--
|
|
delete this.selectedFields[value]
|
|
} else {
|
|
this.selectedFieldsCount++
|
|
if (value === 'own') {
|
|
// preselect first field if nothing was selected
|
|
if (!this.ownField.props.name) {
|
|
this.ownField = this.ownFields[0]
|
|
}
|
|
this.selectedFields.own = this.ownField
|
|
} else {
|
|
const selectedItem = this.whatItems[value]
|
|
if (this.isNameUsed(selectedItem.props.name)) {
|
|
const useCount = this.useCount(selectedItem.props.name)
|
|
selectedItem.props.name = `${selectedItem.props.name} ${
|
|
useCount + 1
|
|
}`
|
|
} else {
|
|
selectedItem.props.name = selectedItem.name
|
|
}
|
|
|
|
this.selectedFields[value] = selectedItem
|
|
}
|
|
}
|
|
this.forceValidation(value)
|
|
this.updateValue()
|
|
},
|
|
updateValue() {
|
|
const fields = this.selectedFields
|
|
this.$emit('update-data', { fields })
|
|
},
|
|
getSelectedFieldNames(excludeField) {
|
|
return Object.entries(this.selectedFields)
|
|
.filter(([key, value]) => key !== excludeField)
|
|
.map(([key, value]) => value.props.name)
|
|
},
|
|
useCount(value, excludeField) {
|
|
return this.getSelectedFieldNames(excludeField).filter(
|
|
(name) => name === value
|
|
).length
|
|
},
|
|
isNameUsed(value, excludeField) {
|
|
const selectedFieldNames = this.getSelectedFieldNames(excludeField)
|
|
return selectedFieldNames && selectedFieldNames.includes(value)
|
|
},
|
|
forceValidation(value) {
|
|
// This is needed because we need to trigger validation without
|
|
// changing the value (by clicking on chips). Vuelidate
|
|
// doesn't trigger validation if the value doesn't change.
|
|
// We want only to trigger validation if own field is selected
|
|
if (value !== 'own' && this.isChipActive('own')) {
|
|
const tmp = this.$v.ownField.props.name.$model
|
|
this.$v.ownField.props.name.$model = ''
|
|
this.$v.ownField.props.name.$model = tmp
|
|
this.$v.ownField.props.name.$touch()
|
|
}
|
|
},
|
|
},
|
|
validations() {
|
|
return {
|
|
ownField: {
|
|
props: {
|
|
name: {
|
|
required: requiredIf(() => this.isOwnFieldValidationEnabled),
|
|
uniqueNameValidator: (value) => {
|
|
return !this.isNameUsed(value, 'own')
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
</script>
|