diff options
Diffstat (limited to 'client/src/app')
17 files changed, 60 insertions, 23 deletions
diff --git a/client/src/app/+admin/users/user-edit/user-edit.ts b/client/src/app/+admin/users/user-edit/user-edit.ts index 99ce5804b..0b3511e8e 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/users/user-edit/user-edit.ts | |||
@@ -4,10 +4,10 @@ import { USER_ROLE_LABELS, VideoResolution } from '../../../../../../shared' | |||
4 | import { ConfigService } from '@app/+admin/config/shared/config.service' | 4 | import { ConfigService } from '@app/+admin/config/shared/config.service' |
5 | 5 | ||
6 | export abstract class UserEdit extends FormReactive { | 6 | export abstract class UserEdit extends FormReactive { |
7 | |||
8 | videoQuotaOptions: { value: string, label: string }[] = [] | 7 | videoQuotaOptions: { value: string, label: string }[] = [] |
9 | videoQuotaDailyOptions: { value: string, label: string }[] = [] | 8 | videoQuotaDailyOptions: { value: string, label: string }[] = [] |
10 | roles = Object.keys(USER_ROLE_LABELS).map(key => ({ value: key.toString(), label: USER_ROLE_LABELS[key] })) | 9 | roles = Object.keys(USER_ROLE_LABELS).map(key => ({ value: key.toString(), label: USER_ROLE_LABELS[key] })) |
10 | username: string | ||
11 | 11 | ||
12 | protected abstract serverService: ServerService | 12 | protected abstract serverService: ServerService |
13 | protected abstract configService: ConfigService | 13 | protected abstract configService: ConfigService |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html index eb8d30e17..5684004a5 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.html +++ b/client/src/app/+admin/users/user-list/user-list.component.html | |||
@@ -86,4 +86,4 @@ | |||
86 | </ng-template> | 86 | </ng-template> |
87 | </p-table> | 87 | </p-table> |
88 | 88 | ||
89 | <my-user-ban-modal #userBanModal (userBanned)="onUsersBanned()"></my-user-ban-modal> | 89 | <my-user-ban-modal #userBanModal (userBanned)="onUserChanged()"></my-user-ban-modal> |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index 3859af9ff..31e783622 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts | |||
@@ -66,7 +66,7 @@ export class UserListComponent extends RestTable implements OnInit { | |||
66 | this.userBanModal.openModal(users) | 66 | this.userBanModal.openModal(users) |
67 | } | 67 | } |
68 | 68 | ||
69 | onUsersBanned () { | 69 | onUserChanged () { |
70 | this.loadData() | 70 | this.loadData() |
71 | } | 71 | } |
72 | 72 | ||
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.ts index ccdd9a3dc..4dc65dd99 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.ts +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.ts | |||
@@ -4,7 +4,11 @@ import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | |||
4 | export abstract class MyAccountVideoChannelEdit extends FormReactive { | 4 | export abstract class MyAccountVideoChannelEdit extends FormReactive { |
5 | // We need it even in the create component because it's used in the edit template | 5 | // We need it even in the create component because it's used in the edit template |
6 | videoChannelToUpdate: VideoChannel | 6 | videoChannelToUpdate: VideoChannel |
7 | instanceHost: string | ||
7 | 8 | ||
8 | abstract isCreation (): boolean | 9 | abstract isCreation (): boolean |
9 | abstract getFormButtonTitle (): string | 10 | abstract getFormButtonTitle (): string |
11 | |||
12 | // FIXME: We need this method so angular does not complain in the child template | ||
13 | onAvatarChange (formData: FormData) { /* empty */ } | ||
10 | } | 14 | } |
diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts index 800d97b7f..1f0744fb1 100644 --- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts | |||
@@ -25,7 +25,7 @@ import { ScreenService } from '@app/shared/misc/screen.service' | |||
25 | export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { | 25 | export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { |
26 | titlePage: string | 26 | titlePage: string |
27 | marginContent = false // Disable margin | 27 | marginContent = false // Disable margin |
28 | currentRoute = '/video-channel/videos' | 28 | currentRoute = '/video-channels/videos' |
29 | loadOnInit = false | 29 | loadOnInit = false |
30 | 30 | ||
31 | private videoChannel: VideoChannel | 31 | private videoChannel: VideoChannel |
@@ -55,7 +55,7 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On | |||
55 | this.videoChannelSub = this.videoChannelService.videoChannelLoaded | 55 | this.videoChannelSub = this.videoChannelService.videoChannelLoaded |
56 | .subscribe(videoChannel => { | 56 | .subscribe(videoChannel => { |
57 | this.videoChannel = videoChannel | 57 | this.videoChannel = videoChannel |
58 | this.currentRoute = '/video-channel/' + this.videoChannel.uuid + '/videos' | 58 | this.currentRoute = '/video-channels/' + this.videoChannel.uuid + '/videos' |
59 | 59 | ||
60 | this.reloadVideos() | 60 | this.reloadVideos() |
61 | this.generateSyndicationList() | 61 | this.generateSyndicationList() |
diff --git a/client/src/app/header/header.component.scss b/client/src/app/header/header.component.scss index bd03c338a..2f9820665 100644 --- a/client/src/app/header/header.component.scss +++ b/client/src/app/header/header.component.scss | |||
@@ -50,7 +50,7 @@ | |||
50 | .icon.icon-upload { | 50 | .icon.icon-upload { |
51 | @include icon(22px); | 51 | @include icon(22px); |
52 | 52 | ||
53 | background-image: url('../../assets/images/header/upload.svg'); | 53 | background-image: url('../../assets/images/header/upload-white.svg'); |
54 | height: 24px; | 54 | height: 24px; |
55 | vertical-align: middle; | 55 | vertical-align: middle; |
56 | margin-right: 6px; | 56 | margin-right: 6px; |
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss index a842765ba..b271ebfd2 100644 --- a/client/src/app/menu/menu.component.scss +++ b/client/src/app/menu/menu.component.scss | |||
@@ -131,10 +131,14 @@ menu { | |||
131 | transition: background-color .1s ease-in-out; | 131 | transition: background-color .1s ease-in-out; |
132 | @include disable-default-a-behaviour; | 132 | @include disable-default-a-behaviour; |
133 | 133 | ||
134 | &:hover, &.focus-visible { | 134 | &.active { |
135 | background-color: rgba(255, 255, 255, 0.15); | 135 | background-color: rgba(255, 255, 255, 0.15); |
136 | } | 136 | } |
137 | 137 | ||
138 | &:hover, &.focus-visible { | ||
139 | background-color: rgba(255, 255, 255, 0.10); | ||
140 | } | ||
141 | |||
138 | .icon { | 142 | .icon { |
139 | @include icon(22px); | 143 | @include icon(22px); |
140 | 144 | ||
diff --git a/client/src/app/shared/forms/index.ts b/client/src/app/shared/forms/index.ts index 41c321c4c..8febbfee9 100644 --- a/client/src/app/shared/forms/index.ts +++ b/client/src/app/shared/forms/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './form-validators' | 1 | export * from './form-validators' |
2 | export * from './form-reactive' | 2 | export * from './form-reactive' |
3 | export * from './reactive-file.component' | 3 | export * from './reactive-file.component' |
4 | export * from './textarea-autoresize.directive' | ||
diff --git a/client/src/app/shared/forms/textarea-autoresize.directive.ts b/client/src/app/shared/forms/textarea-autoresize.directive.ts new file mode 100644 index 000000000..f8c855c16 --- /dev/null +++ b/client/src/app/shared/forms/textarea-autoresize.directive.ts | |||
@@ -0,0 +1,25 @@ | |||
1 | // Thanks: https://github.com/evseevdev/ngx-textarea-autosize | ||
2 | import { AfterViewInit, Directive, ElementRef, HostBinding, HostListener } from '@angular/core' | ||
3 | |||
4 | @Directive({ | ||
5 | selector: 'textarea[myAutoResize]' | ||
6 | }) | ||
7 | export class TextareaAutoResizeDirective implements AfterViewInit { | ||
8 | @HostBinding('attr.rows') rows = '1' | ||
9 | @HostBinding('style.overflow') overflow = 'hidden' | ||
10 | |||
11 | constructor (private elem: ElementRef) { } | ||
12 | |||
13 | public ngAfterViewInit () { | ||
14 | this.resize() | ||
15 | } | ||
16 | |||
17 | @HostListener('input') | ||
18 | resize () { | ||
19 | const textarea = this.elem.nativeElement as HTMLTextAreaElement | ||
20 | // Reset textarea height to auto that correctly calculate the new height | ||
21 | textarea.style.height = 'auto' | ||
22 | // Set new height | ||
23 | textarea.style.height = `${textarea.scrollHeight}px` | ||
24 | } | ||
25 | } | ||
diff --git a/client/src/app/shared/misc/from-now.pipe.ts b/client/src/app/shared/misc/from-now.pipe.ts index 33e6d25fe..00b5be6c9 100644 --- a/client/src/app/shared/misc/from-now.pipe.ts +++ b/client/src/app/shared/misc/from-now.pipe.ts | |||
@@ -7,8 +7,9 @@ export class FromNowPipe implements PipeTransform { | |||
7 | 7 | ||
8 | constructor (private i18n: I18n) { } | 8 | constructor (private i18n: I18n) { } |
9 | 9 | ||
10 | transform (value: number) { | 10 | transform (arg: number | Date | string) { |
11 | const seconds = Math.floor((Date.now() - value) / 1000) | 11 | const argDate = new Date(arg) |
12 | const seconds = Math.floor((Date.now() - argDate.getTime()) / 1000) | ||
12 | 13 | ||
13 | let interval = Math.floor(seconds / 31536000) | 14 | let interval = Math.floor(seconds / 31536000) |
14 | if (interval > 1) { | 15 | if (interval > 1) { |
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 0ec2a9b15..a2fa27b72 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts | |||
@@ -37,13 +37,15 @@ import { | |||
37 | LoginValidatorsService, | 37 | LoginValidatorsService, |
38 | ReactiveFileComponent, | 38 | ReactiveFileComponent, |
39 | ResetPasswordValidatorsService, | 39 | ResetPasswordValidatorsService, |
40 | TextareaAutoResizeDirective, | ||
40 | UserValidatorsService, | 41 | UserValidatorsService, |
41 | VideoAbuseValidatorsService, | 42 | VideoAbuseValidatorsService, |
43 | VideoAcceptOwnershipValidatorsService, | ||
42 | VideoBlacklistValidatorsService, | 44 | VideoBlacklistValidatorsService, |
45 | VideoChangeOwnershipValidatorsService, | ||
43 | VideoChannelValidatorsService, | 46 | VideoChannelValidatorsService, |
44 | VideoCommentValidatorsService, | 47 | VideoCommentValidatorsService, |
45 | VideoValidatorsService, | 48 | VideoValidatorsService |
46 | VideoChangeOwnershipValidatorsService, VideoAcceptOwnershipValidatorsService | ||
47 | } from '@app/shared/forms' | 49 | } from '@app/shared/forms' |
48 | import { I18nPrimengCalendarService } from '@app/shared/i18n/i18n-primeng-calendar' | 50 | import { I18nPrimengCalendarService } from '@app/shared/i18n/i18n-primeng-calendar' |
49 | import { ScreenService } from '@app/shared/misc/screen.service' | 51 | import { ScreenService } from '@app/shared/misc/screen.service' |
@@ -53,7 +55,7 @@ import { PeertubeCheckboxComponent } from '@app/shared/forms/peertube-checkbox.c | |||
53 | import { VideoImportService } from '@app/shared/video-import/video-import.service' | 55 | import { VideoImportService } from '@app/shared/video-import/video-import.service' |
54 | import { ActionDropdownComponent } from '@app/shared/buttons/action-dropdown.component' | 56 | import { ActionDropdownComponent } from '@app/shared/buttons/action-dropdown.component' |
55 | import { NgbDropdownModule, NgbModalModule, NgbPopoverModule, NgbTabsetModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' | 57 | import { NgbDropdownModule, NgbModalModule, NgbPopoverModule, NgbTabsetModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' |
56 | import { SubscribeButtonComponent, RemoteSubscribeComponent, UserSubscriptionService } from '@app/shared/user-subscription' | 58 | import { RemoteSubscribeComponent, SubscribeButtonComponent, UserSubscriptionService } from '@app/shared/user-subscription' |
57 | import { InstanceFeaturesTableComponent } from '@app/shared/instance/instance-features-table.component' | 59 | import { InstanceFeaturesTableComponent } from '@app/shared/instance/instance-features-table.component' |
58 | import { OverviewService } from '@app/shared/overview' | 60 | import { OverviewService } from '@app/shared/overview' |
59 | import { UserBanModalComponent } from '@app/shared/moderation' | 61 | import { UserBanModalComponent } from '@app/shared/moderation' |
@@ -92,6 +94,7 @@ import { BlocklistService } from '@app/shared/blocklist' | |||
92 | FromNowPipe, | 94 | FromNowPipe, |
93 | MarkdownTextareaComponent, | 95 | MarkdownTextareaComponent, |
94 | InfiniteScrollerDirective, | 96 | InfiniteScrollerDirective, |
97 | TextareaAutoResizeDirective, | ||
95 | HelpComponent, | 98 | HelpComponent, |
96 | ReactiveFileComponent, | 99 | ReactiveFileComponent, |
97 | PeertubeCheckboxComponent, | 100 | PeertubeCheckboxComponent, |
@@ -129,6 +132,7 @@ import { BlocklistService } from '@app/shared/blocklist' | |||
129 | ActionDropdownComponent, | 132 | ActionDropdownComponent, |
130 | MarkdownTextareaComponent, | 133 | MarkdownTextareaComponent, |
131 | InfiniteScrollerDirective, | 134 | InfiniteScrollerDirective, |
135 | TextareaAutoResizeDirective, | ||
132 | HelpComponent, | 136 | HelpComponent, |
133 | ReactiveFileComponent, | 137 | ReactiveFileComponent, |
134 | PeertubeCheckboxComponent, | 138 | PeertubeCheckboxComponent, |
diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html index 277a0cf35..2c635fa2f 100644 --- a/client/src/app/shared/video/video-miniature.component.html +++ b/client/src/app/shared/video/video-miniature.component.html | |||
@@ -7,10 +7,10 @@ | |||
7 | class="video-miniature-name" | 7 | class="video-miniature-name" |
8 | [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }" | 8 | [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }" |
9 | > | 9 | > |
10 | {{ video.name }} | ||
11 | |||
12 | <span *ngIf="isUnlistedVideo()" class="badge badge-warning" i18n>Unlisted</span> | 10 | <span *ngIf="isUnlistedVideo()" class="badge badge-warning" i18n>Unlisted</span> |
13 | <span *ngIf="isPrivateVideo()" class="badge badge-danger" i18n>Private</span> | 11 | <span *ngIf="isPrivateVideo()" class="badge badge-danger" i18n>Private</span> |
12 | |||
13 | {{ video.name }} | ||
14 | </a> | 14 | </a> |
15 | 15 | ||
16 | <span i18n class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> | 16 | <span i18n class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> |
diff --git a/client/src/app/shared/video/video.service.ts b/client/src/app/shared/video/video.service.ts index 65297d7a1..55844f988 100644 --- a/client/src/app/shared/video/video.service.ts +++ b/client/src/app/shared/video/video.service.ts | |||
@@ -6,11 +6,11 @@ import { Video as VideoServerModel, VideoDetails as VideoDetailsServerModel } fr | |||
6 | import { ResultList } from '../../../../../shared/models/result-list.model' | 6 | import { ResultList } from '../../../../../shared/models/result-list.model' |
7 | import { | 7 | import { |
8 | UserVideoRate, | 8 | UserVideoRate, |
9 | UserVideoRateType, | ||
9 | UserVideoRateUpdate, | 10 | UserVideoRateUpdate, |
10 | VideoConstant, | 11 | VideoConstant, |
11 | VideoFilter, | 12 | VideoFilter, |
12 | VideoPrivacy, | 13 | VideoPrivacy, |
13 | VideoRateType, | ||
14 | VideoUpdate | 14 | VideoUpdate |
15 | } from '../../../../../shared/models/videos' | 15 | } from '../../../../../shared/models/videos' |
16 | import { FeedFormat } from '../../../../../shared/models/feeds/feed-format.enum' | 16 | import { FeedFormat } from '../../../../../shared/models/feeds/feed-format.enum' |
@@ -332,7 +332,7 @@ export class VideoService implements VideosProvider { | |||
332 | return privacies | 332 | return privacies |
333 | } | 333 | } |
334 | 334 | ||
335 | private setVideoRate (id: number, rateType: VideoRateType) { | 335 | private setVideoRate (id: number, rateType: UserVideoRateType) { |
336 | const url = VideoService.BASE_VIDEO_URL + id + '/rate' | 336 | const url = VideoService.BASE_VIDEO_URL + id + '/rate' |
337 | const body: UserVideoRateUpdate = { | 337 | const body: UserVideoRateUpdate = { |
338 | rating: rateType | 338 | rating: rateType |
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html index b58a56596..d8a7a78c4 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html | |||
@@ -3,7 +3,7 @@ | |||
3 | <img [src]="getAvatarUrl()" alt="Avatar" /> | 3 | <img [src]="getAvatarUrl()" alt="Avatar" /> |
4 | 4 | ||
5 | <div class="form-group"> | 5 | <div class="form-group"> |
6 | <textarea i18n-placeholder placeholder="Add comment..." autosize | 6 | <textarea i18n-placeholder placeholder="Add comment..." myAutoResize |
7 | [readonly]="(user === null) ? true : false" | 7 | [readonly]="(user === null) ? true : false" |
8 | (click)="openVisitorModal($event)" | 8 | (click)="openVisitorModal($event)" |
9 | formControlName="text" [ngClass]="{ 'input-error': formErrors['text'] }" | 9 | formControlName="text" [ngClass]="{ 'input-error': formErrors['text'] }" |
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts index ba3c0398e..6db0eb55d 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts | |||
@@ -29,9 +29,9 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit { | |||
29 | @Output() commentCreated = new EventEmitter<VideoCommentCreate>() | 29 | @Output() commentCreated = new EventEmitter<VideoCommentCreate>() |
30 | 30 | ||
31 | @ViewChild('visitorModal') visitorModal: NgbModal | 31 | @ViewChild('visitorModal') visitorModal: NgbModal |
32 | @ViewChild('textarea') private textareaElement: ElementRef | 32 | @ViewChild('textarea') textareaElement: ElementRef |
33 | 33 | ||
34 | private addingComment = false | 34 | addingComment = false |
35 | 35 | ||
36 | constructor ( | 36 | constructor ( |
37 | protected formValidatorService: FormValidatorService, | 37 | protected formValidatorService: FormValidatorService, |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index dda870905..d0151ceb1 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -450,7 +450,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
450 | this.checkUserRating() | 450 | this.checkUserRating() |
451 | } | 451 | } |
452 | 452 | ||
453 | private setRating (nextRating: VideoRateType) { | 453 | private setRating (nextRating: UserVideoRateType) { |
454 | let method | 454 | let method |
455 | switch (nextRating) { | 455 | switch (nextRating) { |
456 | case 'like': | 456 | case 'like': |
@@ -476,7 +476,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
476 | ) | 476 | ) |
477 | } | 477 | } |
478 | 478 | ||
479 | private updateVideoRating (oldRating: UserVideoRateType, newRating: VideoRateType) { | 479 | private updateVideoRating (oldRating: UserVideoRateType, newRating: UserVideoRateType) { |
480 | let likesToIncrement = 0 | 480 | let likesToIncrement = 0 |
481 | let dislikesToIncrement = 0 | 481 | let dislikesToIncrement = 0 |
482 | 482 | ||
diff --git a/client/src/app/videos/+video-watch/video-watch.module.ts b/client/src/app/videos/+video-watch/video-watch.module.ts index 5582ab40f..54a12c126 100644 --- a/client/src/app/videos/+video-watch/video-watch.module.ts +++ b/client/src/app/videos/+video-watch/video-watch.module.ts | |||
@@ -17,7 +17,6 @@ import { NgxQRCodeModule } from 'ngx-qrcode2' | |||
17 | import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' | 17 | import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' |
18 | import { VideoBlacklistComponent } from '@app/videos/+video-watch/modal/video-blacklist.component' | 18 | import { VideoBlacklistComponent } from '@app/videos/+video-watch/modal/video-blacklist.component' |
19 | import { RecommendationsModule } from '@app/videos/recommendations/recommendations.module' | 19 | import { RecommendationsModule } from '@app/videos/recommendations/recommendations.module' |
20 | import { TextareaAutosizeModule } from 'ngx-textarea-autosize' | ||
21 | 20 | ||
22 | @NgModule({ | 21 | @NgModule({ |
23 | imports: [ | 22 | imports: [ |
@@ -26,7 +25,6 @@ import { TextareaAutosizeModule } from 'ngx-textarea-autosize' | |||
26 | ClipboardModule, | 25 | ClipboardModule, |
27 | NgbTooltipModule, | 26 | NgbTooltipModule, |
28 | NgxQRCodeModule, | 27 | NgxQRCodeModule, |
29 | TextareaAutosizeModule, | ||
30 | RecommendationsModule | 28 | RecommendationsModule |
31 | ], | 29 | ], |
32 | 30 | ||