Merge pull request #11962 from Budibase/budi-7583/filtering-data-provider-with-a-user-column-does-not-work

Filtering data providers by the new user column type
This commit is contained in:
Adria Navarro 2023-10-03 17:47:28 +02:00 committed by GitHub
commit 0867219a6e
5 changed files with 113 additions and 26 deletions

View File

@ -660,7 +660,8 @@
>Open schema editor</Button
>
{:else if editableColumn.type === USER_REFRENCE_TYPE}
<Toggle
<!-- Disabled temporally -->
<!-- <Toggle
value={editableColumn.relationshipType === RelationshipType.MANY_TO_MANY}
on:change={e =>
(editableColumn.relationshipType = e.detail
@ -669,7 +670,7 @@
disabled={!isCreating}
thin
text="Allow multiple users"
/>
/> -->
{/if}
{#if editableColumn.type === AUTO_TYPE || editableColumn.autocolumn}
<Select

View File

@ -17,7 +17,10 @@
import { generate } from "shortid"
import { LuceneUtils, Constants } from "@budibase/frontend-core"
import { getFields } from "helpers/searchFields"
import { FieldType } from "@budibase/types"
import { createEventDispatcher, onMount } from "svelte"
import FilterUsers from "./FilterUsers.svelte"
import { RelationshipType } from "constants/backend"
export let schemaFields
export let filters = []
@ -29,7 +32,6 @@
const dispatch = createEventDispatcher()
const { OperatorOptions } = Constants
const { getValidOperatorsForType } = LuceneUtils
const KeyedFieldRegex = /\d[0-9]*:/g
const behaviourOptions = [
{ value: "and", label: "Match all filters" },
@ -131,11 +133,7 @@
const santizeOperator = filter => {
// Ensure a valid operator is selected
const operators = getValidOperatorsForType(
filter.type,
filter.field,
datasource
).map(x => x.value)
const operators = getValidOperatorsForType(filter).map(x => x.value)
if (!operators.includes(filter.operator)) {
filter.operator = operators[0] ?? OperatorOptions.Equals.value
}
@ -148,7 +146,7 @@
filter.noValue = noValueOptions.includes(filter.operator)
}
const santizeValue = filter => {
const santizeValue = (filter, previousType) => {
// Check if the operator allows a value at all
if (filter.noValue) {
filter.value = null
@ -162,13 +160,20 @@
}
} else if (filter.type === "array" && filter.valueType === "Value") {
filter.value = []
} else if (
previousType !== filter.type &&
(previousType === FieldType.BB_REFERENCE ||
filter.type === FieldType.BB_REFERENCE)
) {
filter.value = filter.type === "array" ? [] : null
}
}
const onFieldChange = filter => {
const previousType = filter.type
santizeTypes(filter)
santizeOperator(filter)
santizeValue(filter)
santizeValue(filter, previousType)
}
const onOperatorChange = filter => {
@ -184,6 +189,32 @@
const schema = enrichedSchemaFields.find(x => x.name === field)
return schema?.constraints?.inclusion || []
}
const getValidOperatorsForType = filter => {
if (!filter) {
return []
}
let type = filter.type
if (type === FieldType.BB_REFERENCE) {
const fieldSchema = getSchema(filter)
if (fieldSchema) {
type = {
type: fieldSchema.type,
multiple:
fieldSchema.relationshipType === RelationshipType.MANY_TO_MANY,
}
}
}
const operators = LuceneUtils.getValidOperatorsForType(
type,
filter.field,
datasource
)
return operators
}
</script>
<DrawerContent>
@ -228,11 +259,7 @@
/>
<Select
disabled={!filter.field}
options={getValidOperatorsForType(
filter.type,
filter.field,
datasource
)}
options={getValidOperatorsForType(filter)}
bind:value={filter.operator}
on:change={() => onOperatorChange(filter)}
placeholder={null}
@ -285,6 +312,14 @@
timeOnly={getSchema(filter)?.timeOnly}
bind:value={filter.value}
/>
{:else if filter.type === FieldType.BB_REFERENCE}
<FilterUsers
bind:value={filter.value}
multiselect={getSchema(filter).relationshipType ===
RelationshipType.MANY_TO_MANY ||
filter.operator === OperatorOptions.In.value}
disabled={filter.noValue}
/>
{:else}
<DrawerBindableInput disabled />
{/if}

View File

@ -0,0 +1,34 @@
<script>
import { Select, Multiselect } from "@budibase/bbui"
import { fetchData } from "@budibase/frontend-core"
import { API } from "api"
export let value = null
export let disabled
export let multiselect = false
$: fetch = fetchData({
API,
datasource: {
type: "user",
},
options: {
limit: 100,
},
})
$: options = $fetch.rows
$: component = multiselect ? Multiselect : Select
</script>
<svelte:component
this={component}
bind:value
autocomplete
{options}
getOptionLabel={option => option.email}
getOptionValue={option => option._id}
{disabled}
/>

View File

@ -2,7 +2,7 @@ version: "3.8"
services:
db:
container_name: postgres
image: postgres
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_USER: root
@ -25,4 +25,4 @@ services:
- "5050:80"
volumes:
pg_data:
pg_data:

View File

@ -12,12 +12,22 @@ import { deepGet } from "./helpers"
const HBS_REGEX = /{{([^{].*?)}}/g
type RequestedFieldType =
| Exclude<FieldType, FieldType.BB_REFERENCE>
| { type: FieldType.BB_REFERENCE; multiple: boolean }
export function isFieldType(
r: RequestedFieldType
): r is Exclude<FieldType, FieldType.BB_REFERENCE> {
return typeof r === "string" && Object.values(FieldType).includes(r)
}
/**
* Returns the valid operator options for a certain data type
* @param type the data type
*/
export const getValidOperatorsForType = (
type: FieldType,
type: RequestedFieldType,
field: string,
datasource: Datasource & { tableId: any } // TODO: is this table id ever populated?
) => {
@ -44,22 +54,29 @@ export const getValidOperatorsForType = (
value: string
label: string
}[] = []
if (type === "string") {
if (type === FieldType.STRING) {
ops = stringOps
} else if (type === "number" || type === "bigint") {
} else if (type === FieldType.NUMBER || type === FieldType.BIGINT) {
ops = numOps
} else if (type === "options") {
} else if (type === FieldType.OPTIONS) {
ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty, Op.In]
} else if (type === "array") {
} else if (type === FieldType.ARRAY) {
ops = [Op.Contains, Op.NotContains, Op.Empty, Op.NotEmpty, Op.ContainsAny]
} else if (type === "boolean") {
} else if (type === FieldType.BOOLEAN) {
ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty]
} else if (type === "longform") {
} else if (type === FieldType.LONGFORM) {
ops = stringOps
} else if (type === "datetime") {
} else if (type === FieldType.DATETIME) {
ops = numOps
} else if (type === "formula") {
} else if (type === FieldType.FORMULA) {
ops = stringOps.concat([Op.MoreThan, Op.LessThan])
} else if (!isFieldType(type) && type.type === FieldType.BB_REFERENCE) {
if (type.multiple) {
// Temporally disabled
ops = []
} else {
ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty, Op.In]
}
}
// Only allow equal/not equal for _id in SQL tables