Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
webapp/node_modules

webapp/package-lock.json
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ RUN npm run build

FROM nginx:stable-alpine-slim AS serve
COPY scripts/docker/docker_nginx.conf /etc/nginx/conf.d/default.conf
COPY scripts/docker/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

WORKDIR /usr/share/nginx/html
COPY --from=build /app/dist/webapp/browser .
EXPOSE 80

ENTRYPOINT ["/docker-entrypoint.sh"]
9 changes: 9 additions & 0 deletions scripts/docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
set -e

# Update runtime variables
envsubst '${AUTO_ATTACH_PUBSUB_PROJECTS}' < /usr/share/nginx/html/index.html > /usr/share/nginx/html/index.html.tmp
envsubst '${DEFAULT_PUBSUB_EMULATOR_HOST}' < /usr/share/nginx/html/index.html.tmp > /usr/share/nginx/html/index.html

# Start nginx
exec nginx -g 'daemon off;'
63 changes: 60 additions & 3 deletions webapp/src/app/services/pubsub.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@ import { Injectable, inject } from '@angular/core';
import { BehaviorSubject, EMPTY, map, Observable, ReplaySubject } from 'rxjs';
import { NewSubscriptionRequest } from '../components/subscription-list/new-subscription-dialog/new-subscription-dialog.component';

// Declare window.APP_CONFIG for runtime configuration
declare global {
interface Window {
APP_CONFIG?: {
autoAttachPubsubProjects?: string;
defaultPubsubEmulatorHost?: string;
};
}
}

@Injectable({
providedIn: 'root'
})
export class PubsubService {
private http = inject(HttpClient);

public _currentHost$ = new BehaviorSubject<string>("http://localhost:8681")
public _currentHost$ = new BehaviorSubject<string>("")

private _projectList = new BehaviorSubject<string[]>([])
private _currentProject = new ReplaySubject<string>()
Expand All @@ -23,21 +33,68 @@ export class PubsubService {
public currentSubscription$ = this._currentSubscription.asObservable()

constructor() {
let defaultHost = window.APP_CONFIG?.defaultPubsubEmulatorHost || ""
if (!defaultHost || defaultHost === '${DEFAULT_PUBSUB_EMULATOR_HOST}') {
defaultHost = "http://localhost:8681"
}

if (!defaultHost.match(/^http[s]?:\/\//)) {
defaultHost = `http://${defaultHost}`
}

const prevHost = localStorage.getItem("host")
if (prevHost) {
console.log('loaded previous host', prevHost)
this._currentHost$.next(prevHost)
} else {
console.log('loaded default host', defaultHost)
this._currentHost$.next(defaultHost)
}

const prevProjects = localStorage.getItem("projects") ?? "[]"
const projects: string[] = JSON.parse(prevProjects) ?? []
this._projectList.next(projects)

// Auto-attach projects from environment variable (idempotent)
const autoAttachProjects = this.getAutoAttachProjects()
const mergedProjects = this.mergeProjectsIdempotently(projects, autoAttachProjects)

this._projectList.next(mergedProjects)

// Save merged list to localStorage if auto-attach added new projects
if (mergedProjects.length !== projects.length) {
localStorage.setItem("projects", JSON.stringify(mergedProjects))
console.log('auto-attached projects:', autoAttachProjects)
}

this.currentProject$.subscribe(project =>
this.topicList$ = this.listTopics(project)
)
}

private getAutoAttachProjects(): string[] {
const autoAttachProjects = window.APP_CONFIG?.autoAttachPubsubProjects || ''
if (!autoAttachProjects || autoAttachProjects === "${AUTO_ATTACH_PUBSUB_PROJECTS}") {
return []
}

return autoAttachProjects
.split(',')
.map(project => project.trim())
.filter(project => project.length > 0)
}

private mergeProjectsIdempotently(existing: string[], autoAttach: string[]): string[] {
const merged = [...existing]

for (const project of autoAttach) {
if (!merged.includes(project)) {
merged.push(project)
}
}

return merged
}

setHost(hostUrl: string) {
this._currentHost$.next(hostUrl)

Expand Down Expand Up @@ -141,7 +198,7 @@ export interface ReceivedMessage {
}

export interface PubsubMessage {
data: string
data: string
attributes?: { [key: string]: string }
messageId?: string
publishTime?: string
Expand Down
6 changes: 6 additions & 0 deletions webapp/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="http://fonts.cdnfonts.com/css/cascadia-code" rel="stylesheet">

<script>
window.APP_CONFIG = {
autoAttachPubsubProjects: '${AUTO_ATTACH_PUBSUB_PROJECTS}',
defaultPubsubEmulatorHost: '${DEFAULT_PUBSUB_EMULATOR_HOST}'
};
</script>
</head>
<body class="mat-app-background">
<app-root></app-root>
Expand Down