Skip to content

Commit

Permalink
Added topic information
Browse files Browse the repository at this point in the history
  • Loading branch information
mligtenberg committed Jan 10, 2025
1 parent 92eae14 commit 9f59c35
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import { TableModule } from 'primeng/table';
styleUrl: './queue-management.component.scss',
})
export class QueueManagementComponent {
newParams$ = new Subject<void>();
activeRoute = inject(ActivatedRoute);
store = inject(Store);
form = this.createForm();
Expand All @@ -68,7 +67,6 @@ export class QueueManagementComponent {
constructor() {
combineLatest([this.activeRoute.params, this.activeRoute.data])
.pipe(
takeUntilDestroyed(),
switchMap(([params, data]) => {
const action = data['action'] as 'create' | 'modify';

Expand All @@ -83,10 +81,6 @@ export class QueueManagementComponent {
return of({ action: 'create', queue: undefined });
}

this.newParams$.next();
this.newParams$.complete();
this.newParams$ = new Subject<void>();

// new queue form
if (!queueId) {
throw new Error('Queue ID is required for modify action');
Expand All @@ -101,7 +95,8 @@ export class QueueManagementComponent {
queue,
}))
);
})
}),
takeUntilDestroyed(),
)
.subscribe(({ action, queue }) => {
this.form = this.createForm();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,25 @@
<label for="supportOrdering">Support ordering</label>
</div>
</p-card>

@if (action() === 'modify') {
<p-card class="information" header="Topic Information">
<p-table [columns]="informationCols" [value]="currentTopicInformation()" [scrollable]="true">
<ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex" let-columns="columns">
<tr style="height:30px">
<td *ngFor="let col of columns">
@if (isDate(rowData[col.field])) {
{{ rowData[col.field] | date: 'medium' }}
} @else {
{{ rowData[col.field] }}
}
</td>
</tr>
</ng-template>
</p-table>
</p-card>
}

<div class="actions">
<button pButton type="button" (click)="save()" [disabled]="form.invalid">Save</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@ form {
'actions actions';
grid-template-columns: 3fr 2fr;

@media (max-width: 1024px) {
grid-template-areas:
'name'
'settings'
'properties'
'actions';
grid-template-columns: 1fr;
}

.name {
grid-area: name;
}
Expand All @@ -49,12 +40,25 @@ form {
grid-area: settings;
}

.information {
grid-area: information;
}

.actions {
grid-area: actions;
display: flex;
justify-content: flex-end;
gap: 0.5rem;
}

@container mainContent (width < 900px) {
grid-template-areas:
'name actions'
'settings settings'
'properties properties'
'information information';
grid-template-columns: 1fr;
}
}

.checkbox {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { Component, inject } from '@angular/core';
import { Component, computed, inject, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Card } from 'primeng/card';
import { Checkbox } from 'primeng/checkbox';
import { DurationInputComponent } from '@service-bus-browser/shared-components';
import { EndpointSelectorInputComponent } from '@service-bus-browser/topology-components';
import { FloatLabel } from 'primeng/floatlabel';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { InputNumber } from 'primeng/inputnumber';
import { InputText } from 'primeng/inputtext';
import { QueueForm } from '../queue-management/form';
import { TopicForm } from './form';
import { Textarea } from 'primeng/textarea';
import { combineLatest, Subject, takeUntil } from 'rxjs';
import { combineLatest, map, of, switchMap } from 'rxjs';
import { ActivatedRoute } from '@angular/router';
import { Store } from '@ngrx/store';
import { UUID } from '@service-bus-browser/shared-contracts';
import { TopologyActions, TopologySelectors } from '@service-bus-browser/topology-store';
import { latestValueFrom } from 'nx/src/adapter/rxjs-for-await';
import { ButtonDirective } from 'primeng/button';
import { Queue, Topic } from '@service-bus-browser/topology-contracts';
import { Topic, TopicWithMetaData } from '@service-bus-browser/topology-contracts';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { PrimeTemplate } from 'primeng/api';
import { TableModule } from 'primeng/table';

@Component({
selector: 'lib-topic-management',
Expand All @@ -34,64 +34,85 @@ import { Queue, Topic } from '@service-bus-browser/topology-contracts';
ReactiveFormsModule,
Textarea,
ButtonDirective,
PrimeTemplate,
TableModule,
],
templateUrl: './topic-management.component.html',
styleUrl: './topic-management.component.scss',
})
export class TopicManagementComponent {
destroy$ = new Subject<void>();
newParams$ = new Subject<void>();
activeRoute = inject(ActivatedRoute);
store = inject(Store);
form = this.createForm();
action: 'create' | 'modify' = 'create';
action = signal<'create' | 'modify'>('create');
currentTopic = signal<TopicWithMetaData | undefined>(undefined);
currentTopicInformation = computed(() => {
const topic = this.currentTopic();
if (!topic) {
return [];
}

return Object.entries(topic.metadata).map(([key, value]) => ({
key,
value,
}));
});
informationCols = [
{ field: 'key', header: 'Key' },
{ field: 'value', header: 'Value' },
];

constructor() {
combineLatest([this.activeRoute.params, this.activeRoute.data])
.pipe(takeUntil(this.destroy$))
.subscribe(([params, data]) => {
const namespaceId = params['namespaceId'] as UUID | undefined;
const topicId = params['topicId'] as string | undefined;
this.action = data['action'] as 'create' | 'modify';

this.newParams$.next();
this.newParams$.complete();
this.newParams$ = new Subject<void>();

if (namespaceId === undefined) {
throw new Error('Namespace ID is required');
}
.pipe(
switchMap(([params, data]) => {
const namespaceId = params['namespaceId'] as UUID | undefined;
const topicId = params['topicId'] as string | undefined;
const action = data['action'] as 'create' | 'modify';

if (namespaceId === undefined) {
throw new Error('Namespace ID is required');
}

if (action === 'create') {
return of({ action: action, topic: undefined });
}

if (topicId === undefined) {
throw new Error('Topic ID is required for modify action');
}

return this.store
.select(TopologySelectors.selectTopicById(namespaceId, topicId))
.pipe(map((topic) => ({ action: action, topic: topic })));
}),
takeUntilDestroyed()
)
.subscribe(({ topic, action }) => {
this.action.set(action);
this.currentTopic.set(topic);

// new queue form
if (this.action === 'create') {
if (action === 'create') {
this.form = this.createForm();
this.configureFormAsCreate();
return;
}

if (topicId === undefined) {
throw new Error('Topic ID is required for modify action');
}

this.configureFormAsEdit();

this.store
.select(TopologySelectors.selectTopicById(namespaceId, topicId))
.pipe(takeUntil(this.newParams$), takeUntil(this.destroy$))
.subscribe((topic) => {
if (!topic) {
return;
}

this.form.setValue(
{
name: topic.name,
properties: topic.properties,
settings: topic.settings,
},
{ emitEvent: false }
);
});
if (!topic) {
return;
}

this.form.setValue(
{
name: topic.name,
properties: topic.properties,
settings: topic.settings,
},
{ emitEvent: false }
);
});
}

Expand All @@ -109,11 +130,6 @@ export class TopicManagementComponent {
this.form.controls.settings.controls.requiresDuplicateDetection.enable();
}

ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}

createForm() {
return new FormGroup<TopicForm>({
name: new FormControl<string>('', {
Expand Down Expand Up @@ -165,26 +181,30 @@ export class TopicManagementComponent {
name: formValue.name ?? '',
properties: {
maxSizeInMegabytes: formValue.properties.maxSizeInMegabytes ?? 0,
defaultMessageTimeToLive: formValue.properties.defaultMessageTimeToLive ?? '',
duplicateDetectionHistoryTimeWindow: formValue.properties.duplicateDetectionHistoryTimeWindow ?? '',
defaultMessageTimeToLive:
formValue.properties.defaultMessageTimeToLive ?? '',
duplicateDetectionHistoryTimeWindow:
formValue.properties.duplicateDetectionHistoryTimeWindow ?? '',
userMetadata: formValue.properties.userMetadata ?? null,
autoDeleteOnIdle: formValue.properties.autoDeleteOnIdle ?? '',
},
settings: {
requiresDuplicateDetection: formValue.settings.requiresDuplicateDetection ?? false,
requiresDuplicateDetection:
formValue.settings.requiresDuplicateDetection ?? false,
supportOrdering: formValue.settings.supportOrdering ?? false,
enableBatchedOperations: formValue.settings.enableBatchedOperations ?? false,
enableBatchedOperations:
formValue.settings.enableBatchedOperations ?? false,
enableExpress: formValue.settings.enableExpress ?? false,
enablePartitioning: formValue.settings.enablePartitioning ?? false,
},
}
};

// save queue
if (this.action === 'create') {
if (this.action() === 'create') {
this.store.dispatch(
TopologyActions.addTopic({
namespaceId: this.activeRoute.snapshot.params['namespaceId'],
topic
topic,
})
);
return;
Expand All @@ -194,8 +214,12 @@ export class TopicManagementComponent {
this.store.dispatch(
TopologyActions.editTopic({
namespaceId: this.activeRoute.snapshot.params['namespaceId'],
topic
topic,
})
);
}

isDate(value: unknown): boolean {
return value instanceof Date;
}
}

0 comments on commit 9f59c35

Please sign in to comment.