From 232b63c21498d5e5d572cc205c654bfeb87e5d26 Mon Sep 17 00:00:00 2001 From: Cleopatra Enjeck M Date: Mon, 13 May 2024 17:40:45 +0100 Subject: [PATCH] feat: add new column for user and group to backend Signed-off-by: Cleopatra Enjeck M --- appinfo/routes.php | 1 + lib/Capabilities.php | 1 + lib/Controller/Api1Controller.php | 64 ++- lib/Controller/ApiColumnsController.php | 79 +++ lib/Controller/ColumnController.php | 47 +- lib/Db/Column.php | 45 ++ lib/Db/ColumnTypes/UsergroupColumnQB.php | 15 + lib/Db/LegacyRowMapper.php | 5 + lib/Db/RowCellUsergroup.php | 12 + lib/Db/RowCellUsergroupMapper.php | 34 ++ lib/Helper/ColumnsHelper.php | 3 +- .../Version000000Date20210921000000.php | 23 +- .../Version000700Date20230916000000.php | 4 + lib/ResponseDefinitions.php | 25 +- lib/Service/ColumnService.php | 44 +- lib/Service/ColumnTypes/UsergroupBusiness.php | 50 ++ lib/Service/TableTemplateService.php | 17 +- openapi.json | 522 +++++++++++++++++- src/types/openapi/openapi.ts | 128 ++++- 19 files changed, 1093 insertions(+), 26 deletions(-) create mode 100644 lib/Db/ColumnTypes/UsergroupColumnQB.php create mode 100644 lib/Db/RowCellUsergroup.php create mode 100644 lib/Db/RowCellUsergroupMapper.php create mode 100644 lib/Service/ColumnTypes/UsergroupBusiness.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 0dadf1058..0a127d929 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -128,6 +128,7 @@ ['name' => 'ApiColumns#createTextColumn', 'url' => '/api/2/columns/text', 'verb' => 'POST'], ['name' => 'ApiColumns#createSelectionColumn', 'url' => '/api/2/columns/selection', 'verb' => 'POST'], ['name' => 'ApiColumns#createDatetimeColumn', 'url' => '/api/2/columns/datetime', 'verb' => 'POST'], + ['name' => 'ApiColumns#createUsergroupColumn', 'url' => '/api/2/columns/usergroup', 'verb' => 'POST'], ['name' => 'ApiFavorite#create', 'url' => '/api/2/favorites/{nodeType}/{nodeId}', 'verb' => 'POST', 'requirements' => ['nodeType' => '(\d+)', 'nodeId' => '(\d+)']], ['name' => 'ApiFavorite#destroy', 'url' => '/api/2/favorites/{nodeType}/{nodeId}', 'verb' => 'DELETE', 'requirements' => ['nodeType' => '(\d+)', 'nodeId' => '(\d+)']], diff --git a/lib/Capabilities.php b/lib/Capabilities.php index f80adc6b5..f285da4be 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -80,6 +80,7 @@ public function getCapabilities(): array { 'datetime', 'datetime-date', 'datetime-time', + 'usergroup', ] ], ]; diff --git a/lib/Controller/Api1Controller.php b/lib/Controller/Api1Controller.php index 911845b79..d9d2d2a6d 100644 --- a/lib/Controller/Api1Controller.php +++ b/lib/Controller/Api1Controller.php @@ -710,7 +710,7 @@ public function indexViewColumns(int $viewId): DataResponse { * @param int|null $tableId Table ID * @param int|null $viewId View ID * @param string $title Title - * @param 'text'|'number'|'datetime'|'select' $type Column main type + * @param 'text'|'number'|'datetime'|'select'|'usergroup' $type Column main type * @param string|null $subtype Column sub type * @param bool $mandatory Is the column mandatory * @param string|null $description Description @@ -726,6 +726,11 @@ public function indexViewColumns(int $viewId): DataResponse { * @param string|null $selectionOptions Options for a selection (json array{id: int, label: string}) * @param string|null $selectionDefault Default option IDs for a selection (json int[]) * @param string|null $datetimeDefault Default value, if column is datetime + * @param string|null $usergroupDefault Default value, if column is usergroup (json array{id: string, icon: string, isUser: bool, displayName: string}) + * @param bool|null $usergroupMultipleItems Can select multiple users or/and groups, if column is usergroup + * @param bool|null $usergroupSelectUsers Can select users, if column type is usergroup + * @param bool|null $usergroupSelectGroups Can select groups, if column type is usergroup + * @param bool|null $showUserStatus Whether to show the user's status, if column type is usergroup * @param int[]|null $selectedViewIds View IDs where this column should be added to be presented * * @return DataResponse|DataResponse @@ -757,6 +762,13 @@ public function createColumn( ?string $selectionDefault = '', ?string $datetimeDefault = '', + + ?string $usergroupDefault = '', + ?bool $usergroupMultipleItems, + ?bool $usergroupSelectUsers, + ?bool $usergroupSelectGroups, + ?bool $showUserStatus, + ?array $selectedViewIds = [] ): DataResponse { try { @@ -785,6 +797,13 @@ public function createColumn( $selectionDefault, $datetimeDefault, + + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, + $selectedViewIds )->jsonSerialize()); } catch (PermissionError $e) { @@ -826,6 +845,11 @@ public function createColumn( * @param string|null $selectionOptions Options for a selection (json array{id: int, label: string}) * @param string|null $selectionDefault Default option IDs for a selection (json int[]) * @param string|null $datetimeDefault Default value, if column is datetime + * @param string|null $usergroupDefault Default value, if column is usergroup + * @param bool|null $usergroupMultipleItems Can select multiple users or/and groups, if column is usergroup + * @param bool|null $usergroupSelectUsers Can select users, if column type is usergroup + * @param bool|null $usergroupSelectGroups Can select groups, if column type is usergroup + * @param bool|null $showUserStatus Whether to show the user's status, if column type is usergroup * * @return DataResponse|DataResponse * @@ -852,7 +876,14 @@ public function updateColumn( ?string $selectionOptions, ?string $selectionDefault, - ?string $datetimeDefault + ?string $datetimeDefault, + + ?string $usergroupDefault, + ?bool $usergroupMultipleItems, + ?bool $usergroupSelectUsers, + ?bool $usergroupSelectGroups, + ?bool $showUserStatus, + ): DataResponse { try { $item = $this->columnService->update( @@ -878,7 +909,13 @@ public function updateColumn( $selectionOptions, $selectionDefault, - $datetimeDefault + $datetimeDefault, + + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, ); return new DataResponse($item->jsonSerialize()); } catch (InternalError $e) { @@ -1390,7 +1427,7 @@ public function createTableShare(int $tableId, string $receiver, string $receive * * @param int $tableId Table ID * @param string $title Title - * @param 'text'|'number'|'datetime'|'select' $type Column main type + * @param 'text'|'number'|'datetime'|'select'|'usergroup' $type Column main type * @param string|null $subtype Column sub type * @param bool $mandatory Is the column mandatory * @param string|null $description Description @@ -1406,6 +1443,11 @@ public function createTableShare(int $tableId, string $receiver, string $receive * @param string|null $selectionOptions Options for a selection (json array{id: int, label: string}) * @param string|null $selectionDefault Default option IDs for a selection (json int[]) * @param string|null $datetimeDefault Default value, if column is datetime + * @param string|null $usergroupDefault Default value, if column is usergroup + * @param bool|null $usergroupMultipleItems Can select multiple users or/and groups, if column is usergroup + * @param bool|null $usergroupSelectUsers Can select users, if column type is usergroup + * @param bool|null $usergroupSelectGroups Can select groups, if column type is usergroup + * @param bool|null $showUserStatus Whether to show the user's status, if column type is usergroup * @param int[]|null $selectedViewIds View IDs where this column should be added to be presented * * @return DataResponse|DataResponse @@ -1437,6 +1479,13 @@ public function createTableColumn( ?string $selectionDefault = '', ?string $datetimeDefault = '', + + ?string $usergroupDefault = '', + ?bool $usergroupMultipleItems, + ?bool $usergroupSelectUsers, + ?bool $usergroupSelectGroups, + ?bool $showUserStatus, + ?array $selectedViewIds = [] ): DataResponse { try { @@ -1465,6 +1514,13 @@ public function createTableColumn( $selectionDefault, $datetimeDefault, + + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, + $selectedViewIds ); return new DataResponse($item->jsonSerialize()); diff --git a/lib/Controller/ApiColumnsController.php b/lib/Controller/ApiColumnsController.php index 6e8c080d1..2cff5ef50 100644 --- a/lib/Controller/ApiColumnsController.php +++ b/lib/Controller/ApiColumnsController.php @@ -140,6 +140,11 @@ public function createNumberColumn(int $baseNodeId, string $title, ?float $numbe null, null, null, + null, + null, + null, + null, + null, $selectedViewIds ); return new DataResponse($column->jsonSerialize()); @@ -195,6 +200,11 @@ public function createTextColumn(int $baseNodeId, string $title, ?string $textDe null, null, null, + null, + null, + null, + null, + null, $selectedViewIds ); return new DataResponse($column->jsonSerialize()); @@ -249,6 +259,11 @@ public function createSelectionColumn(int $baseNodeId, string $title, string $se $selectionOptions, $selectionDefault, null, + null, + null, + null, + null, + null, $selectedViewIds ); return new DataResponse($column->jsonSerialize()); @@ -302,6 +317,70 @@ public function createDatetimeColumn(int $baseNodeId, string $title, ?string $da null, null, $datetimeDefault, + null, + null, + null, + null, + null, + $selectedViewIds + ); + return new DataResponse($column->jsonSerialize()); + } + + /** + * [api v2] Create new usergroup column + * + * @NoAdminRequired + * + * @param int $baseNodeId Context of the column creation + * @param string $title Title + * @param string|null $usergroupDefault Json array{id: string, isUser: bool, displayName: string}, eg [{"id": "admin", "isUser": true, "displayName": "admin"}, {"id": "user1", "isUser": true, "displayName": "user1"}] + * @param boolean $usergroupMultipleItems Whether you can select multiple users or/and groups + * @param boolean $usergroupSelectUsers Whether you can select users + * @param boolean $usergroupSelectGroups Whether you can select groups + * @param boolean $showUserStatus Whether to show the user's status + * @param string|null $description Description + * @param int[]|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 + * @return DataResponse|DataResponse + * + * 200: Column created + * 403: No permission + * 404: Not found + * @throws InternalError + * @throws NotFoundError + * @throws PermissionError + */ + public function createUsergroupColumn(int $baseNodeId, string $title, ?string $usergroupDefault, bool $usergroupMultipleItems = null, bool $usergroupSelectUsers = null, bool $usergroupSelectGroups = null, bool $showUserStatus = null, string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table'): DataResponse { + $tableId = $baseNodeType === 'table' ? $baseNodeId : null; + $viewId = $baseNodeType === 'view' ? $baseNodeId : null; + $column = $this->service->create( + $this->userId, + $tableId, + $viewId, + 'usergroup', + null, + $title, + $mandatory, + $description, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, $selectedViewIds ); return new DataResponse($column->jsonSerialize()); diff --git a/lib/Controller/ColumnController.php b/lib/Controller/ColumnController.php index 41f49aa4f..33e909451 100644 --- a/lib/Controller/ColumnController.php +++ b/lib/Controller/ColumnController.php @@ -92,6 +92,13 @@ public function create( ?string $selectionDefault, ?string $datetimeDefault, + + ?string $usergroupDefault, + ?bool $usergroupMultipleItems, + ?bool $usergroupSelectUsers, + ?bool $usergroupSelectGroups, + ?bool $showUserStatus, + ?array $selectedViewIds ): DataResponse { return $this->handleError(function () use ( @@ -118,6 +125,13 @@ public function create( $selectionDefault, $datetimeDefault, + + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, + $selectedViewIds) { return $this->service->create( $this->userId, @@ -144,6 +158,13 @@ public function create( $selectionDefault, $datetimeDefault, + + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, + $selectedViewIds); }); } @@ -174,7 +195,13 @@ public function update( ?string $selectionOptions, ?string $selectionDefault, - ?string $datetimeDefault + ?string $datetimeDefault, + + ?string $usergroupDefault, + ?bool $usergroupMultipleItems, + ?bool $usergroupSelectUsers, + ?bool $usergroupSelectGroups, + ?bool $showUserStatus, ): DataResponse { return $this->handleError(function () use ( $id, @@ -199,7 +226,14 @@ public function update( $selectionOptions, $selectionDefault, - $datetimeDefault + $datetimeDefault, + + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, + ) { return $this->service->update( $id, @@ -225,7 +259,14 @@ public function update( $selectionOptions, $selectionDefault, - $datetimeDefault); + $datetimeDefault, + + $usergroupDefault, + $usergroupMultipleItems, + $usergroupSelectUsers, + $usergroupSelectGroups, + $showUserStatus, + ); }); } diff --git a/lib/Db/Column.php b/lib/Db/Column.php index a59fd586b..5a408dc46 100644 --- a/lib/Db/Column.php +++ b/lib/Db/Column.php @@ -60,6 +60,16 @@ * @method setSelectionDefault(?string $selectionDefault) * @method getDatetimeDefault(): string * @method setDatetimeDefault(?string $datetimeDefault) + * @method getUsergroupDefault(): string + * @method setUsergroupDefault(?string $usergroupDefaultArray) + * @method getUsergroupMultipleItems(): bool + * @method setUsergroupMultipleItems(?bool $usergroupMultipleItems) + * @method getUsergroupSelectUsers(): bool + * @method setUsergroupSelectUsers(?bool $usergroupSelectUsers) + * @method getUsergroupSelectGroups(): bool + * @method setUsergroupSelectGroups(?bool $usergroupSelectGroups) + * @method getShowUserStatus(): bool + * @method setShowUserStatus(?bool $showUserStatus) */ class Column extends Entity implements JsonSerializable { // Meta column types @@ -73,6 +83,7 @@ class Column extends Entity implements JsonSerializable { public const TYPE_TEXT = 'text'; public const TYPE_NUMBER = 'number'; public const TYPE_DATETIME = 'datetime'; + public const TYPE_USERGROUP = 'usergroup'; protected ?string $title = null; protected ?int $tableId = null; @@ -108,6 +119,13 @@ class Column extends Entity implements JsonSerializable { // type datetime protected ?string $datetimeDefault = null; + // type usergroup + protected ?string $usergroupDefault = null; + protected ?bool $usergroupMultipleItems = null; + protected ?bool $usergroupSelectUsers = null; + protected ?bool $usergroupSelectGroups = null; + protected ?bool $showUserStatus = null; + public function __construct() { $this->addType('id', 'integer'); $this->addType('tableId', 'integer'); @@ -121,6 +139,26 @@ public function __construct() { // type text $this->addType('textMaxLength', 'integer'); + + // // type usergroup + $this->addType('usergroupMultipleItems', 'boolean'); + $this->addType('usergroupSelectUsers', 'boolean'); + $this->addType('usergroupSelectGroups', 'boolean'); + $this->addType('showUserStatus', 'boolean'); + } + + public function getUsergroupDefaultArray():array { + $default = $this->getUsergroupDefault(); + if ($default !== "" && $default !== null && $default !== 'null') { + return \json_decode($default, true); + } else { + return []; + } + } + + public function setUsergroupDefaultArray(array $array):void { + $json = \json_encode($array); + $this->setUsergroup($json); } public function getSelectionOptionsArray():array { @@ -175,6 +213,13 @@ public function jsonSerialize(): array { // type datetime 'datetimeDefault' => $this->datetimeDefault, + + // type usergroup + 'usergroupDefault' => $this->getUsergroupDefaultArray(), + 'usergroupMultipleItems' => $this->usergroupMultipleItems, + 'usergroupSelectUsers' => $this->usergroupSelectUsers, + 'usergroupSelectGroups' => $this->usergroupSelectGroups, + 'showUserStatus' => $this->showUserStatus, ]; } } diff --git a/lib/Db/ColumnTypes/UsergroupColumnQB.php b/lib/Db/ColumnTypes/UsergroupColumnQB.php new file mode 100644 index 000000000..faa2c6184 --- /dev/null +++ b/lib/Db/ColumnTypes/UsergroupColumnQB.php @@ -0,0 +1,15 @@ +setParameter($searchValuePlaceHolder, $unformattedSearchValue, IQueryBuilder::PARAM_STR); + } + } +} \ No newline at end of file diff --git a/lib/Db/LegacyRowMapper.php b/lib/Db/LegacyRowMapper.php index ae7b3996b..2738cfd21 100644 --- a/lib/Db/LegacyRowMapper.php +++ b/lib/Db/LegacyRowMapper.php @@ -8,6 +8,7 @@ use OCA\Tables\Db\ColumnTypes\SelectionColumnQB; use OCA\Tables\Db\ColumnTypes\SuperColumnQB; use OCA\Tables\Db\ColumnTypes\TextColumnQB; +use OCA\Tables\Db\ColumnTypes\UsergroupColumnQB; use OCA\Tables\Errors\InternalError; use OCA\Tables\Helper\UserHelper; use OCP\AppFramework\Db\DoesNotExistException; @@ -29,6 +30,7 @@ class LegacyRowMapper extends QBMapper { protected SelectionColumnQB $selectionColumnQB; protected NumberColumnQB $numberColumnQB; protected DatetimeColumnQB $datetimeColumnQB; + protected UsergroupColumnQB $usergroupColumnQB; protected SuperColumnQB $genericColumnQB; protected ColumnMapper $columnMapper; protected LoggerInterface $logger; @@ -44,6 +46,7 @@ public function __construct( SelectionColumnQB $selectionColumnQB, NumberColumnQB $numberColumnQB, DatetimeColumnQB $datetimeColumnQB, + UsergroupColumnQB $usergroupColumnQB, SuperColumnQB $columnQB, ColumnMapper $columnMapper, UserHelper $userHelper, @@ -54,6 +57,7 @@ public function __construct( $this->numberColumnQB = $numberColumnQB; $this->selectionColumnQB = $selectionColumnQB; $this->datetimeColumnQB = $datetimeColumnQB; + $this->usergroupColumnQB = $usergroupColumnQB; $this->genericColumnQB = $columnQB; $this->columnMapper = $columnMapper; $this->userHelper = $userHelper; @@ -74,6 +78,7 @@ private function setPlatform() { $this->numberColumnQB->setPlatform($this->platform); $this->selectionColumnQB->setPlatform($this->platform); $this->datetimeColumnQB->setPlatform($this->platform); + $this->usergroupColumnQB->setPlatform($this->platform); } /** diff --git a/lib/Db/RowCellUsergroup.php b/lib/Db/RowCellUsergroup.php new file mode 100644 index 000000000..0af3666c4 --- /dev/null +++ b/lib/Db/RowCellUsergroup.php @@ -0,0 +1,12 @@ + */ +class RowCellUsergroup extends RowCellSuper { + protected ?string $value = null; + + public function jsonSerialize(): array { + return parent::jsonSerializePreparation($this->value); + } +} \ No newline at end of file diff --git a/lib/Db/RowCellUsergroupMapper.php b/lib/Db/RowCellUsergroupMapper.php new file mode 100644 index 000000000..0ae14aea4 --- /dev/null +++ b/lib/Db/RowCellUsergroupMapper.php @@ -0,0 +1,34 @@ + */ +class RowCellUsergroupMapper extends RowCellMapperSuper +{ + protected string $table = 'tables_row_cells_usergroup'; + + public function __construct(IDBConnection $db) + { + parent::__construct($db, $this->table, RowCellUsergroup::class); + } + + /** + * @inheritDoc + */ + public function parseValueIncoming(Column $column, $value): string + { + // need to convert from array to string before saving + // TODO figure out whether to handle these conversions in the BE or FE; confusing to have both + return json_encode($value); + } + + /** + * @inheritDoc + */ + public function parseValueOutgoing(Column $column, $value) + { + return json_decode($value); + } +} \ No newline at end of file diff --git a/lib/Helper/ColumnsHelper.php b/lib/Helper/ColumnsHelper.php index 338ad07cd..8045422dc 100644 --- a/lib/Helper/ColumnsHelper.php +++ b/lib/Helper/ColumnsHelper.php @@ -8,6 +8,7 @@ class ColumnsHelper { 'text', 'number', 'datetime', - 'selection' + 'selection', + 'usergroup' ]; } diff --git a/lib/Migration/Version000000Date20210921000000.php b/lib/Migration/Version000000Date20210921000000.php index b8fc7013c..1f4879981 100644 --- a/lib/Migration/Version000000Date20210921000000.php +++ b/lib/Migration/Version000000Date20210921000000.php @@ -159,6 +159,27 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt 'notnull' => false, ]); + // type usergroup + $table->addColumn('usergroup_default', Types::TEXT, [ + 'notnull' => false, + ]); + $table->addColumn('usergroup_multiple_items', Types::BOOLEAN, [ + 'notnull' => false, + 'default' => 0, + ]); + $table->addColumn('usergroup_select_users', Types::BOOLEAN, [ + 'notnull' => false, + 'default' => 0, + ]); + $table->addColumn('usergroup_select_groups', Types::BOOLEAN, [ + 'notnull' => false, + 'default' => 0, + ]); + $table->addColumn('show_user_status', Types::BOOLEAN, [ + 'notnull' => false, + 'default' => 0, + ]); + $table->setPrimaryKey(['id']); } @@ -228,4 +249,4 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt return $schema; } -} +} \ No newline at end of file diff --git a/lib/Migration/Version000700Date20230916000000.php b/lib/Migration/Version000700Date20230916000000.php index b9e138c0f..e55f13fad 100644 --- a/lib/Migration/Version000700Date20230916000000.php +++ b/lib/Migration/Version000700Date20230916000000.php @@ -38,6 +38,10 @@ class Version000700Date20230916000000 extends SimpleMigrationStep { 'name' => 'selection', 'db_type' => Types::TEXT, ], + [ + 'name' => 'usergroup', + 'db_type' => Types::TEXT, + ], ]; /** diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 554c14940..a9dbbc9dc 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -108,16 +108,21 @@ * orderWeight: int, * numberDefault: float, * numberMin: float, - * numberMax: float, - * numberDecimals: int, - * numberPrefix: string, - * numberSuffix: string, - * textDefault: string, - * textAllowedPattern: string, - * textMaxLength: int, - * selectionOptions: string, - * selectionDefault: string, - * datetimeDefault: string, + * numberMax: float, + * numberDecimals: int, + * numberPrefix: string, + * numberSuffix: string, + * textDefault: string, + * textAllowedPattern: string, + * textMaxLength: int, + * selectionOptions: string, + * selectionDefault: string, + * datetimeDefault: string, + * usergroupDefault: string, + * usergroupMultipleItems: bool, + * usergroupSelectUsers: bool, + * usergroupSelectGroups: bool, + * showUserStatus: bool, * } * * @psalm-type TablesImportState = array{ diff --git a/lib/Service/ColumnService.php b/lib/Service/ColumnService.php index b65c3e532..be0543545 100644 --- a/lib/Service/ColumnService.php +++ b/lib/Service/ColumnService.php @@ -168,6 +168,11 @@ public function find(int $id, string $userId = null): Column { * @param string|null $selectionOptions * @param string|null $selectionDefault * @param string|null $datetimeDefault + * @param string|null $usergroupDefault + * @param bool|null $usergroupMultipleItems + * @param bool|null $usergroupSelectUsers + * @param bool|null $usergroupSelectGroups + * @param bool|null $showUserStatus * @param array $selectedViewIds * @return Column * @@ -199,6 +204,13 @@ public function create( ?string $selectionDefault, ?string $datetimeDefault, + + ?string $usergroupDefault, + ?bool $usergroupMultipleItems, + ?bool $usergroupSelectUsers, + ?bool $usergroupSelectGroups, + ?bool $showUserStatus, + array $selectedViewIds = [] ):Column { // security @@ -262,6 +274,11 @@ public function create( $item->setSelectionOptions($selectionOptions); $item->setSelectionDefault($selectionDefault); $item->setDatetimeDefault($datetimeDefault); + $item->setUsergroupDefault($usergroupDefault); + $item->setUsergroupMultipleItems($usergroupMultipleItems); + $item->setUsergroupSelectUsers($usergroupSelectUsers); + $item->setUsergroupSelectGroups($usergroupSelectGroups); + $item->setShowUserStatus($showUserStatus); try { $entity = $this->mapper->insert($item); @@ -312,6 +329,11 @@ public function create( * @param string|null $selectionOptions * @param string|null $selectionDefault * @param string|null $datetimeDefault + * @param string|null $usergroupDefault + * @param bool|null $usergroupMultipleItems + * @param bool|null $usergroupSelectUsers + * @param bool|null $usergroupSelectGroups + * @param bool|null $showUserStatus * @return Column * @throws InternalError */ @@ -338,7 +360,14 @@ public function update( ?string $selectionOptions, ?string $selectionDefault, - ?string $datetimeDefault + + ?string $datetimeDefault, + + ?string $usergroupDefault, + ?bool $usergroupMultipleItems, + ?bool $usergroupSelectUsers, + ?bool $usergroupSelectGroups, + ?bool $showUserStatus, ):Column { try { /** @var Column $item */ @@ -386,6 +415,14 @@ public function update( } $item->setDatetimeDefault($datetimeDefault); + if ($usergroupDefault !== null) { + $item->setUsergroupDefault($usergroupDefault); + } + $item->setUsergroupMultipleItems($usergroupMultipleItems); + $item->setUsergroupSelectUsers($usergroupSelectUsers); + $item->setUsergroupSelectGroups($usergroupSelectGroups); + $item->setShowUserStatus($showUserStatus); + $this->updateMetadata($item, $userId); return $this->enhanceColumn($this->mapper->update($item)); } catch (Exception $e) { @@ -544,6 +581,11 @@ public function findOrCreateColumnsByTitleForTableAsArray(?int $tableId, ?int $v null, $dataTypes[$i]['selection_default'] ?? null, null, + null, + null, + null, + null, + null, [] ); $countCreatedColumns++; diff --git a/lib/Service/ColumnTypes/UsergroupBusiness.php b/lib/Service/ColumnTypes/UsergroupBusiness.php new file mode 100644 index 000000000..389815876 --- /dev/null +++ b/lib/Service/ColumnTypes/UsergroupBusiness.php @@ -0,0 +1,50 @@ +logger->warning('No column given, but expected on '.__FUNCTION__.' within '.__CLASS__, ['exception' => new \Exception()]); + return json_encode([]); + } + + if($value === null) { + return json_encode([]); + } + + return json_encode($value); + } + + /** + * @param mixed $value array{id: string, isUser: bool, displayName: string} + * @param Column|null $column + * @return bool + */ + public function canBeParsed($value, ?Column $column = null): bool { + if(!$column) { + $this->logger->warning('No column given, but expected on '.__FUNCTION__.' within '.__CLASS__, ['exception' => new \Exception()]); + return false; + } + + if($value === null) { + return true; + } + + foreach ($value as $v) { + // TODO: maybe check if key exists first + if(!is_string($v['id']) && !is_string($v['displayName']) && !is_bool($v['isUser'])){ + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/lib/Service/TableTemplateService.php b/lib/Service/TableTemplateService.php index 9f3d2213b..ee2ebc842 100644 --- a/lib/Service/TableTemplateService.php +++ b/lib/Service/TableTemplateService.php @@ -853,6 +853,21 @@ private function createColumn(int $tableId, array $parameters): ?Column { // datetimeDefault (isset($parameters['datetimeDefault'])) ? $parameters['datetimeDefault'] : '', + // usergroupDefault + (isset($parameters['usergroupDefault'])) ? $parameters['usergroupDefault'] : '', + + // usergroupMultipleItems + (isset($parameters['usergroupMultipleItems'])) ? $parameters['usergroupMultipleItems'] : null, + + // usergroupSelectUsers + (isset($parameters['usergroupSelectUsers'])) ? $parameters['usergroupSelectUsers'] : null, + + // usergroupSelectGroups + (isset($parameters['usergroupSelectGroups'])) ? $parameters['usergroupSelectGroups'] : null, + + // showUserStatus + (isset($parameters['showUserStatus'])) ? $parameters['showUserStatus'] : null, + // additional view ids [] ); @@ -896,4 +911,4 @@ private function createView(Table $table, array $data): void { $this->logger->warning('Cannot create view, permission denied: '.$e->getMessage()); } } -} +} \ No newline at end of file diff --git a/openapi.json b/openapi.json index 659c19227..7c59923a7 100644 --- a/openapi.json +++ b/openapi.json @@ -90,7 +90,12 @@ "textMaxLength", "selectionOptions", "selectionDefault", - "datetimeDefault" + "datetimeDefault", + "usergroupDefault", + "usergroupMultipleItems", + "usergroupSelectUsers", + "usergroupSelectGroups", + "showUserStatus" ], "properties": { "id": { @@ -172,6 +177,21 @@ }, "datetimeDefault": { "type": "string" + }, + "usergroupDefault": { + "type": "string" + }, + "usergroupMultipleItems": { + "type": "boolean" + }, + "usergroupSelectUsers": { + "type": "boolean" + }, + "usergroupSelectGroups": { + "type": "boolean" + }, + "showUserStatus": { + "type": "boolean" } } }, @@ -2811,7 +2831,8 @@ "text", "number", "datetime", - "select" + "select", + "usergroup" ] } }, @@ -2962,6 +2983,68 @@ "default": "" } }, + { + "name": "usergroupDefault", + "in": "query", + "description": "Default value, if column is usergroup", + "schema": { + "type": "string", + "nullable": true, + "default": "" + } + }, + { + "name": "usergroupMultipleItems", + "in": "query", + "description": "Can select multiple users or/and groups, if column is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectUsers", + "in": "query", + "description": "Can select users, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectGroups", + "in": "query", + "description": "Can select groups, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "showUserStatus", + "in": "query", + "description": "Whether to show the user's status, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, { "name": "selectedViewIds[]", "in": "query", @@ -3203,7 +3286,8 @@ "text", "number", "datetime", - "select" + "select", + "usergroup" ] } }, @@ -3354,6 +3438,68 @@ "default": "" } }, + { + "name": "usergroupDefault", + "in": "query", + "description": "Default value, if column is usergroup (json array{id: string, icon: string, isUser: bool, displayName: string})", + "schema": { + "type": "string", + "nullable": true, + "default": "" + } + }, + { + "name": "usergroupMultipleItems", + "in": "query", + "description": "Can select multiple users or/and groups, if column is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectUsers", + "in": "query", + "description": "Can select users, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectGroups", + "in": "query", + "description": "Can select groups, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "showUserStatus", + "in": "query", + "description": "Whether to show the user's status, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, { "name": "selectedViewIds[]", "in": "query", @@ -3603,6 +3749,67 @@ "nullable": true } }, + { + "name": "usergroupDefault", + "in": "query", + "description": "Default value, if column is usergroup", + "schema": { + "type": "string", + "nullable": true + } + }, + { + "name": "usergroupMultipleItems", + "in": "query", + "description": "Can select multiple users or/and groups, if column is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectUsers", + "in": "query", + "description": "Can select users, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectGroups", + "in": "query", + "description": "Can select groups, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "showUserStatus", + "in": "query", + "description": "Whether to show the user's status, if column type is usergroup", + "schema": { + "type": "integer", + "nullable": true, + "enum": [ + 0, + 1 + ] + } + }, { "name": "columnId", "in": "path", @@ -7686,6 +7893,315 @@ } } }, + "/ocs/v2.php/apps/tables/api/2/columns/usergroup": { + "post": { + "operationId": "api_columns-create-usergroup-column", + "summary": "[api v2] Create new usergroup column", + "tags": [ + "api_columns" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "baseNodeId", + "in": "query", + "description": "Context of the column creation", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "title", + "in": "query", + "description": "Title", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "usergroupDefault", + "in": "query", + "description": "Json array{id: string, isUser: bool, displayName: string}, eg [{\"id\": \"admin\", \"isUser\": true, \"displayName\": \"admin\"}, {\"id\": \"user1\", \"isUser\": true, \"displayName\": \"user1\"}]", + "schema": { + "type": "string", + "nullable": true + } + }, + { + "name": "usergroupMultipleItems", + "in": "query", + "description": "Whether you can select multiple users or/and groups", + "schema": { + "type": "integer", + "default": 0, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectUsers", + "in": "query", + "description": "Whether you can select users", + "schema": { + "type": "integer", + "default": 0, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "usergroupSelectGroups", + "in": "query", + "description": "Whether you can select groups", + "schema": { + "type": "integer", + "default": 0, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "showUserStatus", + "in": "query", + "description": "Whether to show the user's status", + "schema": { + "type": "integer", + "default": 0, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "description", + "in": "query", + "description": "Description", + "schema": { + "type": "string", + "nullable": true + } + }, + { + "name": "selectedViewIds[]", + "in": "query", + "description": "View IDs where this columns should be added", + "schema": { + "type": "array", + "nullable": true, + "default": [], + "items": { + "type": "integer", + "format": "int64" + } + } + }, + { + "name": "mandatory", + "in": "query", + "description": "Is mandatory", + "schema": { + "type": "integer", + "default": 0, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "baseNodeType", + "in": "query", + "description": "Context type of the column creation", + "schema": { + "type": "string", + "default": "table", + "enum": [ + "table", + "view" + ] + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Column created", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Column" + } + } + } + } + } + } + } + }, + "403": { + "description": "No permission", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/apps/tables/api/2/favorites/{nodeType}/{nodeId}": { "post": { "operationId": "api_favorite-create", diff --git a/src/types/openapi/openapi.ts b/src/types/openapi/openapi.ts index ea2c07618..37da5719d 100644 --- a/src/types/openapi/openapi.ts +++ b/src/types/openapi/openapi.ts @@ -189,6 +189,10 @@ export type paths = { */ post: operations["api_columns-create-datetime-column"]; }; + "/ocs/v2.php/apps/tables/api/2/columns/usergroup": { + /** [api v2] Create new usergroup column */ + post: operations["api_columns-create-usergroup-column"]; + }; "/ocs/v2.php/apps/tables/api/2/favorites/{nodeType}/{nodeId}": { /** [api v2] Add a node (table or view) to user favorites */ post: operations["api_favorite-create"]; @@ -276,6 +280,11 @@ export type components = { selectionOptions: string; selectionDefault: string; datetimeDefault: string; + usergroupDefault: string; + usergroupMultipleItems: boolean; + usergroupSelectUsers: boolean; + usergroupSelectGroups: boolean; + showUserStatus: boolean; }; Context: { /** Format: int64 */ @@ -1233,7 +1242,7 @@ export type operations = { /** @description Title */ title: string; /** @description Column main type */ - type: "text" | "number" | "datetime" | "select"; + type: "text" | "number" | "datetime" | "select" | "usergroup"; /** @description Column sub type */ subtype?: string | null; /** @description Is the column mandatory */ @@ -1264,6 +1273,16 @@ export type operations = { selectionDefault?: string | null; /** @description Default value, if column is datetime */ datetimeDefault?: string | null; + /** @description Default value, if column is usergroup */ + usergroupDefault?: string | null; + /** @description Can select multiple users or/and groups, if column is usergroup */ + usergroupMultipleItems?: 0 | 1 | null; + /** @description Can select users, if column type is usergroup */ + usergroupSelectUsers?: 0 | 1 | null; + /** @description Can select groups, if column type is usergroup */ + usergroupSelectGroups?: 0 | 1 | null; + /** @description Whether to show the user's status, if column type is usergroup */ + showUserStatus?: 0 | 1 | null; /** @description View IDs where this column should be added to be presented */ "selectedViewIds[]"?: number[] | null; }; @@ -1355,7 +1374,7 @@ export type operations = { /** @description Title */ title: string; /** @description Column main type */ - type: "text" | "number" | "datetime" | "select"; + type: "text" | "number" | "datetime" | "select" | "usergroup"; /** @description Column sub type */ subtype?: string | null; /** @description Is the column mandatory */ @@ -1386,6 +1405,16 @@ export type operations = { selectionDefault?: string | null; /** @description Default value, if column is datetime */ datetimeDefault?: string | null; + /** @description Default value, if column is usergroup (json array{id: string, icon: string, isUser: bool, displayName: string}) */ + usergroupDefault?: string | null; + /** @description Can select multiple users or/and groups, if column is usergroup */ + usergroupMultipleItems?: 0 | 1 | null; + /** @description Can select users, if column type is usergroup */ + usergroupSelectUsers?: 0 | 1 | null; + /** @description Can select groups, if column type is usergroup */ + usergroupSelectGroups?: 0 | 1 | null; + /** @description Whether to show the user's status, if column type is usergroup */ + showUserStatus?: 0 | 1 | null; /** @description View IDs where this column should be added to be presented */ "selectedViewIds[]"?: number[] | null; }; @@ -1498,6 +1527,16 @@ export type operations = { selectionDefault?: string | null; /** @description Default value, if column is datetime */ datetimeDefault?: string | null; + /** @description Default value, if column is usergroup */ + usergroupDefault?: string | null; + /** @description Can select multiple users or/and groups, if column is usergroup */ + usergroupMultipleItems?: 0 | 1 | null; + /** @description Can select users, if column type is usergroup */ + usergroupSelectUsers?: 0 | 1 | null; + /** @description Can select groups, if column type is usergroup */ + usergroupSelectGroups?: 0 | 1 | null; + /** @description Whether to show the user's status, if column type is usergroup */ + showUserStatus?: 0 | 1 | null; }; path: { /** @description Column ID that will be updated */ @@ -2907,6 +2946,91 @@ export type operations = { }; }; }; + /** [api v2] Create new usergroup column */ + "api_columns-create-usergroup-column": { + parameters: { + query: { + /** @description Context of the column creation */ + baseNodeId: number; + /** @description Title */ + title: string; + /** @description Json array{id: string, isUser: bool, displayName: string}, eg [{"id": "admin", "isUser": true, "displayName": "admin"}, {"id": "user1", "isUser": true, "displayName": "user1"}] */ + usergroupDefault?: string | null; + /** @description Whether you can select multiple users or/and groups */ + usergroupMultipleItems?: 0 | 1; + /** @description Whether you can select users */ + usergroupSelectUsers?: 0 | 1; + /** @description Whether you can select groups */ + usergroupSelectGroups?: 0 | 1; + /** @description Whether to show the user's status */ + showUserStatus?: 0 | 1; + /** @description Description */ + description?: string | null; + /** @description View IDs where this columns should be added */ + "selectedViewIds[]"?: number[] | null; + /** @description Is mandatory */ + mandatory?: 0 | 1; + /** @description Context type of the column creation */ + baseNodeType?: "table" | "view"; + }; + header: { + /** @description Required to be true for the API request to pass */ + "OCS-APIRequest": boolean; + }; + }; + responses: { + /** @description Column created */ + 200: { + content: { + "application/json": { + ocs: { + meta: components["schemas"]["OCSMeta"]; + data: components["schemas"]["Column"]; + }; + }; + }; + }; + /** @description No permission */ + 403: { + content: { + "application/json": { + ocs: { + meta: components["schemas"]["OCSMeta"]; + data: { + message: string; + }; + }; + }; + }; + }; + /** @description Not found */ + 404: { + content: { + "application/json": { + ocs: { + meta: components["schemas"]["OCSMeta"]; + data: { + message: string; + }; + }; + }; + }; + }; + 500: { + content: { + "application/json": { + ocs: { + meta: components["schemas"]["OCSMeta"]; + data: { + message: string; + }; + }; + }; + "text/plain": string; + }; + }; + }; + }; /** [api v2] Add a node (table or view) to user favorites */ "api_favorite-create": { parameters: {