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
11 changes: 11 additions & 0 deletions src/app/components/dashboard/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ header {
padding-bottom: 20px;
}

nav {
display: flex;
align-items: center;
gap: 20px;
}

.workspace-card-link {
text-decoration: none;
color: inherit;
}

.logout-btn {
background-color: #f44336;
color: white;
Expand Down
14 changes: 8 additions & 6 deletions src/app/components/dashboard/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ <h2>Your Workspaces</h2>
</div>

<div class="workspace-list">
<div *ngFor="let ws of workspaces" class="workspace-card">
<h3>{{ ws.name }}</h3>
<p>{{ ws.description }}</p>
<small>Created: {{ ws.createdDate | date }}</small>
</div>
<a *ngFor="let ws of workspaces" [routerLink]="['/workspaces', ws.id]" class="workspace-card-link">
<div class="workspace-card">
<h3>{{ ws.name }}</h3>
<p>{{ ws.description }}</p>
<small>Created: {{ ws.createdDate | date }}</small>
</div>
</a>
</div>

<div *ngIf="workspaces.length === 0" class="empty-state">
<p>No workspaces found. Create one to get started!</p>
</div>
Expand Down
67 changes: 67 additions & 0 deletions src/app/components/decision-form/decision-form.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
.form-container {
max-width: 600px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #fff;
}

.form-group {
margin-bottom: 15px;
}

.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}

.form-control {
width: 100%;
padding: 8px;
border: 1px solid #ced4da;
border-radius: 4px;
box-sizing: border-box;
/* Ensures padding doesn't increase width */
}

.form-control.is-invalid {
border-color: #dc3545;
}

.invalid-feedback {
color: #dc3545;
font-size: 12px;
margin-top: 5px;
}

.form-actions {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
}

.btn-primary {
background-color: #007bff;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}

.btn-primary:disabled {
background-color: #a0c4ff;
cursor: not-allowed;
}

.btn-secondary {
background-color: #6c757d;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}
36 changes: 36 additions & 0 deletions src/app/components/decision-form/decision-form.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div class="form-container">
<h2>{{ isEditMode ? 'Edit Decision' : 'Create New Decision' }}</h2>

<form [formGroup]="decisionForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="title">Title *</label>
<input type="text" id="title" formControlName="title" class="form-control"
[ngClass]="{'is-invalid': decisionForm.get('title')?.invalid && decisionForm.get('title')?.touched}">
<div *ngIf="decisionForm.get('title')?.invalid && decisionForm.get('title')?.touched"
class="invalid-feedback">
Title is required.
</div>
</div>

<div class="form-group">
<label for="description">Description</label>
<textarea id="description" formControlName="description" class="form-control" rows="4"></textarea>
</div>

<div class="form-group">
<label for="status">Status</label>
<select id="status" formControlName="status" class="form-control">
<option value="DRAFT">Draft</option>
<option value="OPEN">Open</option>
<option value="CLOSED">Closed</option>
</select>
</div>

<div class="form-actions">
<button type="button" routerLink="../" class="btn-secondary">Cancel</button>
<button type="submit" [disabled]="decisionForm.invalid || isLoading" class="btn-primary">
{{ isEditMode ? 'Update Decision' : 'Create Decision' }}
</button>
</div>
</form>
</div>
88 changes: 88 additions & 0 deletions src/app/components/decision-form/decision-form.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { DecisionService } from '../../services/decision.service';
import { Decision } from '../../models/decision.model';

@Component({
selector: 'app-decision-form',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, RouterModule],
templateUrl: './decision-form.component.html',
styleUrls: ['./decision-form.component.css']
})
export class DecisionFormComponent implements OnInit {
decisionForm: FormGroup;
isEditMode = false;
decisionId: string | null = null;
isLoading = false;

constructor(
private fb: FormBuilder,
private decisionService: DecisionService,
private route: ActivatedRoute,
private router: Router
) {
this.decisionForm = this.fb.group({
title: ['', Validators.required],
description: [''],
status: ['DRAFT', Validators.required]
});
}

ngOnInit(): void {
// Get workspaceId from parent
this.route.parent?.paramMap.subscribe(params => {
const workspaceId = params.get('id');
if (workspaceId) {
this.decisionForm.patchValue({ workspaceId });
}
});

// Get decisionId from current route
this.route.paramMap.subscribe(params => {
this.decisionId = params.get('decisionId');
if (this.decisionId) {
this.isEditMode = true;
this.loadDecision(this.decisionId);
}
});
}

loadDecision(id: string): void {
this.isLoading = true;
this.decisionService.getDecision(id).subscribe(decision => {
this.isLoading = false;
if (decision) {
this.decisionForm.patchValue({
title: decision.title,
description: decision.description,
status: decision.status
});
} else {
this.router.navigate(['../'], { relativeTo: this.route });
}
});
}

onSubmit(): void {
if (this.decisionForm.invalid) {
return;
}

const formValue = this.decisionForm.value;

if (this.isEditMode && this.decisionId) {
this.decisionService.updateDecision(this.decisionId, formValue).subscribe(() => {
this.router.navigate(['../../'], { relativeTo: this.route });
});
} else {
// Include workspaceId from parent route if available
const workspaceId = this.route.parent?.snapshot.paramMap.get('id');
this.decisionService.createDecision({ ...formValue, workspaceId }).subscribe(() => {
this.router.navigate(['../'], { relativeTo: this.route });
});
}
}
}
Empty file.
1 change: 1 addition & 0 deletions src/app/components/decision-form/decision-form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>decision-form works!</p>
11 changes: 11 additions & 0 deletions src/app/components/decision-form/decision-form.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from '@angular/core';

@Component({
selector: 'app-decision-form',
imports: [],
templateUrl: './decision-form.html',
styleUrl: './decision-form.css',
})
export class DecisionForm {

}
87 changes: 87 additions & 0 deletions src/app/components/decision-list/decision-list.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
.decision-container {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}

.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}

