mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 21:03:03 -05:00
fix: run prettier on all file to avoid prettier issue inside PR
This commit is contained in:
@@ -3,7 +3,8 @@ import { Component } from '@angular/core';
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app-root',
|
||||
template: ` <label for="agree">Agreed</label>
|
||||
template: `
|
||||
<label for="agree">Agreed</label>
|
||||
<input
|
||||
class="ml-2"
|
||||
id="agree"
|
||||
@@ -11,12 +12,13 @@ import { Component } from '@angular/core';
|
||||
[value]="check"
|
||||
(input)="toggleCheck()" />
|
||||
<button
|
||||
class="border p-2 rounded-lg ml-10"
|
||||
class="ml-10 rounded-lg border p-2"
|
||||
[class.bg-gray-500]="!check"
|
||||
[class.text-white]="!check"
|
||||
[disabled]="!check">
|
||||
Submit
|
||||
</button>`,
|
||||
</button>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {
|
||||
check = false;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -11,7 +11,7 @@ import { skip } from 'rxjs';
|
||||
template: `
|
||||
<mat-card class="items-center">
|
||||
<mat-card-content>
|
||||
<div class="flex gap-10 items-center">
|
||||
<div class="flex items-center gap-10">
|
||||
<button id="minusButton" mat-mini-fab (click)="back()">
|
||||
<mat-icon>arrow_back_ios</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { appConfig } from './app/app.config';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
console.error(err),
|
||||
);
|
||||
|
||||
@@ -5,7 +5,9 @@ import { ChildComponent } from './child.component';
|
||||
standalone: true,
|
||||
imports: [ChildComponent],
|
||||
selector: 'app-root',
|
||||
template: `<app-child />`,
|
||||
template: `
|
||||
<app-child />
|
||||
`,
|
||||
styles: [''],
|
||||
})
|
||||
export class AppComponent {}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { MatSliderModule } from '@angular/material/slider';
|
||||
<h2 class="my-3">Slider configuration</h2>
|
||||
|
||||
<section class="flex items-center">
|
||||
<mat-form-field class="m-4 max-w-[180px] w-full">
|
||||
<mat-form-field class="m-4 w-full max-w-[180px]">
|
||||
<mat-label>Value</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -23,15 +23,15 @@ import { MatSliderModule } from '@angular/material/slider';
|
||||
[(ngModel)]="value"
|
||||
id="input-value" />
|
||||
</mat-form-field>
|
||||
<mat-form-field class="m-4 max-w-[180px] w-full">
|
||||
<mat-form-field class="m-4 w-full max-w-[180px]">
|
||||
<mat-label>Min value</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="min" id="input-min" />
|
||||
</mat-form-field>
|
||||
<mat-form-field class="m-4 max-w-[180px] w-full">
|
||||
<mat-form-field class="m-4 w-full max-w-[180px]">
|
||||
<mat-label>Max value</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="max" id="input-max" />
|
||||
</mat-form-field>
|
||||
<mat-form-field class="m-4 max-w-[180px] w-full">
|
||||
<mat-form-field class="m-4 w-full max-w-[180px]">
|
||||
<mat-label>Step size</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="step" id="input-step" />
|
||||
</mat-form-field>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { appConfig } from './app/app.config';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
console.error(err),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing';
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
component: nxComponentTestingPreset(__filename),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing';
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
component: nxComponentTestingPreset(__filename),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -58,8 +58,8 @@ export class AppComponent {
|
||||
.afterClosed()
|
||||
.subscribe((result) =>
|
||||
this.result.next(
|
||||
result ? 'Name has been submitted' : 'Name is invalid !!'
|
||||
)
|
||||
result ? 'Name has been submitted' : 'Name is invalid !!',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import { MatDialogModule } from '@angular/material/dialog';
|
||||
template: `
|
||||
<h1 mat-dialog-title>Error</h1>
|
||||
<div mat-dialog-content>
|
||||
You must enter a <span class="font-bold">name</span> first!!
|
||||
You must enter a
|
||||
<span class="font-bold">name</span>
|
||||
first!!
|
||||
</div>
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button mat-dialog-close>OK</button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { appConfig } from './app/app.config';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
|
||||
import { AppComponent } from './app/app.component';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
console.error(err),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing';
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
component: nxComponentTestingPreset(__filename),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -5,6 +5,8 @@ import { ChildComponent } from './child.component';
|
||||
standalone: true,
|
||||
imports: [ChildComponent],
|
||||
selector: 'app-root',
|
||||
template: ` <app-child></app-child> `,
|
||||
template: `
|
||||
<app-child></app-child>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {}
|
||||
|
||||
@@ -14,7 +14,9 @@ import { HttpService } from './http.service';
|
||||
selector: 'app-input',
|
||||
standalone: true,
|
||||
imports: [ReactiveFormsModule],
|
||||
template: ` <input type="text" [formControl]="title" /> `,
|
||||
template: `
|
||||
<input type="text" [formControl]="title" />
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class InputComponent {
|
||||
@@ -24,7 +26,9 @@ export class InputComponent {
|
||||
@Component({
|
||||
selector: 'result',
|
||||
standalone: true,
|
||||
template: ` <p>Title is {{ title }}</p> `,
|
||||
template: `
|
||||
<p>Title is {{ title }}</p>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ResultComponent {
|
||||
@@ -34,7 +38,9 @@ export class ResultComponent {
|
||||
@Component({
|
||||
selector: 'app-button',
|
||||
standalone: true,
|
||||
template: `<button (click)="validate.emit()">Validate</button>`,
|
||||
template: `
|
||||
<button (click)="validate.emit()">Validate</button>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ButtonComponent {
|
||||
@@ -44,7 +50,9 @@ export class ButtonComponent {
|
||||
@Component({
|
||||
selector: 'app-error',
|
||||
standalone: true,
|
||||
template: `<p>Title is required !!!</p>`,
|
||||
template: `
|
||||
<p>Title is required !!!</p>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ErrorComponent {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing';
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
component: nxComponentTestingPreset(__filename),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -4,7 +4,7 @@ import { availableBooks } from './book.model';
|
||||
|
||||
export const bookGuard = (
|
||||
route: ActivatedRouteSnapshot,
|
||||
router = inject(Router)
|
||||
router = inject(Router),
|
||||
) => {
|
||||
const searchParam = route.queryParams?.['book'].toLowerCase();
|
||||
|
||||
@@ -13,7 +13,7 @@ export const bookGuard = (
|
||||
availableBooks.some(
|
||||
(b) =>
|
||||
b.author.toLowerCase().includes(searchParam) ||
|
||||
b.name.toLowerCase().includes(searchParam)
|
||||
b.name.toLowerCase().includes(searchParam),
|
||||
);
|
||||
|
||||
return isBookAvailable || router.parseUrl('no-result');
|
||||
|
||||
@@ -2,7 +2,9 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
template: ` <div>No book found for this search</div> `,
|
||||
template: `
|
||||
<div>No book found for this search</div>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export default class ShelfComponent {}
|
||||
|
||||
@@ -25,8 +25,8 @@ export default class ShelfComponent {
|
||||
availableBooks.filter(
|
||||
(b) =>
|
||||
b.name.toLowerCase().includes(param) ||
|
||||
b.author.toLowerCase().includes(param)
|
||||
)
|
||||
)
|
||||
b.author.toLowerCase().includes(param),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { appConfig } from './app/app.config';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
|
||||
import { AppComponent } from './app/app.component';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
console.error(err),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing';
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
component: nxComponentTestingPreset(__filename),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -5,6 +5,8 @@ import { TableComponent } from './table.component';
|
||||
standalone: true,
|
||||
imports: [TableComponent],
|
||||
selector: 'app-root',
|
||||
template: ` <app-table /> `,
|
||||
template: `
|
||||
<app-table />
|
||||
`,
|
||||
})
|
||||
export class AppComponent {}
|
||||
|
||||
@@ -94,7 +94,7 @@ export class TableComponent
|
||||
private api = inject(FakeBackendService);
|
||||
|
||||
readonly issues$ = this.select((s) => s.users).pipe(
|
||||
tap((t) => console.log('UserNEw ', t))
|
||||
tap((t) => console.log('UserNEw ', t)),
|
||||
);
|
||||
readonly loading$ = this.select((s) => s.loading);
|
||||
readonly error$ = this.select((s) => s.error);
|
||||
@@ -124,11 +124,11 @@ export class TableComponent
|
||||
tap((t) => console.log('user', t)),
|
||||
tapResponse(
|
||||
(data) => this.patchState({ users: data, loading: false }),
|
||||
(err) => this.patchState({ error: err as string, loading: false })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(err) => this.patchState({ error: err as string, loading: false }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
@@ -137,7 +137,7 @@ export class TableComponent
|
||||
this.loadData(
|
||||
this.select({
|
||||
sortActive: this.sort.sortChange.pipe(
|
||||
map((s) => s.active as keyof User)
|
||||
map((s) => s.active as keyof User),
|
||||
),
|
||||
sortDir: this.sort.sortChange.pipe(map((s) => s.direction)),
|
||||
pageIndex: this.paginator.page.pipe(map((p) => p.pageIndex)),
|
||||
@@ -146,8 +146,8 @@ export class TableComponent
|
||||
sortActive: this.sort.active as keyof User,
|
||||
sortDir: this.sort.direction,
|
||||
pageIndex: 1,
|
||||
})
|
||||
)
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing';
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
component: nxComponentTestingPreset(__filename),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -5,6 +5,8 @@ import { RouterOutlet } from '@angular/router';
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet],
|
||||
template: `<router-outlet></router-outlet>`,
|
||||
template: `
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {}
|
||||
|
||||
@@ -101,7 +101,7 @@ export class BackendService {
|
||||
const updatedTicket = { ...foundTicket, ...updates };
|
||||
|
||||
this.storedTickets = this.storedTickets.map((t) =>
|
||||
t.id === ticketId ? updatedTicket : t
|
||||
t.id === ticketId ? updatedTicket : t,
|
||||
);
|
||||
|
||||
return of(updatedTicket).pipe(delay(randomDelay()));
|
||||
|
||||
@@ -19,22 +19,28 @@ import { DetailStore } from './detail.store';
|
||||
LetDirective,
|
||||
],
|
||||
template: `
|
||||
<h2 class="text-xl mb-2">Ticket Detail:</h2>
|
||||
<h2 class="mb-2 text-xl">Ticket Detail:</h2>
|
||||
<ng-container *ngrxLet="vm$ as vm">
|
||||
<mat-progress-bar
|
||||
mode="query"
|
||||
*ngIf="vm.loading"
|
||||
class="mt-5"></mat-progress-bar>
|
||||
<section *ngIf="vm.ticket as ticket" class="flex flex-col gap-4">
|
||||
<div><span class="font-bold">Ticket:</span> {{ ticket.id }}</div>
|
||||
<div>
|
||||
<span class="font-bold">Description:</span> {{ ticket.description }}
|
||||
<span class="font-bold">Ticket:</span>
|
||||
{{ ticket.id }}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-bold">AssigneeId:</span> {{ ticket.assigneeId }}
|
||||
<span class="font-bold">Description:</span>
|
||||
{{ ticket.description }}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-bold">Is done:</span> {{ ticket.completed }}
|
||||
<span class="font-bold">AssigneeId:</span>
|
||||
{{ ticket.assigneeId }}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-bold">Is done:</span>
|
||||
{{ ticket.completed }}
|
||||
</div>
|
||||
</section>
|
||||
</ng-container>
|
||||
|
||||
@@ -36,14 +36,17 @@ export class DetailStore
|
||||
loading: this.loading$,
|
||||
});
|
||||
|
||||
constructor(private backend: BackendService, private route: ActivatedRoute) {
|
||||
constructor(
|
||||
private backend: BackendService,
|
||||
private route: ActivatedRoute,
|
||||
) {
|
||||
super(initialState);
|
||||
}
|
||||
|
||||
readonly loadTicket = this.effect<void>(
|
||||
pipe(
|
||||
concatLatestFrom(() =>
|
||||
this.route.params.pipe(map((p) => p[PARAM_TICKET_ID]))
|
||||
this.route.params.pipe(map((p) => p[PARAM_TICKET_ID])),
|
||||
),
|
||||
tap(() => this.patchState({ loading: true, error: '' })),
|
||||
mergeMap(([, id]) =>
|
||||
@@ -54,11 +57,11 @@ export class DetailStore
|
||||
loading: false,
|
||||
ticket,
|
||||
}),
|
||||
(error: unknown) => this.patchState({ error })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(error: unknown) => this.patchState({ error }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
ngrxOnStateInit() {
|
||||
|
||||
@@ -25,7 +25,7 @@ import { RowComponent } from './ui/row.component';
|
||||
LetDirective,
|
||||
],
|
||||
template: `
|
||||
<h2 class="text-xl mb-2">Tickets</h2>
|
||||
<h2 class="mb-2 text-xl">Tickets</h2>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Search</mat-label>
|
||||
@@ -45,14 +45,13 @@ import { RowComponent } from './ui/row.component';
|
||||
mode="query"
|
||||
*ngIf="vm.loading"
|
||||
class="mt-5"></mat-progress-bar>
|
||||
<ul class="flex flex-col gap-4 max-w-3xl">
|
||||
<ul class="flex max-w-3xl flex-col gap-4">
|
||||
<app-row
|
||||
*ngFor="let t of vm.tickets"
|
||||
[ticket]="t"
|
||||
[users]="vm.users"
|
||||
(assign)="ticketStore.assignTicket($event)"
|
||||
(closeTicket)="ticketStore.done($event)">
|
||||
</app-row>
|
||||
(closeTicket)="ticketStore.done($event)"></app-row>
|
||||
</ul>
|
||||
<footer class="text-red-500">
|
||||
{{ vm.error }}
|
||||
|
||||
@@ -47,7 +47,7 @@ export class TicketStore
|
||||
users.find((user) => user.id === ticket.assigneeId)?.name ??
|
||||
'unassigned',
|
||||
}))
|
||||
: tickets
|
||||
: tickets,
|
||||
);
|
||||
|
||||
readonly tickets$ = this.select(
|
||||
@@ -55,8 +55,8 @@ export class TicketStore
|
||||
this.search$,
|
||||
(tickets, search) =>
|
||||
tickets.filter((t) =>
|
||||
t.description.toLowerCase().includes(search.toLowerCase())
|
||||
)
|
||||
t.description.toLowerCase().includes(search.toLowerCase()),
|
||||
),
|
||||
);
|
||||
|
||||
readonly vm$ = this.select(
|
||||
@@ -66,7 +66,7 @@ export class TicketStore
|
||||
loading: this.loading$,
|
||||
error: this.error$,
|
||||
},
|
||||
{ debounce: true }
|
||||
{ debounce: true },
|
||||
);
|
||||
|
||||
readonly updateAssignee = this.updater((state, ticket: Ticket) => {
|
||||
@@ -107,11 +107,11 @@ export class TicketStore
|
||||
loading: false,
|
||||
tickets,
|
||||
}),
|
||||
(error: unknown) => this.patchState({ error, loading: false })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(error: unknown) => this.patchState({ error, loading: false }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
readonly loadUsers = this.effect<void>(
|
||||
@@ -125,11 +125,11 @@ export class TicketStore
|
||||
loading: false,
|
||||
users,
|
||||
}),
|
||||
(error: unknown) => this.patchState({ error, loading: false })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(error: unknown) => this.patchState({ error, loading: false }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
readonly addTicket = this.effect<string>(
|
||||
@@ -143,11 +143,11 @@ export class TicketStore
|
||||
loading: false,
|
||||
tickets: [...state.tickets, newTicket],
|
||||
})),
|
||||
(error: unknown) => this.patchState({ error, loading: false })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(error: unknown) => this.patchState({ error, loading: false }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
readonly assignTicket = this.effect<{ userId: number; ticketId: number }>(
|
||||
@@ -157,11 +157,11 @@ export class TicketStore
|
||||
this.backend.assign(info.ticketId, Number(info.userId)).pipe(
|
||||
tapResponse(
|
||||
(newTicket) => this.updateAssignee(newTicket),
|
||||
(error: unknown) => this.patchState({ error, loading: false })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(error: unknown) => this.patchState({ error, loading: false }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
readonly done = this.effect<number>(
|
||||
@@ -171,10 +171,10 @@ export class TicketStore
|
||||
this.backend.complete(ticketId, true).pipe(
|
||||
tapResponse(
|
||||
(newTicket) => this.updateAssignee(newTicket),
|
||||
(error: unknown) => this.patchState({ error, loading: false })
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(error: unknown) => this.patchState({ error, loading: false }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,27 +20,30 @@ import { MatInputModule } from '@angular/material/input';
|
||||
MatButtonModule,
|
||||
NgIf,
|
||||
],
|
||||
template: ` <form [formGroup]="form" #ngForm="ngForm" (ngSubmit)="submit()">
|
||||
<mat-form-field class="example-full-width" appearance="fill">
|
||||
<mat-label>Description</mat-label>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
formControlName="description"
|
||||
placeholder="My new task" />
|
||||
<mat-error *ngIf="form.controls.description.hasError('required')">
|
||||
Description is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<button
|
||||
class="ml-4"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
type="submit"
|
||||
[disabled]="loading">
|
||||
Add new Ticket
|
||||
</button>
|
||||
</form>`,
|
||||
template: `
|
||||
<form [formGroup]="form" #ngForm="ngForm" (ngSubmit)="submit()">
|
||||
<mat-form-field class="example-full-width" appearance="fill">
|
||||
<mat-label>Description</mat-label>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
formControlName="description"
|
||||
placeholder="My new task" />
|
||||
<mat-error *ngIf="form.controls.description.hasError('required')">
|
||||
Description is
|
||||
<strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<button
|
||||
class="ml-4"
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
type="submit"
|
||||
[disabled]="loading">
|
||||
Add new Ticket
|
||||
</button>
|
||||
</form>
|
||||
`,
|
||||
})
|
||||
export class AddComponent {
|
||||
@Input() loading = false;
|
||||
|
||||
@@ -22,30 +22,38 @@ import { Ticket, TicketUser, User } from '../../backend.service';
|
||||
],
|
||||
template: `
|
||||
<li
|
||||
class="flex-grow flex items-center gap-5 justify-between"
|
||||
class="flex flex-grow items-center justify-between gap-5"
|
||||
[class.bg-green-200]="ticket.completed">
|
||||
<button [routerLink]="['/detail', ticket.id]" class="flex flex-col gap-2">
|
||||
<div><span class="font-bold">Ticket:</span> {{ ticket.id }}</div>
|
||||
<div>
|
||||
<span class="font-bold">Description:</span> {{ ticket.description }}
|
||||
<span class="font-bold">Ticket:</span>
|
||||
{{ ticket.id }}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-bold">Assignee:</span> {{ $any(ticket).assignee }}
|
||||
<span class="font-bold">Description:</span>
|
||||
{{ ticket.description }}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-bold">Assignee:</span>
|
||||
{{ $any(ticket).assignee }}
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-bold">Done:</span>
|
||||
{{ ticket.completed }}
|
||||
</div>
|
||||
<div><span class="font-bold">Done:</span> {{ ticket.completed }}</div>
|
||||
</button>
|
||||
<div class="flex flex-col">
|
||||
<form
|
||||
[formGroup]="form"
|
||||
#ngForm="ngForm"
|
||||
(ngSubmit)="submit()"
|
||||
class="flex justify-center items-center gap-4">
|
||||
class="flex items-center justify-center gap-4">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Assign to</mat-label>
|
||||
<mat-select formControlName="assignee">
|
||||
<mat-option *ngFor="let user of users" [value]="user.id">{{
|
||||
user.name
|
||||
}}</mat-option>
|
||||
<mat-option *ngFor="let user of users" [value]="user.id">
|
||||
{{ user.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<button mat-flat-button color="primary" type="submit">Assign</button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { appConfig } from './app/app.config';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
|
||||
import { AppComponent } from './app/app.component';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
console.error(err),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user