22//
33// SPDX-License-Identifier: AGPL-3.0-only
44
5- import { Component , OnInit , inject } from "@angular/core" ;
5+ import { Component , OnInit , inject , signal } from "@angular/core" ;
66import { HttpEventType , HttpResponse } from "@angular/common/http" ;
77import { MatChipsModule } from "@angular/material/chips" ;
88import { MatDialog , MatDialogModule } from "@angular/material/dialog" ;
@@ -62,60 +62,61 @@ export class AppDetailsScreenComponent implements OnInit {
6262 private snackbar = inject ( MatSnackBar ) ;
6363 private updateService = inject ( UpdateService ) ;
6464
65- app ?: App ;
66- updates : Update [ ] = [ ] ;
67- edits : Edit [ ] = [ ] ;
68- uploadProgress ?: number = undefined ;
65+ readonly app = signal < App | undefined > ( undefined ) ;
66+ readonly updates = signal < Update [ ] > ( [ ] ) ;
67+ readonly edits = signal < Edit [ ] > ( [ ] ) ;
68+ readonly uploadProgress = signal < number | undefined > ( undefined ) ;
6969
70- showRejectedEdits = false ;
71- showPublishedEdits = false ;
72- showRejectedUpdates = false ;
73- showPublishedUpdates = false ;
74- submitDisabled = false ;
70+ readonly showRejectedEdits = signal ( false ) ;
71+ readonly showPublishedEdits = signal ( false ) ;
72+ readonly showRejectedUpdates = signal ( false ) ;
73+ readonly showPublishedUpdates = signal ( false ) ;
74+ readonly submitDisabled = signal ( false ) ;
7575
7676 ngOnInit ( ) : void {
7777 this . activatedRoute . paramMap . subscribe ( ( params ) => {
7878 // TODO: Handle error case
7979 const appId = params . get ( "id" ) ;
8080 if ( appId !== null ) {
8181 this . appService . getApp ( appId ) . subscribe ( {
82- next : ( app ) => ( this . app = app ) ,
82+ next : ( app ) => this . app . set ( app ) ,
8383 error : showApiErrorSnackbar ( this . snackbar ) ,
8484 } ) ;
8585 this . editService . getEdits ( appId ) . subscribe ( {
86- next : ( edits ) => ( this . edits = edits ) ,
86+ next : ( edits ) => this . edits . set ( edits ) ,
8787 error : showApiErrorSnackbar ( this . snackbar ) ,
8888 } ) ;
8989 this . updateService . getUpdates ( appId ) . subscribe ( {
90- next : ( updates ) => ( this . updates = updates ) ,
90+ next : ( updates ) => this . updates . set ( updates ) ,
9191 error : showApiErrorSnackbar ( this . snackbar ) ,
9292 } ) ;
9393 }
9494 } ) ;
9595 }
9696
9797 createUpdate ( form : NewUpdateForm ) : void {
98- if ( this . app !== undefined ) {
99- this . submitDisabled = true ;
98+ const app = this . app ( ) ;
99+ if ( app !== undefined ) {
100+ this . submitDisabled . set ( true ) ;
100101 this . updateService
101- . createUpdate ( this . app . id , form )
102- . pipe ( finalize ( ( ) => ( this . submitDisabled = false ) ) )
102+ . createUpdate ( app . id , form )
103+ . pipe ( finalize ( ( ) => this . submitDisabled . set ( false ) ) )
103104 . subscribe ( {
104105 next : ( event ) => {
105106 if ( event . type === HttpEventType . UploadProgress ) {
106- this . uploadProgress = ( 100 * event . loaded ) / event . total ! ;
107+ this . uploadProgress . set ( ( 100 * event . loaded ) / event . total ! ) ;
107108
108109 // Clear the progress bar once the upload is complete
109110 if ( event . loaded === event . total ! ) {
110- this . uploadProgress = undefined ;
111+ this . uploadProgress . set ( undefined ) ;
111112 }
112113 } else if ( event instanceof HttpResponse ) {
113114 const update = event . body ! ;
114115
115- this . updates . push ( update ) ;
116+ this . updates . update ( ( updates ) => [ ... updates , update ] ) ;
116117 this . dialog
117118 . open ( UpdateSubmissionDialogComponent , {
118- data : { app : this . app , update : update } ,
119+ data : { app, update } ,
119120 } )
120121 . afterClosed ( )
121122 . subscribe ( ( confirmed ) => {
@@ -134,19 +135,20 @@ export class AppDetailsScreenComponent implements OnInit {
134135 this . updateService . submitUpdate ( id ) . subscribe ( {
135136 next : ( submittedUpdate ) => {
136137 // Mark as submitted in the UI
137- const update = this . updates . find (
138- ( update ) => update . id === id && update . status === UpdateStatus . Unsubmitted ,
138+ this . updates . update ( ( updates ) =>
139+ updates . map ( ( update ) =>
140+ update . id === id && update . status === UpdateStatus . Unsubmitted
141+ ? { ...update , status : submittedUpdate . status }
142+ : update ,
143+ ) ,
139144 ) ;
140- if ( update !== undefined ) {
141- update . status = submittedUpdate . status ;
142- }
143145 } ,
144146 error : showApiErrorSnackbar ( this . snackbar ) ,
145147 } ) ;
146148 }
147149
148150 deleteUpdate ( id : string ) : void {
149- const update = this . updates . find ( ( update ) => update . id === id ) ;
151+ const update = this . updates ( ) . find ( ( update ) => update . id === id ) ;
150152
151153 this . dialog
152154 . open ( UpdateDeletionDialogComponent , { data : update } )
@@ -156,10 +158,9 @@ export class AppDetailsScreenComponent implements OnInit {
156158 this . updateService . deleteUpdate ( id ) . subscribe ( {
157159 next : ( ) => {
158160 // Remove update from the UI
159- const i = this . updates . findIndex ( ( update ) => update . id === id ) ;
160- if ( i > - 1 ) {
161- this . updates . splice ( i , 1 ) ;
162- }
161+ this . updates . update ( ( updates ) =>
162+ updates . filter ( ( update ) => update . id !== id ) ,
163+ ) ;
163164 } ,
164165 error : showApiErrorSnackbar ( this . snackbar ) ,
165166 } ) ;
@@ -168,16 +169,17 @@ export class AppDetailsScreenComponent implements OnInit {
168169 }
169170
170171 createEdit ( form : NewEditForm ) : void {
171- if ( this . app !== undefined ) {
172- this . editService . createEdit ( this . app . id , form ) . subscribe ( {
172+ const app = this . app ( ) ;
173+ if ( app !== undefined ) {
174+ this . editService . createEdit ( app . id , form ) . subscribe ( {
173175 next : ( event ) => {
174176 if ( event instanceof HttpResponse ) {
175177 const edit = event . body ! ;
176178
177- this . edits . push ( edit ) ;
179+ this . edits . update ( ( edits ) => [ ... edits , edit ] ) ;
178180 this . dialog
179181 . open ( EditSubmissionDialogComponent , {
180- data : { app : this . app , edit : edit } ,
182+ data : { app, edit } ,
181183 } )
182184 . afterClosed ( )
183185 . subscribe ( ( confirmed ) => {
@@ -196,19 +198,20 @@ export class AppDetailsScreenComponent implements OnInit {
196198 this . editService . submitEdit ( id ) . subscribe ( {
197199 next : ( ) => {
198200 // Mark as submitted in the UI
199- const edit = this . edits . find (
200- ( edit ) => edit . id === id && edit . status === EditStatus . Unsubmitted ,
201+ this . edits . update ( ( edits ) =>
202+ edits . map ( ( edit ) =>
203+ edit . id === id && edit . status === EditStatus . Unsubmitted
204+ ? { ...edit , status : EditStatus . Submitted }
205+ : edit ,
206+ ) ,
201207 ) ;
202- if ( edit !== undefined ) {
203- edit . status = EditStatus . Submitted ;
204- }
205208 } ,
206209 error : showApiErrorSnackbar ( this . snackbar ) ,
207210 } ) ;
208211 }
209212
210213 deleteEdit ( id : string ) : void {
211- const edit = this . edits . find ( ( edit ) => edit . id === id ) ;
214+ const edit = this . edits ( ) . find ( ( edit ) => edit . id === id ) ;
212215
213216 this . dialog
214217 . open ( EditDeletionDialogComponent , { data : edit } )
@@ -217,11 +220,8 @@ export class AppDetailsScreenComponent implements OnInit {
217220 if ( confirmed ) {
218221 this . editService . deleteEdit ( id ) . subscribe ( {
219222 next : ( ) => {
220- // Remove update from the UI
221- const i = this . edits . findIndex ( ( edit ) => edit . id === id ) ;
222- if ( i > - 1 ) {
223- this . edits . splice ( i , 1 ) ;
224- }
223+ // Remove edit from the UI
224+ this . edits . update ( ( edits ) => edits . filter ( ( edit ) => edit . id !== id ) ) ;
225225 } ,
226226 error : showApiErrorSnackbar ( this . snackbar ) ,
227227 } ) ;
0 commit comments