Skip to content

Commit

Permalink
Configure UI default settings (springwolf#1076)
Browse files Browse the repository at this point in the history
* feat(core): expose initial ui config via endpoint

* feat(ui): consume initial dummy ui config

* feat(core): introduce ui config in application.properties

- fix ui tests

* feat(ui): add tests for toggle header and bindings settings

---------

Co-authored-by: Jennifer Meyer <[email protected]>
Co-authored-by: Peter Zahn <[email protected]>
Co-authored-by: Christoph Volkert <[email protected]>
  • Loading branch information
4 people authored and ruskaof committed Nov 20, 2024
1 parent 5a68088 commit 77af185
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.github.springwolf.core.asyncapi.AsyncApiService;
import io.github.springwolf.core.asyncapi.components.ComponentsService;
import io.github.springwolf.core.asyncapi.grouping.AsyncApiGroupService;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
import io.github.springwolf.core.controller.ActuatorAsyncApiController;
import io.github.springwolf.core.controller.AsyncApiController;
import io.github.springwolf.core.controller.PublishingPayloadCreator;
Expand Down Expand Up @@ -52,8 +53,9 @@ public ActuatorAsyncApiController actuatorAsyncApiController(
@Bean
@ConditionalOnProperty(name = SPRINGWOLF_ENDPOINT_ACTUATOR_ENABLED, havingValue = "false", matchIfMissing = true)
@ConditionalOnMissingBean
public UiConfigController uiConfigController(AsyncApiGroupService asyncApiGroupService) {
return new UiConfigController(asyncApiGroupService);
public UiConfigController uiConfigController(
AsyncApiGroupService asyncApiGroupService, SpringwolfConfigProperties configProperties) {
return new UiConfigController(asyncApiGroupService, configProperties);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ public enum InitMode {

private ConfigDocket docket = new ConfigDocket();

/**
* The UI configuration properties.
*
* @see UI
*/
private UI ui = new UI();

@Nullable
private Scanner scanner;

Expand Down Expand Up @@ -222,6 +229,20 @@ public static class Group {
}
}

@Getter
@Setter
public static class UI {
/**
* Allows to show or hide the bindings in the UI when opening the UI.
*/
private boolean initiallyShowBindings = true;

/**
* Allows to show or hide the headers in the UI when opening the UI.
*/
private boolean initiallyShowHeaders = true;
}

@Getter
@Setter
public static class Scanner {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package io.github.springwolf.core.controller;

import io.github.springwolf.core.asyncapi.grouping.AsyncApiGroupService;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
Expand All @@ -16,18 +17,35 @@
public class UiConfigController {

private final AsyncApiGroupService asyncApiGroupService;
private final SpringwolfConfigProperties configProperties;

@GetMapping(
path = {"${springwolf.path.base:/springwolf}/ui-config"},
produces = MediaType.APPLICATION_JSON_VALUE)
public UiConfig getUiConfig() {
return new UiConfig(asyncApiGroupService

final UiConfig.InitialConfig initial = createInitialConfig();
final List<UiConfig.UiConfigGroup> groups = createGroups();

return new UiConfig(initial, groups);
}

private List<UiConfig.UiConfigGroup> createGroups() {
return asyncApiGroupService
.getAsyncApiGroups()
.map(el -> new UiConfig.UiConfigGroup(el.getGroupName()))
.toList());
.toList();
}

private record UiConfig(List<UiConfigGroup> groups) {
private UiConfig.InitialConfig createInitialConfig() {
return new UiConfig.InitialConfig(
configProperties.getUi().isInitiallyShowBindings(),
configProperties.getUi().isInitiallyShowHeaders());
}

private record UiConfig(InitialConfig initialConfig, List<UiConfigGroup> groups) {
private record InitialConfig(boolean showBindings, boolean showHeaders) {}

private record UiConfigGroup(String name) {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,44 @@ void groupConfigIsMappedCorrectly() {
assertThat(actual.get(1)).isEqualTo(receiveGroup);
}
}

@Nested
@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties(SpringwolfConfigProperties.class)
@TestPropertySource(
properties = {"springwolf.ui.initially-show-bindings=false", "springwolf.ui.initially-show-headers=true"})
class UiConfigTest {

@Autowired
private SpringwolfConfigProperties properties;

@Test
void uiConfigIsMappedCorrectly() {
// when
final SpringwolfConfigProperties.UI actual = properties.getUi();

// then
assertThat(actual.isInitiallyShowBindings()).isFalse();
assertThat(actual.isInitiallyShowHeaders()).isTrue();
}
}

@Nested
@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties(SpringwolfConfigProperties.class)
class DefaultConfigTest {

@Autowired
private SpringwolfConfigProperties properties;

@Test
void uiConfigIsMappedCorrectly() {
// when
final SpringwolfConfigProperties.UI actual = properties.getUi();

// then
assertThat(actual.isInitiallyShowBindings()).isTrue();
assertThat(actual.isInitiallyShowHeaders()).isTrue();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ springwolf.docket.servers.amqp-server.host=${spring.rabbitmq.host}:${spring.rabb

springwolf.plugin.amqp.publishing.enabled=true

# Springwolf ui configuration
springwolf.ui.initially-show-bindings=true
springwolf.ui.initially-show-headers=true

# For debugging purposes
logging.level.io.github.springwolf=DEBUG
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ springwolf.docket.servers.kafka-server.protocol=kafka
springwolf.docket.servers.kafka-server.host=${spring.cloud.stream.binders.kafka.environment.spring.kafka.bootstrap-servers}
springwolf.use-fqn=false

# Springwolf ui configuration
springwolf.ui.initially-show-bindings=true
springwolf.ui.initially-show-headers=true

# For debugging purposes
logging.level.io.github.springwolf=DEBUG
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ springwolf.docket.servers.jms-server.host=${spring.activemq.broker-url}

springwolf.plugin.jms.publishing.enabled=true

# Springwolf ui configuration
springwolf.ui.initially-show-bindings=true
springwolf.ui.initially-show-headers=true

# For debugging purposes
logging.level.io.github.springwolf=DEBUG
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ springwolf.payload.extractable-classes.org.apache.kafka.clients.consumer.Consume
springwolf.docket.group-configs[0].group=Only Vehicles
springwolf.docket.group-configs[0].message-name-to-match=.*Vehicle.*

# Springwolf ui configuration
springwolf.ui.initially-show-bindings=true
springwolf.ui.initially-show-headers=true

# Springwolf kafka configuration
springwolf.docket.servers.kafka-server.protocol=kafka
springwolf.docket.servers.kafka-server.host=${spring.kafka.bootstrap-servers}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"groups":[{"name":"Only Vehicles"}]}
{"initialConfig":{"showBindings":true,"showHeaders":true},"groups":[{"name":"Only Vehicles"}]}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ springwolf.docket.servers.sns-server.host=http://localhost:4566

springwolf.plugin.sns.publishing.enabled=true

# Springwolf ui configuration
springwolf.ui.initially-show-bindings=true
springwolf.ui.initially-show-headers=true

# For debugging purposes
logging.level.io.github.springwolf=DEBUG
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ springwolf.docket.servers.sqs-server.host=http://localhost:4566

springwolf.plugin.sqs.publishing.enabled=true

# Springwolf ui configuration
springwolf.ui.initially-show-bindings=true
springwolf.ui.initially-show-headers=true

# For debugging purposes
logging.level.io.github.springwolf=DEBUG
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ springwolf.docket.servers.stomp.host=localhost:8080/myendpoint
springwolf.plugin.stomp.endpoint.app=/app
springwolf.plugin.stomp.endpoint.user=/user

# Springwolf ui configuration
springwolf.ui.initially-show-bindings=true
springwolf.ui.initially-show-headers=true

# For debugging purposes
logging.level.io.github.springwolf=DEBUG
12 changes: 10 additions & 2 deletions springwolf-ui/src/app/components/header/header.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,21 @@ <h1 class="width-s-hide">{{ title }}</h1>
}
</mat-menu>

<button mat-menu-item (click)="toggleIsShowBindings()">
<button
mat-menu-item
(click)="toggleIsShowBindings()"
data-testid="settings-bindings"
>
<mat-icon>{{
isShowBindings ? "check_box" : "check_box_outline_blank"
}}</mat-icon>
Show bindings
</button>
<button mat-menu-item (click)="toggleIsShowHeaders()">
<button
mat-menu-item
(click)="toggleIsShowHeaders()"
data-testid="settings-headers"
>
<mat-icon>{{
isShowHeaders ? "check_box" : "check_box_outline_blank"
}}</mat-icon>
Expand Down
33 changes: 33 additions & 0 deletions springwolf-ui/src/app/components/header/header.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe("HeaderComponent", () => {

it("should show groups when the uiConfig is updated", () => {
uiConfigSubject.next({
initialConfig: { showBindings: true, showHeaders: true },
groups: [{ name: "group1" }, { name: "group2" }],
});

Expand All @@ -57,4 +58,36 @@ describe("HeaderComponent", () => {
fireEvent.click(screen.getByText("group1"));
expect(mockedUiService.changeGroup).toHaveBeenCalledWith("group1");
});

it("should trigger show bindings when clicked in settings menu", () => {
uiConfigSubject.next({
initialConfig: { showBindings: true, showHeaders: true },
groups: [{ name: "group1" }, { name: "group2" }],
});

// when clicking the checkbox
const settingButton = screen.getByTestId("settings");
fireEvent.click(settingButton);
const checkBox = screen.getByTestId("settings-bindings");
fireEvent.click(checkBox);

// then toggleIsShowBindings is called
expect(mockedUiService.toggleIsShowBindings).toBeCalled();
});

it("should trigger show headers when clicked in settings menu", () => {
uiConfigSubject.next({
initialConfig: { showBindings: true, showHeaders: true },
groups: [{ name: "group1" }, { name: "group2" }],
});

// when clicking the checkbox
const settingButton = screen.getByTestId("settings");
fireEvent.click(settingButton);
const checkBox = screen.getByTestId("settings-headers");
fireEvent.click(checkBox);

// then toggleIsShowHeaders is called
expect(mockedUiService.toggleIsShowHeaders).toBeCalled();
});
});
4 changes: 4 additions & 0 deletions springwolf-ui/src/app/service/asyncapi/models/ui.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
/* SPDX-License-Identifier: Apache-2.0 */
export interface ServerUiConfig {
initialConfig: {
showBindings: boolean;
showHeaders: boolean;
};
groups: {
name: string;
}[];
Expand Down
4 changes: 4 additions & 0 deletions springwolf-ui/src/app/service/ui.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export class UiService extends IUiService {
this.uiConfig = this.http
.get<ServerUiConfig>(EndpointService.uiConfig)
.pipe(shareReplay());
this.uiConfig.subscribe((serverUiConfig: ServerUiConfig) => {
this.toggleIsShowBindings(serverUiConfig.initialConfig.showBindings);
this.toggleIsShowHeaders(serverUiConfig.initialConfig.showHeaders);
});
}

toggleIsShowBindings(value: boolean) {
Expand Down

0 comments on commit 77af185

Please sign in to comment.