Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bulk-import): adding sorting based on column in /imports #178

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions workspaces/bulk-import/.changeset/four-buses-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@red-hat-developer-hub/backstage-plugin-bulk-import-backend': patch
'@red-hat-developer-hub/backstage-plugin-bulk-import': patch
---

Sort based on column name

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,21 @@ declare namespace Components {
export type SizePerIntegrationQueryParam = number;
export type SizePerIntegrationQueryParamDeprecated = number;
export type SizeQueryParam = number;
export type SortColumnQueryParam =
| 'repository.name'
| 'repository.organization'
| 'repository.url'
| 'lastUpdate'
| 'status'
| '';
export type SortOrderQueryParam = 'asc' | 'desc' | '';
}
export interface QueryParameters {
pagePerIntegrationQueryParam?: Parameters.PagePerIntegrationQueryParam;
sizePerIntegrationQueryParam?: Parameters.SizePerIntegrationQueryParam;
pagePerIntegrationQueryParamDeprecated?: Parameters.PagePerIntegrationQueryParamDeprecated;
sortColumnQueryParam?: Parameters.SortColumnQueryParam;
sortOrderQueryParam?: Parameters.SortOrderQueryParam;
sizePerIntegrationQueryParamDeprecated?: Parameters.SizePerIntegrationQueryParamDeprecated;
searchQueryParam?: Parameters.SearchQueryParam;
pageQueryParam?: Parameters.PageQueryParam;
Expand Down Expand Up @@ -328,17 +338,26 @@ declare namespace Paths {
export type Search = string;
export type Size = number;
export type SizePerIntegration = number;
export type SortColumn =
| 'repository.name'
| 'repository.organization'
| 'repository.url'
| 'lastUpdate'
| 'status'
| '';
export type SortOrder = 'asc' | 'desc' | '';
}
export interface QueryParameters {
pagePerIntegration?: Parameters.PagePerIntegration;
sizePerIntegration?: Parameters.SizePerIntegration;
page?: Parameters.Page;
size?: Parameters.Size;
sortOrder?: Parameters.SortOrder;
sortColumn?: Parameters.SortColumn;
search?: Parameters.Search;
}
namespace Responses {
export type $200 =
/* Import Job with source it originates from */
export type $200 = /* Import Job with source it originates from */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dzemanov Now CI is failing due to prettier issue

I got permission denied for making changes. Just remove this change and prettier should be fixed :).

| Components.Schemas.SourceImport[]
| /* Import Job List */ Components.Schemas.ImportJobListV2;
export type $500 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ const OPENAPI = `
{
"$ref": "#/components/parameters/sizeQueryParam"
},
{
"$ref": "#/components/parameters/sortOrderQueryParam"
},
{
"$ref": "#/components/parameters/sortColumnQueryParam"
},
{
"$ref": "#/components/parameters/searchQueryParam"
}
Expand Down Expand Up @@ -562,6 +568,38 @@ const OPENAPI = `
"default": 1
}
},
"sortColumnQueryParam": {
"in": "query",
"name": "sortColumn",
"description": "The allowed values for sorting columns:\\n- repository.name: Sort by repository name.\\n- repository.organization: Sort by organization URL.\\n- repository.url: Sort by repository URL.\\n- lastUpdate: Sort by the last time the catalog-info.yaml was updated.\\n- status: Sort by the status of the catalog-info.yaml.\\n",
"required": false,
"schema": {
"enum": [
"repository.name",
"repository.organization",
"repository.url",
"lastUpdate",
"status",
""
],
"default": "repository.name"
}
},
"sortOrderQueryParam": {
"in": "query",
"name": "sortOrder",
"description": "The order of sorting asc for ascending or desc for descending",
"required": false,
"schema": {
"type": "string",
"enum": [
"asc",
"desc",
""
],
"default": "asc"
}
},
"sizePerIntegrationQueryParamDeprecated": {
"in": "query",
"name": "sizePerIntegration",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
export * from './auth';
export * from './loggingUtils';
export * from './pagination';
export * from './utils';
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export function getNestedValue<T>(obj: T, path: string): any {
return path
.split('.')
.reduce(
(acc, key) =>
acc && (acc as Record<string, any>)[key]
? (acc as Record<string, any>)[key]
: undefined,
obj,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ paths:
- $ref: '#/components/parameters/sizePerIntegrationQueryParamDeprecated'
- $ref: '#/components/parameters/pageQueryParam'
- $ref: '#/components/parameters/sizeQueryParam'

- $ref: '#/components/parameters/sortOrderQueryParam'
- $ref: '#/components/parameters/sortColumnQueryParam'
- $ref: '#/components/parameters/searchQueryParam'

responses:
Expand Down Expand Up @@ -360,6 +361,40 @@ components:
schema:
type: integer
default: 1
sortColumnQueryParam:
in: query
name: sortColumn
description: |
The allowed values for sorting columns:
- `repository.name`: Sort by repository name.
- `repository.organization`: Sort by organization URL.
- `repository.url`: Sort by repository URL.
- `lastUpdate`: Sort by the last time the catalog-info.yaml was updated.
- `status`: Sort by the status of the catalog-info.yaml.
required: false
schema:
enum:
its-mitesh-kumar marked this conversation as resolved.
Show resolved Hide resolved
- repository.name
- repository.organization
- repository.url
- lastUpdate
- status
- ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- ''

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to support empty columnName .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to sort by empty column name? What does it mean sorting by empty column name?

default: repository.name

sortOrderQueryParam:
in: query
name: sortOrder
description: The order of sorting asc for ascending or desc for descending
required: false
schema:
type: string
enum:
- asc
- desc
- ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- ''

default: asc

sizePerIntegrationQueryParamDeprecated:
in: query
name: sizePerIntegration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Components } from '../../generated/openapi';

export const DefaultPageNumber = 1;
export const DefaultPageSize = 20;

export const DefaultSortColumn: Components.Parameters.SortColumnQueryParam =
'repository.name';
export const DefaultSortOrder: Components.Parameters.SortOrderQueryParam =
'asc';

export interface HandlerResponse<ResponseBody = any> {
statusCode: number;
responseBody?: ResponseBody;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,121 @@ describe('bulkimports.ts unit tests', () => {
}
expect(resp.responseBody).toEqual(expectedResponse);

// Unit test for sort if empty string is provided sorting should be based on name in asc order
resp = await findAllImports(
{
logger,
config,
githubApiService: mockGithubApiService,
catalogHttpClient: mockCatalogHttpClient,
},
{
apiVersion,
},
{
pageNumber: 1,
pageSize: 6,
sortColumn: '',
sortOrder: '',
},
);
const sortedNames =
apiVersion === 'v2'
? (
resp?.responseBody as {
imports: { repository: { name: any } }[];
}
)?.imports?.map(importObj => importObj.repository.name)
: (resp?.responseBody as { repository: { name: any } }[])?.map(
importObj => importObj.repository.name,
);
let expectedSortedArray = [
'my-repo-11',
'my-repo-123',
'my-repo-21',
'my-repo-22',
'my-repo-31',
'my-repo-32',
];
expect(sortedNames).toEqual(expectedSortedArray);

// sorting based on organization in asc order
resp = await findAllImports(
{
logger,
config,
githubApiService: mockGithubApiService,
catalogHttpClient: mockCatalogHttpClient,
},
{
apiVersion,
},
{
pageNumber: 1,
pageSize: 6,
sortColumn: 'repository.organization',
sortOrder: 'asc',
},
);

let sortedOrganization =
apiVersion === 'v2'
? (
resp?.responseBody as {
imports: { repository: { organization: any } }[];
}
)?.imports?.map(importObj => importObj.repository.organization)
: (
resp?.responseBody as { repository: { organization: any } }[]
)?.map(importObj => importObj.repository.organization);
expectedSortedArray = [
'my-org-1',
'my-org-2',
'my-org-2',
'my-org-3',
'my-org-3',
'my-user',
];
expect(sortedOrganization).toEqual(expectedSortedArray);
// sorting based on organization in desc order
resp = await findAllImports(
{
logger,
config,
githubApiService: mockGithubApiService,
catalogHttpClient: mockCatalogHttpClient,
},
{
apiVersion,
},
{
pageNumber: 1,
pageSize: 6,
sortColumn: 'repository.organization',
sortOrder: 'desc',
},
);

sortedOrganization =
apiVersion === 'v2'
? (
resp?.responseBody as {
imports: { repository: { organization: any } }[];
}
)?.imports?.map(importObj => importObj.repository.organization)
: (
resp?.responseBody as { repository: { organization: any } }[]
)?.map(importObj => importObj.repository.organization);
expectedSortedArray = [
'my-user',
'my-org-3',
'my-org-3',
'my-org-2',
'my-org-2',
'my-org-1',
];
expect(sortedOrganization).toEqual(expectedSortedArray);

// No data for this page
resp = await findAllImports(
{
Expand Down
Loading
Loading