diff --git a/cypress/e2e/ToDo list.json b/cypress/e2e/ToDo list.json index 31f3d4de50..00931bb745 100644 --- a/cypress/e2e/ToDo list.json +++ b/cypress/e2e/ToDo list.json @@ -35,7 +35,8 @@ "usergroupSelectUsers": false, "usergroupSelectGroups": false, "usergroupSelectTeams": false, - "showUserStatus": false + "showUserStatus": false, + "customSettings": {} }, { "id": 92, @@ -70,7 +71,10 @@ "usergroupSelectUsers": false, "usergroupSelectGroups": false, "usergroupSelectTeams": false, - "showUserStatus": false + "showUserStatus": false, + "customSettings": { + "width": 300 + } }, { "id": 93, @@ -105,7 +109,8 @@ "usergroupSelectUsers": false, "usergroupSelectGroups": false, "usergroupSelectTeams": false, - "showUserStatus": false + "showUserStatus": false, + "customSettings": {} }, { "id": 94, @@ -140,7 +145,8 @@ "usergroupSelectUsers": false, "usergroupSelectGroups": false, "usergroupSelectTeams": false, - "showUserStatus": false + "showUserStatus": false, + "customSettings": {} }, { "id": 95, @@ -175,7 +181,8 @@ "usergroupSelectUsers": false, "usergroupSelectGroups": false, "usergroupSelectTeams": false, - "showUserStatus": false + "showUserStatus": false, + "customSettings": {} }, { "id": 96, @@ -210,7 +217,8 @@ "usergroupSelectUsers": false, "usergroupSelectGroups": false, "usergroupSelectTeams": false, - "showUserStatus": false + "showUserStatus": false, + "customSettings": {} } ], "views": [ diff --git a/lib/Controller/Api1Controller.php b/lib/Controller/Api1Controller.php index f5e9049fe3..559f5598b0 100644 --- a/lib/Controller/Api1Controller.php +++ b/lib/Controller/Api1Controller.php @@ -818,6 +818,7 @@ public function indexViewColumns(int $viewId): DataResponse { * @param bool|null $usergroupSelectTeams Can select teams, if column type is usergroup * @param bool|null $usergroupShowUserStatus Whether to show the user's status, if column type is usergroup * @param list|null $selectedViewIds View IDs where this column should be added to be presented + * @param array $customSettings Custom settings for the column * * @return DataResponse|DataResponse * @@ -862,6 +863,7 @@ public function createColumn( ?bool $usergroupShowUserStatus = null, ?array $selectedViewIds = [], + ?array $customSettings = [], ): DataResponse { try { return new DataResponse($this->columnService->create( @@ -892,7 +894,8 @@ public function createColumn( usergroupSelectUsers: $usergroupSelectUsers, usergroupSelectGroups: $usergroupSelectGroups, usergroupSelectTeams: $usergroupSelectTeams, - showUserStatus: $usergroupShowUserStatus + showUserStatus: $usergroupShowUserStatus, + customSettings: json_encode($customSettings), ), $selectedViewIds )->jsonSerialize()); @@ -938,6 +941,7 @@ public function createColumn( * @param bool|null $usergroupSelectGroups Can select groups, if column type is usergroup * @param bool|null $usergroupSelectTeams Can select teams, if column type is usergroup * @param bool|null $usergroupShowUserStatus Whether to show the user's status, if column type is usergroup + * @param array $customSettings Custom settings for the column * * @return DataResponse|DataResponse * @@ -977,7 +981,7 @@ public function updateColumn( ?bool $usergroupSelectGroups, ?bool $usergroupSelectTeams, ?bool $usergroupShowUserStatus, - + ?array $customSettings = [], ): DataResponse { try { $item = $this->columnService->update( @@ -1006,7 +1010,8 @@ public function updateColumn( usergroupSelectUsers: $usergroupSelectUsers, usergroupSelectGroups: $usergroupSelectGroups, usergroupSelectTeams: $usergroupSelectTeams, - showUserStatus: $usergroupShowUserStatus + showUserStatus: $usergroupShowUserStatus, + customSettings: json_encode($customSettings), ) ); return new DataResponse($item->jsonSerialize()); @@ -1576,6 +1581,7 @@ public function createTableShare(int $tableId, string $receiver, string $receive * @param bool|null $usergroupSelectTeams Can select teams, if column type is usergroup * @param bool|null $usergroupShowUserStatus Whether to show the user's status, if column type is usergroup * @param list|null $selectedViewIds View IDs where this column should be added to be presented + * @param array $customSettings Custom settings for the column * * @return DataResponse|DataResponse * @@ -1620,6 +1626,7 @@ public function createTableColumn( ?bool $usergroupSelectTeams = null, ?bool $usergroupShowUserStatus = null, ?array $selectedViewIds = [], + array $customSettings = [], ): DataResponse { try { $item = $this->columnService->create( @@ -1650,7 +1657,8 @@ public function createTableColumn( usergroupSelectUsers: $usergroupSelectUsers, usergroupSelectGroups: $usergroupSelectGroups, usergroupSelectTeams: $usergroupSelectTeams, - showUserStatus: $usergroupShowUserStatus + showUserStatus: $usergroupShowUserStatus, + customSettings: json_encode($customSettings), ), $selectedViewIds ); diff --git a/lib/Controller/ApiColumnsController.php b/lib/Controller/ApiColumnsController.php index fa02bfcf87..e1284ba746 100644 --- a/lib/Controller/ApiColumnsController.php +++ b/lib/Controller/ApiColumnsController.php @@ -112,6 +112,8 @@ public function show(int $id): DataResponse { * @param 'progress'|'stars'|null $subtype Subtype for the new column * @param string|null $description Description * @param list|null $selectedViewIds View IDs where this columns should be added + * @param array $customSettings Custom settings for the column + * * @return DataResponse|DataResponse * * 200: Column created @@ -123,7 +125,7 @@ public function show(int $id): DataResponse { */ #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')] - public function createNumberColumn(int $baseNodeId, string $title, ?float $numberDefault, ?int $numberDecimals, ?string $numberPrefix, ?string $numberSuffix, ?float $numberMin, ?float $numberMax, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table'): DataResponse { + public function createNumberColumn(int $baseNodeId, string $title, ?float $numberDefault, ?int $numberDecimals, ?string $numberPrefix, ?string $numberSuffix, ?float $numberMin, ?float $numberMax, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse { $tableId = $baseNodeType === 'table' ? $baseNodeId : null; $viewId = $baseNodeType === 'view' ? $baseNodeId : null; $column = $this->service->create( @@ -141,7 +143,8 @@ public function createNumberColumn(int $baseNodeId, string $title, ?float $numbe numberMax: $numberMax, numberDecimals: $numberDecimals, numberPrefix: $numberPrefix, - numberSuffix: $numberSuffix + numberSuffix: $numberSuffix, + customSettings: json_encode($customSettings), ), $selectedViewIds ); @@ -164,6 +167,7 @@ public function createNumberColumn(int $baseNodeId, string $title, ?float $numbe * @param list|null $selectedViewIds View IDs where this columns should be added * @param boolean $mandatory Is mandatory * @param 'table'|'view' $baseNodeType Context type of the column creation + * @param array $customSettings Custom settings for the column * @return DataResponse|DataResponse * * 200: Column created @@ -175,7 +179,7 @@ public function createNumberColumn(int $baseNodeId, string $title, ?float $numbe */ #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')] - public function createTextColumn(int $baseNodeId, string $title, ?string $textDefault, ?string $textAllowedPattern, ?int $textMaxLength, ?bool $textUnique = false, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table'): DataResponse { + public function createTextColumn(int $baseNodeId, string $title, ?string $textDefault, ?string $textAllowedPattern, ?int $textMaxLength, ?bool $textUnique = false, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse { $tableId = $baseNodeType === 'table' ? $baseNodeId : null; $viewId = $baseNodeType === 'view' ? $baseNodeId : null; $column = $this->service->create( @@ -191,7 +195,8 @@ public function createTextColumn(int $baseNodeId, string $title, ?string $textDe textDefault: $textDefault, textAllowedPattern: $textAllowedPattern, textMaxLength: $textMaxLength, - textUnique: $textUnique + textUnique: $textUnique, + customSettings: json_encode($customSettings), ), $selectedViewIds ); @@ -212,6 +217,8 @@ public function createTextColumn(int $baseNodeId, string $title, ?string $textDe * @param list|null $selectedViewIds View IDs where this columns should be added * @param boolean $mandatory Is mandatory * @param 'table'|'view' $baseNodeType Context type of the column creation + * @param array $customSettings Custom settings for the column + * * @return DataResponse|DataResponse * * 200: Column created @@ -223,7 +230,7 @@ public function createTextColumn(int $baseNodeId, string $title, ?string $textDe */ #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')] - public function createSelectionColumn(int $baseNodeId, string $title, string $selectionOptions, ?string $selectionDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table'): DataResponse { + public function createSelectionColumn(int $baseNodeId, string $title, string $selectionOptions, ?string $selectionDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse { $tableId = $baseNodeType === 'table' ? $baseNodeId : null; $viewId = $baseNodeType === 'view' ? $baseNodeId : null; $column = $this->service->create( @@ -237,7 +244,8 @@ public function createSelectionColumn(int $baseNodeId, string $title, string $se mandatory: $mandatory, description: $description, selectionOptions: $selectionOptions, - selectionDefault: $selectionDefault + selectionDefault: $selectionDefault, + customSettings: json_encode($customSettings), ), $selectedViewIds ); @@ -257,6 +265,8 @@ public function createSelectionColumn(int $baseNodeId, string $title, string $se * @param list|null $selectedViewIds View IDs where this columns should be added * @param boolean $mandatory Is mandatory * @param 'table'|'view' $baseNodeType Context type of the column creation + * @param array $customSettings Custom settings for the column + * * @return DataResponse|DataResponse * * 200: Column created @@ -268,7 +278,7 @@ public function createSelectionColumn(int $baseNodeId, string $title, string $se */ #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')] - public function createDatetimeColumn(int $baseNodeId, string $title, ?string $datetimeDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table'): DataResponse { + public function createDatetimeColumn(int $baseNodeId, string $title, ?string $datetimeDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse { $tableId = $baseNodeType === 'table' ? $baseNodeId : null; $viewId = $baseNodeType === 'view' ? $baseNodeId : null; $column = $this->service->create( @@ -281,7 +291,8 @@ public function createDatetimeColumn(int $baseNodeId, string $title, ?string $da subtype: $subtype, mandatory: $mandatory, description: $description, - datetimeDefault: $datetimeDefault + datetimeDefault: $datetimeDefault, + customSettings: json_encode($customSettings), ), $selectedViewIds ); @@ -303,6 +314,8 @@ public function createDatetimeColumn(int $baseNodeId, string $title, ?string $da * @param list|null $selectedViewIds View IDs where this columns should be added * @param boolean $mandatory Is mandatory * @param 'table'|'view' $baseNodeType Context type of the column creation + * @param array $customSettings Custom settings for the column + * * @return DataResponse|DataResponse * * 200: Column created @@ -314,7 +327,7 @@ public function createDatetimeColumn(int $baseNodeId, string $title, ?string $da */ #[NoAdminRequired] #[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')] - public function createUsergroupColumn(int $baseNodeId, string $title, ?string $usergroupDefault, ?bool $usergroupMultipleItems = null, ?bool $usergroupSelectUsers = null, ?bool $usergroupSelectGroups = null, ?bool $usergroupSelectTeams = null, ?bool $showUserStatus = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table'): DataResponse { + public function createUsergroupColumn(int $baseNodeId, string $title, ?string $usergroupDefault, ?bool $usergroupMultipleItems = null, ?bool $usergroupSelectUsers = null, ?bool $usergroupSelectGroups = null, ?bool $usergroupSelectTeams = null, ?bool $showUserStatus = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse { $tableId = $baseNodeType === 'table' ? $baseNodeId : null; $viewId = $baseNodeType === 'view' ? $baseNodeId : null; $column = $this->service->create( @@ -331,7 +344,8 @@ public function createUsergroupColumn(int $baseNodeId, string $title, ?string $u usergroupSelectUsers: $usergroupSelectUsers, usergroupSelectGroups: $usergroupSelectGroups, usergroupSelectTeams: $usergroupSelectTeams, - showUserStatus: $showUserStatus + showUserStatus: $showUserStatus, + customSettings: json_encode($customSettings), ), $selectedViewIds ); diff --git a/lib/Controller/ApiTablesController.php b/lib/Controller/ApiTablesController.php index f6816a4a27..5644734311 100644 --- a/lib/Controller/ApiTablesController.php +++ b/lib/Controller/ApiTablesController.php @@ -169,6 +169,7 @@ public function createFromScheme(string $title, string $emoji, string $descripti usergroupSelectGroups: $column['usergroupSelectGroups'], usergroupSelectTeams: $column['usergroupSelectTeams'], showUserStatus: $column['showUserStatus'], + customSettings: empty($column['customSettings']) ? null : json_encode($column['customSettings']) ) ); $colMap[$column['id']] = $col->getId(); diff --git a/lib/Db/Column.php b/lib/Db/Column.php index 8d4623fe6c..2eaa96135c 100644 --- a/lib/Db/Column.php +++ b/lib/Db/Column.php @@ -82,6 +82,8 @@ * @method setShowUserStatus(?bool $showUserStatus) * @method getViewColumnInformation(): ViewColumnInformation * @method setViewColumnInformation(ViewColumnInformation $viewColumnInformation) + * @method getCustomSettings(): ?string + * @method setCustomSettings(?string $customSettings) */ class Column extends EntitySuper implements JsonSerializable { // Meta column types @@ -146,6 +148,7 @@ class Column extends EntitySuper implements JsonSerializable { protected ?bool $usergroupSelectGroups = null; protected ?bool $usergroupSelectTeams = null; protected ?bool $showUserStatus = null; + protected ?string $customSettings = null; // virtual properties protected ?string $createdByDisplayName = null; @@ -175,6 +178,8 @@ public function __construct() { $this->addType('usergroupSelectGroups', 'boolean'); $this->addType('usergroupSelectTeams', 'boolean'); $this->addType('showUserStatus', 'boolean'); + + $this->addType('customSettings', 'string'); } public static function isValidMetaTypeId(int $metaTypeId): bool { @@ -213,6 +218,7 @@ public static function fromDto(ColumnDto $data): self { $column->setUsergroupSelectGroups($data->getUsergroupSelectGroups()); $column->setUsergroupSelectTeams($data->getUsergroupSelectTeams()); $column->setShowUserStatus($data->getShowUserStatus()); + $column->setCustomSettings($data->getCustomSettings()); return $column; } @@ -292,6 +298,11 @@ public function jsonSerialize(): array { 'usergroupSelectGroups' => $this->usergroupSelectGroups, 'usergroupSelectTeams' => $this->usergroupSelectTeams, 'showUserStatus' => $this->showUserStatus, + 'customSettings' => $this->getCustomSettingsArray() ?: new \stdClass(), ]; } + + public function getCustomSettingsArray(): array { + return json_decode($this->customSettings, true) ?: []; + } } diff --git a/lib/Dto/Column.php b/lib/Dto/Column.php index c1877f4040..9d4f61fb4c 100644 --- a/lib/Dto/Column.php +++ b/lib/Dto/Column.php @@ -33,6 +33,7 @@ public function __construct( private ?bool $usergroupSelectGroups = null, private ?bool $usergroupSelectTeams = null, private ?bool $showUserStatus = null, + private ?string $customSettings = null, ) { } @@ -62,6 +63,7 @@ public static function createFromArray(array $data): self { usergroupSelectGroups: $data['usergroupSelectGroups'] ?? null, usergroupSelectTeams: $data['usergroupSelectTeams'] ?? null, showUserStatus: $data['showUserStatus'] ?? null, + customSettings: $data['customSettings'] ?? null, ); } @@ -160,4 +162,8 @@ public function getUsergroupSelectTeams(): ?bool { public function getShowUserStatus(): ?bool { return $this->showUserStatus; } + + public function getCustomSettings(): ?string { + return $this->customSettings; + } } diff --git a/lib/Migration/Version001000Date20250720000000.php b/lib/Migration/Version001000Date20250720000000.php new file mode 100644 index 0000000000..883ad7c92d --- /dev/null +++ b/lib/Migration/Version001000Date20250720000000.php @@ -0,0 +1,40 @@ +getTable('tables_columns'); + if (!$table->hasColumn('custom_settings')) { + $table->addColumn('custom_settings', Types::JSON, [ + 'notnull' => false, + ]); + } + + return $schema; + } +} diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 1d2e64947e..8b2ce56928 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -137,6 +137,9 @@ * order: int, * readonly: bool, * }, + * customSettings: ?array{ + * width: int, + * }, * } * * @psalm-type TablesImportState = array{ diff --git a/lib/Service/ColumnService.php b/lib/Service/ColumnService.php index 3001d2d6d8..ed4707c7d7 100644 --- a/lib/Service/ColumnService.php +++ b/lib/Service/ColumnService.php @@ -336,6 +336,7 @@ public function update( $item->setUsergroupSelectGroups($columnDto->getUsergroupSelectGroups()); $item->setUsergroupSelectTeams($columnDto->getUsergroupSelectTeams()); $item->setShowUserStatus($columnDto->getShowUserStatus()); + $item->setCustomSettings($columnDto->getCustomSettings()); $this->updateMetadata($item, $userId); return $this->enhanceColumn($this->mapper->update($item)); diff --git a/openapi.json b/openapi.json index 273954189a..e280c51cb2 100644 --- a/openapi.json +++ b/openapi.json @@ -102,7 +102,8 @@ "usergroupSelectGroups", "usergroupSelectTeams", "showUserStatus", - "viewColumnInformation" + "viewColumnInformation", + "customSettings" ], "properties": { "id": { @@ -227,6 +228,19 @@ "type": "boolean" } } + }, + "customSettings": { + "type": "object", + "nullable": true, + "required": [ + "width" + ], + "properties": { + "width": { + "type": "integer", + "format": "int64" + } + } } } }, @@ -3488,6 +3502,14 @@ "type": "integer", "format": "int64" } + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } @@ -3891,6 +3913,14 @@ "type": "integer", "format": "int64" } + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } @@ -4124,6 +4154,14 @@ "type": "boolean", "nullable": true, "description": "Whether to show the user's status, if column type is usergroup" + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } @@ -8135,6 +8173,14 @@ "view" ], "description": "Context type of the column creation" + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } @@ -8431,6 +8477,14 @@ "view" ], "description": "Context type of the column creation" + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } @@ -8715,6 +8769,14 @@ "view" ], "description": "Context type of the column creation" + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } @@ -8998,6 +9060,14 @@ "view" ], "description": "Context type of the column creation" + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } @@ -9291,6 +9361,14 @@ "view" ], "description": "Context type of the column creation" + }, + "customSettings": { + "type": "object", + "default": {}, + "description": "Custom settings for the column", + "additionalProperties": { + "type": "object" + } } } } diff --git a/src/modules/modals/CreateColumn.vue b/src/modules/modals/CreateColumn.vue index af607f7ffc..91c70d8a17 100644 --- a/src/modules/modals/CreateColumn.vue +++ b/src/modules/modals/CreateColumn.vue @@ -13,8 +13,10 @@ + :title-missing-error="titleMissingError" + :width-invalid-error="widthInvalidError" />
@@ -114,6 +116,7 @@ import UsergroupForm from '../../shared/components/ncTable/partials/columnTypePa import { useTablesStore } from '../../store/store.js' import { useDataStore } from '../../store/data.js' import { mapActions } from 'pinia' +import { COLUMN_WIDTH_MAX, COLUMN_WIDTH_MIN } from '../../shared/constants.js' export default { name: 'CreateColumn', @@ -187,10 +190,12 @@ export default { usergroupSelectGroups: false, usergroupSelectTeams: false, showUserStatus: false, + customSettings: {}, }, textAppAvailable: !!window.OCA?.Text?.createEditor, addNewAfterSave: false, typeMissingError: false, + widthInvalidError: false, titleMissingError: false, typeOptions: [ { id: 'text', label: t('tables', 'Text') }, @@ -287,6 +292,10 @@ export default { if (!this.column.title) { showInfo(t('tables', 'Please insert a title for the new column.')) this.titleMissingError = true + } else if (this.column.customSettings?.width + && (this.column.customSettings?.width < COLUMN_WIDTH_MIN || this.column.customSettings?.width > COLUMN_WIDTH_MAX)) { + showError(t('tables', 'Cannot save column. Column width must be between {min} and {max}.', { min: COLUMN_WIDTH_MIN, max: COLUMN_WIDTH_MAX })) + this.widthInvalidError = true } else if (this.column.type === null) { this.titleMissingError = false showInfo(t('tables', 'You need to select a type for the new column.')) @@ -321,6 +330,7 @@ export default { mandatory: this.column.mandatory, viewId: this.isView ? this.element.id : null, tableId: !this.isView ? this.element.id : null, + customSettings: { width: this.column.customSettings.width }, } if (this.combinedType === ColumnTypes.TextLine) { data.textUnique = this.column.textUnique @@ -410,6 +420,7 @@ export default { usergroupSelectGroups: false, usergroupSelectTeams: false, showUserStatus: false, + customSettings: {}, } if (mainForm) { this.column.title = '' @@ -424,6 +435,7 @@ export default { this.column.selectedViews = [] } this.titleMissingError = false + this.widthInvalidError = false this.typeMissingError = false }, }, diff --git a/src/modules/modals/EditColumn.vue b/src/modules/modals/EditColumn.vue index c17e1882c9..e5981514a4 100644 --- a/src/modules/modals/EditColumn.vue +++ b/src/modules/modals/EditColumn.vue @@ -13,8 +13,10 @@ + :title-missing-error="editErrorTitle" + :width-invalid-error="widthInvalidError" />
@@ -68,6 +70,7 @@ import { ColumnTypes } from '../../shared/components/ncTable/mixins/columnHandle import moment from '@nextcloud/moment' import { mapActions } from 'pinia' import { useDataStore } from '../../store/data.js' +import { COLUMN_WIDTH_MAX, COLUMN_WIDTH_MIN } from '../../shared/constants.js' export default { name: 'EditColumn', @@ -119,9 +122,10 @@ export default { data() { return { loading: false, - editColumn: Object.assign({}, this.column), + editColumn: JSON.parse(JSON.stringify(this.column)), deleteId: null, editErrorTitle: false, + widthInvalidError: false, canSave: true, // used to avoid saving an incorrect config } }, @@ -166,7 +170,14 @@ export default { this.editErrorTitle = true return } - this.editErrorTitle = false + + if (this.editColumn.customSettings?.width + && (this.editColumn.customSettings?.width < COLUMN_WIDTH_MIN || this.editColumn.customSettings?.width > COLUMN_WIDTH_MAX)) { + showError(t('tables', 'Cannot save column. Column width must be between {min} and {max}.', { min: COLUMN_WIDTH_MIN, max: COLUMN_WIDTH_MAX })) + this.widthInvalidError = true + return + } + await this.updateLocalColumn() this.reset() this.$emit('close') @@ -176,6 +187,7 @@ export default { this.editColumn = null this.deleteId = null this.editErrorTitle = false + this.widthInvalidError = false }, async updateLocalColumn() { const data = Object.assign({}, this.editColumn) @@ -191,6 +203,7 @@ export default { delete data.createdBy delete data.lastEditAt delete data.lastEditBy + data.customSettings = { width: data.customSettings.width } console.debug('this column data will be send', data) const res = await this.updateColumn({ id: this.editColumn.id, diff --git a/src/shared/components/ncTable/mixins/columnClass.js b/src/shared/components/ncTable/mixins/columnClass.js index 51651131c8..87604acb69 100644 --- a/src/shared/components/ncTable/mixins/columnClass.js +++ b/src/shared/components/ncTable/mixins/columnClass.js @@ -22,6 +22,7 @@ export class AbstractColumn { this.createdByDisplayName = data.createdByDisplayName this.viewColumnInformation = data.viewColumnInformation this.lastEditByDisplayName = data.lastEditByDisplayName + this.customSettings = data.customSettings } canSort() { diff --git a/src/shared/components/ncTable/mixins/columnHandler.js b/src/shared/components/ncTable/mixins/columnHandler.js index 62f7181ef4..8bae9c213c 100644 --- a/src/shared/components/ncTable/mixins/columnHandler.js +++ b/src/shared/components/ncTable/mixins/columnHandler.js @@ -18,3 +18,9 @@ export const ColumnTypes = { Datetime: 'datetime', Usergroup: 'usergroup', } + +export function getColumnWidthStyle(column) { + const width = column.customSettings?.width ? `min(${column.customSettings.width}px, 90vw)` : null + + return width ? { width, maxWidth: width, minWidth: width } : null +} diff --git a/src/shared/components/ncTable/partials/TableHeader.vue b/src/shared/components/ncTable/partials/TableHeader.vue index 612847d851..86b0e5a80c 100644 --- a/src/shared/components/ncTable/partials/TableHeader.vue +++ b/src/shared/components/ncTable/partials/TableHeader.vue @@ -10,7 +10,7 @@
- +
@@ -48,6 +48,7 @@ import { NcCheckboxRadioSwitch } from '@nextcloud/vue' import TableHeaderColumnOptions from './TableHeaderColumnOptions.vue' import FilterLabel from './FilterLabel.vue' import { getFilterWithId } from '../mixins/filter.js' +import { getColumnWidthStyle } from '../mixins/columnHandler.js' export default { @@ -110,6 +111,7 @@ export default { methods: { getFilterWithId, + getColumnWidthStyle, updateOpenState(columnId) { this.openedColumnHeaderMenus[columnId] = !this.openedColumnHeaderMenus[columnId] this.openedColumnHeaderMenus = Object.assign({}, this.openedColumnHeaderMenus) @@ -140,6 +142,10 @@ export default { diff --git a/src/shared/components/ncTable/partials/columnTypePartials/forms/MainForm.vue b/src/shared/components/ncTable/partials/columnTypePartials/forms/MainForm.vue index 3856f0a751..030a878a1e 100644 --- a/src/shared/components/ncTable/partials/columnTypePartials/forms/MainForm.vue +++ b/src/shared/components/ncTable/partials/columnTypePartials/forms/MainForm.vue @@ -28,6 +28,20 @@
+ +
+ {{ t('tables', 'Column width') }} +
+
+ +
+
{{ t('tables', 'Add column to other views') }} @@ -63,6 +77,7 @@ import { NcCheckboxRadioSwitch, NcSelect } from '@nextcloud/vue' import { mapState } from 'pinia' import { translate as t } from '@nextcloud/l10n' import { useTablesStore } from '../../../../../../store/store.js' +import { COLUMN_WIDTH_MAX, COLUMN_WIDTH_MIN } from '../../../../../constants.js' export default { name: 'MainForm', @@ -91,10 +106,26 @@ export default { type: Boolean, default: false, }, + widthInvalidError: { + type: Boolean, + default: false, + }, editColumn: { type: Boolean, default: false, }, + customSettings: { + type: Object, + default() { + return {} + }, + }, + }, + data() { + return { + COLUMN_WIDTH_MIN, + COLUMN_WIDTH_MAX, + } }, computed: { ...mapState(useTablesStore, ['views', 'activeElement', 'isView']), @@ -116,6 +147,12 @@ export default { this.$emit('update:selectedViews', selectedViews) }, }, + localColumnWidth: { + get() { return this.customSettings?.width ?? null }, + set(width) { + this.$emit('update:customSettings', { ...this.customSettings, ...{ width } }) + }, + }, viewsForTable() { if (this.isView) { return this.views.filter(view => view.tableId === this.activeElement.tableId && view !== this.activeElement).filter(view => !this.localSelectedViews.includes(view)) @@ -137,3 +174,13 @@ export default { }, } + + diff --git a/src/shared/components/ncTable/sections/CustomTable.vue b/src/shared/components/ncTable/sections/CustomTable.vue index 000c0a42bf..d1d345a1d4 100644 --- a/src/shared/components/ncTable/sections/CustomTable.vue +++ b/src/shared/components/ncTable/sections/CustomTable.vue @@ -408,7 +408,6 @@ export default {