From 0dff4a9f6952a6b75dbbefcc5398b38712e54ee7 Mon Sep 17 00:00:00 2001 From: Philipp Hempel Date: Wed, 31 May 2023 11:01:14 +0200 Subject: [PATCH 1/3] refactor: OO approach for better handling of columns and more Signed-off-by: Philipp Hempel --- src/modules/main/modals/CreateRow.vue | 57 ++-- src/modules/main/modals/EditRow.vue | 57 ++-- src/pages/DefaultMainView.vue | 3 +- .../components/ncTable/mixins/columnClass.js | 103 +++++++ .../ncTable/mixins/columnHandler.js | 49 ++++ .../ncTable/mixins/columnsTypes/datetime.js | 57 ++++ .../mixins/columnsTypes/datetimeDate.js | 57 ++++ .../mixins/columnsTypes/datetimeDateMixin.js | 66 ----- .../mixins/columnsTypes/datetimeMixin.js | 66 ----- .../mixins/columnsTypes/datetimeTime.js | 57 ++++ .../mixins/columnsTypes/datetimeTimeMixin.js | 66 ----- .../ncTable/mixins/columnsTypes/number.js | 52 ++++ .../mixins/columnsTypes/numberMixin.js | 60 ---- .../mixins/columnsTypes/numberProgress.js | 40 +++ .../columnsTypes/numberProgressMixin.js | 54 ---- .../mixins/columnsTypes/numberStars.js | 40 +++ .../mixins/columnsTypes/numberStarsMixin.js | 50 ---- .../ncTable/mixins/columnsTypes/selection.js | 55 ++++ .../mixins/columnsTypes/selectionCheck.js | 38 +++ .../columnsTypes/selectionCheckMixin.js | 28 -- .../mixins/columnsTypes/selectionMixin.js | 73 ----- .../mixins/columnsTypes/selectionMulti.js | 72 +++++ .../columnsTypes/selectionMultiMixin.js | 80 ----- .../ncTable/mixins/columnsTypes/textLine.js | 44 +++ .../mixins/columnsTypes/textLineMixin.js | 47 --- .../ncTable/mixins/columnsTypes/textLink.js | 37 +++ .../mixins/columnsTypes/textLinkMixin.js | 44 --- .../ncTable/mixins/columnsTypes/textLong.js | 29 ++ .../mixins/columnsTypes/textLongMixin.js | 29 -- .../ncTable/mixins/columnsTypes/textRich.js | 25 ++ .../mixins/columnsTypes/textRichMixin.js | 27 -- .../ncTable/mixins/exportTableMixin.js | 11 +- .../components/ncTable/mixins/filter.js | 96 ++++++ .../components/ncTable/mixins/magicFields.js | 164 +++++++++++ .../ncTable/mixins/searchAndFilterMixin.js | 273 ------------------ .../ncTable/partials/FilterLabel.vue | 6 +- .../ncTable/partials/TableCellDateTime.vue | 34 +-- .../partials/TableCellMultiSelection.vue | 10 +- .../ncTable/partials/TableCellSelection.vue | 10 +- .../ncTable/partials/TableHeader.vue | 9 +- .../partials/TableHeaderColumnOptions.vue | 67 ++--- .../components/ncTable/partials/TableRow.vue | 86 +++--- .../ncTable/sections/CustomTable.vue | 69 +---- 43 files changed, 1151 insertions(+), 1246 deletions(-) create mode 100644 src/shared/components/ncTable/mixins/columnClass.js create mode 100644 src/shared/components/ncTable/mixins/columnHandler.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/datetime.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/datetimeDate.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/datetimeDateMixin.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/datetimeMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/datetimeTime.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/datetimeTimeMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/number.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/numberMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/numberProgress.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/numberProgressMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/numberStars.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/numberStarsMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/selection.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/selectionCheck.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/selectionCheckMixin.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/selectionMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/selectionMulti.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/selectionMultiMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textLine.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textLineMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textLink.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textLinkMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textLong.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textLongMixin.js create mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textRich.js delete mode 100644 src/shared/components/ncTable/mixins/columnsTypes/textRichMixin.js create mode 100644 src/shared/components/ncTable/mixins/filter.js create mode 100644 src/shared/components/ncTable/mixins/magicFields.js delete mode 100644 src/shared/components/ncTable/mixins/searchAndFilterMixin.js diff --git a/src/modules/main/modals/CreateRow.vue b/src/modules/main/modals/CreateRow.vue index bcfba2f41..f43812f22 100644 --- a/src/modules/main/modals/CreateRow.vue +++ b/src/modules/main/modals/CreateRow.vue @@ -9,43 +9,7 @@
- - - - - - - - - - - - -
@@ -83,6 +47,7 @@ import DatetimeForm from '../../../shared/components/ncTable/partials/rowTypePar import DatetimeDateForm from '../../../shared/components/ncTable/partials/rowTypePartials/DatetimeDateForm.vue' import DatetimeTimeForm from '../../../shared/components/ncTable/partials/rowTypePartials/DatetimeTimeForm.vue' import TextRichForm from '../../../shared/components/ncTable/partials/rowTypePartials/TextRichForm.vue' +import { ColumnTypes } from '../../../shared/components/ncTable/mixins/columnHandler.js' export default { name: 'CreateRow', @@ -124,6 +89,24 @@ export default { ...mapGetters(['activeTable']), }, methods: { + getFormComponent(column) { + switch (column.type) { + case ColumnTypes.TextLine: return 'TextLineForm' + case ColumnTypes.TextLong: return 'TextLongForm' + case ColumnTypes.TextLink: return 'TextLinkForm' + case ColumnTypes.TextRich: return 'TextRichForm' + case ColumnTypes.Number: return 'NumberForm' + case ColumnTypes.NumberStars: return 'NumberStarsForm' + case ColumnTypes.NumberProgress: return 'NumberProgressForm' + case ColumnTypes.Selection: return 'SelectionForm' + case ColumnTypes.SelectionMulti: return 'SelectionMultiForm' + case ColumnTypes.SelectionCheck: return 'SelectionCheckForm' + case ColumnTypes.Datetime: return 'DatetimeForm' + case ColumnTypes.DatetimeDate: return 'DatetimeDateForm' + case ColumnTypes.DatetimeTime: return 'DatetimeTimeForm' + default: throw Error('No form exists for the column type ' + column.type) + } + }, actionCancel() { this.reset() this.addNewAfterSave = false diff --git a/src/modules/main/modals/EditRow.vue b/src/modules/main/modals/EditRow.vue index ba88dd3a1..a11066992 100644 --- a/src/modules/main/modals/EditRow.vue +++ b/src/modules/main/modals/EditRow.vue @@ -7,43 +7,7 @@
- - - - - - - - - - - - -
@@ -89,6 +53,7 @@ import DatetimeForm from '../../../shared/components/ncTable/partials/rowTypePar import DatetimeDateForm from '../../../shared/components/ncTable/partials/rowTypePartials/DatetimeDateForm.vue' import DatetimeTimeForm from '../../../shared/components/ncTable/partials/rowTypePartials/DatetimeTimeForm.vue' import tablePermissions from '../mixins/tablePermissions.js' +import { ColumnTypes } from '../../../shared/components/ncTable/mixins/columnHandler.js' export default { name: 'EditRow', @@ -143,6 +108,24 @@ export default { }, }, methods: { + getFormComponent(column) { + switch (column.type) { + case ColumnTypes.TextLine: return 'TextLineForm' + case ColumnTypes.TextLong: return 'TextLongForm' + case ColumnTypes.TextLink: return 'TextLinkForm' + case ColumnTypes.TextRich: return 'TextRichForm' + case ColumnTypes.Number: return 'NumberForm' + case ColumnTypes.NumberStars: return 'NumberStarsForm' + case ColumnTypes.NumberProgress: return 'NumberProgressForm' + case ColumnTypes.Selection: return 'SelectionForm' + case ColumnTypes.SelectionMulti: return 'SelectionMultiForm' + case ColumnTypes.SelectionCheck: return 'SelectionCheckForm' + case ColumnTypes.Datetime: return 'DatetimeForm' + case ColumnTypes.DatetimeDate: return 'DatetimeDateForm' + case ColumnTypes.DatetimeTime: return 'DatetimeTimeForm' + default: throw Error('No form exists for the column type ' + column.type) + } + }, loadValues() { if (this.row) { const tmp = {} diff --git a/src/pages/DefaultMainView.vue b/src/pages/DefaultMainView.vue index eb83d781c..9f385fb7f 100644 --- a/src/pages/DefaultMainView.vue +++ b/src/pages/DefaultMainView.vue @@ -51,6 +51,7 @@ import DeleteRows from '../modules/main/modals/DeleteRows.vue' import EmptyTable from '../modules/main/sections/EmptyTable.vue' import permissionsMixin from '../shared/components/ncTable/mixins/permissionsMixin.js' import { emit } from '@nextcloud/event-bus' +import { parseCol } from '../shared/components/ncTable/mixins/columnHandler.js' export default { name: 'DefaultMainView', @@ -80,7 +81,7 @@ export default { }, computed: { ...mapState({ - columns: state => state.data.columns, + columns: state => state.data.columns.map(col => parseCol(col)), loading: state => state.data.loading, rows: state => state.data.rows, view: state => state.data.view, diff --git a/src/shared/components/ncTable/mixins/columnClass.js b/src/shared/components/ncTable/mixins/columnClass.js new file mode 100644 index 000000000..7d596f16a --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnClass.js @@ -0,0 +1,103 @@ +import { Filters } from './filter.js' +import { MagicFields } from './magicFields.js' + +export class AbstractColumn { + + type = null + + constructor(data) { + this.createdAt = data.createdAt + this.createdBy = data.createdBy + this.id = data.id + this.lastEditAt = data.lastEditAt + this.lastEditBy = data.lastEditBy + this.mandatory = data.mandatory + this.orderWeight = data.orderWeight + this.tableId = data.tableId + this.title = data.title + this.description = data.description + } + + canSort() { + return typeof this.sort === 'function' + } + + getPossibleOperators() { + return Object.values(Filters).filter(fil => fil.goodFor.includes(this.type)) + } + + getPossibleMagicFields() { + return Object.values(MagicFields).filter(item => item.goodFor.includes(this.type)) + } + + isSearchStringFound(cellValue, cell, searchString) { + if (cellValue != null && cellValue.toLowerCase().includes(searchString)) { + cell.searchStringFound = true + return true + } + return false + } + + isFilterFound(filterMethod, cell) { + if (filterMethod()) { + cell.filterFound = true + return true + } + return false + } + +} + +export class AbstractNumberColumn extends AbstractColumn { + + constructor(data) { + super(data) + this.numberDefault = data.numberDefault + } + + default() { + return this.numberDefault + } + +} + +export class AbstractDatetimeColumn extends AbstractColumn { + + constructor(data) { + super(data) + this.datetimeDefault = data.datetimeDefault + } + + formatValue(value) {} + + default() { + return this.datetimeDefault + } + +} + +export class AbstractTextColumn extends AbstractColumn { + + constructor(data) { + super(data) + this.textDefault = data.textDefault + } + + default() { + return this.textDefault + } + +} + +export class AbstractSelectionColumn extends AbstractColumn { + + constructor(data) { + super(data) + this.selectionDefault = data.selectionDefault + } + + default() { + return this.selectionDefault + } + +} diff --git a/src/shared/components/ncTable/mixins/columnHandler.js b/src/shared/components/ncTable/mixins/columnHandler.js new file mode 100644 index 000000000..226e287ad --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnHandler.js @@ -0,0 +1,49 @@ +import DatetimeDateColumn from './columnsTypes/datetimeDate.js' +import DatetimeColumn from './columnsTypes/datetime.js' +import DatetimeTimeColumn from './columnsTypes/datetimeTime.js' +import NumberColumn from './columnsTypes/number.js' +import NumberProgressColumn from './columnsTypes/numberProgress.js' +import NumberStarsColumn from './columnsTypes/numberStars.js' +import SelectionCheckColumn from './columnsTypes/selectionCheck.js' +import SelectionColumn from './columnsTypes/selection.js' +import SelectionMutliColumn from './columnsTypes/selectionMulti.js' +import TextLineColumn from './columnsTypes/textLine.js' +import TextLinkColumn from './columnsTypes/textLink.js' +import TextLongColumn from './columnsTypes/textLong.js' +import TextRichColumn from './columnsTypes/textRich.js' + +export function parseCol(col) { + const columnType = col.type + (col.subtype === '' ? '' : '-' + col.subtype) + switch (columnType) { + case 'text-line': return new TextLineColumn(col) + case 'text-link': return new TextLinkColumn(col) + case 'text-long': return new TextLongColumn(col) + case 'text-rich': return new TextRichColumn(col) + case 'number': return new NumberColumn(col) + case 'number-stars': return new NumberStarsColumn(col) + case 'number-progress': return new NumberProgressColumn(col) + case 'selection': return new SelectionColumn(col) + case 'selection-multi': return new SelectionMutliColumn(col) + case 'selection-check': return new SelectionCheckColumn(col) + case 'datetime': return new DatetimeColumn(col) + case 'datetime-date': return new DatetimeDateColumn(col) + case 'datetime-time': return new DatetimeTimeColumn(col) + default: throw Error(col.type + '-' + col.subtype + ' is not a valid column type!') + } +} + +export const ColumnTypes = { + TextLine: 'text-line', + TextLong: 'text-long', + TextRich: 'text-rich', + Selection: 'selection', + SelectionMulti: 'selection-multi', + Number: 'number', + SelectionCheck: 'selection-check', + TextLink: 'text-link', + NumberStars: 'number-stars', + NumberProgress: 'number-progress', + DatetimeDate: 'datetime-date', + DatetimeTime: 'datetime-time', + Datetime: 'datetime', +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/datetime.js b/src/shared/components/ncTable/mixins/columnsTypes/datetime.js new file mode 100644 index 000000000..9e346ad8e --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/datetime.js @@ -0,0 +1,57 @@ +import { AbstractDatetimeColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import Moment from '@nextcloud/moment' +import { Filters } from '../filter.js' + +export default class DatetimeColumn extends AbstractDatetimeColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.Datetime + } + + formatValue(value) { + return Moment(value, 'YYYY-MM-DD HH:mm:ss').format('lll') + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const tmpA = rowA.data.find(item => item.columnId === this.id)?.value || '' + const valueA = new Moment(tmpA, 'YYY-MM-DD HH:mm') + const tmpB = rowB.data.find(item => item.columnId === this.id)?.value || '' + const valueB = new Moment(tmpB, 'YYY-MM-DD HH:mm') + if (!tmpA && tmpB) { + return -1 * factor + } + if (tmpA && !tmpB) { + return 1 * factor + } + if (!tmpA && !tmpB) { + return 0 + } + return (valueA.diff(valueB)) * factor + } + } + + isSearchStringFound(cell, searchString) { + const date = new Moment(cell.value, 'YYYY-MM-DD HH:mm').format('lll') + return super.isSearchStringFound(date, cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + const filterDate = new Moment(filterValue, 'YYY-MM-DD HH:mm') + const valueDate = new Moment(cell.value, 'YYY-MM-DD HH:mm') + + const filterMethod = { + [Filters.IsEqual.id]() { return filterDate.isSame(valueDate) }, + [Filters.IsGreaterThan.id]() { return filterDate.isBefore(valueDate) }, + [Filters.IsGreaterThanOrEqual.id]() { return filterDate.isSameOrBefore(valueDate) }, + [Filters.IsLowerThan.id]() { return filterDate.isAfter(valueDate) }, + [Filters.IsLowerThanOrEqual.id]() { return filterDate.isSameOrAfter(valueDate) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/datetimeDate.js b/src/shared/components/ncTable/mixins/columnsTypes/datetimeDate.js new file mode 100644 index 000000000..9a2bbf22e --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/datetimeDate.js @@ -0,0 +1,57 @@ +import { AbstractDatetimeColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import Moment from '@nextcloud/moment' +import { Filters } from '../filter.js' + +export default class DatetimeDateColumn extends AbstractDatetimeColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.DatetimeDate + } + + formatValue(value) { + return Moment(value, 'YYYY-MM-DD HH:mm:ss').format('ll') + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const tmpA = rowA.data.find(item => item.columnId === this.id)?.value || '' + const valueA = new Moment(tmpA) + const tmpB = rowB.data.find(item => item.columnId === this.id)?.value || '' + const valueB = new Moment(tmpB) + if (!tmpA && tmpB) { + return -1 * factor + } + if (tmpA && !tmpB) { + return 1 * factor + } + if (!tmpA && !tmpB) { + return 0 + } + return (valueA.diff(valueB)) * factor + } + } + + isSearchStringFound(cell, searchString) { + const date = new Moment(cell.value, 'YYYY-MM-DD').format('ll') + return super.isSearchStringFound(date, cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + const filterDate = new Moment(filterValue) + const valueDate = new Moment(cell.value) + + const filterMethod = { + [Filters.IsEqual.id]() { return filterDate.isSame(valueDate) }, + [Filters.IsGreaterThan.id]() { return filterDate.isBefore(valueDate) }, + [Filters.IsGreaterThanOrEqual.id]() { return filterDate.isSameOrBefore(valueDate) }, + [Filters.IsLowerThan.id]() { return filterDate.isAfter(valueDate) }, + [Filters.IsLowerThanOrEqual.id]() { return filterDate.isSameOrAfter(valueDate) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/datetimeDateMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/datetimeDateMixin.js deleted file mode 100644 index ea9cc1ed0..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/datetimeDateMixin.js +++ /dev/null @@ -1,66 +0,0 @@ -import Moment from '@nextcloud/moment' - -export default { - - methods: { - sortingDatetimeDate(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const tmpA = rowA.data.find(item => item.columnId === column.id)?.value || '' - const valueA = new Moment(tmpA) - const tmpB = rowB.data.find(item => item.columnId === column.id)?.value || '' - const valueB = new Moment(tmpB) - if (!tmpA && tmpB) { - return -1 * factor - } - if (tmpA && !tmpB) { - return 1 * factor - } - if (!tmpA && !tmpB) { - return 0 - } - return (valueA.diff(valueB)) * factor - } - }, - isSearchStringFoundForDatetimeDate(column, cell, searchString) { - const date = new Moment(cell.value, 'YYYY-MM-DD').format('ll') - if (date.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForDatetimeDate(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - const filterDate = new Moment(filterValue) - const valueDate = new Moment(cell.value) - - if (filter.operator === 'is-equal' && filterDate.isSame(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than' && filterDate.isBefore(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than-or-equal' && filterDate.isSameOrBefore(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than' && filterDate.isAfter(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than-or-equal' && filterDate.isSameOrAfter(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !valueDate) { - cell.filterFound = true - return true - } - return false - }, - - }, -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/datetimeMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/datetimeMixin.js deleted file mode 100644 index 34265f757..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/datetimeMixin.js +++ /dev/null @@ -1,66 +0,0 @@ -import Moment from '@nextcloud/moment' - -export default { - - methods: { - sortingDatetime(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const tmpA = rowA.data.find(item => item.columnId === column.id)?.value || '' - const valueA = new Moment(tmpA, 'YYY-MM-DD HH:mm') - const tmpB = rowB.data.find(item => item.columnId === column.id)?.value || '' - const valueB = new Moment(tmpB, 'YYY-MM-DD HH:mm') - if (!tmpA && tmpB) { - return -1 * factor - } - if (tmpA && !tmpB) { - return 1 * factor - } - if (!tmpA && !tmpB) { - return 0 - } - return (valueA.diff(valueB)) * factor - } - }, - isSearchStringFoundForDatetime(column, cell, searchString) { - const date = new Moment(cell.value, 'YYYY-MM-DD HH:mm').format('lll') - if (date.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForDatetime(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - const filterDate = new Moment(filterValue, 'YYY-MM-DD HH:mm') - const valueDate = new Moment(cell.value, 'YYY-MM-DD HH:mm') - - if (filter.operator === 'is-equal' && filterDate.isSame(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than' && filterDate.isBefore(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than-or-equal' && filterDate.isSameOrBefore(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than' && filterDate.isAfter(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than-or-equal' && filterDate.isSameOrAfter(valueDate)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !valueDate) { - cell.filterFound = true - return true - } - return false - }, - - }, -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/datetimeTime.js b/src/shared/components/ncTable/mixins/columnsTypes/datetimeTime.js new file mode 100644 index 000000000..c23198f0e --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/datetimeTime.js @@ -0,0 +1,57 @@ +import { AbstractDatetimeColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import Moment from '@nextcloud/moment' +import { Filters } from '../filter.js' + +export default class DatetimeTimeColumn extends AbstractDatetimeColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.DatetimeTime + } + + formatValue(value) { + return Moment(value, 'HH:mm:ss').format('LT') + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const tmpA = rowA.data.find(item => item.columnId === this.id)?.value || '' + const valueA = new Moment(tmpA, 'HH:mm') + const tmpB = rowB.data.find(item => item.columnId === this.id)?.value || '' + const valueB = new Moment(tmpB, 'HH:mm') + if (!tmpA && tmpB) { + return -1 * factor + } + if (tmpA && !tmpB) { + return 1 * factor + } + if (!tmpA && !tmpB) { + return 0 + } + return (valueA.diff(valueB)) * factor + } + } + + isSearchStringFound(cell, searchString) { + const time = new Moment(cell.value, 'YYYY-MM-DD HH:mm').format('lll') + return super.isSearchStringFound(time, cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + const filterTime = new Moment(filterValue, 'HH:mm') + const valueTime = new Moment(cell.value, 'HH:mm') + + const filterMethod = { + [Filters.IsEqual.id]() { return filterTime.isSame(valueTime) }, + [Filters.IsGreaterThan.id]() { return filterTime.isBefore(valueTime) }, + [Filters.IsGreaterThanOrEqual.id]() { return filterTime.isSameOrBefore(valueTime) }, + [Filters.IsLowerThan.id]() { return filterTime.isAfter(valueTime) }, + [Filters.IsLowerThanOrEqual.id]() { return filterTime.isSameOrAfter(valueTime) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/datetimeTimeMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/datetimeTimeMixin.js deleted file mode 100644 index 2d65408cd..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/datetimeTimeMixin.js +++ /dev/null @@ -1,66 +0,0 @@ -import Moment from '@nextcloud/moment' - -export default { - - methods: { - sortingDatetimeTime(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const tmpA = rowA.data.find(item => item.columnId === column.id)?.value || '' - const valueA = new Moment(tmpA, 'HH:mm') - const tmpB = rowB.data.find(item => item.columnId === column.id)?.value || '' - const valueB = new Moment(tmpB, 'HH:mm') - if (!tmpA && tmpB) { - return -1 * factor - } - if (tmpA && !tmpB) { - return 1 * factor - } - if (!tmpA && !tmpB) { - return 0 - } - return (valueA.diff(valueB)) * factor - } - }, - isSearchStringFoundForDatetimeTime(column, cell, searchString) { - const time = new Moment(cell.value, 'HH:mm').format('LT') - if (time.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForDatetimeTime(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - const filterTime = new Moment(filterValue, 'HH:mm') - const valueTime = new Moment(cell.value, 'HH:mm') - - if (filter.operator === 'is-equal' && filterTime.isSame(valueTime)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than' && filterTime.isBefore(valueTime)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than-or-equal' && filterTime.isSameOrBefore(valueTime)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than' && filterTime.isAfter(valueTime)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than-or-equal' && filterTime.isSameOrAfter(valueTime)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !valueTime) { - cell.filterFound = true - return true - } - return false - }, - - }, -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/number.js b/src/shared/components/ncTable/mixins/columnsTypes/number.js new file mode 100644 index 000000000..788693e36 --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/number.js @@ -0,0 +1,52 @@ +import { AbstractNumberColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class NumberColumn extends AbstractNumberColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.Number + this.numberDecimals = data.numberDecimals + this.numberMax = data.numberMax + this.numberMin = data.numberMin + this.numberPrefix = data.numberPrefix + this.numberSuffix = data.numberSuffix + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const valueA = rowA.data.find(item => item.columnId === this.id)?.value || null + const valueB = rowB.data.find(item => item.columnId === this.id)?.value || null + if (!valueA && valueB) { + return -1 * factor + } + if (valueA && !valueB) { + return 1 * factor + } + if (!valueA && !valueB) { + return 0 + } + return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor + } + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(('' + cell.value), cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.IsEqual.id]() { return parseInt(cell.value) === parseInt(filterValue) }, + [Filters.IsGreaterThan.id]() { return parseInt(cell.value) > parseInt(filterValue) }, + [Filters.IsGreaterThanOrEqual.id]() { return parseInt(cell.value) >= parseInt(filterValue) }, + [Filters.IsLowerThan.id]() { return parseInt(cell.value) < parseInt(filterValue) }, + [Filters.IsLowerThanOrEqual.id]() { return parseInt(cell.value) <= parseInt(filterValue) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/numberMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/numberMixin.js deleted file mode 100644 index 1fa75a199..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/numberMixin.js +++ /dev/null @@ -1,60 +0,0 @@ -export default { - - methods: { - - sortingNumber(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const valueA = rowA.data.find(item => item.columnId === column.id)?.value || null - const valueB = rowB.data.find(item => item.columnId === column.id)?.value || null - if (!valueA && valueB) { - return -1 * factor - } - if (valueA && !valueB) { - return 1 * factor - } - if (!valueA && !valueB) { - return 0 - } - return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor - } - }, - isSearchStringFoundForNumber(column, cell, searchString) { - if (('' + cell.value).toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForNumber(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - if (filter.operator === 'is-equal' && parseFloat(cell.value) === parseFloat(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than' && parseFloat(cell.value) > parseFloat(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than-or-equal' && parseFloat(cell.value) >= parseFloat(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than' && parseFloat(cell.value) < parseFloat(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than-or-equal' && parseFloat(cell.value) <= parseFloat(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !cell.value) { - cell.filterFound = true - return true - } - return false - }, - - }, - -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/numberProgress.js b/src/shared/components/ncTable/mixins/columnsTypes/numberProgress.js new file mode 100644 index 000000000..f0d09bdc6 --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/numberProgress.js @@ -0,0 +1,40 @@ +import { AbstractNumberColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class NumberProgressColumn extends AbstractNumberColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.NumberProgress + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const tmpA = rowA.data.find(item => item.columnId === this.id)?.value || null + const valueA = parseInt(tmpA) + const tmpB = rowB.data.find(item => item.columnId === this.id)?.value || null + const valueB = parseInt(tmpB) + return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor + } + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(('' + cell.value), cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.IsEqual.id]() { return parseInt(cell.value) === parseInt(filterValue) }, + [Filters.IsGreaterThan.id]() { return parseInt(cell.value) > parseInt(filterValue) }, + [Filters.IsGreaterThanOrEqual.id]() { return parseInt(cell.value) >= parseInt(filterValue) }, + [Filters.IsLowerThan.id]() { return parseInt(cell.value) < parseInt(filterValue) }, + [Filters.IsLowerThanOrEqual.id]() { return parseInt(cell.value) <= parseInt(filterValue) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/numberProgressMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/numberProgressMixin.js deleted file mode 100644 index a1df56497..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/numberProgressMixin.js +++ /dev/null @@ -1,54 +0,0 @@ -export default { - - methods: { - - sortingNumberProgress(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const tmpA = rowA.data.find(item => item.columnId === column.id)?.value || null - const valueA = parseInt(tmpA) - const tmpB = rowB.data.find(item => item.columnId === column.id)?.value || null - const valueB = parseInt(tmpB) - return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor - } - }, - isSearchStringFoundForNumberProgress(column, cell, searchString) { - if (('' + cell.value).toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForNumberProgress(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - - if (filter.operator === 'is-equal' && parseInt(cell.value) === parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than' && parseInt(cell.value) > parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than-or-equal' && parseInt(cell.value) >= parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than' && parseInt(cell.value) < parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than-or-equal' && parseInt(cell.value) <= parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !cell.value) { - cell.filterFound = true - return true - } - return false - }, - - }, - -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/numberStars.js b/src/shared/components/ncTable/mixins/columnsTypes/numberStars.js new file mode 100644 index 000000000..39874d3e7 --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/numberStars.js @@ -0,0 +1,40 @@ +import { AbstractNumberColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class NumberStarsColumn extends AbstractNumberColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.NumberStars + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const tmpA = rowA.data.find(item => item.columnId === this.id)?.value + const valueA = parseInt(tmpA) + const tmpB = rowB.data.find(item => item.columnId === this.id)?.value + const valueB = parseInt(tmpB) + return ((valueA < valueB) ? 1 : (valueA > valueB) ? -1 : 0) * factor + } + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(('' + cell.value), cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.IsEqual.id]() { return parseInt(cell.value) === parseInt(filterValue) }, + [Filters.IsGreaterThan.id]() { return parseInt(cell.value) > parseInt(filterValue) }, + [Filters.IsGreaterThanOrEqual.id]() { return parseInt(cell.value) >= parseInt(filterValue) }, + [Filters.IsLowerThan.id]() { return parseInt(cell.value) < parseInt(filterValue) }, + [Filters.IsLowerThanOrEqual.id]() { return parseInt(cell.value) <= parseInt(filterValue) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/numberStarsMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/numberStarsMixin.js deleted file mode 100644 index fedf189d5..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/numberStarsMixin.js +++ /dev/null @@ -1,50 +0,0 @@ -export default { - - methods: { - - sortingNumberStars(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const tmpA = rowA.data.find(item => item.columnId === column.id)?.value - const valueA = parseInt(tmpA) - const tmpB = rowB.data.find(item => item.columnId === column.id)?.value - const valueB = parseInt(tmpB) - return ((valueA < valueB) ? 1 : (valueA > valueB) ? -1 : 0) * factor - } - }, - isSearchStringFoundForNumberStars(column, cell, searchString) { - if (('' + cell.value).toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForNumberStars(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - - if (filter.operator === 'is-equal' && parseInt(cell.value) === parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than' && parseInt(cell.value) > parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-greater-than-or-equal' && parseInt(cell.value) >= parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than' && parseInt(cell.value) < parseInt(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-lower-than-or-equal' && parseInt(cell.value) <= parseInt(filterValue)) { - cell.filterFound = true - return true - } - return false - }, - - }, - -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/selection.js b/src/shared/components/ncTable/mixins/columnsTypes/selection.js new file mode 100644 index 000000000..ab5b43cab --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/selection.js @@ -0,0 +1,55 @@ +import { AbstractSelectionColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class SelectionColumn extends AbstractSelectionColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.Selection + this.selectionOptions = data.selectionOptions + } + + getValueString(valueObject) { + valueObject = valueObject || this.value || null + return this.getLabel(valueObject.value) + } + + getLabel(id) { + const i = this.selectionOptions?.findIndex((obj) => obj.id === id) + return this.selectionOptions[i]?.label + } + + isDeletedLabel(value) { + const i = this.selectionOptions?.findIndex((obj) => obj.id === value) + return !!this.selectionOptions[i]?.deleted + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const selectionIdA = rowA.data.find(item => item.columnId === this.id)?.value || null + const valueA = selectionIdA !== null ? this.selectionOptions.find(item => item.id === selectionIdA)?.label : '' + const selectionIdB = rowB.data.find(item => item.columnId === this.id)?.value || null + const valueB = selectionIdB !== null ? this.selectionOptions.find(item => item.id === selectionIdB)?.label : '' + return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor + } + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(this.getLabel(cell.value), cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.Contains.id]() { return this.getLabel(cell.value)?.includes(filterValue) }, + [Filters.BeginsWith.id]() { return this.getLabel(cell.value)?.startsWith(filterValue) }, + [Filters.EndsWith.id]() { return this.getLabel(cell.value)?.endsWith(filterValue) }, + [Filters.IsEqual.id]() { return this.getLabel(cell.value) === filterValue }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/selectionCheck.js b/src/shared/components/ncTable/mixins/columnsTypes/selectionCheck.js new file mode 100644 index 000000000..32e38f6f9 --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/selectionCheck.js @@ -0,0 +1,38 @@ +import { AbstractSelectionColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class SelectionCheckColumn extends AbstractSelectionColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.SelectionCheck + } + + sort(mode) { + const factor = mode === 'desc' ? 1 : -1 + return (rowA, rowB) => { + const tmpA = rowA.data.find(item => item.columnId === this.id)?.value || '' + const valueA = (tmpA === true || tmpA === 'true') + const tmpB = rowB.data.find(item => item.columnId === this.id)?.value || '' + const valueB = (tmpB === true || tmpB === 'true') + return (valueA - valueB) * factor + } + } + + isSearchStringFound(cell, searchString) { + return false + } + + isFilterFound(cell, filter) { + const yesPossibilities = ['yes', 'true', 'check', 'checked', 'y'] + const noPossibilities = ['no', 'false', 'unchecked', 'uncheck', 'n'] + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.Contains.id]() { return (cell.value === 'true' && yesPossibilities.findIndex(item => item === filterValue) !== -1) || (cell.value === 'false' && noPossibilities.findIndex(item => item === filterValue) !== -1) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/selectionCheckMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/selectionCheckMixin.js deleted file mode 100644 index 79e8907c4..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/selectionCheckMixin.js +++ /dev/null @@ -1,28 +0,0 @@ -export default { - - methods: { - sortingSelectionCheck(column, mode) { - const factor = mode === 'desc' ? 1 : -1 - return function(rowA, rowB) { - const tmpA = rowA.data.find(item => item.columnId === column.id)?.value || '' - const valueA = (tmpA === true || tmpA === 'true') - const tmpB = rowB.data.find(item => item.columnId === column.id)?.value || '' - const valueB = (tmpB === true || tmpB === 'true') - return (valueA - valueB) * factor - } - }, - - isFilterFoundForSelectionCheck(column, cell, filter) { - const filterValue = '' + filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - if (filter.operator === 'is-equal' && cell?.value === 'true' && filterValue === 'yes') { - cell.filterFound = true - return true - } - if (filter.operator === 'is-equal' && cell?.value !== 'true' && filterValue === 'no') { - cell.filterFound = true - return true - } - return false - }, - }, -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/selectionMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/selectionMixin.js deleted file mode 100644 index d8dc30766..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/selectionMixin.js +++ /dev/null @@ -1,73 +0,0 @@ -export default { - - methods: { - getValueStringForSelection(valueObject, column) { - column = column || this.column || null - valueObject = valueObject || this.value || null - - return this.getLabelForSelection(valueObject.value, column) - }, - - getLabelForSelection(id, column) { - column = column || this.column - id = this.value || this.value === 0 ? this.value : id - const i = column?.selectionOptions?.findIndex((obj) => obj.id === id) - return column?.selectionOptions[i]?.label - }, - - isDeletedLabelForSelection(selectionOptions, value) { - selectionOptions = selectionOptions || this.column?.selectionOptions - value = value || this.value - const i = selectionOptions?.findIndex((obj) => obj.id === value) - return !!selectionOptions[i]?.deleted - }, - - sortingSelection(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const selectionIdA = rowA.data.find(item => item.columnId === column.id)?.value || null - const valueA = selectionIdA !== null ? column.selectionOptions.find(item => item.id === selectionIdA)?.label : '' - const selectionIdB = rowB.data.find(item => item.columnId === column.id)?.value || null - const valueB = selectionIdB !== null ? column.selectionOptions.find(item => item.id === selectionIdB)?.label : '' - return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor - } - }, - isSearchStringFoundForSelection(column, cell, searchString) { - if (cell.value !== null && (this.getLabelForSelection(cell.value, column))?.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForSelection(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - - console.debug('Selection:', this.getLabelForSelection(cell.value, column), cell.value, column, filterValue) - - if (filter.operator === 'contains' && (this.getLabelForSelection(cell.value, column))?.includes(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'begins-with' && (this.getLabelForSelection(cell.value, column))?.startsWith(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'ends-with' && (this.getLabelForSelection(cell.value, column))?.endsWith(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-equal' && this.getLabelForSelection(cell.value, column) === filterValue) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !this.getLabelForSelection(cell.value, column)) { - cell.filterFound = true - return true - } - - return false - }, - - }, - -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/selectionMulti.js b/src/shared/components/ncTable/mixins/columnsTypes/selectionMulti.js new file mode 100644 index 000000000..92abc56cd --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/selectionMulti.js @@ -0,0 +1,72 @@ +import { AbstractSelectionColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class SelectionMutliColumn extends AbstractSelectionColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.SelectionMulti + this.selectionOptions = data.selectionOptions + } + + getValueString(valueObject) { + valueObject = valueObject || this.value || null + + const valueObjects = this.getObjects(valueObject.value) + let ret = '' + valueObjects?.forEach(obj => { + if (ret === '') { + ret = obj.label + } else { + ret += ', ' + obj.label + } + }) + return ret + } + + getObjects(values) { + // values is an array of option-ids as string + const objects = [] + values?.forEach(id => { + objects.push(this.getOptionObject(parseInt(id))) + }) + return objects + } + + getOptionObject(id) { + const i = this.selectionOptions?.findIndex(obj => { + return obj.id === id + }) + if (i !== undefined) { + return this.selectionOptions[i] || null + } + } + + getDefaultObjects() { + if (!this.selectionDefault) { + return [] + } + + const defaultObjects = [] + JSON.parse(this.selectionDefault)?.forEach(id => { + defaultObjects.push(this.getOptionObjectForSelectionMulti(parseInt(id), this)) + }) + return defaultObjects + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(this.getValueString(cell), cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.Contains.id]() { return this.getValueString(cell)?.includes(filterValue) }, + [Filters.IsEqual.id]() { return this.getValueString(cell) === filterValue }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/selectionMultiMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/selectionMultiMixin.js deleted file mode 100644 index 86bb7e76c..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/selectionMultiMixin.js +++ /dev/null @@ -1,80 +0,0 @@ -export default { - - methods: { - getValueStringForSelectionMulti(valueObject, column) { - column = column || this.column || null - valueObject = valueObject || this.value || null - - const valueObjects = this.getObjectsForSelectionMulti(valueObject.value, column) - let ret = '' - valueObjects?.forEach(obj => { - if (ret === '') { - ret = obj.label - } else { - ret += ', ' + obj.label - } - }) - return ret - }, - - getObjectsForSelectionMulti(values, column) { - // values is an array of option-ids as string - - const objects = [] - values?.forEach(id => { - objects.push(this.getOptionObjectForSelectionMulti(parseInt(id), column)) - }) - return objects - }, - - getOptionObjectForSelectionMulti(id, column) { - const i = column?.selectionOptions?.findIndex(obj => { - return obj.id === id - }) - if (i !== undefined) { - return column?.selectionOptions[i] || null - } - }, - - getDefaultObjectsForSelectionMulti(column) { - column = column || this.column || null - - if (!column?.selectionDefault) { - return [] - } - - const defaultObjects = [] - JSON.parse(column?.selectionDefault)?.forEach(id => { - defaultObjects.push(this.getOptionObjectForSelectionMulti(parseInt(id), column)) - }) - return defaultObjects - }, - - isSearchStringFoundForSelectionMulti(column, cell, searchString) { - if (cell.value !== null && (this.getValueStringForSelectionMulti(cell, column)).toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForSelectionMulti(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - - if (filter.operator === 'contains' && (this.getValueStringForSelectionMulti(cell, column))?.includes(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-equal' && this.getValueStringForSelectionMulti(cell, column) === filterValue) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !this.getValueStringForSelectionMulti(cell, column)) { - cell.filterFound = true - return true - } - return false - }, - - }, - -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textLine.js b/src/shared/components/ncTable/mixins/columnsTypes/textLine.js new file mode 100644 index 000000000..585cde591 --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/textLine.js @@ -0,0 +1,44 @@ +import { AbstractTextColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class TextLineColumn extends AbstractTextColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.TextLine + this.textMaxLength = data.textMaxLength + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const valueA = rowA.data.find(item => item.columnId === this.id)?.value || '' + const valueB = rowB.data.find(item => item.columnId === this.id)?.value || '' + return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor + } + } + + getValueString(valueObject) { + return valueObject.value.replace(/(<([^>]+)>)/ig, '') + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(cell.value, cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.Contains.id]() { return cell.value.includes(filterValue) }, + [Filters.BeginsWith.id]() { return cell.value.startsWith(filterValue) }, + [Filters.EndsWith.id]() { return cell.value.endsWith(filterValue) }, + [Filters.IsEqual.id]() { return cell.value === filterValue }, + }[filter.operator] + + return super.isFilterFound(filterMethod, cell) + + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textLineMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/textLineMixin.js deleted file mode 100644 index 13d983641..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/textLineMixin.js +++ /dev/null @@ -1,47 +0,0 @@ -export default { - - methods: { - getValueStringForTextLine(valueObject) { - return valueObject.value.replace(/(<([^>]+)>)/ig, '') - }, - sortingTextLine(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const valueA = rowA.data.find(item => item.columnId === column.id)?.value || '' - const valueB = rowB.data.find(item => item.columnId === column.id)?.value || '' - return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor - } - }, - isSearchStringFoundForTextLine(column, cell, searchString) { - if (cell.value.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForTextLine(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - if (filter.operator === 'contains' && cell.value.includes(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'begins-with' && cell.value.startsWith(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'ends-with' && cell.value.endsWith(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-equal' && cell.value === filterValue) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !cell.value) { - cell.filterFound = true - return true - } - return false - }, - }, -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textLink.js b/src/shared/components/ncTable/mixins/columnsTypes/textLink.js new file mode 100644 index 000000000..ce8963c34 --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/textLink.js @@ -0,0 +1,37 @@ +import { AbstractTextColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class TextLinkColumn extends AbstractTextColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.TextLink + } + + sort(mode) { + const factor = mode === 'desc' ? -1 : 1 + return (rowA, rowB) => { + const valueA = rowA.data.find(item => item.columnId === this.id)?.value || '' + const valueB = rowB.data.find(item => item.columnId === this.id)?.value || '' + return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor + } + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(cell.value, cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.Contains.id]() { return cell.value.includes(filterValue) }, + [Filters.BeginsWith.id]() { return cell.value.startsWith(filterValue) }, + [Filters.EndsWith.id]() { return cell.value.endsWith(filterValue) }, + [Filters.IsEqual.id]() { return cell.value === filterValue }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textLinkMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/textLinkMixin.js deleted file mode 100644 index 9e3cdb9a9..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/textLinkMixin.js +++ /dev/null @@ -1,44 +0,0 @@ -export default { - - methods: { - sortingTextLink(column, mode) { - const factor = mode === 'desc' ? -1 : 1 - return function(rowA, rowB) { - const valueA = rowA.data.find(item => item.columnId === column.id)?.value || '' - const valueB = rowB.data.find(item => item.columnId === column.id)?.value || '' - return ((valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0) * factor - } - }, - isSearchStringFoundForTextLink(column, cell, searchString) { - if (cell.value.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForTextLink(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - if (filter.operator === 'contains' && cell.value.includes(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'begins-with' && cell.value.startsWith(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'ends-with' && cell.value.endsWith(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-equal' && cell.value === filterValue) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !cell.value) { - cell.filterFound = true - return true - } - return false - }, - }, -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textLong.js b/src/shared/components/ncTable/mixins/columnsTypes/textLong.js new file mode 100644 index 000000000..2f4872d3b --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/textLong.js @@ -0,0 +1,29 @@ +import { AbstractTextColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class TextLongColumn extends AbstractTextColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.TextLong + } + + getValueString(valueObject) { + return valueObject.value.replace(/(<([^>]+)>)/ig, '') + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(cell.value, cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.Contains.id]() { return cell.value.includes(filterValue) }, + }[filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textLongMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/textLongMixin.js deleted file mode 100644 index 78b730bd1..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/textLongMixin.js +++ /dev/null @@ -1,29 +0,0 @@ -export default { - - methods: { - getValueStringForTextLong(valueObject) { - return valueObject.value.replace(/(<([^>]+)>)/ig, '') - }, - isSearchStringFoundForTextLong(column, cell, searchString) { - if (cell.value.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForTextLong(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - - if (filter.operator === 'contains' && cell.value.includes(filterValue)) { - cell.filterFound = true - return true - } - if (filter.operator === 'is-empty' && !cell.value) { - cell.filterFound = true - return true - } - return false - }, - - }, -} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textRich.js b/src/shared/components/ncTable/mixins/columnsTypes/textRich.js new file mode 100644 index 000000000..42a7278fa --- /dev/null +++ b/src/shared/components/ncTable/mixins/columnsTypes/textRich.js @@ -0,0 +1,25 @@ +import { AbstractTextColumn } from '../columnClass.js' +import { ColumnTypes } from '../columnHandler.js' +import { Filters } from '../filter.js' + +export default class TextRichColumn extends AbstractTextColumn { + + constructor(data) { + super(data) + this.type = ColumnTypes.TextRich + } + + isSearchStringFound(cell, searchString) { + return super.isSearchStringFound(cell.value, cell, searchString) + } + + isFilterFound(cell, filter) { + const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value + + const filterMethod = { + [Filters.Contains.id]() { return cell.value.includes(filterValue) }, + }[filter.operator][filter.operator] + return super.isFilterFound(filterMethod, cell) + } + +} diff --git a/src/shared/components/ncTable/mixins/columnsTypes/textRichMixin.js b/src/shared/components/ncTable/mixins/columnsTypes/textRichMixin.js deleted file mode 100644 index 0fcee8852..000000000 --- a/src/shared/components/ncTable/mixins/columnsTypes/textRichMixin.js +++ /dev/null @@ -1,27 +0,0 @@ -export default { - - methods: { - isSearchStringFoundForTextRich(column, cell, searchString) { - if (cell.value.toLowerCase().includes(searchString)) { - cell.searchStringFound = true - return true - } - return false - }, - isFilterFoundForTextRich(column, cell, filter) { - const filterValue = filter.magicValuesEnriched ? filter.magicValuesEnriched : filter.value - - if (filter.operator === 'contains' && cell.value.includes(filterValue)) { - cell.filterFound = true - return true - } - console.debug('submit clicked', cell.value) - if (filter.operator === 'is-empty' && !cell.value) { - cell.filterFound = true - return true - } - return false - }, - - }, -} diff --git a/src/shared/components/ncTable/mixins/exportTableMixin.js b/src/shared/components/ncTable/mixins/exportTableMixin.js index 4c055b01b..3ce16bbb1 100644 --- a/src/shared/components/ncTable/mixins/exportTableMixin.js +++ b/src/shared/components/ncTable/mixins/exportTableMixin.js @@ -1,12 +1,9 @@ import moment from '@nextcloud/moment' -import textLongMixin from '../mixins/columnsTypes/textLongMixin.js' -import selectionMultiMixin from '../mixins/columnsTypes/selectionMultiMixin.js' -import selectionMixin from '../mixins/columnsTypes/selectionMixin.js' import generalHelper from '../../../mixins/generalHelper.js' export default { - mixins: [textLongMixin, selectionMultiMixin, selectionMixin, generalHelper], + mixins: [generalHelper], methods: { @@ -32,11 +29,7 @@ export default { this.$papa.download(csv, moment().format('YY-MM-DD_HH-mm') + '_' + tableTitle) }, getValueByColumnType(set, column) { - const methodName = 'getValueStringFor' + this.ucfirst(column.type) + this.ucfirst(column.subtype) || '' - if (this[methodName] instanceof Function) { - return this[methodName](set, column) - } - return set ? set.value : '' + return column.getValueString(set) }, }, } diff --git a/src/shared/components/ncTable/mixins/filter.js b/src/shared/components/ncTable/mixins/filter.js new file mode 100644 index 000000000..469f129a4 --- /dev/null +++ b/src/shared/components/ncTable/mixins/filter.js @@ -0,0 +1,96 @@ +import { ColumnTypes } from './columnHandler.js' + +class Filter { + + constructor({ id, label, icon, source, subline, goodFor, shortLabel = null, replace = null } = {}) { + this.id = id + this.label = label + this.shortLabel = shortLabel + this.icon = icon + this.source = source + this.subline = subline + this.goodFor = goodFor + this.replace = replace + } + + getOperatorLabel() { + return this.shortLabel ?? this.label + } + +} + +export function getFilterWithId(id) { + return Object.values(Filters).find(fil => fil.id === id) +} + +export const Filters = { + Contains: new Filter({ + id: 'contains', + label: t('tables', 'Contains'), + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.TextLine, ColumnTypes.TextLong, ColumnTypes.Selection, ColumnTypes.SelectionMulti, ColumnTypes.TextLink, ColumnTypes.TextRich], + }), + BeginsWith: new Filter({ + id: 'begins-with', + label: t('tables', 'Begins with'), + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.TextLine, ColumnTypes.Selection, ColumnTypes.TextLink], + }), + EndsWith: new Filter({ + id: 'ends-with', + label: t('tables', 'Ends with'), + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.TextLine, ColumnTypes.Selection, ColumnTypes.TextLink], + }), + IsEqual: new Filter({ + id: 'is-equal', + label: t('tables', 'Is equal'), + shortLabel: '=', + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.TextLine, ColumnTypes.Selection, ColumnTypes.SelectionMulti, ColumnTypes.Number, ColumnTypes.SelectionCheck, ColumnTypes.TextLink, ColumnTypes.NumberStars, ColumnTypes.NumberProgress, ColumnTypes.DatetimeDate, ColumnTypes.DatetimeTime, ColumnTypes.Datetime], + }), + IsGreaterThan: new Filter({ + id: 'is-greater-than', + label: t('tables', 'Is greater than'), + shortLabel: '>', + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.Number, ColumnTypes.NumberStars, ColumnTypes.NumberProgress, ColumnTypes.DatetimeDate, ColumnTypes.DatetimeTime, ColumnTypes.Datetime], + }), + IsGreaterThanOrEqual: new Filter({ + id: 'is-greater-than-or-equal', + label: t('tables', 'Is greater than or equal'), + shortLabel: '>=', + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.Number, ColumnTypes.NumberStars, ColumnTypes.NumberProgress, ColumnTypes.DatetimeDate, ColumnTypes.DatetimeTime, ColumnTypes.Datetime], + }), + IsLowerThan: new Filter({ + id: 'is-lower-than', + label: t('tables', 'Is lower than'), + shortLabel: '<', + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.Number, ColumnTypes.NumberStars, ColumnTypes.NumberProgress, ColumnTypes.DatetimeDate, ColumnTypes.DatetimeTime, ColumnTypes.Datetime], + }), + IsLowerThanOrEqual: new Filter({ + id: 'is-lower-than-or-equal', + label: t('tables', 'Is lower than or equal'), + shortLabel: '<=', + icon: 'icon-add', + source: 'operators', + subline: t('tables', 'Filter operator'), + goodFor: [ColumnTypes.Number, ColumnTypes.NumberStars, ColumnTypes.NumberProgress, ColumnTypes.DatetimeDate, ColumnTypes.DatetimeTime, ColumnTypes.Datetime], + }), +} diff --git a/src/shared/components/ncTable/mixins/magicFields.js b/src/shared/components/ncTable/mixins/magicFields.js new file mode 100644 index 000000000..fd87c8b2a --- /dev/null +++ b/src/shared/components/ncTable/mixins/magicFields.js @@ -0,0 +1,164 @@ +import { getCurrentUser } from '@nextcloud/auth' +import Moment from '@nextcloud/moment' +import { ColumnTypes } from './columnHandler.js' + +class MagicField { + + constructor({ id, label, icon, source, subline, goodFor, replace } = {}) { + this.id = id + this.label = label + this.icon = icon + this.source = source + this.subline = subline + this.goodFor = goodFor + this.replace = replace + } + +} + +export const MagicFields = { + Me: new MagicField({ + id: 'me', + label: t('tables', 'Me (user ID)'), + icon: 'icon-user', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.TextLine, ColumnTypes.Selection, ColumnTypes.SelectionMulti, ColumnTypes.TextRich], + replace: getCurrentUser().uid, + }), + MyName: new MagicField({ + id: 'my-name', + label: t('tables', 'Me (name)'), + icon: 'icon-user', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.TextLine, ColumnTypes.Selection, ColumnTypes.SelectionMulti, ColumnTypes.TextRich], + replace: getCurrentUser().displayName, + }), + Checked: new MagicField({ + id: 'checked', + label: t('tables', 'Checked'), + icon: 'icon-checkmark', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.SelectionCheck], + replace: 'yes', + }), + Unchecked: new MagicField({ + id: 'unchecked', + label: t('tables', 'Unchecked'), + icon: 'icon-close', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.SelectionCheck], + replace: 'no', + }), + Stars0: new MagicField({ + id: 'stars-0', + label: '☆☆☆☆☆', + icon: 'icon-star', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.NumberStars], + replace: '0', + }), + Stars1: new MagicField({ + id: 'stars-1', + label: '★☆☆☆☆', + icon: 'icon-star', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.NumberStars], + replace: '1', + }), + Stars2: new MagicField({ + id: 'stars-2', + label: '★★☆☆☆', + icon: 'icon-star', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.NumberStars], + replace: '2', + }), + Stars3: new MagicField({ + id: 'stars-3', + label: '★★★☆☆', + icon: 'icon-star', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.NumberStars], + replace: '3', + }), + Stars4: new MagicField({ + id: 'stars-4', + label: '★★★★☆', + icon: 'icon-star', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.NumberStars], + replace: '4', + }), + Stars5: new MagicField({ + id: 'stars-5', + label: '★★★★★', + icon: 'icon-star', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.NumberStars], + replace: '5', + }), + DatetimeDateToday: new MagicField({ + id: 'datetime-date-today', + label: t('tables', 'Today'), + icon: 'icon-calendar-dark', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.DatetimeDate], + replace: new Moment().format('YYYY-MM-DD'), + }), + DatetimeDateStartOfYear: new MagicField({ + id: 'datetime-date-start-of-year', + label: t('tables', 'Start of the year'), + icon: 'icon-history', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.DatetimeDate], + replace: new Moment().startOf('year').format('YYYY-MM-DD'), + }), + DatetimeDateStartOfMonth: new MagicField({ + id: 'datetime-date-start-of-month', + label: t('tables', 'Start of the month'), + icon: 'icon-history', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.DatetimeDate], + replace: new Moment().startOf('month').format('YYYY-MM-DD'), + }), + DatetimeDateStartOfWeek: new MagicField({ + id: 'datetime-date-start-of-week', + label: t('tables', 'Start of the week'), + icon: 'icon-history', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.DatetimeDate], + replace: new Moment().startOf('week').format('YYYY-MM-DD'), + }), + DatetimeTimeNow: new MagicField({ + id: 'datetime-time-now', + label: t('tables', 'Now'), + icon: 'icon-calendar-dark', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.DatetimeTime], + replace: new Moment().format('HH:mm'), + }), + DatetimeNow: new MagicField({ + id: 'datetime-now', + label: t('tables', 'Now'), + icon: 'icon-calendar-dark', + source: 'magic-fields', + subline: t('tables', 'Magic field'), + goodFor: [ColumnTypes.Datetime], + replace: new Moment().format('YYYY-MM-DD HH:mm'), + }), +} diff --git a/src/shared/components/ncTable/mixins/searchAndFilterMixin.js b/src/shared/components/ncTable/mixins/searchAndFilterMixin.js deleted file mode 100644 index b4da90857..000000000 --- a/src/shared/components/ncTable/mixins/searchAndFilterMixin.js +++ /dev/null @@ -1,273 +0,0 @@ -import { getCurrentUser } from '@nextcloud/auth' -import Moment from '@nextcloud/moment' - -export default { - - data() { - return { - operators: { - 'operator-contains': { - id: 'operator-contains', - label: t('tables', 'Contains'), - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['text-line', 'text-long', 'selection', 'selection-multi', 'text-link', 'text-rich'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal'], - }, - 'operator-begins-with': { - id: 'operator-begins-with', - label: t('tables', 'Begins with'), - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['text-line', 'selection', 'text-link'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal', 'operator-begins-with'], - }, - 'operator-ends-with': { - id: 'operator-ends-with', - label: t('tables', 'Ends with'), - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['text-line', 'selection', 'text-link'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal', 'operator-ends-with'], - }, - 'operator-is-equal': { - id: 'operator-is-equal', - label: t('tables', 'Is equal'), - shortLabel: '=', - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['text-line', 'selection', 'selection-multi', 'number', 'selection-check', 'text-link', 'number-stars', 'number-progress', 'datetime-date', 'datetime-time', 'datetime'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal', 'operator-begins-with', 'operator-ends-with', 'operator-contains', 'operator-is-greater-than', 'operator-is-greater-than-or-equal', 'operator-is-lower-than', 'operator-is-lower-than-or-equal'], - }, - 'operator-is-greater-than': { - id: 'operator-is-greater-than', - label: t('tables', 'Is greater than'), - shortLabel: '>', - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['number', 'number-stars', 'number-progress', 'datetime-date', 'datetime-time', 'datetime'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal', 'operator-is-greater-than', 'operator-is-greater-than-or-equal'], - }, - 'operator-is-greater-than-or-equal': { - id: 'operator-is-greater-than-or-equal', - label: t('tables', 'Is greater than or equal'), - shortLabel: '>=', - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['number', 'number-stars', 'number-progress', 'datetime-date', 'datetime-time', 'datetime'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal', 'operator-is-greater-than', 'operator-is-greater-than-or-equal'], - }, - 'operator-is-lower-than': { - id: 'operator-is-lower-than', - label: t('tables', 'Is lower than'), - shortLabel: '<', - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['number', 'number-stars', 'number-progress', 'datetime-date', 'datetime-time', 'datetime'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal', 'operator-is-lower-than', 'operator-is-lower-than-or-equal'], - }, - 'operator-is-lower-than-or-equal': { - id: 'operator-is-lower-than-or-equal', - label: t('tables', 'Is lower than or equal'), - shortLabel: '<=', - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['number', 'number-stars', 'number-progress', 'datetime-date', 'datetime-time', 'datetime'], - incompatibleWith: ['operator-is-empty', 'operator-is-equal', 'operator-is-lower-than', 'operator-is-lower-than-or-equal'], - }, - 'operator-is-empty': { - id: 'operator-is-empty', - label: t('tables', 'Is empty'), - icon: 'icon-add', - source: 'operators', - subline: t('tables', 'Filter operator'), - goodFor: ['text-line', 'text-rich', 'selection', 'selection-multi', 'number', 'text-link', 'number-progress', 'datetime-date', 'datetime-time', 'datetime'], - incompatibleWith: ['operator-contains', 'operator-begins-with', 'operator-ends-with', 'operator-is-equal', 'operator-is-greater-than', 'operator-is-greater-than-or-equal', 'operator-is-lower-than', 'operator-is-lower-than-or-equal', 'operator-is-empty'], - }, - }, - magicFields: { - 'magic-field-me': { - id: 'magic-field-me', - label: t('tables', 'Me (user ID)'), - icon: 'icon-user', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['text-line', 'selection', 'selection-multi', 'text-rich'], - replace: getCurrentUser().uid, - }, - 'magic-field-my-name': { - id: 'magic-field-my-name', - label: t('tables', 'Me (name)'), - icon: 'icon-user', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['text-line', 'selection', 'selection-multi', 'text-rich'], - replace: getCurrentUser().displayName, - }, - 'magic-field-checked': { - id: 'magic-field-checked', - label: t('tables', 'Checked'), - icon: 'icon-checkmark', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['selection-check'], - replace: 'yes', - }, - 'magic-field-unchecked': { - id: 'magic-field-unchecked', - label: t('tables', 'Unchecked'), - icon: 'icon-close', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['selection-check'], - replace: 'no', - }, - 'magic-field-stars-0': { - id: 'magic-field-stars-0', - label: '☆☆☆☆☆', - icon: 'icon-star', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['number-stars'], - replace: '0', - }, - 'magic-field-stars-1': { - id: 'magic-field-stars-1', - label: '★☆☆☆☆', - icon: 'icon-star', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['number-stars'], - replace: '1', - }, - 'magic-field-stars-2': { - id: 'magic-field-stars-2', - label: '★★☆☆☆', - icon: 'icon-star', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['number-stars'], - replace: '2', - }, - 'magic-field-stars-3': { - id: 'magic-field-stars-3', - label: '★★★☆☆', - icon: 'icon-star', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['number-stars'], - replace: '3', - }, - 'magic-field-stars-4': { - id: 'magic-field-stars-4', - label: '★★★★☆', - icon: 'icon-star', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['number-stars'], - replace: '4', - }, - 'magic-field-stars-5': { - id: 'magic-field-stars-5', - label: '★★★★★', - icon: 'icon-star', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['number-stars'], - replace: '5', - }, - 'magic-field-datetime-date-today': { - id: 'magic-field-datetime-date-today', - label: t('tables', 'Today'), - icon: 'icon-calendar-dark', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['datetime-date'], - replace: new Moment().format('YYYY-MM-DD'), - }, - 'magic-field-datetime-date-start-of-year': { - id: 'magic-field-datetime-date-start-of-year', - label: t('tables', 'Start of the year'), - icon: 'icon-history', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['datetime-date'], - replace: new Moment().startOf('year').format('YYYY-MM-DD'), - }, - 'magic-field-datetime-date-start-of-month': { - id: 'magic-field-datetime-date-start-of-month', - label: t('tables', 'Start of the month'), - icon: 'icon-history', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['datetime-date'], - replace: new Moment().startOf('month').format('YYYY-MM-DD'), - }, - 'magic-field-datetime-date-start-of-week': { - id: 'magic-field-datetime-date-start-of-week', - label: t('tables', 'Start of the week'), - icon: 'icon-history', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['datetime-date'], - replace: new Moment().startOf('week').format('YYYY-MM-DD'), - }, - 'magic-field-datetime-time-now': { - id: 'magic-field-datetime-time-now', - label: t('tables', 'Now'), - icon: 'icon-calendar-dark', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['datetime-time'], - replace: new Moment().format('HH:mm'), - }, - 'magic-field-datetime-now': { - id: 'magic-field-datetime-now', - label: t('tables', 'Now'), - icon: 'icon-calendar-dark', - source: 'magic-fields', - subline: t('tables', 'Magic field'), - goodFor: ['datetime'], - replace: new Moment().format('YYYY-MM-DD HH:mm'), - }, - }, - hideFilterInputForColumnTypes: [ - 'selection-check', - 'number-stars', - ], - } - }, - - methods: { - getOperatorLabel(id) { - if (id.substring(0, 9) !== 'operator-') { - id = 'operator-' + id - } - return this.operators[id]?.shortLabel ?? this.operators[id]?.label - }, - getPossibleOperators(column) { - const columnType = column.type + (column.subtype ? '-' + column.subtype : '') - return Object.values(this.operators).filter(item => item.goodFor.includes(columnType)) - }, - getPossibleMagicFields(column) { - const columnType = column.type + (column.subtype ? '-' + column.subtype : '') - return Object.values(this.magicFields).filter(item => item.goodFor.includes(columnType)) - }, - getIncompatibleFilters(id) { - if (id.substring(0, 9) !== 'operator-') { - id = 'operator-' + id - } - return this.operators[id]?.incompatibleWith - }, - - }, - -} diff --git a/src/shared/components/ncTable/partials/FilterLabel.vue b/src/shared/components/ncTable/partials/FilterLabel.vue index a8a97982d..9fc378e47 100644 --- a/src/shared/components/ncTable/partials/FilterLabel.vue +++ b/src/shared/components/ncTable/partials/FilterLabel.vue @@ -8,7 +8,7 @@ diff --git a/src/shared/components/ncTable/partials/TableCellSelection.vue b/src/shared/components/ncTable/partials/TableCellSelection.vue index 3f353edc0..c480a7a85 100644 --- a/src/shared/components/ncTable/partials/TableCellSelection.vue +++ b/src/shared/components/ncTable/partials/TableCellSelection.vue @@ -1,17 +1,14 @@ diff --git a/src/shared/components/ncTable/partials/TableHeader.vue b/src/shared/components/ncTable/partials/TableHeader.vue index 949d28d1a..3195e4244 100644 --- a/src/shared/components/ncTable/partials/TableHeader.vue +++ b/src/shared/components/ncTable/partials/TableHeader.vue @@ -18,8 +18,10 @@ :id="filter.columnId + filter.operator + filter.value" :key="filter.columnId + filter.operator + filter.value" :operator="filter.operator" + :operator-label="getFilterWithId(filter.operator).getOperatorLabel()" :value="filter.value" @delete-filter="id => $emit('delete-filter', id)" /> + @@ -75,9 +77,9 @@ import TableEdit from 'vue-material-design-icons/TableEdit.vue' import TableColumnPlusAfter from 'vue-material-design-icons/TableColumnPlusAfter.vue' import IconImport from 'vue-material-design-icons/Import.vue' import TableHeaderColumnOptions from './TableHeaderColumnOptions.vue' -import searchAndFilterMixin from '../mixins/searchAndFilterMixin.js' import FilterLabel from './FilterLabel.vue' import permissionsMixin from '../mixins/permissionsMixin.js' +import { Filters } from '../mixins/filter.js' export default { @@ -93,7 +95,7 @@ export default { TableColumnPlusAfter, }, - mixins: [searchAndFilterMixin, permissionsMixin], + mixins: [permissionsMixin], props: { columns: { @@ -142,6 +144,9 @@ export default { getFilterForColumn(column) { return this.view?.filter?.filter(item => item.columnId === column.id) }, + getFilterWithId(id) { + return Object.values(Filters).find(fil => fil.id === id) || null + }, downloadCSV() { this.$emit('download-csv', this.rows) }, diff --git a/src/shared/components/ncTable/partials/TableHeaderColumnOptions.vue b/src/shared/components/ncTable/partials/TableHeaderColumnOptions.vue index 8599f2d02..e543e67ee 100644 --- a/src/shared/components/ncTable/partials/TableHeaderColumnOptions.vue +++ b/src/shared/components/ncTable/partials/TableHeaderColumnOptions.vue @@ -41,10 +41,10 @@ diff --git a/src/shared/components/ncTable/mixins/columnParser.js b/src/shared/components/ncTable/mixins/columnParser.js index dc9a713d4..dd93eb51d 100644 --- a/src/shared/components/ncTable/mixins/columnParser.js +++ b/src/shared/components/ncTable/mixins/columnParser.js @@ -1,3 +1,4 @@ +import { ColumnTypes } from './columnHandler.js' import DatetimeDateColumn from './columnsTypes/datetimeDate.js' import DatetimeColumn from './columnsTypes/datetime.js' import DatetimeTimeColumn from './columnsTypes/datetimeTime.js' @@ -15,19 +16,19 @@ import TextRichColumn from './columnsTypes/textRich.js' export function parseCol(col) { const columnType = col.type + (col.subtype === '' ? '' : '-' + col.subtype) switch (columnType) { - case 'text-line': return new TextLineColumn(col) - case 'text-link': return new TextLinkColumn(col) - case 'text-long': return new TextLongColumn(col) - case 'text-rich': return new TextRichColumn(col) - case 'number': return new NumberColumn(col) - case 'number-stars': return new NumberStarsColumn(col) - case 'number-progress': return new NumberProgressColumn(col) - case 'selection': return new SelectionColumn(col) - case 'selection-multi': return new SelectionMutliColumn(col) - case 'selection-check': return new SelectionCheckColumn(col) - case 'datetime': return new DatetimeColumn(col) - case 'datetime-date': return new DatetimeDateColumn(col) - case 'datetime-time': return new DatetimeTimeColumn(col) - default: throw Error(col.type + '-' + col.subtype + ' is not a valid column type!') + case ColumnTypes.TextLine: return new TextLineColumn(col) + case ColumnTypes.TextLink: return new TextLinkColumn(col) + case ColumnTypes.TextLong: return new TextLongColumn(col) + case ColumnTypes.TextRich: return new TextRichColumn(col) + case ColumnTypes.Number: return new NumberColumn(col) + case ColumnTypes.NumberStars: return new NumberStarsColumn(col) + case ColumnTypes.NumberProgress: return new NumberProgressColumn(col) + case ColumnTypes.Selection: return new SelectionColumn(col) + case ColumnTypes.SelectionMulti: return new SelectionMutliColumn(col) + case ColumnTypes.SelectionCheck: return new SelectionCheckColumn(col) + case ColumnTypes.Datetime: return new DatetimeColumn(col) + case ColumnTypes.DatetimeDate: return new DatetimeDateColumn(col) + case ColumnTypes.DatetimeTime: return new DatetimeTimeColumn(col) + default: throw Error(columnType + ' is not a valid column type!') } } diff --git a/src/shared/components/ncTable/mixins/exportTableMixin.js b/src/shared/components/ncTable/mixins/exportTableMixin.js index 3ce16bbb1..8bf42dcfb 100644 --- a/src/shared/components/ncTable/mixins/exportTableMixin.js +++ b/src/shared/components/ncTable/mixins/exportTableMixin.js @@ -17,7 +17,7 @@ export default { const rowData = {} columns.forEach(column => { const set = row.data ? row.data.find(d => d.columnId === column.id) || '' : null - rowData[column.title] = set ? this.getValueByColumnType(set, column) : '' + rowData[column.title] = set ? column.getValueString(set) : '' }) data.push(rowData) }) @@ -28,8 +28,5 @@ export default { const tableTitle = table.title.replace(/([#0-9]\u20E3)|[\xA9\xAE\u203C\u2047-\u2049\u2122\u2139\u3030\u303D\u3297\u3299][\uFE00-\uFEFF]?|[\u2190-\u21FF][\uFE00-\uFEFF]?|[\u2300-\u23FF][\uFE00-\uFEFF]?|[\u2460-\u24FF][\uFE00-\uFEFF]?|[\u25A0-\u25FF][\uFE00-\uFEFF]?|[\u2600-\u27BF][\uFE00-\uFEFF]?|[\u2900-\u297F][\uFE00-\uFEFF]?|[\u2B00-\u2BF0][\uFE00-\uFEFF]?|(?:\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDEFF])[\uFE00-\uFEFF]?/g, '') this.$papa.download(csv, moment().format('YY-MM-DD_HH-mm') + '_' + tableTitle) }, - getValueByColumnType(set, column) { - return column.getValueString(set) - }, }, }