diff --git a/CHANGELOG.md b/CHANGELOG.md index ae9f0c23..f4ea2e22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased + +## [1.73.5] - 2025-12-17 +### Fixed +- USABILITY UI CleanUp: Group Filters - API improvements. Additional fixes[#613](https://github.com/rokwire/groups-building-block/issues/613) + ## [1.73.4] - 2025-12-17 ### Fixed - USABILITY UI CleanUp: Group Filters - API improvements. Additional fixes[#613](https://github.com/rokwire/groups-building-block/issues/613) diff --git a/core/model/filters.go b/core/model/filters.go index 64446bc0..91790812 100644 --- a/core/model/filters.go +++ b/core/model/filters.go @@ -17,29 +17,30 @@ type MembershipFilter struct { // GroupsFilter Wraps all possible filters for getting a group type GroupsFilter struct { - GroupIDs []string `json:"ids"` // membership id - MemberID *string `json:"member_id"` // member id - MemberUserID *string `json:"member_user_id"` // member user id - MemberExternalID *string `json:"member_external_id"` // member user external id - MemberStatus []string `json:"member_status"` // member user status - Title *string `json:"title"` // group title - Category *string `json:"category"` // group category - Privacy *string `json:"privacy"` // group privacy - Tags []string `json:"tags"` // group tags - IncludeHidden *bool `json:"include_hidden"` // Include hidden groups - Hidden *bool `json:"hidden"` // Filter by hidden flag. Values: true (show only hidden), false (show only not hidden), missing - don't do any filtering on this field. - ExcludeMyGroups *bool `json:"exclude_my_groups"` // Exclude My groups - AuthmanEnabled *bool `json:"authman_enabled"` - ResearchOpen *bool `json:"research_open"` - ResearchGroup *bool `json:"research_group"` - ResearchAnswers map[string]map[string][]string `json:"research_answers"` - Attributes map[string]interface{} `json:"attributes"` - Order *string `json:"order"` // order by category & name (asc desc) - Offset *int64 `json:"offset"` // result offset - Limit *int64 `json:"limit"` // result limit - LimitID *string `json:"limit_id"` // limit id - DaysInactive *int64 `json:"days_inactive"` - Administrative *bool `json:"administrative"` + GroupIDs []string `json:"ids"` // membership id + MemberID *string `json:"member_id"` // member id + MemberUserID *string `json:"member_user_id"` // member user id + MemberExternalID *string `json:"member_external_id"` // member user external id + MemberStatus []string `json:"member_status"` // member user status + Title *string `json:"title"` // group title + Category *string `json:"category"` // group category + Privacy *string `json:"privacy"` // group privacy + Tags []string `json:"tags"` // group tags + IncludeHidden *bool `json:"include_hidden"` // Include hidden groups + Hidden *bool `json:"hidden"` // Filter by hidden flag. Values: true (show only hidden), false (show only not hidden), missing - don't do any filtering on this field. + ExcludeMyGroups *bool `json:"exclude_my_groups"` // Exclude My groups + AuthmanEnabled *bool `json:"authman_enabled"` + ResearchOpen *bool `json:"research_open"` + ResearchGroup *bool `json:"research_group"` + ResearchAnswers map[string]map[string][]string `json:"research_answers"` + Attributes map[string]interface{} `json:"attributes"` + Order *string `json:"order"` // order by category & name (asc desc) + Offset *int64 `json:"offset"` // result offset + Limit *int64 `json:"limit"` // result limit + LimitID *string `json:"limit_id"` // limit id + LimitIDExtraRecords *int64 `json:"limit_id_extra_records"` // limit id number of extra records, default 0 + DaysInactive *int64 `json:"days_inactive"` + Administrative *bool `json:"administrative"` } // @name GroupsFilter // PostsFilter Wraps all possible filters for getting group post call diff --git a/docs/docs.go b/docs/docs.go index 8389dfd1..2c69c36d 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -4532,6 +4532,168 @@ const docTemplate = `{ } } }, + "/api/v2/groups": { + "get": { + "security": [ + { + "AppUserAuth": [] + } + ], + "description": "Gives the groups list. It can be filtered by category, title and privacy. V2", + "consumes": [ + "application/json" + ], + "tags": [ + "Client" + ], + "operationId": "GetGroupsV2", + "parameters": [ + { + "type": "string", + "description": "APP", + "name": "APP", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! Filtering by group's title (case-insensitive)", + "name": "title", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! category - filter by category", + "name": "category", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! privacy - filter by privacy", + "name": "privacy", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! offset - skip number of records", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! limit - limit the result", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! include_hidden - Includes hidden groups if a search by title is performed. Possible value is true. Default false.", + "name": "include_hidden", + "in": "query" + }, + { + "description": "body data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/GroupsFilter" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Group" + } + } + } + } + }, + "post": { + "security": [ + { + "AppUserAuth": [] + } + ], + "description": "Gives the groups list. It can be filtered by category, title and privacy. V2", + "consumes": [ + "application/json" + ], + "tags": [ + "Client" + ], + "operationId": "GetGroupsV2", + "parameters": [ + { + "type": "string", + "description": "APP", + "name": "APP", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! Filtering by group's title (case-insensitive)", + "name": "title", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! category - filter by category", + "name": "category", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! privacy - filter by privacy", + "name": "privacy", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! offset - skip number of records", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! limit - limit the result", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! include_hidden - Includes hidden groups if a search by title is performed. Possible value is true. Default false.", + "name": "include_hidden", + "in": "query" + }, + { + "description": "body data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/GroupsFilter" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Group" + } + } + } + } + } + }, "/api/v2/groups/{id}": { "get": { "security": [ @@ -5430,6 +5592,10 @@ const docTemplate = `{ "description": "limit id", "type": "string" }, + "limit_id_extra_records": { + "description": "limit id number of extra records, default 0", + "type": "integer" + }, "member_external_id": { "description": "member user external id", "type": "string" @@ -5438,7 +5604,7 @@ const docTemplate = `{ "description": "member id", "type": "string" }, - "member_statuses": { + "member_status": { "description": "member user status", "type": "array", "items": { diff --git a/docs/swagger.json b/docs/swagger.json index 1dda218d..df8ec4d5 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -4529,6 +4529,168 @@ } } }, + "/api/v2/groups": { + "get": { + "security": [ + { + "AppUserAuth": [] + } + ], + "description": "Gives the groups list. It can be filtered by category, title and privacy. V2", + "consumes": [ + "application/json" + ], + "tags": [ + "Client" + ], + "operationId": "GetGroupsV2", + "parameters": [ + { + "type": "string", + "description": "APP", + "name": "APP", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! Filtering by group's title (case-insensitive)", + "name": "title", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! category - filter by category", + "name": "category", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! privacy - filter by privacy", + "name": "privacy", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! offset - skip number of records", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! limit - limit the result", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! include_hidden - Includes hidden groups if a search by title is performed. Possible value is true. Default false.", + "name": "include_hidden", + "in": "query" + }, + { + "description": "body data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/GroupsFilter" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Group" + } + } + } + } + }, + "post": { + "security": [ + { + "AppUserAuth": [] + } + ], + "description": "Gives the groups list. It can be filtered by category, title and privacy. V2", + "consumes": [ + "application/json" + ], + "tags": [ + "Client" + ], + "operationId": "GetGroupsV2", + "parameters": [ + { + "type": "string", + "description": "APP", + "name": "APP", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! Filtering by group's title (case-insensitive)", + "name": "title", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! category - filter by category", + "name": "category", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! privacy - filter by privacy", + "name": "privacy", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! offset - skip number of records", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! limit - limit the result", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Deprecated - instead use request body filter! include_hidden - Includes hidden groups if a search by title is performed. Possible value is true. Default false.", + "name": "include_hidden", + "in": "query" + }, + { + "description": "body data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/GroupsFilter" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Group" + } + } + } + } + } + }, "/api/v2/groups/{id}": { "get": { "security": [ @@ -5427,6 +5589,10 @@ "description": "limit id", "type": "string" }, + "limit_id_extra_records": { + "description": "limit id number of extra records, default 0", + "type": "integer" + }, "member_external_id": { "description": "member user external id", "type": "string" @@ -5435,7 +5601,7 @@ "description": "member id", "type": "string" }, - "member_statuses": { + "member_status": { "description": "member user status", "type": "array", "items": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 7022e8c9..f31c82ac 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -287,13 +287,16 @@ definitions: limit_id: description: limit id type: string + limit_id_extra_records: + description: limit id number of extra records, default 0 + type: integer member_external_id: description: member user external id type: string member_id: description: member id type: string - member_statuses: + member_status: description: member user status items: type: string @@ -4154,6 +4157,127 @@ paths: - AppUserAuth: [] tags: - Client + /api/v2/groups: + get: + consumes: + - application/json + description: Gives the groups list. It can be filtered by category, title and + privacy. V2 + operationId: GetGroupsV2 + parameters: + - description: APP + in: header + name: APP + required: true + type: string + - description: Deprecated - instead use request body filter! Filtering by group's + title (case-insensitive) + in: query + name: title + type: string + - description: Deprecated - instead use request body filter! category - filter + by category + in: query + name: category + type: string + - description: Deprecated - instead use request body filter! privacy - filter + by privacy + in: query + name: privacy + type: string + - description: Deprecated - instead use request body filter! offset - skip number + of records + in: query + name: offset + type: string + - description: Deprecated - instead use request body filter! limit - limit the + result + in: query + name: limit + type: string + - description: Deprecated - instead use request body filter! include_hidden + - Includes hidden groups if a search by title is performed. Possible value + is true. Default false. + in: query + name: include_hidden + type: string + - description: body data + in: body + name: data + required: true + schema: + $ref: '#/definitions/GroupsFilter' + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/Group' + type: array + security: + - AppUserAuth: [] + tags: + - Client + post: + consumes: + - application/json + description: Gives the groups list. It can be filtered by category, title and + privacy. V2 + operationId: GetGroupsV2 + parameters: + - description: APP + in: header + name: APP + required: true + type: string + - description: Deprecated - instead use request body filter! Filtering by group's + title (case-insensitive) + in: query + name: title + type: string + - description: Deprecated - instead use request body filter! category - filter + by category + in: query + name: category + type: string + - description: Deprecated - instead use request body filter! privacy - filter + by privacy + in: query + name: privacy + type: string + - description: Deprecated - instead use request body filter! offset - skip number + of records + in: query + name: offset + type: string + - description: Deprecated - instead use request body filter! limit - limit the + result + in: query + name: limit + type: string + - description: Deprecated - instead use request body filter! include_hidden + - Includes hidden groups if a search by title is performed. Possible value + is true. Default false. + in: query + name: include_hidden + type: string + - description: body data + in: body + name: data + required: true + schema: + $ref: '#/definitions/GroupsFilter' + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/Group' + type: array + security: + - AppUserAuth: [] + tags: + - Client /api/v2/groups/{id}: get: consumes: diff --git a/driven/storage/adapter.go b/driven/storage/adapter.go index 554823f8..c304e503 100644 --- a/driven/storage/adapter.go +++ b/driven/storage/adapter.go @@ -714,8 +714,12 @@ func (sa *Adapter) FindGroups(clientID string, userID *string, groupsFilter mode } if groupsFilter.Limit != nil { if limitIDRowNumber > 0 { + var extraRecords int64 = 0 + if groupsFilter.LimitIDExtraRecords != nil { + extraRecords = *groupsFilter.LimitIDExtraRecords + } // Hardcoded for now... 5 extra rows to ensure we get enough results after the limitID offset. - limitIDRowNumber = int64(math.Max(float64(limitIDRowNumber+5), float64(*groupsFilter.Limit))) + limitIDRowNumber = int64(math.Max(float64(limitIDRowNumber+extraRecords), float64(*groupsFilter.Limit))) pipeline = append(pipeline, bson.D{{Key: "$limit", Value: int64(limitIDRowNumber)}}) } else { pipeline = append(pipeline, bson.D{{Key: "$limit", Value: *groupsFilter.Limit}})