Skip to content

Commit

Permalink
resolve #1912 | Add buttons for switching between different environments
Browse files Browse the repository at this point in the history
  • Loading branch information
kasptom committed Oct 30, 2024
1 parent 4180225 commit 5757719
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 3 deletions.
12 changes: 11 additions & 1 deletion hermes-console/json-server/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,17 @@
"title": "hermes console",
"contactLink": "https://google.com",
"environmentName": "LOCAL",
"criticalEnvironment": false
"criticalEnvironment": false,
"knownEnvironments": [
{
"name": "local",
"url": "localhost:5173"
},
{
"name": "also-local",
"url": "127.0.0.1:5173"
}
]
},
"dashboard": {
"metrics": "http://localhost:8082",
Expand Down
6 changes: 6 additions & 0 deletions hermes-console/src/api/app-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ export interface ConsoleConfiguration {
contactLink: string;
environmentName: string;
criticalEnvironment: boolean;
knownEnvironments: ConsoleEnvironment[];
}

export interface ConsoleEnvironment {
name: string;
url: string;
}

export interface DashboardConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { useRouter } from 'vue-router';
import { useTheme } from 'vuetify';
import EnvironmentBadge from '@/components/environment-badge/EnviromentBadge.vue';
import EnvironmentSwitch from '@/components/environment-switch/EnvironmentSwitch.vue';
import ThemeSwitch from '@/components/theme-switch/ThemeSwitch.vue';
const { t } = useI18n();
Expand All @@ -17,6 +18,9 @@
const authStore = useAuthStore();
const isLoggedIn = computed(() => authStore.isUserAuthorized);
const knownEnvironments = computed(
() => configStore.appConfig?.console.knownEnvironments || [],
);
function logIn() {
authStore.login(window.location.pathname);
Expand Down Expand Up @@ -57,6 +61,8 @@
configStore.appConfig?.console.criticalEnvironment || false
"
/>
<v-divider vertical v-if="knownEnvironments.length > 0"></v-divider>
<environment-switch :known-environments="knownEnvironments" />
</div>
<div>
<theme-switch />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { expect } from 'vitest';
import { fireEvent } from '@testing-library/vue';
import { render } from '@/utils/test-utils';
import EnvironmentSwitch from '@/components/environment-switch/EnvironmentSwitch.vue';

const mockReplace = vi.fn();
const mockHref = vi.fn();

Object.defineProperty(window, 'location', {
value: {
get href() {
return mockHref();
},
replace: mockReplace,
},
});

const TEST_URL_ENV_1 =
'http://localhost:3000/ui/groups/pl.example.hermes/topics/pl.example.hermes.TemperatureChanged';
const TEST_URL_ENV_2 =
'http://127.0.0.1:3000/ui/groups/pl.example.hermes/topics/pl.example.hermes.TemperatureChanged';

describe('EnvironmentSwitch', () => {
it('should highlight the button for the selected environment', () => {
// given
mockHref.mockReturnValue(TEST_URL_ENV_1);

// when
const { getByText } = render(EnvironmentSwitch, {
props: {
knownEnvironments: [
{
name: 'env1',
url: 'localhost:3000',
},
{
name: 'env2',
url: '127.0.0.1:3000',
},
],
},
});

// then
expect(location.href).toBe(
'http://localhost:3000/ui/groups/pl.example.hermes/topics/pl.example.hermes.TemperatureChanged',
);
expect(getByText('env1')).toBeVisible();
expect(getByText('env2')).toBeVisible();
expect(getByText('env1').closest('button')).toHaveClass('v-btn--active', {
exact: false,
});
expect(getByText('env2').closest('button')).not.toHaveClass(
'v-btn--active',
{ exact: false },
);
});

it('should switch between urls without changing the rest of the path', async () => {
// given
mockHref.mockReturnValue(TEST_URL_ENV_1);

// and
const { getByText } = render(EnvironmentSwitch, {
props: {
knownEnvironments: [
{
name: 'env1',
url: 'localhost:3000',
},
{
name: 'env2',
url: '127.0.0.1:3000',
},
],
},
});

// when
await fireEvent.click(getByText('env2').closest('button'));

// then
expect(mockReplace).toHaveBeenCalledWith(TEST_URL_ENV_2);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script setup lang="ts">
import { computed } from 'vue';
import type { ConsoleEnvironment } from '@/api/app-configuration';
const props = defineProps<{
knownEnvironments: ConsoleEnvironment[];
}>();
const selectedEnv = computed(() =>
props.knownEnvironments.indexOf(getCurrentEnv()),
);
function getCurrentEnv(): ConsoleEnvironment {
const url = location.href;
const envs = props.knownEnvironments;
return envs.find(
(env) =>
url.startsWith(env.url) ||
url.startsWith(`http://${env.url}`) ||
url.startsWith(`https://${env.url}`),
);
}
function switchToEnv(env: ConsoleEnvironment): string {
const currentUrl = location.href;
const currentEnv: ConsoleEnvironment = getCurrentEnv();
const switchedUrl = currentUrl.replace(currentEnv.url, env.url);
window.location.replace(switchedUrl);
}
</script>

<template>
<v-btn-toggle color="primary" rounded="0" v-model="selectedEnv" group>
<v-btn
v-for="env in knownEnvironments"
min-width="100"
v-bind:key="env.name"
v-on:click="switchToEnv(env)"
>
{{ env.name }}
</v-btn>
</v-btn-toggle>
</template>

<style scoped lang="scss"></style>
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ public static final class Console {

private boolean criticalEnvironment = false;

private List<ConsoleEnvironment> knownEnvironments = Collections.emptyList();

public String getTitle() {
return title;
}
Expand Down Expand Up @@ -129,6 +131,35 @@ public String getEnvironmentName() {
public void setEnvironmentName(String environmentName) {
this.environmentName = environmentName;
}

public List<ConsoleEnvironment> getKnownEnvironments() {
return knownEnvironments;
}

public void setKnownEnvironments(List<ConsoleEnvironment> knownEnvironments) {
this.knownEnvironments = knownEnvironments;
}
}

public static final class ConsoleEnvironment {
private String name;
private String url;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}

public Owner getOwner() {
Expand Down
7 changes: 6 additions & 1 deletion hermes-management/src/main/resources/application-local.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
console:
console:
title: hermes console
knownEnvironments:
- name: localhost
url: http://localhost:8090
- name: also-localhost
url: http://127.0.0.1:8090
dashboard:
metrics: http://localhost:8082
docs: http://hermes-pubsub.rtfd.org
Expand Down Expand Up @@ -51,4 +56,4 @@ spring:
order: 2147483647
mvc:
servlet:
path: /
path: /
12 changes: 11 additions & 1 deletion hermes-management/src/main/resources/console/config-local.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
{
"console": {
"title": "hermes console"
"title": "hermes console",
"knownEnvironments": [
{
"name": "local",
"url": "localhost:8090"
},
{
"name": "also-local",
"url": "127.0.0.1:8090"
}
]
},
"dashboard": {
"metrics": "http://localhost:8082",
Expand Down

0 comments on commit 5757719

Please sign in to comment.