From 80e14e97d72d77b1caed8798d8da46d81a8acc73 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:58:09 +0800 Subject: [PATCH] refactor: optimize old attachment query parameters using index (#5363) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.13.x #### What this PR does / why we need it: 使用索引功能优化附件列表查询 #### Does this PR introduce a user-facing change? ```release-note 使用索引功能优化附件列表查询 ``` --- .../halo/app/extension/index/query/Not.java | 27 +++ .../extension/index/query/QueryFactory.java | 4 + .../index/query/QueryFactoryTest.java | 10 ++ .../endpoint/AttachmentEndpoint.java | 167 +++++------------- .../run/halo/app/infra/SchemeInitializer.java | 34 +++- .../endpoint/AttachmentEndpointTest.java | 72 +------- .../contents/attachments/AttachmentList.vue | 8 +- .../components/AttachmentGroupList.vue | 4 +- .../components/AttachmentPoliciesModal.vue | 2 +- .../attachments/composables/use-attachment.ts | 28 ++- ...onsole-halo-run-v1alpha1-attachment-api.ts | 76 ++------ 11 files changed, 169 insertions(+), 263 deletions(-) create mode 100644 api/src/main/java/run/halo/app/extension/index/query/Not.java diff --git a/api/src/main/java/run/halo/app/extension/index/query/Not.java b/api/src/main/java/run/halo/app/extension/index/query/Not.java new file mode 100644 index 0000000000..908507ff9c --- /dev/null +++ b/api/src/main/java/run/halo/app/extension/index/query/Not.java @@ -0,0 +1,27 @@ +package run.halo.app.extension.index.query; + +import static java.util.Objects.requireNonNull; + +import java.util.Collections; +import java.util.NavigableSet; +import lombok.Getter; + +@Getter +public class Not extends LogicalQuery { + + private final Query negatedQuery; + + public Not(Query negatedQuery) { + super(Collections.singleton( + requireNonNull(negatedQuery, "The negated query must not be null."))); + this.negatedQuery = negatedQuery; + } + + @Override + public NavigableSet matches(QueryIndexView indexView) { + var negatedResult = negatedQuery.matches(indexView); + var allIds = indexView.getAllIds(); + allIds.removeAll(negatedResult); + return allIds; + } +} diff --git a/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java b/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java index 22b698246f..8ac83ef2f5 100644 --- a/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java +++ b/api/src/main/java/run/halo/app/extension/index/query/QueryFactory.java @@ -173,6 +173,10 @@ public static Query or(Query query1, Query query2, Collection additionalQ return new Or(queries); } + public static Query not(Query query) { + return new Not(query); + } + public static Query betweenLowerExclusive(String fieldName, String lowerValue, String upperValue) { return new Between(fieldName, lowerValue, false, upperValue, true); diff --git a/api/src/test/java/run/halo/app/extension/index/query/QueryFactoryTest.java b/api/src/test/java/run/halo/app/extension/index/query/QueryFactoryTest.java index c69e44228a..acce9acd19 100644 --- a/api/src/test/java/run/halo/app/extension/index/query/QueryFactoryTest.java +++ b/api/src/test/java/run/halo/app/extension/index/query/QueryFactoryTest.java @@ -248,4 +248,14 @@ void containsTest() { "104", "105" ); } + + @Test + void notTest() { + var indexView = IndexViewDataSet.createEmployeeIndexView(); + var resultSet = + QueryFactory.not(QueryFactory.contains("firstName", "i")).matches(indexView); + assertThat(resultSet).containsExactlyInAnyOrder( + "100", "101", "103", "104", "105" + ); + } } diff --git a/application/src/main/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpoint.java b/application/src/main/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpoint.java index d8b41c0f60..03aea1a5c6 100644 --- a/application/src/main/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpoint.java +++ b/application/src/main/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpoint.java @@ -1,25 +1,27 @@ package run.halo.app.core.extension.attachment.endpoint; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; -import static java.util.Comparator.comparing; import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; import static org.springframework.boot.convert.ApplicationConversionService.getSharedInstance; import static org.springframework.web.reactive.function.server.RequestPredicates.contentType; import static run.halo.app.extension.ListResult.generateGenericClass; +import static run.halo.app.extension.index.query.QueryFactory.all; +import static run.halo.app.extension.index.query.QueryFactory.and; +import static run.halo.app.extension.index.query.QueryFactory.contains; +import static run.halo.app.extension.index.query.QueryFactory.in; +import static run.halo.app.extension.index.query.QueryFactory.isNull; +import static run.halo.app.extension.index.query.QueryFactory.not; import static run.halo.app.extension.router.QueryParamBuildUtil.buildParametersFromType; -import static run.halo.app.extension.router.selector.SelectorUtil.labelAndFieldSelectorToPredicate; +import static run.halo.app.extension.router.selector.SelectorUtil.labelAndFieldSelectorToListOptions; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Schema; -import java.util.ArrayList; -import java.util.Comparator; import java.util.List; -import java.util.Objects; import java.util.Optional; -import java.util.function.Predicate; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; import org.springdoc.core.fn.builders.requestbody.Builder; import org.springdoc.webflux.core.fn.SpringdocRouteBuilder; import org.springframework.data.domain.Sort; @@ -42,11 +44,12 @@ import run.halo.app.core.extension.endpoint.CustomEndpoint; import run.halo.app.core.extension.endpoint.SortResolver; import run.halo.app.core.extension.service.AttachmentService; -import run.halo.app.extension.Comparators; -import run.halo.app.extension.MetadataUtil; +import run.halo.app.extension.ListOptions; +import run.halo.app.extension.PageRequestImpl; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.extension.router.IListRequest; import run.halo.app.extension.router.IListRequest.QueryListRequest; +import run.halo.app.extension.router.selector.LabelSelector; @Slf4j @Component @@ -107,50 +110,35 @@ public RouterFunction endpoint() { Mono search(ServerRequest request) { var searchRequest = new SearchRequest(request); - return client.list(Group.class, group -> MetadataUtil.nullSafeLabels(group) - .containsKey(Group.HIDDEN_LABEL), null) + var groupListOptions = new ListOptions(); + groupListOptions.setLabelSelector(LabelSelector.builder() + .exists(Group.HIDDEN_LABEL) + .build()); + return client.listAll(Group.class, groupListOptions, Sort.unsorted()) .map(group -> group.getMetadata().getName()) .collectList() .defaultIfEmpty(List.of()) - .flatMap(groups -> client.list(Attachment.class, - searchRequest.toPredicate().and(visibleGroupPredicate(groups)), - searchRequest.toComparator(), - searchRequest.getPage(), searchRequest.getSize()) - .flatMap(listResult -> ServerResponse.ok() - .contentType(MediaType.APPLICATION_JSON) - .bodyValue(listResult) - ) + .flatMap(hiddenGroups -> client.listBy(Attachment.class, + searchRequest.toListOptions(hiddenGroups), + PageRequestImpl.of(searchRequest.getPage(), searchRequest.getSize(), + searchRequest.getSort()) + ) + .flatMap(listResult -> ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(listResult) + ) ); - - } - - static Predicate visibleGroupPredicate(List hiddenGroups) { - return attachment -> { - if (!StringUtils.hasText(attachment.getSpec().getGroupName())) { - return true; - } - return !hiddenGroups.contains(attachment.getSpec().getGroupName()); - }; } public interface ISearchRequest extends IListRequest { - @Schema(description = "Display name of attachment") - Optional getDisplayName(); - - @Schema(description = "Name of policy") - Optional getPolicy(); - - @Schema(description = "Name of group") - Optional getGroup(); + @Schema(description = "Keyword for searching.") + Optional getKeyword(); @Schema(description = "Filter attachments without group. This parameter will ignore group" + " parameter.") Optional getUngrouped(); - @Schema(description = "Name of user who uploaded the attachment") - Optional getUploadedBy(); - @ArraySchema(uniqueItems = true, arraySchema = @Schema(name = "sort", description = "Sort property and direction of the list result. Supported fields: " @@ -159,7 +147,6 @@ public interface ISearchRequest extends IListRequest { implementation = String.class, example = "creationTimestamp,desc")) Sort getSort(); - } public static class SearchRequest extends QueryListRequest implements ISearchRequest { @@ -172,20 +159,8 @@ public SearchRequest(ServerRequest request) { } @Override - public Optional getDisplayName() { - return Optional.ofNullable(queryParams.getFirst("displayName")) - .filter(StringUtils::hasText); - } - - @Override - public Optional getPolicy() { - return Optional.ofNullable(queryParams.getFirst("policy")) - .filter(StringUtils::hasText); - } - - @Override - public Optional getGroup() { - return Optional.ofNullable(queryParams.getFirst("group")) + public Optional getKeyword() { + return Optional.ofNullable(queryParams.getFirst("keyword")) .filter(StringUtils::hasText); } @@ -195,81 +170,35 @@ public Optional getUngrouped() { .map(ungroupedStr -> getSharedInstance().convert(ungroupedStr, Boolean.class)); } - @Override - public Optional getUploadedBy() { - return Optional.ofNullable(queryParams.getFirst("uploadedBy")) - .filter(StringUtils::hasText); - } - @Override public Sort getSort() { - return SortResolver.defaultInstance.resolve(exchange); + var sort = SortResolver.defaultInstance.resolve(exchange); + sort = sort.and(Sort.by( + Sort.Order.desc("metadata.creationTimestamp"), + Sort.Order.asc("metadata.name") + )); + return sort; } - public Predicate toPredicate() { - Predicate displayNamePred = attachment -> getDisplayName() - .map(displayNameInParam -> { - String displayName = attachment.getSpec().getDisplayName(); - return displayName.contains(displayNameInParam); - }).orElse(true); - - Predicate policyPred = attachment -> getPolicy() - .map(policy -> Objects.equals(policy, attachment.getSpec().getPolicyName())) - .orElse(true); - - Predicate groupPred = attachment -> getGroup() - .map(group -> Objects.equals(group, attachment.getSpec().getGroupName())) - .orElse(true); - - Predicate ungroupedPred = attachment -> getUngrouped() - .filter(Boolean::booleanValue) - .map(ungrouped -> !StringUtils.hasText(attachment.getSpec().getGroupName())) - .orElseGet(() -> groupPred.test(attachment)); + public ListOptions toListOptions(List hiddenGroups) { + final var listOptions = + labelAndFieldSelectorToListOptions(getLabelSelector(), getFieldSelector()); - Predicate uploadedByPred = attachment -> getUploadedBy() - .map(uploadedBy -> Objects.equals(uploadedBy, attachment.getSpec().getOwnerName())) - .orElse(true); - - - var selectorPred = - labelAndFieldSelectorToPredicate(getLabelSelector(), getFieldSelector()); - - return displayNamePred - .and(policyPred) - .and(ungroupedPred) - .and(uploadedByPred) - .and(selectorPred); - } + var fieldQuery = all(); + if (getKeyword().isPresent()) { + fieldQuery = and(fieldQuery, contains("spec.displayName", getKeyword().get())); + } - public Comparator toComparator() { - var sort = getSort(); - List> comparators = new ArrayList<>(); - var creationOrder = sort.getOrderFor("creationTimestamp"); - if (creationOrder != null) { - Comparator comparator = comparing( - attachment -> attachment.getMetadata().getCreationTimestamp()); - if (creationOrder.isDescending()) { - comparator = comparator.reversed(); - } - comparators.add(comparator); + if (getUngrouped().isPresent() && BooleanUtils.isTrue(getUngrouped().get())) { + fieldQuery = and(fieldQuery, isNull("spec.groupName")); } - var sizeOrder = sort.getOrderFor("size"); - if (sizeOrder != null) { - Comparator comparator = - comparing(attachment -> attachment.getSpec().getSize()); - if (sizeOrder.isDescending()) { - comparator = comparator.reversed(); - } - comparators.add(comparator); + if (!hiddenGroups.isEmpty()) { + fieldQuery = and(fieldQuery, not(in("spec.groupName", hiddenGroups))); } - // add default comparator - comparators.add(Comparators.compareCreationTimestamp(false)); - comparators.add(Comparators.compareName(true)); - return comparators.stream() - .reduce(Comparator::thenComparing) - .orElse(null); + listOptions.setFieldSelector(listOptions.getFieldSelector().andQuery(fieldQuery)); + return listOptions; } } diff --git a/application/src/main/java/run/halo/app/infra/SchemeInitializer.java b/application/src/main/java/run/halo/app/infra/SchemeInitializer.java index ad73b12882..8fb6349a98 100644 --- a/application/src/main/java/run/halo/app/infra/SchemeInitializer.java +++ b/application/src/main/java/run/halo/app/infra/SchemeInitializer.java @@ -6,6 +6,7 @@ import java.util.Set; import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.boot.context.event.ApplicationContextInitializedEvent; import org.springframework.context.ApplicationListener; import org.springframework.lang.NonNull; @@ -191,7 +192,38 @@ public void onApplicationEvent(@NonNull ApplicationContextInitializedEvent event // storage.halo.run schemeManager.register(Group.class); schemeManager.register(Policy.class); - schemeManager.register(Attachment.class); + schemeManager.register(Attachment.class, indexSpecs -> { + indexSpecs.add(new IndexSpec() + .setName("spec.displayName") + .setIndexFunc(simpleAttribute(Attachment.class, + attachment -> attachment.getSpec().getDisplayName())) + ); + indexSpecs.add(new IndexSpec() + .setName("spec.policyName") + .setIndexFunc(simpleAttribute(Attachment.class, + attachment -> attachment.getSpec().getPolicyName())) + ); + indexSpecs.add(new IndexSpec() + .setName("spec.groupName") + .setIndexFunc(simpleAttribute(Attachment.class, attachment -> { + var group = attachment.getSpec().getGroupName(); + return StringUtils.isBlank(group) ? null : group; + })) + ); + indexSpecs.add(new IndexSpec() + .setName("spec.ownerName") + .setIndexFunc(simpleAttribute(Attachment.class, + attachment -> attachment.getSpec().getOwnerName())) + ); + indexSpecs.add(new IndexSpec() + .setName("spec.size") + .setIndexFunc(simpleAttribute(Attachment.class, + attachment -> { + var size = attachment.getSpec().getSize(); + return size != null ? size.toString() : null; + })) + ); + }); schemeManager.register(PolicyTemplate.class); // metrics.halo.run schemeManager.register(Counter.class); diff --git a/application/src/test/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpointTest.java b/application/src/test/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpointTest.java index 873065269c..7736c42b2d 100644 --- a/application/src/test/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpointTest.java +++ b/application/src/test/java/run/halo/app/core/extension/attachment/endpoint/AttachmentEndpointTest.java @@ -1,10 +1,6 @@ package run.halo.app.core.extension.attachment.endpoint; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.mock; @@ -17,32 +13,28 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; -import java.util.function.Predicate; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Sort; import org.springframework.http.MediaType; import org.springframework.http.client.MultipartBodyBuilder; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.reactive.function.server.MockServerRequest; -import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.reactive.function.BodyInserters; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import run.halo.app.core.extension.attachment.Attachment; -import run.halo.app.core.extension.attachment.Attachment.AttachmentSpec; import run.halo.app.core.extension.attachment.Group; import run.halo.app.core.extension.attachment.Policy; import run.halo.app.core.extension.attachment.Policy.PolicySpec; -import run.halo.app.core.extension.attachment.endpoint.AttachmentEndpoint.SearchRequest; import run.halo.app.core.extension.service.impl.DefaultAttachmentService; import run.halo.app.extension.ConfigMap; import run.halo.app.extension.ListResult; import run.halo.app.extension.Metadata; +import run.halo.app.extension.PageRequest; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.plugin.ExtensionComponentsFinder; @@ -241,10 +233,10 @@ class SearchTest { @Test void shouldListUngroupedAttachments() { - when(client.list(eq(Group.class), any(), any())) + when(client.listAll(eq(Group.class), any(), any(Sort.class))) .thenReturn(Flux.empty()); - when(client.list(same(Attachment.class), any(), any(), anyInt(), anyInt())) + when(client.listBy(same(Attachment.class), any(), any(PageRequest.class))) .thenReturn(Mono.just(ListResult.emptyResult())); webClient @@ -256,35 +248,12 @@ void shouldListUngroupedAttachments() { .jsonPath("items.length()").isEqualTo(0); } - @Test - void shouldFilterWithUngrouped() { - var httpRequest = MockServerHttpRequest.get("/attachments") - .build(); - var exchange = new MockServerWebExchange.Builder(httpRequest) - .build(); - MockServerRequest request = MockServerRequest.builder() - .queryParam("ungrouped", "true") - .queryParam("group", "halo") - .exchange(exchange) - .build(); - var searchRequest = new SearchRequest(request); - var pred = searchRequest.toPredicate(); - var attachment = new Attachment(); - var spec = new AttachmentSpec(); - attachment.setSpec(spec); - - assertTrue(pred.test(attachment)); - - spec.setGroupName("halo"); - assertFalse(pred.test(attachment)); - } - @Test void searchAttachmentWhenGroupIsEmpty() { - when(client.list(eq(Group.class), any(), any())) + when(client.listAll(eq(Group.class), any(), any(Sort.class))) .thenReturn(Flux.empty()); - when(client.list(eq(Attachment.class), any(), any(), anyInt(), anyInt())) + when(client.listBy(eq(Attachment.class), any(), any(PageRequest.class))) .thenReturn(Mono.empty()); webClient @@ -293,32 +262,7 @@ void searchAttachmentWhenGroupIsEmpty() { .exchange() .expectStatus().isOk(); - verify(client).list(eq(Attachment.class), any(), any(), anyInt(), anyInt()); + verify(client).listBy(eq(Attachment.class), any(), any(PageRequest.class)); } } - - @Test - void visibleGroupPredicate() { - Predicate noHiddenGroupPredicate = - AttachmentEndpoint.visibleGroupPredicate(List.of()); - - Attachment attachment = mock(Attachment.class); - AttachmentSpec spec = mock(AttachmentSpec.class); - when(attachment.getSpec()).thenReturn(spec); - - when(spec.getGroupName()).thenReturn(""); - assertThat(noHiddenGroupPredicate.test(attachment)).isTrue(); - - when(spec.getGroupName()).thenReturn("test"); - assertThat(noHiddenGroupPredicate.test(attachment)).isTrue(); - - Predicate hasHiddenGroupPredicate = - AttachmentEndpoint.visibleGroupPredicate(List.of("hidden-group")); - when(spec.getGroupName()).thenReturn("fake"); - assertThat(hasHiddenGroupPredicate.test(attachment)).isTrue(); - - when(spec.getGroupName()).thenReturn("hidden-group"); - assertThat(hasHiddenGroupPredicate.test(attachment)).isFalse(); - } - -} \ No newline at end of file +} diff --git a/ui/console-src/modules/contents/attachments/AttachmentList.vue b/ui/console-src/modules/contents/attachments/AttachmentList.vue index 54153f31ff..2168514f09 100644 --- a/ui/console-src/modules/contents/attachments/AttachmentList.vue +++ b/ui/console-src/modules/contents/attachments/AttachmentList.vue @@ -364,23 +364,23 @@ onMounted(() => { label: t( 'core.attachment.filters.sort.items.create_time_desc' ), - value: 'creationTimestamp,desc', + value: 'metadata.creationTimestamp,desc', }, { label: t( 'core.attachment.filters.sort.items.create_time_asc' ), - value: 'creationTimestamp,asc', + value: 'metadata.creationTimestamp,asc', }, { label: t( 'core.attachment.filters.sort.items.size_desc' ), - value: 'size,desc', + value: 'spec.size,desc', }, { label: t('core.attachment.filters.sort.items.size_asc'), - value: 'size,asc', + value: 'spec.size,asc', }, ]" /> diff --git a/ui/console-src/modules/contents/attachments/components/AttachmentGroupList.vue b/ui/console-src/modules/contents/attachments/components/AttachmentGroupList.vue index ace014c8f9..9d7a770a57 100644 --- a/ui/console-src/modules/contents/attachments/components/AttachmentGroupList.vue +++ b/ui/console-src/modules/contents/attachments/components/AttachmentGroupList.vue @@ -102,7 +102,7 @@ const handleDelete = (group: Group) => { onConfirm: async () => { // TODO: 后续将修改为在后端进行批量操作处理 const { data } = await apiClient.attachment.searchAttachments({ - group: group.metadata.name, + fieldSelector: [`spec.groupName=${group.metadata.name}`], page: 0, size: 0, }); @@ -151,7 +151,7 @@ const handleDeleteWithAttachments = (group: Group) => { onConfirm: async () => { // TODO: 后续将修改为在后端进行批量操作处理 const { data } = await apiClient.attachment.searchAttachments({ - group: group.metadata.name, + fieldSelector: [`spec.groupName=${group.metadata.name}`], page: 0, size: 0, }); diff --git a/ui/console-src/modules/contents/attachments/components/AttachmentPoliciesModal.vue b/ui/console-src/modules/contents/attachments/components/AttachmentPoliciesModal.vue index abd7884e94..5803d9f68d 100644 --- a/ui/console-src/modules/contents/attachments/components/AttachmentPoliciesModal.vue +++ b/ui/console-src/modules/contents/attachments/components/AttachmentPoliciesModal.vue @@ -78,7 +78,7 @@ const handleOpenCreateNewPolicyModal = (policyTemplate: PolicyTemplate) => { const handleDelete = async (policy: Policy) => { const { data } = await apiClient.attachment.searchAttachments({ - policy: policy.metadata.name, + fieldSelector: [`spec.policyName=${policy.metadata.name}`], }); if (data.total > 0) { diff --git a/ui/console-src/modules/contents/attachments/composables/use-attachment.ts b/ui/console-src/modules/contents/attachments/composables/use-attachment.ts index 92f85de6d3..021a78133b 100644 --- a/ui/console-src/modules/contents/attachments/composables/use-attachment.ts +++ b/ui/console-src/modules/contents/attachments/composables/use-attachment.ts @@ -50,14 +50,28 @@ export function useAttachmentControl(filterOptions: { const { data, isLoading, isFetching, refetch } = useQuery({ queryKey: ["attachments", policy, keyword, group, user, page, size, sort], queryFn: async () => { + const isUnGrouped = group?.value?.metadata.name === "ungrouped"; + + const fieldSelectorMap: Record = { + "spec.policyName": policy?.value?.metadata.name, + "spec.ownerName": user?.value, + "spec.groupName": isUnGrouped ? undefined : group?.value?.metadata.name, + }; + + const fieldSelector = Object.entries(fieldSelectorMap) + .map(([key, value]) => { + if (value) { + return `${key}=${value}`; + } + }) + .filter(Boolean) as string[]; + const { data } = await apiClient.attachment.searchAttachments({ - policy: policy?.value?.metadata.name, - displayName: keyword?.value, - group: group?.value?.metadata.name, - ungrouped: group?.value?.metadata.name === "ungrouped", - uploadedBy: user?.value, - page: page?.value, - size: size?.value, + fieldSelector, + page: page.value, + size: size.value, + ungrouped: isUnGrouped, + keyword: keyword?.value, sort: [sort?.value as string].filter(Boolean), }); diff --git a/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-attachment-api.ts b/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-attachment-api.ts index 093fb1f845..f0866b1d48 100644 --- a/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-attachment-api.ts +++ b/ui/packages/api-client/src/api/api-console-halo-run-v1alpha1-attachment-api.ts @@ -50,30 +50,24 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiAxiosParamCreator = return { /** * - * @param {string} [displayName] Display name of attachment * @param {Array} [fieldSelector] Field selector for filtering. - * @param {string} [group] Name of group + * @param {string} [keyword] Keyword for searching. * @param {Array} [labelSelector] Label selector for filtering. * @param {number} [page] The page number. Zero indicates no page. - * @param {string} [policy] Name of policy * @param {number} [size] Size of one page. Zero indicates no limit. * @param {Array} [sort] Sort property and direction of the list result. Supported fields: creationTimestamp, size * @param {boolean} [ungrouped] Filter attachments without group. This parameter will ignore group parameter. - * @param {string} [uploadedBy] Name of user who uploaded the attachment * @param {*} [options] Override http request option. * @throws {RequiredError} */ searchAttachments: async ( - displayName?: string, fieldSelector?: Array, - group?: string, + keyword?: string, labelSelector?: Array, page?: number, - policy?: string, size?: number, sort?: Array, ungrouped?: boolean, - uploadedBy?: string, options: AxiosRequestConfig = {} ): Promise => { const localVarPath = `/apis/api.console.halo.run/v1alpha1/attachments`; @@ -100,16 +94,12 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiAxiosParamCreator = // http bearer authentication required await setBearerAuthToObject(localVarHeaderParameter, configuration); - if (displayName !== undefined) { - localVarQueryParameter["displayName"] = displayName; - } - if (fieldSelector) { localVarQueryParameter["fieldSelector"] = fieldSelector; } - if (group !== undefined) { - localVarQueryParameter["group"] = group; + if (keyword !== undefined) { + localVarQueryParameter["keyword"] = keyword; } if (labelSelector) { @@ -120,10 +110,6 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiAxiosParamCreator = localVarQueryParameter["page"] = page; } - if (policy !== undefined) { - localVarQueryParameter["policy"] = policy; - } - if (size !== undefined) { localVarQueryParameter["size"] = size; } @@ -136,10 +122,6 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiAxiosParamCreator = localVarQueryParameter["ungrouped"] = ungrouped; } - if (uploadedBy !== undefined) { - localVarQueryParameter["uploadedBy"] = uploadedBy; - } - setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; @@ -243,46 +225,37 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiFp = function ( return { /** * - * @param {string} [displayName] Display name of attachment * @param {Array} [fieldSelector] Field selector for filtering. - * @param {string} [group] Name of group + * @param {string} [keyword] Keyword for searching. * @param {Array} [labelSelector] Label selector for filtering. * @param {number} [page] The page number. Zero indicates no page. - * @param {string} [policy] Name of policy * @param {number} [size] Size of one page. Zero indicates no limit. * @param {Array} [sort] Sort property and direction of the list result. Supported fields: creationTimestamp, size * @param {boolean} [ungrouped] Filter attachments without group. This parameter will ignore group parameter. - * @param {string} [uploadedBy] Name of user who uploaded the attachment * @param {*} [options] Override http request option. * @throws {RequiredError} */ async searchAttachments( - displayName?: string, fieldSelector?: Array, - group?: string, + keyword?: string, labelSelector?: Array, page?: number, - policy?: string, size?: number, sort?: Array, ungrouped?: boolean, - uploadedBy?: string, options?: AxiosRequestConfig ): Promise< (axios?: AxiosInstance, basePath?: string) => AxiosPromise > { const localVarAxiosArgs = await localVarAxiosParamCreator.searchAttachments( - displayName, fieldSelector, - group, + keyword, labelSelector, page, - policy, size, sort, ungrouped, - uploadedBy, options ); return createRequestFunction( @@ -348,16 +321,13 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiFactory = function ( ): AxiosPromise { return localVarFp .searchAttachments( - requestParameters.displayName, requestParameters.fieldSelector, - requestParameters.group, + requestParameters.keyword, requestParameters.labelSelector, requestParameters.page, - requestParameters.policy, requestParameters.size, requestParameters.sort, requestParameters.ungrouped, - requestParameters.uploadedBy, options ) .then((request) => request(axios, basePath)); @@ -390,13 +360,6 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiFactory = function ( * @interface ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachmentsRequest */ export interface ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachmentsRequest { - /** - * Display name of attachment - * @type {string} - * @memberof ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachments - */ - readonly displayName?: string; - /** * Field selector for filtering. * @type {Array} @@ -405,11 +368,11 @@ export interface ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachmentsRequest readonly fieldSelector?: Array; /** - * Name of group + * Keyword for searching. * @type {string} * @memberof ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachments */ - readonly group?: string; + readonly keyword?: string; /** * Label selector for filtering. @@ -425,13 +388,6 @@ export interface ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachmentsRequest */ readonly page?: number; - /** - * Name of policy - * @type {string} - * @memberof ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachments - */ - readonly policy?: string; - /** * Size of one page. Zero indicates no limit. * @type {number} @@ -452,13 +408,6 @@ export interface ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachmentsRequest * @memberof ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachments */ readonly ungrouped?: boolean; - - /** - * Name of user who uploaded the attachment - * @type {string} - * @memberof ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachments - */ - readonly uploadedBy?: string; } /** @@ -509,16 +458,13 @@ export class ApiConsoleHaloRunV1alpha1AttachmentApi extends BaseAPI { ) { return ApiConsoleHaloRunV1alpha1AttachmentApiFp(this.configuration) .searchAttachments( - requestParameters.displayName, requestParameters.fieldSelector, - requestParameters.group, + requestParameters.keyword, requestParameters.labelSelector, requestParameters.page, - requestParameters.policy, requestParameters.size, requestParameters.sort, requestParameters.ungrouped, - requestParameters.uploadedBy, options ) .then((request) => request(this.axios, this.basePath));