Skip to content

Commit d5e0f4d

Browse files
committed
fix(album): corrige criação de album e progresso de fotos
1 parent 15bc684 commit d5e0f4d

File tree

11 files changed

+230
-12
lines changed

11 files changed

+230
-12
lines changed

apps/devmx/src/app/app.config.ts

+6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ import {
3131
withViewTransitions,
3232
} from '@angular/router';
3333
import {
34+
HttpBackend,
3435
HttpClient,
36+
HttpXhrBackend,
3537
provideHttpClient,
3638
withInterceptors,
3739
} from '@angular/common/http';
@@ -68,6 +70,10 @@ export const appConfig: ApplicationConfig = {
6870
},
6971
provideLayout(appSections),
7072
provideHttpClient(withInterceptors([authInterceptor, loaderInterceptor])),
73+
{
74+
provide: HttpBackend,
75+
useExisting: HttpXhrBackend,
76+
},
7177
provideHttpClientImpl(HttpClient),
7278
...provideAccount(),
7379
provideLayoutToolbar(AuthenticationFacade),
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
export * from './user-complete/user-complete.component';
21
export * from './user-card-skills/user-card-skills.component';
2+
export * from './user-complete/user-complete.component';
3+
export * from './search-user/search-user.component';
34
export * from './code-field/code-field.component';
45
export * from './user-roles/user-roles.component';
56
export * from './user-card/user-card.component';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<mat-form-field>
2+
<mat-label>{{ label() }}</mat-label>
3+
<input matInput [formControl]="control" [matAutocomplete]="auto" />
4+
<mat-hint>{{ hint() }}</mat-hint>
5+
<mat-autocomplete
6+
#auto="matAutocomplete"
7+
[displayWith]="displayFn"
8+
(optionSelected)="onOptionSelected($event.option.value)"
9+
>
10+
@if (userFacade.response$ | async; as response) {
11+
<!-- -->
12+
@for (option of response.data; track option.id) {
13+
<mat-option [value]="option">{{ option.displayName }}</mat-option>
14+
}
15+
<!-- -->
16+
}
17+
</mat-autocomplete>
18+
</mat-form-field>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:host {
2+
flex: 1;
3+
display: flex;
4+
flex-direction: column;
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { MatAutocompleteModule } from '@angular/material/autocomplete';
2+
import { FormControl, ReactiveFormsModule } from '@angular/forms';
3+
import { MatFormFieldModule } from '@angular/material/form-field';
4+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5+
import { MatInputModule } from '@angular/material/input';
6+
import { UserFacade } from '@devmx/account-data-access';
7+
import { User } from '@devmx/shared-api-interfaces';
8+
import { AsyncPipe } from '@angular/common';
9+
import { debounceTime, filter, startWith } from 'rxjs';
10+
import {
11+
input,
12+
inject,
13+
output,
14+
Component,
15+
ChangeDetectionStrategy,
16+
} from '@angular/core';
17+
18+
@Component({
19+
selector: 'devmx-search-user',
20+
templateUrl: './search-user.component.html',
21+
styleUrl: './search-user.component.scss',
22+
changeDetection: ChangeDetectionStrategy.OnPush,
23+
imports: [
24+
ReactiveFormsModule,
25+
MatAutocompleteModule,
26+
MatFormFieldModule,
27+
MatInputModule,
28+
AsyncPipe,
29+
],
30+
})
31+
export class SearchUserComponent {
32+
userFacade = inject(UserFacade);
33+
34+
selected = output<User>();
35+
36+
label = input('Usuário');
37+
38+
hint = input('');
39+
40+
control = new FormControl<string | User>('');
41+
42+
constructor() {
43+
this.control.valueChanges
44+
.pipe(
45+
startWith(' '),
46+
filter((value) => typeof value === 'string'),
47+
filter((value) => value.length > 0),
48+
takeUntilDestroyed(),
49+
debounceTime(400)
50+
)
51+
.subscribe((displayName) => {
52+
this.userFacade.setFilter({ displayName });
53+
this.userFacade.load();
54+
});
55+
}
56+
57+
displayFn(user: User) {
58+
return user && user.displayName ? user.displayName : '';
59+
}
60+
61+
onOptionSelected(user: User) {
62+
this.selected.emit(user);
63+
this.control.setValue('');
64+
}
65+
}

packages/album/feature-admin/src/lib/containers/my-albums/my-albums.container.ts

+15-10
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import { DialogFacade } from '@devmx/shared-ui-global/dialog';
88
import { MatTooltipModule } from '@angular/material/tooltip';
99
import { IconComponent } from '@devmx/shared-ui-global/icon';
1010
import { AlbumCardComponent } from '@devmx/album-ui-shared';
11+
import { SheetFacade } from '@devmx/shared-ui-global/sheet';
1112
import { MatButtonModule } from '@angular/material/button';
1213
import { combineLatest, filter, map, take } from 'rxjs';
1314
import { AlbumFacade } from '@devmx/album-data-access';
1415
import { Album } from '@devmx/shared-api-interfaces';
16+
import { CreateAlbumSheet } from '../../sheets';
1517
import { AsyncPipe } from '@angular/common';
16-
import { AlbumForm } from '../../forms';
1718

1819
@Component({
1920
selector: 'devmx-admin-my-albums',
@@ -38,6 +39,8 @@ export class MyAlbumsContainer {
3839

3940
dialogFacade = inject(DialogFacade);
4041

42+
sheetFacade = inject(SheetFacade);
43+
4144
authFacade = inject(AuthenticationFacade);
4245

4346
albumFacade = inject(AlbumFacade);
@@ -74,15 +77,17 @@ export class MyAlbumsContainer {
7477
}
7578

7679
createAlbum() {
77-
const form = new AlbumForm();
78-
79-
form.patchValue({ title: new Date().toLocaleDateString() });
80-
81-
const request$ = this.albumFacade.create(form.getRawValue());
82-
83-
request$.pipe(take(1)).subscribe((album) => {
84-
this.router.navigate([album.id], { relativeTo: this.route });
85-
});
80+
this.sheetFacade
81+
.open<CreateAlbumSheet, void, Album>(CreateAlbumSheet)
82+
.pipe(take(1))
83+
.subscribe((value) => {
84+
if (value) {
85+
const request$ = this.albumFacade.create(value);
86+
request$.pipe(take(1)).subscribe((album) => {
87+
this.router.navigate([album.id], { relativeTo: this.route });
88+
});
89+
}
90+
});
8691
}
8792

8893
deleteAlbum({ id, title }: Album) {

packages/album/feature-admin/src/lib/forms/album.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class AlbumForm extends FormGroup<TypedForm<EditableAlbum>> {
1919
id: new FormControl('', {
2020
nonNullable: true,
2121
}),
22-
title: new FormControl(new Date().toLocaleDateString(), {
22+
title: new FormControl('', {
2323
nonNullable: true,
2424
validators: [Validators.required],
2525
}),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<form [formGroup]="form" (submit)="onSubmit()">
2+
<mat-form-field>
3+
<mat-label>Título do album</mat-label>
4+
<input matInput formControlName="title" />
5+
<mat-error>Obrigatório</mat-error>
6+
</mat-form-field>
7+
8+
<mat-list formArrayName="contributors">
9+
<p mat-subheader>Contribuidores</p>
10+
11+
@for (control of form.contributors.controls; track control.value; let index
12+
= $index) {
13+
<mat-list-item>
14+
<devmx-icon matListItemIcon name="user-circle" />
15+
16+
<span matListItemTitle>{{control.value.displayName}}</span>
17+
18+
<button
19+
type="button"
20+
mat-icon-button
21+
matListItemMeta
22+
(click)="form.contributors.removeAt(index)"
23+
>
24+
<devmx-icon name="trash" />
25+
</button>
26+
</mat-list-item>
27+
}
28+
</mat-list>
29+
30+
<devmx-search-user
31+
label="Encontre um contribuidor"
32+
hint="Contribuidores também podem editar o album"
33+
(selected)="onContributorSelected($event)"
34+
/>
35+
36+
<footer>
37+
<button mat-flat-button>Salvar</button>
38+
39+
<button type="button" mat-button (click)="close()">Fechar</button>
40+
</footer>
41+
</form>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
:host {
2+
display: flex;
3+
padding: 1.5em 1em 0.5em;
4+
flex-direction: column;
5+
6+
form {
7+
flex: 1;
8+
gap: 1em;
9+
display: flex;
10+
flex-direction: column;
11+
}
12+
13+
footer {
14+
margin-top: 1em;
15+
display: flex;
16+
flex-direction: row-reverse;
17+
justify-content: space-between;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { OnInit, Component, ChangeDetectionStrategy } from '@angular/core';
2+
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
3+
import { EditableAlbum, UserRef } from '@devmx/shared-api-interfaces';
4+
import { MatFormFieldModule } from '@angular/material/form-field';
5+
import { SheetComponent } from '@devmx/shared-ui-global/sheet';
6+
import { IconComponent } from '@devmx/shared-ui-global/icon';
7+
import { MatButtonModule } from '@angular/material/button';
8+
import { MatInputModule } from '@angular/material/input';
9+
import { MatListModule } from '@angular/material/list';
10+
import { ReactiveFormsModule } from '@angular/forms';
11+
import { AlbumForm } from '../../forms';
12+
import {
13+
provideSelectUser,
14+
SearchUserComponent,
15+
} from '@devmx/account-ui-shared';
16+
17+
@Component({
18+
selector: 'devmx-create-album',
19+
templateUrl: './create-album.sheet.html',
20+
styleUrl: './create-album.sheet.scss',
21+
changeDetection: ChangeDetectionStrategy.OnPush,
22+
providers: [provideSelectUser()],
23+
imports: [
24+
SearchUserComponent,
25+
MatBottomSheetModule,
26+
ReactiveFormsModule,
27+
MatFormFieldModule,
28+
MatButtonModule,
29+
MatInputModule,
30+
MatListModule,
31+
IconComponent,
32+
],
33+
})
34+
export class CreateAlbumSheet
35+
extends SheetComponent<EditableAlbum, CreateAlbumSheet, EditableAlbum | null>
36+
implements OnInit
37+
{
38+
form = new AlbumForm();
39+
40+
ngOnInit() {
41+
if (this.data) {
42+
this.form.patch(this.data);
43+
}
44+
}
45+
46+
onContributorSelected(user: UserRef) {
47+
this.form.contributors.add(user);
48+
}
49+
50+
onSubmit() {
51+
if (this.form.valid) {
52+
return this.close(this.form.getRawValue());
53+
}
54+
55+
return this.form.markAllAsTouched();
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './album-details/album-details.sheet';
2+
export * from './create-album/create-album.sheet';

0 commit comments

Comments
 (0)