.btn-primary {
background-color: #007bff;
color: white;
padding: 10px 15px;
text-decoration: none;
border-radius: 4px;
}

.btn-secondary {
background-color: #6c757d;
color: white;
padding: 5px 10px;
text-decoration: none;
border-radius: 4px;
margin-right: 5px;
cursor: pointer;
border: none;
}

.btn-danger {
background-color: #dc3545;
color: white;
padding: 5px 10px;
border: none;
border-radius: 4px;
cursor: pointer;
}

.decision-card {
border: 1px solid #ddd;
padding: 15px;
margin-bottom: 10px;
border-radius: 4px;
background-color: #fff;
}

.decision-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}

.decision-header h3 {
margin: 0;
}

.status-badge {
padding: 3px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
}

.status-badge.draft {
background-color: #e2e3e5;
color: #383d41;
}

.status-badge.open {
background-color: #d4edda;
color: #155724;
}

.status-badge.closed {
background-color: #d1ecf1;
color: #0c5460;
}

.decision-meta {
font-size: 12px;
color: #666;
margin-bottom: 10px;
}
27 changes: 27 additions & 0 deletions src/app/components/decision-list/decision-list.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="decision-container">
<div class="header">
<h2>Decisions</h2>
<a routerLink="new" class="btn-primary">Create New Decision</a>
</div>

<div class="decision-list" *ngIf="decisions$ | async as decisions">
<div *ngIf="decisions.length === 0" class="empty-state">
No decisions found. Create one to get started!
</div>

<div *ngFor="let decision of decisions" class="decision-card">
<div class="decision-header">
<h3>{{ decision.title }}</h3>
<span class="status-badge" [ngClass]="decision.status.toLowerCase()">{{ decision.status }}</span>
</div>
<p class="decision-desc">{{ decision.description || 'No description provided.' }}</p>
<div class="decision-meta">
<span>Created: {{ decision.createdAt | date:'shortDate' }}</span>
</div>
<div class="decision-actions">
<a [routerLink]="[decision.id, 'edit']" class="btn-secondary">Edit</a>
<button (click)="deleteDecision(decision.id)" class="btn-danger">Delete</button>
</div>
</div>
</div>
</div>
Loading