mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-17 18:32:35 +00:00
Resolve "Prefill form values via query parameters"
This commit is contained in:
parent
86867fb88f
commit
4441aff78e
24 changed files with 1176 additions and 12 deletions
changelog.md
docs/tutorials
web-frontend
modules
core
assets/scss/components/views
components
locales
utils
database
test/unit
|
@ -11,6 +11,8 @@ For example:
|
|||
|
||||
### New Features
|
||||
|
||||
* Added prefill query parameters for forms. [#852](https://gitlab.com/bramw/baserow/-/issues/852)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Upload modal no longer closes when removing a file. [#569](https://gitlab.com/bramw/baserow/-/issues/569)
|
||||
|
|
84
docs/tutorials/prefill-forms.md
Normal file
84
docs/tutorials/prefill-forms.md
Normal file
|
@ -0,0 +1,84 @@
|
|||
# Prefill Forms
|
||||
Forms can be prefilled in order to help the user fill in the form faster.
|
||||
|
||||
All fields which are availbale in the form can be prefilled.
|
||||
|
||||
## How to prefill a form
|
||||
If you want to prefill a form with data you can do so via query parameters
|
||||
added to the public form url. These query parameters are prefixed with
|
||||
`prefill` to avoid any collision with potential future query parameters.
|
||||
|
||||
### Format
|
||||
The format of the query parameters is as follows:
|
||||
````
|
||||
?prefill_<field_name>=<value>
|
||||
````
|
||||
|
||||
### Example
|
||||
In the example below we want to prefill a field called `Name` with the value of `Mike`
|
||||
````
|
||||
?prefill_Name=Mike
|
||||
````
|
||||
|
||||
### Spaces
|
||||
Spaces in the field name are replaced with `+` to avoid any issues with the query parameter.
|
||||
````
|
||||
?prefill_my+field=Mike
|
||||
````
|
||||
|
||||
### Multiple values
|
||||
If you want to prefill multiple fields you can do so by adding a `,` between the values.
|
||||
````
|
||||
?prefill_multi+select=Mike,John
|
||||
````
|
||||
|
||||
### Special Field Types
|
||||
Generally the prefill value is the same as the value of the field. But there are some exceptions
|
||||
where the value is translated to a different value.
|
||||
|
||||
#### Rating field
|
||||
A rating field accepts a number to indicate how many stars should be filled.
|
||||
````
|
||||
?prefill_rating=3
|
||||
````
|
||||
|
||||
#### Link Row Field
|
||||
A link row field can accept the value that is shown in the select dropdown.
|
||||
````
|
||||
?prefill_link+row=Mike
|
||||
````
|
||||
|
||||
#### Single Select / Multiple Select field
|
||||
A single select field can accept the value that is shown in the select dropdown.
|
||||
So does the Multiple Select field, but it can also accept multiple values.
|
||||
````
|
||||
?prefill_single+select=Mike
|
||||
````
|
||||
|
||||
#### Date Field
|
||||
A date field can accept a date in the following formats and will use the date format
|
||||
of the field to parse the date.
|
||||
````
|
||||
// Standards
|
||||
ISO_8601
|
||||
|
||||
// General formats
|
||||
'YYYY-MM-DD',
|
||||
'YYYY-MM-DD hh:mm A',
|
||||
'YYYY-MM-DD HH:mm',
|
||||
|
||||
// EU
|
||||
'DD/MM/YYYY',
|
||||
'DD/MM/YYYY hh:mm A',
|
||||
'DD/MM/YYYY HH:mm'
|
||||
|
||||
// US
|
||||
'MM/DD/YYYY',
|
||||
'MM/DD/YYYY hh:mm A',
|
||||
'MM/DD/YYYY HH:mm'
|
||||
````
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
width: 300px;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.form-view__sidebar-fields {
|
||||
|
@ -117,6 +120,10 @@
|
|||
color: $color-primary-900;
|
||||
}
|
||||
|
||||
.form-view__sidebar-prefill-link {
|
||||
padding: 0 30px 30px 30px;
|
||||
}
|
||||
|
||||
.form-view__preview {
|
||||
@include absolute(0, 0, 0, 300px);
|
||||
|
||||
|
|
|
@ -96,11 +96,16 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
initialDisplayName: {
|
||||
type: [String, null],
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fetched: false,
|
||||
displayName: null,
|
||||
displayName: this.initialDisplayName,
|
||||
count: 0,
|
||||
page: 1,
|
||||
loading: false,
|
||||
|
|
|
@ -254,5 +254,67 @@
|
|||
"settingAllowSignupsViaGroupInvitationsName": "",
|
||||
"settingAllowSignupsViaGroupInvitationDescription": "",
|
||||
"enabled": ""
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "",
|
||||
"removeAll": "",
|
||||
"addField": ""
|
||||
},
|
||||
"fieldsDescription": "",
|
||||
"prefillInfoLink": "",
|
||||
"modal": {
|
||||
"title": "",
|
||||
"descriptionPartOne": "",
|
||||
"descriptionPartTwo": "",
|
||||
"howToPrefill": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"format": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"example": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"spaces": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"ratingField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"selectField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"dateField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,5 +278,67 @@
|
|||
"title": "Autorisierungsfehler",
|
||||
"content": "Anscheinend sind Sie nicht berechtigt, diese Ressource anzuzeigen.",
|
||||
"action": "Seite neu laden"
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "Alle hinzufügen",
|
||||
"removeAll": "Alle entfernen",
|
||||
"addField": "Feld hinzufügen"
|
||||
},
|
||||
"fieldsDescription": "Alle Felder sind im Formular",
|
||||
"prefillInfoLink": "Werte dynamisch vorausfüllen",
|
||||
"modal": {
|
||||
"title": "Werte dynamisch vorausfüllen",
|
||||
"descriptionPartOne": "Formular können vorausgefüllt werden, um dem Benutzer zu helfen das Formular schneller auszufüllen.",
|
||||
"descriptionPartTwo": "Alle Felder die im Formular verfügbar sind, können vorausgefüllt werden.",
|
||||
"howToPrefill": {
|
||||
"title": "Wie man ein Formular vorausfüllt",
|
||||
"description": "Wenn Sie ein Formular vorausfüllen wollen, können sie das mit einem Query Paremeter in der URL des Öffentlichen Formulares. Diese Query Parameter haben einen prefix von 'prefill' um potentielle Kollisionen mit anderen Query Parametern zu vermeiden."
|
||||
},
|
||||
"format": {
|
||||
"title": "Format",
|
||||
"description": "Das Format der Query Parameter is das Folgende:",
|
||||
"codeSnippet": "?prefill_<feld_name>=<wert>"
|
||||
},
|
||||
"example": {
|
||||
"title": "Beispiel",
|
||||
"description": "In dem folgenden Beispiel wollen wir ein Feld mit dem Namen `Name` mit dem Wert `Mike` vorausfüllen",
|
||||
"codeSnippet": "?prefill_Name=Mike"
|
||||
},
|
||||
"spaces": {
|
||||
"title": "Leerzeichen",
|
||||
"description": "Leerzeichen in Feldern werden mit einem '+' ersetzt, um Probleme mit den Query Parametern zu vermeiden.",
|
||||
"codeSnippet": "?prefill_mein+Feld=Mike"
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "Mehrere Werte",
|
||||
"description": "Wenn Sie mehrere Werte benötigen, können Sie diese mit einem Komma getrennt angeben.",
|
||||
"codeSnippet": "?prefill_multi+select=Mike,John"
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "Besondere Felder",
|
||||
"description": "Allgemein ist der vorgefüllte Wert der selbe wie der Wert des Feldes, allerdings gibt es Ausnahmen wo der Wert erst noch konvertiert werden muss.",
|
||||
"ratingField": {
|
||||
"title": "Bewertungsfeld",
|
||||
"description": "Ein Bewertungsfeld akzeptiert eine Nummer welche bestimmt wie viele Sterne ausgefüllt werden sollen.",
|
||||
"codeSnippet": "?prefill_Bewertung=3"
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "Zeilenlinkfeld",
|
||||
"description": "Ein Zeilenlinkfeld kann jeden Wert akzeptieren welcher im Dropdown zu sehen ist.",
|
||||
"codeSnippet": "?prefill_zeilenlinkfeld=Mike"
|
||||
},
|
||||
"selectField": {
|
||||
"title": "Einzel/Mehrfachauswahlfeld",
|
||||
"description": "Ein Einzelauswahlfeld akzeptiert jeden Wert der im Dropdown sichtbar ist. Das selbe gilt für das Mehrfachauswahlfeld, allerdings kann dieses auch mehrere Werte akzeptieren.",
|
||||
"codeSnippet": "?prefill_Einzelauswahlfeld=Mike"
|
||||
},
|
||||
"dateField": {
|
||||
"title": "Datumsfeld",
|
||||
"description": "Ein Datumsfeld kann ein Datum in den folgenden Formaten akzeptieren und wir das Datenformat des Feldes benutzen um den Wert richtig darzustellen.",
|
||||
"codeSnippet": "\n// Standards\nISO_8601\n\n// Generelle Formate\n'YYYY-MM-DD',\n'YYYY-MM-DD hh:mm A',\n'YYYY-MM-DD HH:mm',\n\n// EU\n'DD/MM/YYYY', \n'DD/MM/YYYY hh:mm A', \n'DD/MM/YYYY HH:mm'\n\n// US\n'MM/DD/YYYY', \n'MM/DD/YYYY hh:mm A', \n'MM/DD/YYYY HH:mm'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,5 +278,67 @@
|
|||
"settingAllowSignupsViaGroupInvitationsName": "Allow signups via group invitations",
|
||||
"settingAllowSignupsViaGroupInvitationDescription": "Even if the creation of new accounts is disabled, this option permits directly invited users to still create an account.",
|
||||
"enabled": "enabled"
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "Add all",
|
||||
"removeAll": "Remove all",
|
||||
"addField": "Add field"
|
||||
},
|
||||
"fieldsDescription": "All the fields are in the form.",
|
||||
"prefillInfoLink": "Pre-fill values dynamically",
|
||||
"modal": {
|
||||
"title": "Pre-fill values dynamically",
|
||||
"descriptionPartOne": "Forms can be prefilled in order to help the user fill in the form faster.",
|
||||
"descriptionPartTwo": "All fields which are availbale in the form can be prefilled.",
|
||||
"howToPrefill": {
|
||||
"title": "How to prefill a form",
|
||||
"description": "If you want to prefill a form with data you can do so via query parameters added to the public form url. These query parameters are prefixed with `prefill` to avoid any collision with potential future query parameters."
|
||||
},
|
||||
"format": {
|
||||
"title": "Format",
|
||||
"description": "The format of the query parameters is as follows:",
|
||||
"codeSnippet": "?prefill_<field_name>=<value>"
|
||||
},
|
||||
"example": {
|
||||
"title": "Example",
|
||||
"description": "In the example below we want to prefill a field called `Name` with the value of `Mike`",
|
||||
"codeSnippet": "?prefill_Name=Mike"
|
||||
},
|
||||
"spaces": {
|
||||
"title": "Spaces",
|
||||
"description": "Spaces in the field name are replaced with `+` to avoid any issues with the query parameter.",
|
||||
"codeSnippet": "?prefill_my+field=Mike"
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "Multiple values",
|
||||
"description": "If you want to prefill multiple fields you can do so by adding a `,` between the values.",
|
||||
"codeSnippet": "?prefill_multi+select=Mike,John"
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "Special field types",
|
||||
"description": "Generally the prefill value is the same as the value of the field. But there are some exceptions where the value is translated to a different value.",
|
||||
"ratingField": {
|
||||
"title": "Rating field",
|
||||
"description": "A rating field accepts a number to indicate how many stars should be filled.",
|
||||
"codeSnippet": "?prefill_rating=3"
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "Link row field",
|
||||
"description": "A link row field can accept the value that is shown in the select dropdown.",
|
||||
"codeSnippet": "?prefill_link+row=Mike"
|
||||
},
|
||||
"selectField": {
|
||||
"title": "Single Select / Multiple Select field",
|
||||
"description": "A single select field can accept the value that is shown in the select dropdown. So does the Multiple Select field, but it can also accept multiple values.",
|
||||
"codeSnippet": "?prefill_single+select=Mike"
|
||||
},
|
||||
"dateField": {
|
||||
"title": "Date field",
|
||||
"description": "A date field can accept a date in the following formats and will use the date format of the field to parse the date.",
|
||||
"codeSnippet": "\n// Standards\nISO_8601\n\n// General formats\n'YYYY-MM-DD',\n'YYYY-MM-DD hh:mm A',\n'YYYY-MM-DD HH:mm',\n\n// EU\n'DD/MM/YYYY', \n'DD/MM/YYYY hh:mm A', \n'DD/MM/YYYY HH:mm'\n\n// US\n'MM/DD/YYYY', \n'MM/DD/YYYY hh:mm A', \n'MM/DD/YYYY HH:mm'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,5 +274,67 @@
|
|||
"title": "Error de autorización",
|
||||
"content": "Parece que no tienes permisos para ver este recurso.",
|
||||
"action": "Refrescar página"
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "",
|
||||
"removeAll": "",
|
||||
"addField": ""
|
||||
},
|
||||
"fieldsDescription": "",
|
||||
"prefillInfoLink": "",
|
||||
"modal": {
|
||||
"title": "",
|
||||
"descriptionPartOne": "",
|
||||
"descriptionPartTwo": "",
|
||||
"howToPrefill": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"format": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"example": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"spaces": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"ratingField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"selectField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"dateField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,5 +274,67 @@
|
|||
"content": "Vous ne semblez pas avoir la permission de visualiser cette ressource.",
|
||||
"action": "Rafraîchir la page",
|
||||
"title": "Erreur d’autorisation"
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "",
|
||||
"removeAll": "",
|
||||
"addField": ""
|
||||
},
|
||||
"fieldsDescription": "",
|
||||
"prefillInfoLink": "",
|
||||
"modal": {
|
||||
"title": "",
|
||||
"descriptionPartOne": "",
|
||||
"descriptionPartTwo": "",
|
||||
"howToPrefill": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"format": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"example": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"spaces": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"ratingField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"selectField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"dateField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,5 +274,67 @@
|
|||
"title": "Autorizzazione negata",
|
||||
"content": "Sembra tu non abbia i permessi per accedere a questa risorsa.",
|
||||
"action": "Aggiorna pagina"
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "",
|
||||
"removeAll": "",
|
||||
"addField": ""
|
||||
},
|
||||
"fieldsDescription": "",
|
||||
"prefillInfoLink": "",
|
||||
"modal": {
|
||||
"title": "",
|
||||
"descriptionPartOne": "",
|
||||
"descriptionPartTwo": "",
|
||||
"howToPrefill": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"format": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"example": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"spaces": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"ratingField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"selectField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"dateField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,5 +274,67 @@
|
|||
"title": "Autorisatiefout",
|
||||
"content": "Het lijkt erop dat je niet de rechten hebt om deze bron te zien.",
|
||||
"action": "Pagina vernieuwen"
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "",
|
||||
"removeAll": "",
|
||||
"addField": ""
|
||||
},
|
||||
"fieldsDescription": "",
|
||||
"prefillInfoLink": "",
|
||||
"modal": {
|
||||
"title": "",
|
||||
"descriptionPartOne": "",
|
||||
"descriptionPartTwo": "",
|
||||
"howToPrefill": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"format": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"example": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"spaces": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"ratingField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"selectField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"dateField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,5 +269,67 @@
|
|||
"settingAllowSignupsViaGroupInvitationsName": "Permitir inscrições por meio de convites de grupo",
|
||||
"settingAllowSignupsViaGroupInvitationDescription": "Mesmo que a criação de novas contas esteja desativada, esta opção permite que usuários convidados diretamente ainda criem uma conta.",
|
||||
"enabled": "ativar"
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "",
|
||||
"removeAll": "",
|
||||
"addField": ""
|
||||
},
|
||||
"fieldsDescription": "",
|
||||
"prefillInfoLink": "",
|
||||
"modal": {
|
||||
"title": "",
|
||||
"descriptionPartOne": "",
|
||||
"descriptionPartTwo": "",
|
||||
"howToPrefill": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"format": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"example": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"spaces": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"ratingField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"selectField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"dateField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,5 +244,67 @@
|
|||
"settingAllowNewAccountsName": "",
|
||||
"settingAllowNewAccountsDescription": "",
|
||||
"enabled": ""
|
||||
},
|
||||
"formSidebar": {
|
||||
"actions": {
|
||||
"addAll": "",
|
||||
"removeAll": "",
|
||||
"addField": ""
|
||||
},
|
||||
"fieldsDescription": "",
|
||||
"prefillInfoLink": "",
|
||||
"modal": {
|
||||
"title": "",
|
||||
"descriptionPartOne": "",
|
||||
"descriptionPartTwo": "",
|
||||
"howToPrefill": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"format": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"example": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"spaces": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"multipleValues": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"specialFieldTypes": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"ratingField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"linkRowField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"selectField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
},
|
||||
"dateField": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"codeSnippet": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,3 +68,12 @@ export function mappingToStringifiedJSONLines(
|
|||
return first ? lines : index
|
||||
}
|
||||
}
|
||||
|
||||
export function isPromise(p) {
|
||||
return (
|
||||
p !== null &&
|
||||
typeof p === 'object' &&
|
||||
typeof p.then === 'function' &&
|
||||
typeof p.catch === 'function'
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<Modal>
|
||||
<h1>{{ $t('formSidebar.modal.title') }}</h1>
|
||||
<p>{{ $t('formSidebar.modal.descriptionPartOne') }}</p>
|
||||
<p>{{ $t('formSidebar.modal.descriptionPartTwo') }}</p>
|
||||
|
||||
<h2>{{ $t('formSidebar.modal.howToPrefill.title') }}</h2>
|
||||
<p>{{ $t('formSidebar.modal.howToPrefill.description') }}</p>
|
||||
|
||||
<h3>{{ $t('formSidebar.modal.format.title') }}</h3>
|
||||
<p>{{ $t('formSidebar.modal.format.description') }}</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.format.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h3>{{ $t('formSidebar.modal.example.title') }}</h3>
|
||||
<p>{{ $t('formSidebar.modal.example.description') }}</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.example.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h3>{{ $t('formSidebar.modal.spaces.title') }}</h3>
|
||||
<p>{{ $t('formSidebar.modal.spaces.description') }}</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.spaces.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h3>{{ $t('formSidebar.modal.multipleValues.title') }}</h3>
|
||||
<p>{{ $t('formSidebar.modal.multipleValues.description') }}</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.multipleValues.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h3>{{ $t('formSidebar.modal.specialFieldTypes.title') }}</h3>
|
||||
<p>{{ $t('formSidebar.modal.specialFieldTypes.description') }}</p>
|
||||
|
||||
<h4>{{ $t('formSidebar.modal.specialFieldTypes.ratingField.title') }}</h4>
|
||||
<p>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.ratingField.description') }}
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.ratingField.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h4>{{ $t('formSidebar.modal.specialFieldTypes.linkRowField.title') }}</h4>
|
||||
<p>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.linkRowField.description') }}
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.linkRowField.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h4>{{ $t('formSidebar.modal.specialFieldTypes.selectField.title') }}</h4>
|
||||
<p>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.selectField.description') }}
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.selectField.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h4>{{ $t('formSidebar.modal.specialFieldTypes.dateField.title') }}</h4>
|
||||
<p>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.dateField.description') }}
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
{{ $t('formSidebar.modal.specialFieldTypes.dateField.codeSnippet') }}
|
||||
</code>
|
||||
</pre>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from '@baserow/modules/core/mixins/modal'
|
||||
|
||||
export default {
|
||||
name: 'FormPrefillModal',
|
||||
mixins: [modal],
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -3,6 +3,7 @@
|
|||
<PaginatedDropdown
|
||||
:fetch-page="fetchPage"
|
||||
:value="dropdownValue"
|
||||
:initial-display-name="initialDisplayName"
|
||||
:class="{ 'dropdown--error': touched && !valid }"
|
||||
:fetch-on-open="lazyLoad"
|
||||
@input="updateValue($event)"
|
||||
|
@ -45,6 +46,9 @@ export default {
|
|||
dropdownValue() {
|
||||
return this.value.length === 0 ? null : this.value[0].id
|
||||
},
|
||||
initialDisplayName() {
|
||||
return this.value.length === 0 ? null : this.value[0].value
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetchPage(page, search) {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
true
|
||||
)
|
||||
"
|
||||
>add all</a
|
||||
>{{ $t('formSidebar.actions.addAll') }}</a
|
||||
>
|
||||
</li>
|
||||
<li v-show="enabledFields.length > 0">
|
||||
|
@ -27,7 +27,7 @@
|
|||
true
|
||||
)
|
||||
"
|
||||
>remove all</a
|
||||
>{{ $t('formSidebar.actions.removeAll') }}</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -50,7 +50,7 @@
|
|||
</FormViewSidebarField>
|
||||
</div>
|
||||
<p v-else class="form-view__sidebar-fields-description">
|
||||
All the fields are in the form.
|
||||
{{ $t('formSidebar.fieldsDescription') }}
|
||||
</p>
|
||||
<div v-if="!readOnly">
|
||||
<a
|
||||
|
@ -58,7 +58,7 @@
|
|||
@click="$refs.createFieldContext.toggle($refs.createFieldContextLink)"
|
||||
>
|
||||
<i class="fas fa-plus"></i>
|
||||
Create new field
|
||||
{{ $t('formSidebar.actions.addField') }}
|
||||
</a>
|
||||
<CreateFieldContext
|
||||
ref="createFieldContext"
|
||||
|
@ -67,6 +67,13 @@
|
|||
></CreateFieldContext>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-view__sidebar-prefill-link">
|
||||
<a @click="showFormPrefillModal">
|
||||
<i class="fas fa-question-circle"></i>
|
||||
{{ $t('formSidebar.prefillInfoLink') }}
|
||||
</a>
|
||||
<FormPrefillModal ref="formPrefillModal"></FormPrefillModal>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -74,10 +81,11 @@
|
|||
import CreateFieldContext from '@baserow/modules/database/components/field/CreateFieldContext'
|
||||
import formViewHelpers from '@baserow/modules/database/mixins/formViewHelpers'
|
||||
import FormViewSidebarField from '@baserow/modules/database/components/view/form/FormViewSidebarField'
|
||||
import FormPrefillModal from '@baserow/modules/database/components/view/form/FormPrefillModal'
|
||||
|
||||
export default {
|
||||
name: 'FormViewSidebar',
|
||||
components: { CreateFieldContext, FormViewSidebarField },
|
||||
components: { FormPrefillModal, CreateFieldContext, FormViewSidebarField },
|
||||
mixins: [formViewHelpers],
|
||||
props: {
|
||||
table: {
|
||||
|
@ -105,6 +113,9 @@ export default {
|
|||
order(order) {
|
||||
this.$emit('ordered-fields', order)
|
||||
},
|
||||
showFormPrefillModal() {
|
||||
this.$refs.formPrefillModal.show()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -89,6 +89,7 @@ import GridViewFieldFormula from '@baserow/modules/database/components/view/grid
|
|||
import FieldFormulaSubForm from '@baserow/modules/database/components/field/FieldFormulaSubForm'
|
||||
import FieldLookupSubForm from '@baserow/modules/database/components/field/FieldLookupSubForm'
|
||||
import RowEditFieldFormula from '@baserow/modules/database/components/row/RowEditFieldFormula'
|
||||
import ViewService from '@baserow/modules/database/services/view'
|
||||
|
||||
export class FieldType extends Registerable {
|
||||
/**
|
||||
|
@ -508,6 +509,26 @@ export class FieldType extends Registerable {
|
|||
acceptSplitCommaSeparatedSelectOptions() {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the field type value can be set by
|
||||
* parsing a query parameter.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
canParseQueryParameter() {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a value given by a url query parameter.
|
||||
* @param {string} value
|
||||
* @param field
|
||||
* @param options Any additional information that might be needed for the parsing
|
||||
* @returns {*}
|
||||
*/
|
||||
parseQueryParameter(field, value, options) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
export class TextFieldType extends FieldType {
|
||||
|
@ -578,6 +599,10 @@ export class TextFieldType extends FieldType {
|
|||
canBeReferencedByFormulaField() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class LongTextFieldType extends FieldType {
|
||||
|
@ -644,6 +669,10 @@ export class LongTextFieldType extends FieldType {
|
|||
canBeReferencedByFormulaField() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class LinkRowFieldType extends FieldType {
|
||||
|
@ -773,6 +802,24 @@ export class LinkRowFieldType extends FieldType {
|
|||
shouldFetchFieldSelectOptions() {
|
||||
return false
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
async parseQueryParameter(field, value, { client, slug }) {
|
||||
const { data } = await ViewService(client).linkRowFieldLookup(
|
||||
slug,
|
||||
field.field.id,
|
||||
1,
|
||||
value,
|
||||
1
|
||||
)
|
||||
|
||||
const item = data.results.find((item) => item.value === value)
|
||||
|
||||
return item ? [item] : this.getEmptyValue()
|
||||
}
|
||||
}
|
||||
|
||||
export class NumberFieldType extends FieldType {
|
||||
|
@ -954,6 +1001,14 @@ export class NumberFieldType extends FieldType {
|
|||
canBeReferencedByFormulaField() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
parseQueryParameter(field, value) {
|
||||
return NumberFieldType.formatNumber(field.field, value)
|
||||
}
|
||||
}
|
||||
|
||||
export class RatingFieldType extends FieldType {
|
||||
|
@ -1062,6 +1117,24 @@ export class RatingFieldType extends FieldType {
|
|||
canBeReferencedByFormulaField() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
parseQueryParameter(field, value) {
|
||||
const valueParsed = parseInt(value, 10)
|
||||
|
||||
if (isNaN(valueParsed) || valueParsed < 0) {
|
||||
return this.getEmptyValue()
|
||||
}
|
||||
|
||||
if (valueParsed > field.max_value) {
|
||||
return field.max_value
|
||||
}
|
||||
|
||||
return valueParsed
|
||||
}
|
||||
}
|
||||
|
||||
export class BooleanFieldType extends FieldType {
|
||||
|
@ -1134,6 +1207,14 @@ export class BooleanFieldType extends FieldType {
|
|||
canBeReferencedByFormulaField() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
parseQueryParameter(field, value) {
|
||||
return value === 'true'
|
||||
}
|
||||
}
|
||||
|
||||
class BaseDateFieldType extends FieldType {
|
||||
|
@ -1207,7 +1288,11 @@ class BaseDateFieldType extends FieldType {
|
|||
* correct format for the field. If it can't be parsed null is returned.
|
||||
*/
|
||||
prepareValueForPaste(field, clipboardData) {
|
||||
const value = clipboardData.toUpperCase()
|
||||
return DateFieldType.formatDate(field, clipboardData)
|
||||
}
|
||||
|
||||
static formatDate(field, dateString) {
|
||||
const value = dateString.toUpperCase()
|
||||
|
||||
// Formats for ISO dates
|
||||
let formats = [
|
||||
|
@ -1281,6 +1366,14 @@ export class DateFieldType extends BaseDateFieldType {
|
|||
getRowEditFieldComponent() {
|
||||
return RowEditFieldDate
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
parseQueryParameter(field, value) {
|
||||
return DateFieldType.formatDate(field.field, value)
|
||||
}
|
||||
}
|
||||
|
||||
export class CreatedOnLastModifiedBaseFieldType extends BaseDateFieldType {
|
||||
|
@ -1472,6 +1565,10 @@ export class URLFieldType extends FieldType {
|
|||
getContainsFilterFunction() {
|
||||
return genericContainsFilter
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class EmailFieldType extends FieldType {
|
||||
|
@ -1556,6 +1653,10 @@ export class EmailFieldType extends FieldType {
|
|||
canBeReferencedByFormulaField() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class FileFieldType extends FieldType {
|
||||
|
@ -1824,6 +1925,18 @@ export class SingleSelectFieldType extends FieldType {
|
|||
shouldFetchFieldSelectOptions() {
|
||||
return false
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
parseQueryParameter(field, value) {
|
||||
const selectedOption = field.field.select_options.find(
|
||||
(option) => option.value === value
|
||||
)
|
||||
|
||||
return selectedOption ?? this.getEmptyValue()
|
||||
}
|
||||
}
|
||||
|
||||
export class MultipleSelectFieldType extends FieldType {
|
||||
|
@ -1980,6 +2093,23 @@ export class MultipleSelectFieldType extends FieldType {
|
|||
acceptSplitCommaSeparatedSelectOptions() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts the following format: option1,option2,option3
|
||||
*/
|
||||
parseQueryParameter(field, value) {
|
||||
const values = value.split(',')
|
||||
|
||||
const selectOptions = field.field.select_options.filter((option) =>
|
||||
values.includes(option.value)
|
||||
)
|
||||
|
||||
return selectOptions.length > 0 ? selectOptions : this.getEmptyValue()
|
||||
}
|
||||
}
|
||||
|
||||
export class PhoneNumberFieldType extends FieldType {
|
||||
|
@ -2065,6 +2195,14 @@ export class PhoneNumberFieldType extends FieldType {
|
|||
canBeReferencedByFormulaField() {
|
||||
return true
|
||||
}
|
||||
|
||||
canParseQueryParameter() {
|
||||
return true
|
||||
}
|
||||
|
||||
parseQueryParameter(field, value) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
export class FormulaFieldType extends FieldType {
|
||||
|
|
|
@ -67,12 +67,13 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { clone } from '@baserow/modules/core/utils/object'
|
||||
import { clone, isPromise } from '@baserow/modules/core/utils/object'
|
||||
import { notifyIf } from '@baserow/modules/core/utils/error'
|
||||
import Notifications from '@baserow/modules/core/components/notifications/Notifications'
|
||||
import FormService from '@baserow/modules/database/services/view/form'
|
||||
import FormPageField from '@baserow/modules/database/components/view/form/FormPageField'
|
||||
import FormViewPoweredBy from '@baserow/modules/database/components/view/form/FormViewPoweredBy'
|
||||
import { getPrefills } from '@baserow/modules/database/utils/form'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -109,12 +110,34 @@ export default {
|
|||
// After the form field meta data has been fetched, we need to make the values
|
||||
// object with the empty field value as initial form value.
|
||||
const values = {}
|
||||
const prefills = getPrefills(route.query)
|
||||
const promises = []
|
||||
data.fields.forEach((field) => {
|
||||
field._ = { touched: false }
|
||||
const fieldType = app.$registry.get('field', field.field.type)
|
||||
values[`field_${field.field.id}`] = fieldType.getEmptyValue(field.field)
|
||||
const setValue = (value) => {
|
||||
values[`field_${field.field.id}`] = value
|
||||
}
|
||||
|
||||
const prefill = prefills[field.name]
|
||||
values[`field_${field.field.id}`] = fieldType.getEmptyValue(field.field) // Default value
|
||||
if (prefill !== undefined && fieldType.canParseQueryParameter()) {
|
||||
const result = fieldType.parseQueryParameter(field, prefill, {
|
||||
slug,
|
||||
client: app.$client,
|
||||
})
|
||||
|
||||
if (isPromise(result)) {
|
||||
result.then(setValue)
|
||||
promises.push(result)
|
||||
} else {
|
||||
setValue(result)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
// Order the fields directly after fetching the results to make sure the form is
|
||||
// serverside rendered in the right order.
|
||||
data.fields = data.fields.sort((a, b) => {
|
||||
|
|
|
@ -79,11 +79,11 @@ export default (client) => {
|
|||
rotateSlug(viewId) {
|
||||
return client.post(`/database/views/${viewId}/rotate-slug/`)
|
||||
},
|
||||
linkRowFieldLookup(slug, fieldId, page, search = null) {
|
||||
linkRowFieldLookup(slug, fieldId, page, search = null, size = 100) {
|
||||
const config = {
|
||||
params: {
|
||||
page,
|
||||
size: 100,
|
||||
size,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
11
web-frontend/modules/database/utils/form.js
Normal file
11
web-frontend/modules/database/utils/form.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
export function getPrefills(query) {
|
||||
return Object.keys(query).reduce((prefills, key) => {
|
||||
if (key.startsWith('prefill_')) {
|
||||
const keyFormatted = key
|
||||
.replace('prefill_', '') // Remove the prefix
|
||||
.replaceAll('+', ' ') // Replace + with spaces
|
||||
prefills[keyFormatted] = query[key]
|
||||
}
|
||||
return prefills
|
||||
}, Object.create(null))
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
clone,
|
||||
isPromise,
|
||||
mappingToStringifiedJSONLines,
|
||||
} from '@baserow/modules/core/utils/object'
|
||||
|
||||
|
@ -59,4 +60,14 @@ describe('test utils object', () => {
|
|||
20: 'Value 2',
|
||||
})
|
||||
})
|
||||
|
||||
test('test isPromise', () => {
|
||||
expect(isPromise(new Promise(() => null))).toBeTruthy()
|
||||
expect(isPromise('string')).toBeFalsy()
|
||||
|
||||
// This is one downside of the function, it shouldn't return true
|
||||
// but it does. Unfortunately this is as close to a good promise detection
|
||||
// as we can get
|
||||
expect(isPromise({ then: () => null, catch: () => null })).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
import { TestApp } from '@baserow/test/helpers/testApp'
|
||||
import { DateFieldType } from '@baserow/modules/database/fieldTypes'
|
||||
import {
|
||||
BooleanFieldType,
|
||||
DateFieldType,
|
||||
EmailFieldType,
|
||||
LinkRowFieldType,
|
||||
LongTextFieldType,
|
||||
MultipleSelectFieldType,
|
||||
NumberFieldType,
|
||||
PhoneNumberFieldType,
|
||||
RatingFieldType,
|
||||
SingleSelectFieldType,
|
||||
TextFieldType,
|
||||
URLFieldType,
|
||||
} from '@baserow/modules/database/fieldTypes'
|
||||
|
||||
const mockedFields = {
|
||||
text: {
|
||||
|
@ -276,6 +289,147 @@ const datePrepareValueForPaste = [
|
|||
},
|
||||
]
|
||||
|
||||
const queryParametersForParsing = [
|
||||
{
|
||||
fieldType: new TextFieldType(),
|
||||
input: { value: 'test', field: {} },
|
||||
output: 'test',
|
||||
},
|
||||
{
|
||||
fieldType: new LongTextFieldType(),
|
||||
input: { value: 'test', field: {} },
|
||||
output: 'test',
|
||||
},
|
||||
{
|
||||
fieldType: new NumberFieldType(),
|
||||
input: { value: '123', field: { field: { number_decimal_places: 1 } } },
|
||||
output: '123.0',
|
||||
},
|
||||
{
|
||||
fieldType: new NumberFieldType(),
|
||||
input: {
|
||||
value: 'a string',
|
||||
field: { field: { number_decimal_places: 1 } },
|
||||
},
|
||||
output: new NumberFieldType().getEmptyValue(),
|
||||
},
|
||||
{
|
||||
fieldType: new NumberFieldType(),
|
||||
input: { value: '12.55', field: { field: { number_decimal_places: 1 } } },
|
||||
output: '12.6',
|
||||
},
|
||||
{
|
||||
fieldType: new RatingFieldType(),
|
||||
input: { value: '3', field: {} },
|
||||
output: 3,
|
||||
},
|
||||
{
|
||||
fieldType: new RatingFieldType(),
|
||||
input: { value: 7, field: { max_value: 5 } },
|
||||
output: 5,
|
||||
},
|
||||
{
|
||||
fieldType: new BooleanFieldType(),
|
||||
input: { value: 'true', field: {} },
|
||||
output: true,
|
||||
},
|
||||
{
|
||||
fieldType: new BooleanFieldType(),
|
||||
input: { value: 'a string', field: {} },
|
||||
output: false,
|
||||
},
|
||||
{
|
||||
fieldType: new BooleanFieldType(),
|
||||
input: { value: 'false', field: {} },
|
||||
output: false,
|
||||
},
|
||||
{
|
||||
fieldType: new DateFieldType(),
|
||||
input: { value: '2021-12-04', field: { field: { date_format: 'EU' } } },
|
||||
output: '2021-12-04',
|
||||
},
|
||||
{
|
||||
fieldType: new DateFieldType(),
|
||||
input: {
|
||||
value: '2021-12-04T22:57:00Z',
|
||||
field: { field: { date_format: 'EU' } },
|
||||
},
|
||||
output: '2021-12-04',
|
||||
},
|
||||
{
|
||||
fieldType: new URLFieldType(),
|
||||
input: { value: 'http://www.example.com', field: {} },
|
||||
output: 'http://www.example.com',
|
||||
},
|
||||
{
|
||||
fieldType: new EmailFieldType(),
|
||||
input: { value: 'test@test.com', field: {} },
|
||||
output: 'test@test.com',
|
||||
},
|
||||
{
|
||||
fieldType: new SingleSelectFieldType(),
|
||||
input: {
|
||||
value: 'test',
|
||||
field: { field: { select_options: [{ value: 'test' }] } },
|
||||
},
|
||||
output: { value: 'test' },
|
||||
},
|
||||
{
|
||||
fieldType: new SingleSelectFieldType(),
|
||||
input: {
|
||||
value: 'test2',
|
||||
field: {
|
||||
field: { select_options: [{ value: 'test' }, { value: 'test2' }] },
|
||||
},
|
||||
},
|
||||
output: { value: 'test2' },
|
||||
},
|
||||
{
|
||||
fieldType: new MultipleSelectFieldType(),
|
||||
input: {
|
||||
value: 'test,test2',
|
||||
field: {
|
||||
field: {
|
||||
select_options: [{ value: 'test' }, { value: 'test2' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
output: [{ value: 'test' }, { value: 'test2' }],
|
||||
},
|
||||
{
|
||||
fieldType: new MultipleSelectFieldType(),
|
||||
input: {
|
||||
value: 'test,nonsense',
|
||||
field: {
|
||||
field: {
|
||||
select_options: [{ value: 'test' }, { value: 'test2' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
output: [{ value: 'test' }],
|
||||
},
|
||||
{
|
||||
fieldType: new PhoneNumberFieldType(),
|
||||
input: { value: '+1 (123) 456-7890', field: {} },
|
||||
output: '+1 (123) 456-7890',
|
||||
},
|
||||
]
|
||||
|
||||
const queryParametersAsyncForParsing = [
|
||||
{
|
||||
fieldType: new LinkRowFieldType(),
|
||||
data: { results: [{ value: 'test', id: 1 }] },
|
||||
input: { value: 'test', field: { field: { id: 20 } } },
|
||||
output: [{ id: 1, value: 'test' }],
|
||||
},
|
||||
{
|
||||
fieldType: new LinkRowFieldType(),
|
||||
data: { results: [{ value: 'some other value', id: 1 }] },
|
||||
input: { value: 'test', field: { field: { id: 20 } } },
|
||||
output: new LinkRowFieldType().getEmptyValue(),
|
||||
},
|
||||
]
|
||||
|
||||
describe('FieldType tests', () => {
|
||||
let testApp = null
|
||||
let fieldRegistry = null
|
||||
|
@ -332,4 +486,26 @@ describe('FieldType tests', () => {
|
|||
expect(result).toBe(value.expectedValue)
|
||||
}
|
||||
)
|
||||
|
||||
test.each(queryParametersForParsing)(
|
||||
'Verify that parseQueryParameter returns the expected output for each field type',
|
||||
({ input, output, fieldType }) => {
|
||||
expect(
|
||||
fieldType.parseQueryParameter(input.field, input.value)
|
||||
).toStrictEqual(output)
|
||||
}
|
||||
)
|
||||
|
||||
test.each(queryParametersAsyncForParsing)(
|
||||
'Verify that parseQueryParameter for async field types returns the correct output',
|
||||
async ({ data, input, output, fieldType }) => {
|
||||
const client = { get: jest.fn().mockReturnValue({ data }) }
|
||||
const result = await fieldType.parseQueryParameter(
|
||||
input.field,
|
||||
input.value,
|
||||
{ client, slug: expect.anything() }
|
||||
)
|
||||
expect(result).toStrictEqual(output)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
29
web-frontend/test/unit/database/utils/form.spec.js
Normal file
29
web-frontend/test/unit/database/utils/form.spec.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { getPrefills } from '@baserow/modules/database/utils/form'
|
||||
|
||||
const valuesToCall = [
|
||||
{
|
||||
query: {},
|
||||
result: {},
|
||||
},
|
||||
{
|
||||
query: { someUnrelatedQuery: 'someValue' },
|
||||
result: {},
|
||||
},
|
||||
{
|
||||
query: { prefill_value: 'value' },
|
||||
result: { value: 'value' },
|
||||
},
|
||||
{
|
||||
query: { 'prefill_value+with+spaces': 'value' },
|
||||
result: { 'value with spaces': 'value' },
|
||||
},
|
||||
]
|
||||
|
||||
describe('Form utils test', () => {
|
||||
test.each(valuesToCall)(
|
||||
'Test that all values are correctly extracted from the query',
|
||||
({ query, result }) => {
|
||||
expect(getPrefills(query)).toEqual(result)
|
||||
}
|
||||
)
|
||||
})
|
Loading…
Add table
Reference in a new issue