mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-17 18:32:35 +00:00
Merge branch '103-email-field' into 'develop'
Resolve "Email field" Closes #103 See merge request bramw/baserow!101
This commit is contained in:
commit
f74f019f79
16 changed files with 446 additions and 17 deletions
backend
src/baserow/contrib/database
tests/baserow/contrib/database
web-frontend/modules
|
@ -45,11 +45,12 @@ class DatabaseConfig(AppConfig):
|
|||
|
||||
from .fields.field_types import (
|
||||
TextFieldType, LongTextFieldType, URLFieldType, NumberFieldType,
|
||||
BooleanFieldType, DateFieldType, LinkRowFieldType
|
||||
BooleanFieldType, DateFieldType, LinkRowFieldType, EmailFieldType
|
||||
)
|
||||
field_type_registry.register(TextFieldType())
|
||||
field_type_registry.register(LongTextFieldType())
|
||||
field_type_registry.register(URLFieldType())
|
||||
field_type_registry.register(EmailFieldType())
|
||||
field_type_registry.register(NumberFieldType())
|
||||
field_type_registry.register(BooleanFieldType())
|
||||
field_type_registry.register(DateFieldType())
|
||||
|
|
|
@ -6,7 +6,7 @@ from dateutil.parser import ParserError
|
|||
from datetime import datetime, date
|
||||
|
||||
from django.db import models
|
||||
from django.core.validators import URLValidator
|
||||
from django.core.validators import URLValidator, EmailValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.timezone import make_aware
|
||||
|
||||
|
@ -21,7 +21,7 @@ from .handler import FieldHandler
|
|||
from .registries import FieldType
|
||||
from .models import (
|
||||
NUMBER_TYPE_INTEGER, NUMBER_TYPE_DECIMAL, TextField, LongTextField, URLField,
|
||||
NumberField, BooleanField, DateField, LinkRowField
|
||||
NumberField, BooleanField, DateField, LinkRowField, EmailField
|
||||
)
|
||||
from .exceptions import LinkRowTableNotInSameDatabase, LinkRowTableNotProvided
|
||||
|
||||
|
@ -548,3 +548,42 @@ class LinkRowFieldType(FieldType):
|
|||
values.append(instance.id)
|
||||
|
||||
return values
|
||||
|
||||
|
||||
class EmailFieldType(FieldType):
|
||||
type = 'email'
|
||||
model_class = EmailField
|
||||
|
||||
def prepare_value_for_db(self, instance, value):
|
||||
if value == '' or value is None:
|
||||
return ''
|
||||
|
||||
validator = EmailValidator()
|
||||
validator(value)
|
||||
return value
|
||||
|
||||
def get_serializer_field(self, instance, **kwargs):
|
||||
return serializers.EmailField(
|
||||
required=False,
|
||||
allow_null=True,
|
||||
allow_blank=True,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def get_model_field(self, instance, **kwargs):
|
||||
return models.EmailField(default='', blank=True, null=True, **kwargs)
|
||||
|
||||
def random_value(self, instance, fake, cache):
|
||||
return fake.email()
|
||||
|
||||
def get_alter_column_type_function(self, connection, instance):
|
||||
if connection.vendor == 'postgresql':
|
||||
return r"""(
|
||||
case
|
||||
when p_in::text ~* '[A-Z0-9._+-]+@[A-Z0-9.-]+\.[A-Z]{2,}'
|
||||
then p_in::text
|
||||
else ''
|
||||
end
|
||||
)"""
|
||||
|
||||
return super().get_alter_column_type_function(connection, instance)
|
||||
|
|
|
@ -235,3 +235,7 @@ class LinkRowField(Field):
|
|||
raise ValueError('The link row field does not yet have a relation id.')
|
||||
|
||||
return f'database_relation_{self.link_row_relation_id}'
|
||||
|
||||
|
||||
class EmailField(Field):
|
||||
pass
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 2.2.11 on 2020-10-09 13:22
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('database', '0014_viewsort'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EmailField',
|
||||
fields=[
|
||||
('field_ptr', models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True, primary_key=True, serialize=False,
|
||||
to='database.Field'
|
||||
)),
|
||||
],
|
||||
bases=('database.field',),
|
||||
),
|
||||
]
|
|
@ -3,7 +3,8 @@ from baserow.core.models import Application
|
|||
from .table.models import Table
|
||||
from .views.models import View, GridView, GridViewFieldOptions, ViewFilter
|
||||
from .fields.models import (
|
||||
Field, TextField, NumberField, LongTextField, BooleanField, DateField, LinkRowField
|
||||
Field, TextField, NumberField, LongTextField, BooleanField, DateField, LinkRowField,
|
||||
URLField, EmailField
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
|
@ -11,7 +12,7 @@ __all__ = [
|
|||
'Table',
|
||||
'View', 'GridView', 'GridViewFieldOptions', 'ViewFilter',
|
||||
'Field', 'TextField', 'NumberField', 'LongTextField', 'BooleanField', 'DateField',
|
||||
'LinkRowField'
|
||||
'LinkRowField', 'URLField', 'EmailField'
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from django.db.models.fields.related import ManyToManyField
|
|||
|
||||
from baserow.contrib.database.fields.field_types import (
|
||||
TextFieldType, LongTextFieldType, URLFieldType, NumberFieldType, DateFieldType,
|
||||
LinkRowFieldType, BooleanFieldType
|
||||
LinkRowFieldType, BooleanFieldType, EmailFieldType
|
||||
)
|
||||
|
||||
from .registries import ViewFilterType
|
||||
|
@ -35,7 +35,8 @@ class EqualViewFilterType(ViewFilterType):
|
|||
LongTextFieldType.type,
|
||||
URLFieldType.type,
|
||||
NumberFieldType.type,
|
||||
BooleanFieldType.type
|
||||
BooleanFieldType.type,
|
||||
EmailFieldType.type
|
||||
]
|
||||
|
||||
def get_filter(self, field_name, value, model_field):
|
||||
|
@ -70,6 +71,7 @@ class ContainsViewFilterType(ViewFilterType):
|
|||
TextFieldType.type,
|
||||
LongTextFieldType.type,
|
||||
URLFieldType.type,
|
||||
EmailFieldType.type
|
||||
]
|
||||
|
||||
def get_filter(self, field_name, value, model_field):
|
||||
|
@ -248,7 +250,8 @@ class EmptyViewFilterType(ViewFilterType):
|
|||
NumberFieldType.type,
|
||||
BooleanFieldType.type,
|
||||
DateFieldType.type,
|
||||
LinkRowFieldType.type
|
||||
LinkRowFieldType.type,
|
||||
EmailFieldType.type
|
||||
]
|
||||
|
||||
def get_filter(self, field_name, value, model_field):
|
||||
|
|
|
@ -7,7 +7,9 @@ from rest_framework.status import HTTP_200_OK, HTTP_204_NO_CONTENT, HTTP_400_BAD
|
|||
|
||||
from django.shortcuts import reverse
|
||||
|
||||
from baserow.contrib.database.fields.models import LongTextField, URLField, DateField
|
||||
from baserow.contrib.database.fields.models import (
|
||||
LongTextField, URLField, DateField, EmailField
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
@ -288,3 +290,94 @@ def test_date_field_type(api_client, data_fixture):
|
|||
response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {token}')
|
||||
assert response.status_code == HTTP_204_NO_CONTENT
|
||||
assert DateField.objects.all().count() == 1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_email_field_type(api_client, data_fixture):
|
||||
user, token = data_fixture.create_user_and_token(
|
||||
email='test@test.nl', password='password', first_name='Test1')
|
||||
table = data_fixture.create_database_table(user=user)
|
||||
|
||||
response = api_client.post(
|
||||
reverse('api:database:fields:list', kwargs={'table_id': table.id}),
|
||||
{'name': 'Email', 'type': 'email'},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
)
|
||||
response_json = response.json()
|
||||
assert response.status_code == HTTP_200_OK
|
||||
assert response_json['type'] == 'email'
|
||||
assert EmailField.objects.all().count() == 1
|
||||
field_id = response_json['id']
|
||||
|
||||
response = api_client.patch(
|
||||
reverse('api:database:fields:item', kwargs={'field_id': field_id}),
|
||||
{'name': 'Email2'},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
)
|
||||
assert response.status_code == HTTP_200_OK
|
||||
|
||||
response = api_client.post(
|
||||
reverse('api:database:rows:list', kwargs={'table_id': table.id}),
|
||||
{
|
||||
f'field_{field_id}': 'test@test.nl'
|
||||
},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
)
|
||||
response_json = response.json()
|
||||
assert response.status_code == HTTP_200_OK
|
||||
assert response_json[f'field_{field_id}'] == 'test@test.nl'
|
||||
|
||||
model = table.get_model(attribute_names=True)
|
||||
row = model.objects.all().last()
|
||||
assert row.email2 == 'test@test.nl'
|
||||
|
||||
response = api_client.post(
|
||||
reverse('api:database:rows:list', kwargs={'table_id': table.id}),
|
||||
{
|
||||
f'field_{field_id}': ''
|
||||
},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
)
|
||||
response_json = response.json()
|
||||
assert response.status_code == HTTP_200_OK
|
||||
assert response_json[f'field_{field_id}'] == ''
|
||||
|
||||
row = model.objects.all().last()
|
||||
assert row.email2 == ''
|
||||
|
||||
response = api_client.post(
|
||||
reverse('api:database:rows:list', kwargs={'table_id': table.id}),
|
||||
{
|
||||
f'field_{field_id}': None
|
||||
},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
)
|
||||
response_json = response.json()
|
||||
assert response.status_code == HTTP_200_OK
|
||||
assert response_json[f'field_{field_id}'] == ''
|
||||
|
||||
row = model.objects.all().last()
|
||||
assert row.email2 == ''
|
||||
|
||||
response = api_client.post(
|
||||
reverse('api:database:rows:list', kwargs={'table_id': table.id}),
|
||||
{},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
)
|
||||
response_json = response.json()
|
||||
assert response.status_code == HTTP_200_OK
|
||||
assert response_json[f'field_{field_id}'] == ''
|
||||
|
||||
row = model.objects.all().last()
|
||||
assert row.email2 == ''
|
||||
|
||||
email = reverse('api:database:fields:item', kwargs={'field_id': field_id})
|
||||
response = api_client.delete(email, HTTP_AUTHORIZATION=f'JWT {token}')
|
||||
assert response.status_code == HTTP_204_NO_CONTENT
|
||||
assert EmailField.objects.all().count() == 0
|
||||
|
|
|
@ -8,7 +8,9 @@ from django.core.exceptions import ValidationError
|
|||
from django.utils.timezone import make_aware, datetime
|
||||
|
||||
from baserow.contrib.database.fields.field_types import DateFieldType
|
||||
from baserow.contrib.database.fields.models import LongTextField, URLField, DateField
|
||||
from baserow.contrib.database.fields.models import (
|
||||
LongTextField, URLField, DateField, EmailField
|
||||
)
|
||||
from baserow.contrib.database.fields.handler import FieldHandler
|
||||
from baserow.contrib.database.rows.handler import RowHandler
|
||||
|
||||
|
@ -384,3 +386,98 @@ def test_date_field_type(data_fixture):
|
|||
field_handler.delete_field(user=user, field=date_field_2)
|
||||
|
||||
assert len(DateField.objects.all()) == 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_email_field_type(data_fixture):
|
||||
user = data_fixture.create_user()
|
||||
table = data_fixture.create_database_table(user=user)
|
||||
table_2 = data_fixture.create_database_table(user=user, database=table.database)
|
||||
field = data_fixture.create_text_field(table=table, order=1, name='name')
|
||||
|
||||
field_handler = FieldHandler()
|
||||
row_handler = RowHandler()
|
||||
|
||||
field_2 = field_handler.create_field(user=user, table=table, type_name='email',
|
||||
name='email')
|
||||
number = field_handler.create_field(user=user, table=table, type_name='number',
|
||||
name='number')
|
||||
|
||||
assert len(EmailField.objects.all()) == 1
|
||||
model = table.get_model(attribute_names=True)
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
row_handler.create_row(user=user, table=table, values={
|
||||
'email': 'invalid_email'
|
||||
}, model=model)
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
row_handler.create_row(user=user, table=table, values={
|
||||
'email': 'invalid@email'
|
||||
}, model=model)
|
||||
|
||||
row_0 = row_handler.create_row(user=user, table=table, values={
|
||||
'name': 'a.very.STRANGE@email.address.coM',
|
||||
'email': 'test@test.nl',
|
||||
'number': 5
|
||||
}, model=model)
|
||||
row_1 = row_handler.create_row(user=user, table=table, values={
|
||||
'name': 'someuser',
|
||||
'email': 'some@user.com',
|
||||
'number': 10
|
||||
}, model=model)
|
||||
row_2 = row_handler.create_row(user=user, table=table, values={
|
||||
'name': 'http://www.baserow.io',
|
||||
'email': 'bram@test.nl'
|
||||
}, model=model)
|
||||
row_3 = row_handler.create_row(user=user, table=table, values={
|
||||
'name': 'NOT AN EMAIL',
|
||||
'email': 'something@example.com'
|
||||
}, model=model)
|
||||
row_4 = row_handler.create_row(user=user, table=table, values={
|
||||
'name': 'testing@nowhere.org',
|
||||
'email': ''
|
||||
}, model=model)
|
||||
row_5 = row_handler.create_row(user=user, table=table, values={
|
||||
'email': None,
|
||||
}, model=model)
|
||||
row_6 = row_handler.create_row(user=user, table=table, values={}, model=model)
|
||||
|
||||
# Convert the text field to a url field so we can check how the conversion of
|
||||
# values went.
|
||||
field_handler.update_field(user=user, field=field, new_type_name='email')
|
||||
field_handler.update_field(user=user, field=number, new_type_name='email')
|
||||
|
||||
model = table.get_model(attribute_names=True)
|
||||
rows = model.objects.all()
|
||||
|
||||
assert rows[0].name == 'a.very.STRANGE@email.address.coM'
|
||||
assert rows[0].email == 'test@test.nl'
|
||||
assert rows[0].number == ''
|
||||
|
||||
assert rows[1].name == ''
|
||||
assert rows[1].email == 'some@user.com'
|
||||
assert rows[1].number == ''
|
||||
|
||||
assert rows[2].name == ''
|
||||
assert rows[2].email == 'bram@test.nl'
|
||||
assert rows[2].number == ''
|
||||
|
||||
assert rows[3].name == ''
|
||||
assert rows[3].email == 'something@example.com'
|
||||
assert rows[3].number == ''
|
||||
|
||||
assert rows[4].name == 'testing@nowhere.org'
|
||||
assert rows[4].email == ''
|
||||
assert rows[4].number == ''
|
||||
|
||||
assert rows[5].name == ''
|
||||
assert rows[5].email == ''
|
||||
assert rows[5].number == ''
|
||||
|
||||
assert rows[6].name == ''
|
||||
assert rows[6].email == ''
|
||||
assert rows[6].number == ''
|
||||
|
||||
field_handler.delete_field(user=user, field=field_2)
|
||||
assert len(EmailField.objects.all()) == 2
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Highlight the row of a selected cell.
|
||||
* Fixed error when there is no view.
|
||||
* Added Ubuntu installation guide documentation.
|
||||
* Added Email field.
|
||||
|
||||
## Released (2020-10-06)
|
||||
|
||||
|
|
|
@ -47,3 +47,8 @@ export const isValidURL = (str) => {
|
|||
) // fragment locator
|
||||
return !!pattern.test(str)
|
||||
}
|
||||
|
||||
export const isValidEmail = (str) => {
|
||||
const pattern = new RegExp('[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}', 'i') // check email format
|
||||
return !!pattern.test(str)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<div class="control__elements">
|
||||
<input
|
||||
ref="input"
|
||||
v-model="copy"
|
||||
type="text"
|
||||
class="input input--large"
|
||||
:class="{ 'input--error': !isValid() }"
|
||||
@keyup.enter="$refs.input.blur()"
|
||||
@focus="select()"
|
||||
@blur="unselect()"
|
||||
/>
|
||||
<div v-show="!isValid()" class="error">
|
||||
{{ getError() }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import rowEditField from '@baserow/modules/database/mixins/rowEditField'
|
||||
import rowEditFieldInput from '@baserow/modules/database/mixins/rowEditFieldInput'
|
||||
import EmailField from '@baserow/modules/database/mixins/EmailField'
|
||||
|
||||
export default {
|
||||
mixins: [rowEditField, rowEditFieldInput, EmailField],
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div
|
||||
class="grid-view__cell"
|
||||
:class="{
|
||||
active: selected,
|
||||
editing: editing,
|
||||
invalid: editing && !isValid(),
|
||||
}"
|
||||
@contextmenu="stopContextIfEditing($event)"
|
||||
>
|
||||
<div v-show="!editing" class="grid-field-text">
|
||||
<template v-if="!selected">{{ value }}</template>
|
||||
<a v-if="selected" :href="'mailto:' + value" target="_blank">
|
||||
{{ value }}
|
||||
</a>
|
||||
</div>
|
||||
<template v-if="editing">
|
||||
<input
|
||||
ref="input"
|
||||
v-model="copy"
|
||||
type="text"
|
||||
class="grid-field-text__input"
|
||||
/>
|
||||
<div v-show="!isValid()" class="grid-view__cell--error align-right">
|
||||
{{ getError() }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gridField from '@baserow/modules/database/mixins/gridField'
|
||||
import gridFieldInput from '@baserow/modules/database/mixins/gridFieldInput'
|
||||
import EmailField from '@baserow/modules/database/mixins/EmailField'
|
||||
|
||||
export default {
|
||||
mixins: [gridField, gridFieldInput, EmailField],
|
||||
methods: {
|
||||
afterEdit() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.input.focus()
|
||||
this.$refs.input.selectionStart = this.$refs.input.selectionEnd = 100000
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -1,6 +1,6 @@
|
|||
import moment from 'moment'
|
||||
|
||||
import { isValidURL } from '@baserow/modules/core/utils/string'
|
||||
import { isValidURL, isValidEmail } from '@baserow/modules/core/utils/string'
|
||||
import { Registerable } from '@baserow/modules/core/registry'
|
||||
|
||||
import FieldNumberSubForm from '@baserow/modules/database/components/field/FieldNumberSubForm'
|
||||
|
@ -11,6 +11,7 @@ import FieldLinkRowSubForm from '@baserow/modules/database/components/field/Fiel
|
|||
import GridViewFieldText from '@baserow/modules/database/components/view/grid/GridViewFieldText'
|
||||
import GridViewFieldLongText from '@baserow/modules/database/components/view/grid/GridViewFieldLongText'
|
||||
import GridViewFieldURL from '@baserow/modules/database/components/view/grid/GridViewFieldURL'
|
||||
import GridViewFieldEmail from '@baserow/modules/database/components/view/grid/GridViewFieldEmail'
|
||||
import GridViewFieldLinkRow from '@baserow/modules/database/components/view/grid/GridViewFieldLinkRow'
|
||||
import GridViewFieldNumber from '@baserow/modules/database/components/view/grid/GridViewFieldNumber'
|
||||
import GridViewFieldBoolean from '@baserow/modules/database/components/view/grid/GridViewFieldBoolean'
|
||||
|
@ -19,6 +20,7 @@ import GridViewFieldDate from '@baserow/modules/database/components/view/grid/Gr
|
|||
import RowEditFieldText from '@baserow/modules/database/components/row/RowEditFieldText'
|
||||
import RowEditFieldLongText from '@baserow/modules/database/components/row/RowEditFieldLongText'
|
||||
import RowEditFieldURL from '@baserow/modules/database/components/row/RowEditFieldURL'
|
||||
import RowEditFieldEmail from '@baserow/modules/database/components/row/RowEditFieldEmail'
|
||||
import RowEditFieldLinkRow from '@baserow/modules/database/components/row/RowEditFieldLinkRow'
|
||||
import RowEditFieldNumber from '@baserow/modules/database/components/row/RowEditFieldNumber'
|
||||
import RowEditFieldBoolean from '@baserow/modules/database/components/row/RowEditFieldBoolean'
|
||||
|
@ -553,3 +555,41 @@ export class URLFieldType extends FieldType {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class EmailFieldType extends FieldType {
|
||||
static getType() {
|
||||
return 'email'
|
||||
}
|
||||
|
||||
getIconClass() {
|
||||
return 'at'
|
||||
}
|
||||
|
||||
getName() {
|
||||
return 'Email'
|
||||
}
|
||||
|
||||
getGridViewFieldComponent() {
|
||||
return GridViewFieldEmail
|
||||
}
|
||||
|
||||
getRowEditFieldComponent() {
|
||||
return RowEditFieldEmail
|
||||
}
|
||||
|
||||
prepareValueForPaste(field, clipboardData) {
|
||||
const value = clipboardData.getData('text')
|
||||
return isValidEmail(value) ? value : ''
|
||||
}
|
||||
|
||||
getSort(name, order) {
|
||||
return (a, b) => {
|
||||
const stringA = a[name] === null ? '' : '' + a[name]
|
||||
const stringB = b[name] === null ? '' : '' + b[name]
|
||||
|
||||
return order === 'ASC'
|
||||
? stringA.localeCompare(stringB)
|
||||
: stringB.localeCompare(stringA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
26
web-frontend/modules/database/mixins/EmailField.js
Normal file
26
web-frontend/modules/database/mixins/EmailField.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { isValidEmail } from '@baserow/modules/core/utils/string'
|
||||
|
||||
/**
|
||||
* This mixin contains some method overrides for validating and formatting the
|
||||
* email field. This mixin is used in both the GridViewFieldEmail and
|
||||
* RowEditFieldEmail components.
|
||||
*/
|
||||
export default {
|
||||
methods: {
|
||||
/**
|
||||
* Generates a human readable error for the user if something is wrong.
|
||||
*/
|
||||
getError() {
|
||||
if (this.copy === null || this.copy === '') {
|
||||
return null
|
||||
}
|
||||
if (!isValidEmail(this.copy)) {
|
||||
return 'Invalid email'
|
||||
}
|
||||
return null
|
||||
},
|
||||
isValid() {
|
||||
return this.getError() === null
|
||||
},
|
||||
},
|
||||
}
|
|
@ -4,6 +4,7 @@ import {
|
|||
TextFieldType,
|
||||
LongTextFieldType,
|
||||
URLFieldType,
|
||||
EmailFieldType,
|
||||
LinkRowFieldType,
|
||||
NumberFieldType,
|
||||
BooleanFieldType,
|
||||
|
@ -54,4 +55,5 @@ export default ({ store, app }) => {
|
|||
app.$registry.register('field', new BooleanFieldType())
|
||||
app.$registry.register('field', new DateFieldType())
|
||||
app.$registry.register('field', new URLFieldType())
|
||||
app.$registry.register('field', new EmailFieldType())
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ export class EqualViewFilterType extends ViewFilterType {
|
|||
}
|
||||
|
||||
getCompatibleFieldTypes() {
|
||||
return ['text', 'long_text', 'url', 'number']
|
||||
return ['text', 'long_text', 'url', 'email', 'number']
|
||||
}
|
||||
|
||||
matches(rowValue, filterValue) {
|
||||
|
@ -120,7 +120,7 @@ export class NotEqualViewFilterType extends ViewFilterType {
|
|||
}
|
||||
|
||||
getCompatibleFieldTypes() {
|
||||
return ['text', 'long_text', 'url', 'number']
|
||||
return ['text', 'long_text', 'url', 'email', 'number']
|
||||
}
|
||||
|
||||
matches(rowValue, filterValue) {
|
||||
|
@ -148,7 +148,7 @@ export class ContainsViewFilterType extends ViewFilterType {
|
|||
}
|
||||
|
||||
getCompatibleFieldTypes() {
|
||||
return ['text', 'long_text', 'url']
|
||||
return ['text', 'long_text', 'url', 'email']
|
||||
}
|
||||
|
||||
matches(rowValue, filterValue) {
|
||||
|
@ -172,7 +172,7 @@ export class ContainsNotViewFilterType extends ViewFilterType {
|
|||
}
|
||||
|
||||
getCompatibleFieldTypes() {
|
||||
return ['text', 'long_text', 'url']
|
||||
return ['text', 'long_text', 'url', 'email']
|
||||
}
|
||||
|
||||
matches(rowValue, filterValue) {
|
||||
|
@ -336,7 +336,16 @@ export class EmptyViewFilterType extends ViewFilterType {
|
|||
}
|
||||
|
||||
getCompatibleFieldTypes() {
|
||||
return ['text', 'long_text', 'url', 'number', 'date', 'boolean', 'link_row']
|
||||
return [
|
||||
'text',
|
||||
'long_text',
|
||||
'url',
|
||||
'email',
|
||||
'number',
|
||||
'date',
|
||||
'boolean',
|
||||
'link_row',
|
||||
]
|
||||
}
|
||||
|
||||
matches(rowValue, filterValue) {
|
||||
|
@ -363,7 +372,16 @@ export class NotEmptyViewFilterType extends ViewFilterType {
|
|||
}
|
||||
|
||||
getCompatibleFieldTypes() {
|
||||
return ['text', 'long_text', 'url', 'number', 'date', 'boolean', 'link_row']
|
||||
return [
|
||||
'text',
|
||||
'long_text',
|
||||
'url',
|
||||
'email',
|
||||
'number',
|
||||
'date',
|
||||
'boolean',
|
||||
'link_row',
|
||||
]
|
||||
}
|
||||
|
||||
matches(rowValue, filterValue) {
|
||||
|
|
Loading…
Add table
Reference in a new issue