1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-01-26 18:48:15 +02:00
focalboard/webapp/src/cardFilter.ts

147 lines
5.4 KiB
TypeScript
Raw Normal View History

2020-10-20 12:50:53 -07:00
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
2020-10-20 12:52:56 -07:00
import {IPropertyTemplate} from './blocks/board'
import {Card} from './blocks/card'
2021-02-16 10:31:00 -08:00
import {FilterClause} from './blocks/filterClause'
Migrate webapp global state to redux (#737) * Migrating workspace tree to redux * More changes for use the redux store for boads and views * Taking into account the templates on websocket event updates * Fixing bug on boardTree maintenance * Websocket client now connects once and subscribe/desubscribe on the fly * Including usage of the new websocket client * More work around migrating to redux * WIP * WIP * WIP * WIP * WIP * WIP * Fixing some things * WIP * WIP * Another small fix * Restoring filtering, sorting and grouping * Fixing some other bugs * Add search text reducer * Fixing another drag and drop problem * Improve store names and api * Fixing small bgus * Some small fixes * fixing login * Fixing register page * Some other improvements * Removing unneeded old files * Removing the need of userCache * Fixing comments and fixing content ordering * Fixing sort * Fixing some TODOs * Fixing tests * Fixing snapshot * Fixing cypress tests * Fix eslint * Fixing server tests * Updating the add cards actions * Fixing some tiny navigation problems * Mocking the api calls to pass the tests * Migrating a new test to redux * Adding the card right after the insert of the block (not wait for ws event) * Showing the ws disconnect banner only after 5 seconds of disconnection * Fixing share view * Fix eslint * Fixing problem with sort/groupby modifications * Fixing some details on redirections and templates creation * Fixing small bugs around undo * Fix update properties on click outside the dialog * Improving the column resize look and feel * Removing the class based objects from the store (now they are all plain objects * Fix eslint * Fixing tests * Removing unneeded code
2021-08-02 17:46:00 +02:00
import {FilterGroup, isAFilterGroupInstance} from './blocks/filterGroup'
2020-10-20 12:52:56 -07:00
import {Utils} from './utils'
2020-10-08 09:21:27 -07:00
class CardFilter {
2020-10-20 18:28:55 -07:00
static applyFilterGroup(filterGroup: FilterGroup, templates: readonly IPropertyTemplate[], cards: Card[]): Card[] {
2020-10-20 12:50:53 -07:00
return cards.filter((card) => this.isFilterGroupMet(filterGroup, templates, card))
}
2020-10-08 09:21:27 -07:00
2020-10-20 18:28:55 -07:00
static isFilterGroupMet(filterGroup: FilterGroup, templates: readonly IPropertyTemplate[], card: Card): boolean {
2020-10-20 12:50:53 -07:00
const {filters} = filterGroup
2020-10-08 09:21:27 -07:00
2020-10-20 12:50:53 -07:00
if (filterGroup.filters.length < 1) {
return true // No filters = always met
}
2020-10-08 09:21:27 -07:00
2020-10-20 12:50:53 -07:00
if (filterGroup.operation === 'or') {
for (const filter of filters) {
Migrate webapp global state to redux (#737) * Migrating workspace tree to redux * More changes for use the redux store for boads and views * Taking into account the templates on websocket event updates * Fixing bug on boardTree maintenance * Websocket client now connects once and subscribe/desubscribe on the fly * Including usage of the new websocket client * More work around migrating to redux * WIP * WIP * WIP * WIP * WIP * WIP * Fixing some things * WIP * WIP * Another small fix * Restoring filtering, sorting and grouping * Fixing some other bugs * Add search text reducer * Fixing another drag and drop problem * Improve store names and api * Fixing small bgus * Some small fixes * fixing login * Fixing register page * Some other improvements * Removing unneeded old files * Removing the need of userCache * Fixing comments and fixing content ordering * Fixing sort * Fixing some TODOs * Fixing tests * Fixing snapshot * Fixing cypress tests * Fix eslint * Fixing server tests * Updating the add cards actions * Fixing some tiny navigation problems * Mocking the api calls to pass the tests * Migrating a new test to redux * Adding the card right after the insert of the block (not wait for ws event) * Showing the ws disconnect banner only after 5 seconds of disconnection * Fixing share view * Fix eslint * Fixing problem with sort/groupby modifications * Fixing some details on redirections and templates creation * Fixing small bugs around undo * Fix update properties on click outside the dialog * Improving the column resize look and feel * Removing the class based objects from the store (now they are all plain objects * Fix eslint * Fixing tests * Removing unneeded code
2021-08-02 17:46:00 +02:00
if (isAFilterGroupInstance(filter)) {
2020-10-20 12:50:53 -07:00
if (this.isFilterGroupMet(filter, templates, card)) {
return true
}
} else if (this.isClauseMet(filter, templates, card)) {
return true
}
}
return false
}
Utils.assert(filterGroup.operation === 'and')
for (const filter of filters) {
Migrate webapp global state to redux (#737) * Migrating workspace tree to redux * More changes for use the redux store for boads and views * Taking into account the templates on websocket event updates * Fixing bug on boardTree maintenance * Websocket client now connects once and subscribe/desubscribe on the fly * Including usage of the new websocket client * More work around migrating to redux * WIP * WIP * WIP * WIP * WIP * WIP * Fixing some things * WIP * WIP * Another small fix * Restoring filtering, sorting and grouping * Fixing some other bugs * Add search text reducer * Fixing another drag and drop problem * Improve store names and api * Fixing small bgus * Some small fixes * fixing login * Fixing register page * Some other improvements * Removing unneeded old files * Removing the need of userCache * Fixing comments and fixing content ordering * Fixing sort * Fixing some TODOs * Fixing tests * Fixing snapshot * Fixing cypress tests * Fix eslint * Fixing server tests * Updating the add cards actions * Fixing some tiny navigation problems * Mocking the api calls to pass the tests * Migrating a new test to redux * Adding the card right after the insert of the block (not wait for ws event) * Showing the ws disconnect banner only after 5 seconds of disconnection * Fixing share view * Fix eslint * Fixing problem with sort/groupby modifications * Fixing some details on redirections and templates creation * Fixing small bugs around undo * Fix update properties on click outside the dialog * Improving the column resize look and feel * Removing the class based objects from the store (now they are all plain objects * Fix eslint * Fixing tests * Removing unneeded code
2021-08-02 17:46:00 +02:00
if (isAFilterGroupInstance(filter)) {
2020-10-20 12:50:53 -07:00
if (!this.isFilterGroupMet(filter, templates, card)) {
return false
}
} else if (!this.isClauseMet(filter, templates, card)) {
return false
}
}
return true
}
2020-10-08 09:21:27 -07:00
2020-10-20 18:28:55 -07:00
static isClauseMet(filter: FilterClause, templates: readonly IPropertyTemplate[], card: Card): boolean {
Migrate webapp global state to redux (#737) * Migrating workspace tree to redux * More changes for use the redux store for boads and views * Taking into account the templates on websocket event updates * Fixing bug on boardTree maintenance * Websocket client now connects once and subscribe/desubscribe on the fly * Including usage of the new websocket client * More work around migrating to redux * WIP * WIP * WIP * WIP * WIP * WIP * Fixing some things * WIP * WIP * Another small fix * Restoring filtering, sorting and grouping * Fixing some other bugs * Add search text reducer * Fixing another drag and drop problem * Improve store names and api * Fixing small bgus * Some small fixes * fixing login * Fixing register page * Some other improvements * Removing unneeded old files * Removing the need of userCache * Fixing comments and fixing content ordering * Fixing sort * Fixing some TODOs * Fixing tests * Fixing snapshot * Fixing cypress tests * Fix eslint * Fixing server tests * Updating the add cards actions * Fixing some tiny navigation problems * Mocking the api calls to pass the tests * Migrating a new test to redux * Adding the card right after the insert of the block (not wait for ws event) * Showing the ws disconnect banner only after 5 seconds of disconnection * Fixing share view * Fix eslint * Fixing problem with sort/groupby modifications * Fixing some details on redirections and templates creation * Fixing small bugs around undo * Fix update properties on click outside the dialog * Improving the column resize look and feel * Removing the class based objects from the store (now they are all plain objects * Fix eslint * Fixing tests * Removing unneeded code
2021-08-02 17:46:00 +02:00
const value = card.fields.properties[filter.propertyId]
2020-10-20 12:50:53 -07:00
switch (filter.condition) {
case 'includes': {
if (filter.values?.length < 1) {
2020-10-20 12:50:53 -07:00
break
} // No values = ignore clause (always met)
return (filter.values.find((cValue) => (Array.isArray(value) ? value.includes(cValue) : cValue === value)) !== undefined)
2020-10-20 12:50:53 -07:00
}
case 'notIncludes': {
if (filter.values?.length < 1) {
2020-10-20 12:50:53 -07:00
break
} // No values = ignore clause (always met)
return (filter.values.find((cValue) => (Array.isArray(value) ? value.includes(cValue) : cValue === value)) === undefined)
2020-10-20 12:50:53 -07:00
}
case 'isEmpty': {
return (value || '').length <= 0
2020-10-20 12:50:53 -07:00
}
case 'isNotEmpty': {
return (value || '').length > 0
2020-10-20 12:50:53 -07:00
}
default: {
Utils.assertFailure(`Invalid filter condition ${filter.condition}`)
}
}
return true
}
2020-10-08 09:21:27 -07:00
2020-11-12 14:06:02 -08:00
static propertiesThatMeetFilterGroup(filterGroup: FilterGroup | undefined, templates: readonly IPropertyTemplate[]): Record<string, string> {
2020-10-20 12:50:53 -07:00
// TODO: Handle filter groups
2020-11-12 14:06:02 -08:00
if (!filterGroup) {
return {}
}
Migrate webapp global state to redux (#737) * Migrating workspace tree to redux * More changes for use the redux store for boads and views * Taking into account the templates on websocket event updates * Fixing bug on boardTree maintenance * Websocket client now connects once and subscribe/desubscribe on the fly * Including usage of the new websocket client * More work around migrating to redux * WIP * WIP * WIP * WIP * WIP * WIP * Fixing some things * WIP * WIP * Another small fix * Restoring filtering, sorting and grouping * Fixing some other bugs * Add search text reducer * Fixing another drag and drop problem * Improve store names and api * Fixing small bgus * Some small fixes * fixing login * Fixing register page * Some other improvements * Removing unneeded old files * Removing the need of userCache * Fixing comments and fixing content ordering * Fixing sort * Fixing some TODOs * Fixing tests * Fixing snapshot * Fixing cypress tests * Fix eslint * Fixing server tests * Updating the add cards actions * Fixing some tiny navigation problems * Mocking the api calls to pass the tests * Migrating a new test to redux * Adding the card right after the insert of the block (not wait for ws event) * Showing the ws disconnect banner only after 5 seconds of disconnection * Fixing share view * Fix eslint * Fixing problem with sort/groupby modifications * Fixing some details on redirections and templates creation * Fixing small bugs around undo * Fix update properties on click outside the dialog * Improving the column resize look and feel * Removing the class based objects from the store (now they are all plain objects * Fix eslint * Fixing tests * Removing unneeded code
2021-08-02 17:46:00 +02:00
const filters = filterGroup.filters.filter((o) => !isAFilterGroupInstance(o))
2020-10-20 12:50:53 -07:00
if (filters.length < 1) {
return {}
}
2020-10-08 09:21:27 -07:00
2020-10-20 12:50:53 -07:00
if (filterGroup.operation === 'or') {
// Just need to meet the first clause
const property = this.propertyThatMeetsFilterClause(filters[0] as FilterClause, templates)
const result: Record<string, string> = {}
2020-11-12 14:06:02 -08:00
if (property.value) {
result[property.id] = property.value
}
return result
2020-10-20 12:50:53 -07:00
}
2020-11-12 14:17:13 -08:00
// And: Need to meet all clauses
const result: Record<string, string> = {}
filters.forEach((filterClause) => {
const property = this.propertyThatMeetsFilterClause(filterClause as FilterClause, templates)
if (property.value) {
result[property.id] = property.value
}
})
return result
2020-10-20 12:50:53 -07:00
}
2020-10-08 09:21:27 -07:00
2020-10-20 18:28:55 -07:00
static propertyThatMeetsFilterClause(filterClause: FilterClause, templates: readonly IPropertyTemplate[]): { id: string, value?: string } {
2020-10-20 12:50:53 -07:00
const template = templates.find((o) => o.id === filterClause.propertyId)
2020-11-12 14:06:02 -08:00
if (!template) {
Utils.assertFailure(`propertyThatMeetsFilterClause. Cannot find template: ${filterClause.propertyId}`)
return {id: filterClause.propertyId}
}
2020-10-20 12:50:53 -07:00
switch (filterClause.condition) {
case 'includes': {
if (filterClause.values.length < 1) {
return {id: filterClause.propertyId}
}
return {id: filterClause.propertyId, value: filterClause.values[0]}
}
case 'notIncludes': {
return {id: filterClause.propertyId}
}
case 'isEmpty': {
return {id: filterClause.propertyId}
}
case 'isNotEmpty': {
if (template.type === 'select') {
if (template.options.length > 0) {
const option = template.options[0]
2020-10-23 12:59:09 -07:00
return {id: filterClause.propertyId, value: option.id}
2020-10-20 12:50:53 -07:00
}
return {id: filterClause.propertyId}
}
// TODO: Handle non-select types
return {id: filterClause.propertyId}
}
2020-10-20 13:36:54 -07:00
default: {
Utils.assertFailure(`Unexpected filter condition: ${filterClause.condition}`)
return {id: filterClause.propertyId}
}
2020-10-20 12:50:53 -07:00
}
}
2020-10-08 09:21:27 -07:00
}
2020-10-20 12:50:53 -07:00
export {CardFilter}