mirror of https://github.com/halo-dev/halo
refactor: optimize old attachment query parameters using index (#5363)
#### 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 使用索引功能优化附件列表查询 ```pull/5302/head^2
parent
333422a0d4
commit
80e14e97d7
|
@ -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<String> matches(QueryIndexView indexView) {
|
||||
var negatedResult = negatedQuery.matches(indexView);
|
||||
var allIds = indexView.getAllIds();
|
||||
allIds.removeAll(negatedResult);
|
||||
return allIds;
|
||||
}
|
||||
}
|
|
@ -173,6 +173,10 @@ public class QueryFactory {
|
|||
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);
|
||||
|
|
|
@ -248,4 +248,14 @@ class QueryFactoryTest {
|
|||
"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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.attachment.Group;
|
|||
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 class AttachmentEndpoint implements CustomEndpoint {
|
|||
|
||||
Mono<ServerResponse> 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<Attachment> visibleGroupPredicate(List<String> 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<String> getDisplayName();
|
||||
|
||||
@Schema(description = "Name of policy")
|
||||
Optional<String> getPolicy();
|
||||
|
||||
@Schema(description = "Name of group")
|
||||
Optional<String> getGroup();
|
||||
@Schema(description = "Keyword for searching.")
|
||||
Optional<String> getKeyword();
|
||||
|
||||
@Schema(description = "Filter attachments without group. This parameter will ignore group"
|
||||
+ " parameter.")
|
||||
Optional<Boolean> getUngrouped();
|
||||
|
||||
@Schema(description = "Name of user who uploaded the attachment")
|
||||
Optional<String> getUploadedBy();
|
||||
|
||||
@ArraySchema(uniqueItems = true,
|
||||
arraySchema = @Schema(name = "sort",
|
||||
description = "Sort property and direction of the list result. Supported fields: "
|
||||
|
@ -159,7 +147,6 @@ public class AttachmentEndpoint implements CustomEndpoint {
|
|||
implementation = String.class,
|
||||
example = "creationTimestamp,desc"))
|
||||
Sort getSort();
|
||||
|
||||
}
|
||||
|
||||
public static class SearchRequest extends QueryListRequest implements ISearchRequest {
|
||||
|
@ -172,20 +159,8 @@ public class AttachmentEndpoint implements CustomEndpoint {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getDisplayName() {
|
||||
return Optional.ofNullable(queryParams.getFirst("displayName"))
|
||||
.filter(StringUtils::hasText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getPolicy() {
|
||||
return Optional.ofNullable(queryParams.getFirst("policy"))
|
||||
.filter(StringUtils::hasText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getGroup() {
|
||||
return Optional.ofNullable(queryParams.getFirst("group"))
|
||||
public Optional<String> getKeyword() {
|
||||
return Optional.ofNullable(queryParams.getFirst("keyword"))
|
||||
.filter(StringUtils::hasText);
|
||||
}
|
||||
|
||||
|
@ -195,81 +170,35 @@ public class AttachmentEndpoint implements CustomEndpoint {
|
|||
.map(ungroupedStr -> getSharedInstance().convert(ungroupedStr, Boolean.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> 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<Attachment> toPredicate() {
|
||||
Predicate<Attachment> displayNamePred = attachment -> getDisplayName()
|
||||
.map(displayNameInParam -> {
|
||||
String displayName = attachment.getSpec().getDisplayName();
|
||||
return displayName.contains(displayNameInParam);
|
||||
}).orElse(true);
|
||||
public ListOptions toListOptions(List<String> hiddenGroups) {
|
||||
final var listOptions =
|
||||
labelAndFieldSelectorToListOptions(getLabelSelector(), getFieldSelector());
|
||||
|
||||
Predicate<Attachment> policyPred = attachment -> getPolicy()
|
||||
.map(policy -> Objects.equals(policy, attachment.getSpec().getPolicyName()))
|
||||
.orElse(true);
|
||||
|
||||
Predicate<Attachment> groupPred = attachment -> getGroup()
|
||||
.map(group -> Objects.equals(group, attachment.getSpec().getGroupName()))
|
||||
.orElse(true);
|
||||
|
||||
Predicate<Attachment> ungroupedPred = attachment -> getUngrouped()
|
||||
.filter(Boolean::booleanValue)
|
||||
.map(ungrouped -> !StringUtils.hasText(attachment.getSpec().getGroupName()))
|
||||
.orElseGet(() -> groupPred.test(attachment));
|
||||
|
||||
Predicate<Attachment> 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);
|
||||
}
|
||||
|
||||
public Comparator<Attachment> toComparator() {
|
||||
var sort = getSort();
|
||||
List<Comparator<Attachment>> comparators = new ArrayList<>();
|
||||
var creationOrder = sort.getOrderFor("creationTimestamp");
|
||||
if (creationOrder != null) {
|
||||
Comparator<Attachment> comparator = comparing(
|
||||
attachment -> attachment.getMetadata().getCreationTimestamp());
|
||||
if (creationOrder.isDescending()) {
|
||||
comparator = comparator.reversed();
|
||||
}
|
||||
comparators.add(comparator);
|
||||
var fieldQuery = all();
|
||||
if (getKeyword().isPresent()) {
|
||||
fieldQuery = and(fieldQuery, contains("spec.displayName", getKeyword().get()));
|
||||
}
|
||||
|
||||
var sizeOrder = sort.getOrderFor("size");
|
||||
if (sizeOrder != null) {
|
||||
Comparator<Attachment> comparator =
|
||||
comparing(attachment -> attachment.getSpec().getSize());
|
||||
if (sizeOrder.isDescending()) {
|
||||
comparator = comparator.reversed();
|
||||
}
|
||||
comparators.add(comparator);
|
||||
if (getUngrouped().isPresent() && BooleanUtils.isTrue(getUngrouped().get())) {
|
||||
fieldQuery = and(fieldQuery, isNull("spec.groupName"));
|
||||
}
|
||||
|
||||
// add default comparator
|
||||
comparators.add(Comparators.compareCreationTimestamp(false));
|
||||
comparators.add(Comparators.compareName(true));
|
||||
return comparators.stream()
|
||||
.reduce(Comparator::thenComparing)
|
||||
.orElse(null);
|
||||
if (!hiddenGroups.isEmpty()) {
|
||||
fieldQuery = and(fieldQuery, not(in("spec.groupName", hiddenGroups)));
|
||||
}
|
||||
|
||||
listOptions.setFieldSelector(listOptions.getFieldSelector().andQuery(fieldQuery));
|
||||
return listOptions;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import static run.halo.app.extension.index.IndexAttributeFactory.simpleAttribute
|
|||
|
||||
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 class SchemeInitializer implements ApplicationListener<ApplicationContext
|
|||
// 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);
|
||||
|
|
|
@ -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 static org.springframework.security.test.web.reactive.server.SecurityMock
|
|||
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 AttachmentEndpointTest {
|
|||
|
||||
@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 @@ class AttachmentEndpointTest {
|
|||
.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 @@ class AttachmentEndpointTest {
|
|||
.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<Attachment> 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<Attachment> 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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',
|
||||
},
|
||||
]"
|
||||
/>
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -50,14 +50,28 @@ export function useAttachmentControl(filterOptions: {
|
|||
const { data, isLoading, isFetching, refetch } = useQuery<Attachment[]>({
|
||||
queryKey: ["attachments", policy, keyword, group, user, page, size, sort],
|
||||
queryFn: async () => {
|
||||
const isUnGrouped = group?.value?.metadata.name === "ungrouped";
|
||||
|
||||
const fieldSelectorMap: Record<string, string | undefined> = {
|
||||
"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),
|
||||
});
|
||||
|
||||
|
|
|
@ -50,30 +50,24 @@ export const ApiConsoleHaloRunV1alpha1AttachmentApiAxiosParamCreator =
|
|||
return {
|
||||
/**
|
||||
*
|
||||
* @param {string} [displayName] Display name of attachment
|
||||
* @param {Array<string>} [fieldSelector] Field selector for filtering.
|
||||
* @param {string} [group] Name of group
|
||||
* @param {string} [keyword] Keyword for searching.
|
||||
* @param {Array<string>} [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<string>} [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<string>,
|
||||
group?: string,
|
||||
keyword?: string,
|
||||
labelSelector?: Array<string>,
|
||||
page?: number,
|
||||
policy?: string,
|
||||
size?: number,
|
||||
sort?: Array<string>,
|
||||
ungrouped?: boolean,
|
||||
uploadedBy?: string,
|
||||
options: AxiosRequestConfig = {}
|
||||
): Promise<RequestArgs> => {
|
||||
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<string>} [fieldSelector] Field selector for filtering.
|
||||
* @param {string} [group] Name of group
|
||||
* @param {string} [keyword] Keyword for searching.
|
||||
* @param {Array<string>} [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<string>} [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<string>,
|
||||
group?: string,
|
||||
keyword?: string,
|
||||
labelSelector?: Array<string>,
|
||||
page?: number,
|
||||
policy?: string,
|
||||
size?: number,
|
||||
sort?: Array<string>,
|
||||
ungrouped?: boolean,
|
||||
uploadedBy?: string,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<
|
||||
(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AttachmentList>
|
||||
> {
|
||||
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<AttachmentList> {
|
||||
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<string>}
|
||||
|
@ -405,11 +368,11 @@ export interface ApiConsoleHaloRunV1alpha1AttachmentApiSearchAttachmentsRequest
|
|||
readonly fieldSelector?: Array<string>;
|
||||
|
||||
/**
|
||||
* 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));
|
||||
|
|
Loading…
Reference in New Issue