Skip to content

Commit

Permalink
feat(#1510): implement grouping of services in wallboard
Browse files Browse the repository at this point in the history
  • Loading branch information
SteKoe committed Oct 6, 2023
1 parent 3e8cfc7 commit d2f064f
Show file tree
Hide file tree
Showing 5 changed files with 322 additions and 333 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function createApplicationStore() {
}

type ApplicationStoreValue = {
applications: Ref<UnwrapRef<Application[]>>;
applications: Ref<Application[]>;
applicationsInitialized: Ref<boolean>;
error: Ref<any>;
applicationStore: ApplicationStore;
Expand Down
2 changes: 2 additions & 0 deletions spring-boot-admin-server-ui/src/main/frontend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import views from './views';

import eventBus from '@/services/bus';
import sbaShell from '@/shell';
import VueClickAwayPlugin from "vue3-click-away";

const applicationStore = createApplicationStore();
const viewRegistry = createViewRegistry();
Expand Down Expand Up @@ -128,6 +129,7 @@ const app = createApp({

app.use(i18n);
app.use(components);
app.use(VueClickAwayPlugin);
app.use(NotificationcenterPlugin, {
duration: 10_000,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Instance from "@/services/instance";
import {groupBy, sortBy, transform} from "lodash-es";
import Application from "@/services/application";

const groupingFunctions = {
'application': (instance: Instance) => instance.registration.name,
'group': (instance: Instance) => instance.registration.metadata?.['group'] ?? "term.no_group",
}

export type GroupingType = keyof typeof groupingFunctions;

export type InstancesListType = {
name?: string;
statusKey?: string;
status?: string;
instances?: Instance[];
applications?: Application[];
}

export const groupApplicationsBy = (applications: Application[], groupingFunction: GroupingType) => {
const instances = applications.flatMap(application => application.instances);
return groupInstancesBy(instances, groupingFunction);
}

export const groupInstancesBy = (instances: Instance[], groupingFunction: GroupingType) => {
const grouped = groupBy<Instance>(
instances,
groupingFunctions[groupingFunction]
);

const list = transform<Instance[], InstancesListType[]>(
grouped,
(result, instances, name) => {
result.push({
name,
instances: sortBy(instances, [
(instance) => instance.registration.name,
]),
});
}, []);

return sortBy(list, [(item) => item.status]);
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,90 +13,85 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import moment from 'moment';

import sbaConfig from '@/sba-config';
import axios from '@/utils/axios';
import uri from '@/utils/uri';
import Application from "@/services/application";
import Instance from "@/services/instance";

export type NotificationFilterProps = {
id: string,
applicationName: string,
instanceId: string,
expiry: string,
expired: boolean
}

class NotificationFilter {
private id: string;
private applicationName: string;
private instanceId: string;
private expiry: moment.Moment | null;

constructor({ expiry, ...filter }) {
Object.assign(this, filter);
this.expiry = expiry ? moment(expiry) : null;
}

affects(obj) {
if (!obj) {
return false;
public readonly expired: boolean;
private readonly id: string;
private readonly applicationName: string;
private readonly instanceId: string;

constructor({id, applicationName, instanceId, expiry, expired, ...filter}: NotificationFilterProps) {
Object.assign(this, filter);
this.id = id;
this.applicationName = applicationName;
this.instanceId = instanceId;
this.expired = expired;
}

if (this.isApplicationFilter) {
return this.applicationName === obj.name;
static isSupported() {
return Boolean(sbaConfig.uiSettings.notificationFilterEnabled);
}

if (this.isInstanceFilter) {
return this.instanceId === obj.id;
static async getFilters() {
return axios.get('notifications/filters', {
transformResponse: NotificationFilter._transformResponse,
});
}

return false;
}

get isApplicationFilter() {
return this.applicationName != null;
}

get isInstanceFilter() {
return this.instanceId != null;
}
static async addFilter(object: Instance | Application, ttl: number) {
const params = {ttl} as { ttl: number, applicationName?: string; instanceId?: string };
if (object instanceof Application) {
params.applicationName = object.name;
} else if ('id' in object) {
params.instanceId = object.id;
}
return axios.post('notifications/filters', null, {
params,
transformResponse: NotificationFilter._transformResponse,
});
}

async delete() {
return axios.delete(uri`notifications/filters/${this.id}`);
}
static _transformResponse(data: any) {
if (!data) {
return data;
}
const json = JSON.parse(data);
if (json instanceof Array) {
return json
.map((notificationFilter) => new NotificationFilter(notificationFilter))
.filter((f) => !f.expired);
}
return new NotificationFilter(json);
}

static isSupported() {
return Boolean(sbaConfig.uiSettings.notificationFilterEnabled);
}
affects(obj: Instance | Application) {
if (!obj) {
return false;
}

static async getFilters() {
return axios.get('notifications/filters', {
transformResponse: NotificationFilter._transformResponse,
});
}
if (obj instanceof Application) {
return this.applicationName === obj.name;
}

static async addFilter(object, ttl) {
const params = { ttl };
if ('name' in object) {
params.applicationName = object.name;
} else if ('id' in object) {
params.instanceId = object.id;
return this.instanceId === obj.id;
}
return axios.post('notifications/filters', null, {
params,
transformResponse: NotificationFilter._transformResponse,
});
}

static _transformResponse(data) {
if (!data) {
return data;
async delete() {
return axios.delete(uri`notifications/filters/${this.id}`);
}
const json = JSON.parse(data);
if (json instanceof Array) {
return json
.map(NotificationFilter._toNotificationFilters)
.filter((f) => !f.expired);
}
return NotificationFilter._toNotificationFilters(json);
}

static _toNotificationFilters(notificationFilter) {
return new NotificationFilter(notificationFilter);
}
}

export default NotificationFilter;
Loading

0 comments on commit d2f064f

Please sign in to comment.