Skip to content
Merged
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
5 changes: 3 additions & 2 deletions src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClient, withInterceptors } from '@angular/common/http';

import { routes } from './app.routes';
import { authInterceptor } from './auth.interceptor';

export const appConfig: ApplicationConfig = {
providers: [
provideBrowserGlobalErrorListeners(),
provideRouter(routes),
provideHttpClient()
provideHttpClient(withInterceptors([authInterceptor]))
]
};
19 changes: 19 additions & 0 deletions src/app/auth.interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { HttpInterceptorFn } from '@angular/common/http';

const TOKEN_KEY = 'sentinent_token';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
const token = localStorage.getItem(TOKEN_KEY);

if (!token || req.url.startsWith('http://') || req.url.startsWith('https://')) {
return next(req);
}

return next(
req.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
}),
);
};
12 changes: 10 additions & 2 deletions src/app/components/decision-form/decision-form.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ export class DecisionFormComponent implements OnInit {
}

loadDecision(id: string): void {
if (!this.workspaceId) {
return;
}

this.isLoading = true;
this.decisionService.getDecision(id).subscribe(decision => {
this.decisionService.getDecision(this.workspaceId, id).subscribe(decision => {
this.isLoading = false;
if (decision) {
this.decisionForm.patchValue({
Expand All @@ -71,7 +75,11 @@ export class DecisionFormComponent implements OnInit {
const formValue = this.decisionForm.value;

if (this.isEditMode && this.decisionId) {
this.decisionService.updateDecision(this.decisionId, formValue).subscribe(() => {
if (!this.workspaceId) {
return;
}

this.decisionService.updateDecision(this.workspaceId, this.decisionId, formValue).subscribe(() => {
this.router.navigate(['../../'], { relativeTo: this.route });
});
} else {
Expand Down
Empty file.
1 change: 0 additions & 1 deletion src/app/components/decision-form/decision-form.html

This file was deleted.

11 changes: 0 additions & 11 deletions src/app/components/decision-form/decision-form.ts

This file was deleted.

13 changes: 8 additions & 5 deletions src/app/components/decision-list/decision-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,25 @@ import { Observable } from 'rxjs';
})
export class DecisionListComponent implements OnInit {
decisions$: Observable<Decision[]> | undefined;
private workspaceId: string | null = null;

constructor(
private decisionService: DecisionService,
private route: ActivatedRoute
) { }

ngOnInit(): void {
const workspaceId = this.getWorkspaceIdFromRoute();
if (workspaceId) {
this.decisions$ = this.decisionService.getDecisions(workspaceId);
this.workspaceId = this.getWorkspaceIdFromRoute();
if (this.workspaceId) {
this.decisions$ = this.decisionService.getDecisions(this.workspaceId);
}
}

deleteDecision(id: string): void {
if (confirm('Are you sure you want to delete this decision?')) {
this.decisionService.deleteDecision(id);
if (confirm('Are you sure you want to delete this decision?') && this.workspaceId) {
this.decisionService.deleteDecision(this.workspaceId, id).subscribe(() => {
this.decisions$ = this.decisionService.getDecisions(this.workspaceId!);
});
}
}

Expand Down
Empty file.
1 change: 0 additions & 1 deletion src/app/components/decision-list/decision-list.html

This file was deleted.

11 changes: 0 additions & 11 deletions src/app/components/decision-list/decision-list.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,15 @@ describe('WorkspaceIntegrationsComponent', () => {

beforeEach(async () => {
mockIntegrationService = jasmine.createSpyObj<IntegrationService>('IntegrationService', [
'getSlackAuthUrl',
'getSlackChannels',
'connectSlack',
'updateSlackChannels',
'disconnectSlack',
'getGitHubAuthUrl',
'getGitHubRepos',
'connectGitHub',
'updateGitHubRepos',
'disconnectGitHub',
'syncGitHub',
'getSyncStatus'
'syncGitHub'
]);

mockIntegrationService.getSlackChannels.and.returnValue(of({
Expand All @@ -36,8 +33,7 @@ describe('WorkspaceIntegrationsComponent', () => {
}));
mockIntegrationService.updateSlackChannels.and.returnValue(of(void 0));
mockIntegrationService.disconnectSlack.and.returnValue(of(void 0));
mockIntegrationService.getSlackAuthUrl.and.returnValue(of({ authUrl: 'https://slack.com/mock' }));
mockIntegrationService.connectSlack.and.returnValue(of({ connected: true }));
mockIntegrationService.connectSlack.and.returnValue(of(void 0));

mockIntegrationService.getGitHubRepos.and.returnValue(of({
connected: true,
Expand All @@ -49,16 +45,9 @@ describe('WorkspaceIntegrationsComponent', () => {
lastSyncAt: new Date('2026-03-23T10:00:00Z')
}));
mockIntegrationService.updateGitHubRepos.and.returnValue(of(void 0));
mockIntegrationService.syncGitHub.and.returnValue(of({ syncId: 'sync-1' }));
mockIntegrationService.getSyncStatus.and.returnValue(of({
syncId: 'sync-1',
status: 'completed',
itemsSynced: 6,
completedAt: new Date('2026-03-23T10:05:00Z')
}));
mockIntegrationService.syncGitHub.and.returnValue(of({ syncId: 'sync-1', status: 'in_progress' }));
mockIntegrationService.disconnectGitHub.and.returnValue(of(void 0));
mockIntegrationService.getGitHubAuthUrl.and.returnValue(of({ authUrl: 'https://github.com/mock' }));
mockIntegrationService.connectGitHub.and.returnValue(of({ connected: true }));
mockIntegrationService.connectGitHub.and.returnValue(of(void 0));

await TestBed.configureTestingModule({
imports: [WorkspaceIntegrationsComponent],
Expand Down Expand Up @@ -93,13 +82,13 @@ describe('WorkspaceIntegrationsComponent', () => {
fixture.detectChanges();

expect(mockIntegrationService.syncGitHub).toHaveBeenCalled();
expect(component.githubFeedbackMessage).toContain('6 items refreshed');
expect(component.githubFeedbackMessage).toContain('started');
});

it('should save slack channel selection', () => {
component.saveSlackChannelSelection();

expect(mockIntegrationService.updateSlackChannels).toHaveBeenCalled();
expect(mockIntegrationService.updateSlackChannels).toHaveBeenCalledWith('workspace-1', ['C123']);
expect(component.slackFeedbackMessage).toContain('saved');
});
});
42 changes: 20 additions & 22 deletions src/app/components/workspace-integrations/workspace-integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ export class WorkspaceIntegrationsComponent implements OnInit {
connectSlack(): void {
this.slackErrorMessage = '';
this.slackFeedbackMessage = 'Starting Slack connection...';
this.integrationService.getSlackAuthUrl().subscribe(() => {
this.integrationService.connectSlack().subscribe(() => {
this.slackFeedbackMessage = 'Slack workspace connected. Choose the channels you want to monitor.';
this.loadSlackChannels();
});
this.integrationService.connectSlack(this.workspaceId).subscribe({
error: (error: Error) => {
this.slackErrorMessage = error.message;
this.slackFeedbackMessage = '';
}
});
}

disconnectSlack(): void {
this.integrationService.disconnectSlack().subscribe(() => {
this.integrationService.disconnectSlack(this.workspaceId).subscribe(() => {
this.slackFeedbackMessage = 'Slack integration disconnected.';
this.loadSlackChannels();
});
Expand All @@ -66,11 +66,11 @@ export class WorkspaceIntegrationsComponent implements OnInit {
connectGitHub(): void {
this.githubErrorMessage = '';
this.githubFeedbackMessage = 'Starting GitHub connection...';
this.integrationService.getGitHubAuthUrl().subscribe(() => {
this.integrationService.connectGitHub().subscribe(() => {
this.githubFeedbackMessage = 'GitHub account connected. Select the repositories you want Sentinent to monitor.';
this.loadRepos();
});
this.integrationService.connectGitHub().subscribe({
error: (error: Error) => {
this.githubErrorMessage = error.message;
this.githubFeedbackMessage = '';
}
});
}

Expand Down Expand Up @@ -107,7 +107,7 @@ export class WorkspaceIntegrationsComponent implements OnInit {
saveSlackChannelSelection(): void {
this.isSlackSaving = true;
this.slackErrorMessage = '';
this.integrationService.updateSlackChannels(this.selectedSlackChannelIds).subscribe({
this.integrationService.updateSlackChannels(this.workspaceId, this.selectedSlackChannelIds).subscribe({
next: () => {
this.isSlackSaving = false;
this.slackFeedbackMessage = 'Slack channel selection saved.';
Expand Down Expand Up @@ -140,15 +140,13 @@ export class WorkspaceIntegrationsComponent implements OnInit {
this.isSyncing = true;
this.githubErrorMessage = '';
this.integrationService.syncGitHub().subscribe({
next: ({ syncId }) => {
this.integrationService.getSyncStatus(syncId).subscribe(status => {
this.githubSyncStatus = status;
this.isSyncing = false;
this.githubLastSyncAt = status.completedAt;
this.githubFeedbackMessage = status.status === 'completed'
? `Sync completed. ${status.itemsSynced ?? 0} items refreshed.`
: 'GitHub sync failed.';
});
next: (status) => {
this.githubSyncStatus = status;
this.isSyncing = false;
this.githubFeedbackMessage = status.status === 'in_progress'
? 'GitHub sync started. Signals will refresh shortly.'
: 'GitHub sync could not be started.';
this.loadRepos();
},
error: (error: Error) => {
this.isSyncing = false;
Expand All @@ -166,7 +164,7 @@ export class WorkspaceIntegrationsComponent implements OnInit {
}

private loadSlackChannels(): void {
this.integrationService.getSlackChannels().subscribe(response => {
this.integrationService.getSlackChannels(this.workspaceId).subscribe(response => {
this.isSlackConnected = response.connected;
this.slackChannels = response.channels;
this.selectedSlackChannelIds = response.channels.filter(channel => channel.isConnected).map(channel => channel.id);
Expand Down
16 changes: 0 additions & 16 deletions src/app/components/workspace/create-workspace-placeholder.ts

This file was deleted.

Loading
Loading