Skip to content

Commit 1602b5c

Browse files
committed
fix: fix tags API not returning all tags needed in various places
1 parent afeea1c commit 1602b5c

7 files changed

Lines changed: 27 additions & 84 deletions

File tree

app/controllers/api/v1/tags_controller.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ def index
77
return
88
end
99

10-
page = parse_page(params[:page])
11-
per_page = parse_per_page(params[:per_page])
12-
1310
tags = project.tags
1411
if params[:search]
1512
tags = project.tags.where('name ilike :search', search: "%#{params[:search]}%")
@@ -18,8 +15,7 @@ def index
1815
options = {}
1916
options[:meta] = { total: project.tags.size }
2017
options[:include] = []
21-
render json:
22-
TagSerializer.new(tags.order('name ASC').offset(page * per_page).limit(per_page), options).serialized_json
18+
render json: TagSerializer.new(tags.order('name ASC'), options).serialized_json
2319
end
2420

2521
def create

app/javascript/components/api/v1/TagsAPI.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ export interface ITag {
1919

2020
export interface IGetTagsOptions {
2121
projectId: string;
22-
search?: string;
23-
page?: number;
24-
perPage?: number;
22+
search: string | null;
2523
}
2624

2725
export interface IGetTagsResponse {

app/javascript/components/ui/TagsTable.tsx

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import { IGetTagsResponse, ITag, TagsAPI } from "../api/v1/TagsAPI";
77
import { TagFormModal } from "../forms/TagFormModal";
88
import { dashboardStore } from "../stores/DashboardStore";
99
import { PermissionUtils } from "../utilities/PermissionUtils";
10-
import { DEFAULT_PAGE_SIZE, PAGE_SIZE_OPTIONS } from "./Config";
11-
import { DeleteLink } from "./DeleteLink";
10+
import { PAGE_SIZE_OPTIONS } from "./Config";
1211

1312
type DATA_INDEX = "name" | "controls";
1413

@@ -23,32 +22,22 @@ type IRow = {
2322
[k in DATA_INDEX]: React.ReactNode;
2423
};
2524

26-
interface IReloadOptions {
27-
search?: string;
28-
page?: number;
29-
perPage?: number;
30-
}
31-
3225
export function TagsTable(props: { project: IProject; tableReloader?: number; style?: React.CSSProperties }) {
3326
const params = useParams<{ projectId: string }>();
3427

35-
const [page, setPage] = React.useState<number>(1);
36-
const [perPage, setPerPage] = React.useState<number>(DEFAULT_PAGE_SIZE);
37-
const [search, setSearch] = React.useState<string>(null);
38-
const [tagsResponse, setTagsResponse] = React.useState<IGetTagsResponse>(null);
28+
const [search, setSearch] = React.useState<string | null>(null);
29+
const [tagsResponse, setTagsResponse] = React.useState<IGetTagsResponse | null>(null);
3930
const [loading, setLoading] = React.useState<boolean>(false);
4031
const [tagDialogVisible, setTagDialogVisible] = React.useState<boolean>(false);
41-
const [tagToEdit, setTagToEdit] = React.useState<ITag>(null);
32+
const [tagToEdit, setTagToEdit] = React.useState<ITag | null>(null);
4233

43-
async function reload(options?: IReloadOptions) {
34+
async function reload(options?: { search?: string }) {
4435
setLoading(true);
4536

4637
try {
4738
const response = await TagsAPI.getTags({
4839
projectId: params.projectId,
49-
search: options?.search || search,
50-
page: options?.page || page,
51-
perPage: options?.perPage || perPage
40+
search: options?.search || search
5241
});
5342
setTagsResponse(response);
5443
} catch (error) {
@@ -61,7 +50,7 @@ export function TagsTable(props: { project: IProject; tableReloader?: number; st
6150

6251
const debouncedSearch = React.useCallback(
6352
_.debounce((value: string) => {
64-
reload({ search: value, page: 1 });
53+
reload({ search: value });
6554
}, 500),
6655
[]
6756
);
@@ -117,8 +106,7 @@ export function TagsTable(props: { project: IProject; tableReloader?: number; st
117106
}
118107

119108
setLoading(false);
120-
setPage(1);
121-
await reload({ page: 1 });
109+
await reload();
122110
}
123111
});
124112
}}
@@ -190,21 +178,7 @@ export function TagsTable(props: { project: IProject; tableReloader?: number; st
190178
pagination={{
191179
pageSizeOptions: PAGE_SIZE_OPTIONS,
192180
showSizeChanger: true,
193-
current: page,
194-
pageSize: perPage,
195-
total: tagsResponse?.meta?.total || 0,
196-
onChange: async (newPage, newPerPage) => {
197-
const isPageSizeChange = perPage !== newPerPage;
198-
199-
if (isPageSizeChange) {
200-
setPage(1);
201-
setPerPage(newPerPage);
202-
reload({ page: 1, perPage: newPerPage });
203-
} else {
204-
setPage(newPage);
205-
reload({ page: newPage });
206-
}
207-
}
181+
total: tagsResponse?.meta?.total || 0
208182
}}
209183
locale={{
210184
emptyText: <Empty description="No tags found" image={Empty.PRESENTED_IMAGE_SIMPLE} />
@@ -219,7 +193,7 @@ export function TagsTable(props: { project: IProject; tableReloader?: number; st
219193
}}
220194
formProps={{
221195
projectId: params.projectId,
222-
tag: tagToEdit,
196+
tag: tagToEdit ?? undefined,
223197
onSaved: async () => {
224198
setTagDialogVisible(false);
225199
setTagToEdit(null);

spec/requests/api/v1/__snapshots__/tags_controller_index_paginated_1.snap renamed to spec/requests/api/v1/__snapshots__/tags_controller_index.snap

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@
2121
"project_id" => "__REMOVED__",
2222
"disable_translation_for_translators" => false
2323
}
24+
},
25+
[2] {
26+
"id" => "__REMOVED__",
27+
"type" => "tag",
28+
"attributes" => {
29+
"id" => "__REMOVED__",
30+
"name" => "tag_3",
31+
"custom" => false,
32+
"project_id" => "__REMOVED__",
33+
"disable_translation_for_translators" => false
34+
}
2435
}
2536
],
2637
"meta" => {

spec/requests/api/v1/__snapshots__/tags_controller_index_paginated_2.snap

Lines changed: 0 additions & 18 deletions
This file was deleted.

spec/requests/api/v1/__snapshots__/tags_controller_index_paginated_3.snap

Lines changed: 0 additions & 6 deletions
This file was deleted.

spec/requests/api/v1/tags_controller_spec.rb

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,16 @@
2828
expect(body['meta']['total']).to eq(0)
2929
end
3030

31-
it 'has status code 200 and returns data paginated' do
31+
it 'has status code 200 and returns data' do
3232
create(:tag, project_id: @project.id)
3333
create(:tag, project_id: @project.id)
3434
create(:tag, project_id: @project.id)
35-
get "/api/v1/projects/#{@project.id}/tags", headers: @auth_params, params: { per_page: 2 }
35+
get "/api/v1/projects/#{@project.id}/tags", headers: @auth_params
3636
expect(response).to have_http_status(:ok)
3737
body = JSON.parse(response.body)
38-
expect(body['data'].length).to eq(2)
39-
expect(body['meta']['total']).to eq(3)
40-
expect(body).to match_snapshot('tags_controller_index_paginated_1', { snapshot_serializer: StripSerializer })
41-
42-
get "/api/v1/projects/#{@project.id}/tags", headers: @auth_params, params: { per_page: 2, page: 2 }
43-
body = JSON.parse(response.body)
44-
expect(body['data'].length).to eq(1)
45-
expect(body['meta']['total']).to eq(3)
46-
expect(body).to match_snapshot('tags_controller_index_paginated_2', { snapshot_serializer: StripSerializer })
47-
48-
get "/api/v1/projects/#{@project.id}/tags", headers: @auth_params, params: { per_page: 2, page: 3 }
49-
body = JSON.parse(response.body)
50-
expect(body['data'].length).to eq(0)
38+
expect(body['data'].length).to eq(3)
5139
expect(body['meta']['total']).to eq(3)
52-
expect(body).to match_snapshot('tags_controller_index_paginated_3', { snapshot_serializer: StripSerializer })
40+
expect(body).to match_snapshot('tags_controller_index', { snapshot_serializer: StripSerializer })
5341
end
5442
end
5543

0 commit comments

Comments
 (0)