From ce0e281d46a7b574dcccb47958743656532bd312 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 6 Dec 2017 15:07:17 +0100 Subject: Client bulk delete --- .../account-videos/account-videos.component.html | 36 ++++++-- .../account-videos/account-videos.component.scss | 102 +++++++++++++-------- .../account-videos/account-videos.component.ts | 49 +++++++++- 3 files changed, 140 insertions(+), 47 deletions(-) (limited to 'client/src/app/account/account-videos') diff --git a/client/src/app/account/account-videos/account-videos.component.html b/client/src/app/account/account-videos/account-videos.component.html index 30db69429..030c2f19c 100644 --- a/client/src/app/account/account-videos/account-videos.component.html +++ b/client/src/app/account/account-videos/account-videos.component.html @@ -5,7 +5,9 @@ (scrolled)="onNearOfBottom()" (scrolledUp)="onNearOfTop()" > -
+
+ +
@@ -13,14 +15,30 @@ {{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views
- - - Delete - + +
+
+ + Cancel + + + + + Delete + +
+
+ + + + + Delete + - - - Edit - + + + Edit + +
diff --git a/client/src/app/account/account-videos/account-videos.component.scss b/client/src/app/account/account-videos/account-videos.component.scss index e7fe662b1..e76e3f4e5 100644 --- a/client/src/app/account/account-videos/account-videos.component.scss +++ b/client/src/app/account/account-videos/account-videos.component.scss @@ -1,8 +1,74 @@ +.action-selection-mode { + width: 174px; + + .action-selection-mode-child { + position: fixed; + } +} + +.action-button { + @include peertube-button-link; + + font-size: 15px; + font-weight: $font-semibold; + color: #585858; + background-color: #E5E5E5; + + &:hover { + background-color: #EFEFEF; + } + + &.action-button-delete { + margin-right: 10px; + } + + &.action-button-delete-selection { + background-color: $orange-color; + color: #fff; + + &:hover { + background-color: $orange-hoover-color; + } + } + + .icon { + display: inline-block; + background-repeat: no-repeat; + background-size: contain; + width: 21px; + height: 21px; + vertical-align: middle; + position: relative; + top: -2px; + + &.icon-edit { + background-image: url('../../../assets/images/account/edit.svg'); + } + + &.icon-delete-grey { + background-image: url('../../../assets/images/account/delete-grey.svg'); + } + + &.icon-delete-white { + background-image: url('../../../assets/images/account/delete-white.svg'); + } + } +} + .video { display: flex; height: 130px; padding-bottom: 20px; + input[type=checkbox] { + margin-right: 20px; + outline: 0; + } + + &:first-child { + margin-top: 47px; + } + &:not(:last-child) { margin-bottom: 20px; border-bottom: 1px solid #C6C6C6; @@ -24,40 +90,4 @@ font-size: 13px; } } - - .action-button { - @include peertube-button-link; - - font-size: 15px; - font-weight: $font-semibold; - color: #585858; - background-color: #E5E5E5; - - &:hover { - background-color: #EFEFEF; - } - - &.action-button-delete { - margin-right: 10px; - } - - .icon.icon-edit, .icon.icon-delete { - display: inline-block; - background-repeat: no-repeat; - background-size: contain; - width: 21px; - height: 21px; - vertical-align: middle; - position: relative; - top: -2px; - - &.icon-edit { - background-image: url('../../../assets/images/account/edit.svg'); - } - - &.icon-delete { - background-image: url('../../../assets/images/account/delete.svg'); - } - } - } } diff --git a/client/src/app/account/account-videos/account-videos.component.ts b/client/src/app/account/account-videos/account-videos.component.ts index 9c2cc2404..5f12cfce0 100644 --- a/client/src/app/account/account-videos/account-videos.component.ts +++ b/client/src/app/account/account-videos/account-videos.component.ts @@ -1,6 +1,9 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { NotificationsService } from 'angular2-notifications' +import 'rxjs/add/observable/from' +import 'rxjs/add/operator/concatAll' +import { Observable } from 'rxjs/Observable' import { ConfirmService } from '../../core/confirm' import { AbstractVideoList } from '../../shared/video/abstract-video-list' import { Video } from '../../shared/video/video.model' @@ -14,6 +17,7 @@ import { VideoService } from '../../shared/video/video.service' export class AccountVideosComponent extends AbstractVideoList implements OnInit { titlePage = 'My videos' currentRoute = '/account/videos' + checkedVideos: { [ id: number ]: boolean } = {} constructor (protected router: Router, protected route: ActivatedRoute, @@ -27,10 +31,47 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit super.ngOnInit() } + abortSelectionMode () { + this.checkedVideos = {} + } + + isInSelectionMode () { + return Object.keys(this.checkedVideos).some(k => this.checkedVideos[k] === true) + } + getVideosObservable () { return this.videoService.getMyVideos(this.pagination, this.sort) } + deleteSelectedVideos () { + const toDeleteVideosIds = Object.keys(this.checkedVideos) + .filter(k => this.checkedVideos[k] === true) + .map(k => parseInt(k, 10)) + + this.confirmService.confirm(`Do you really want to delete ${toDeleteVideosIds.length} videos?`, 'Delete').subscribe( + res => { + if (res === false) return + + const observables: Observable[] = [] + for (const videoId of toDeleteVideosIds) { + const o = this.videoService + .removeVideo(videoId) + .do(() => this.spliceVideosById(videoId)) + + observables.push(o) + } + + Observable.from(observables) + .concatAll() + .subscribe( + res => this.notificationsService.success('Success', `${toDeleteVideosIds.length} videos deleted.`), + + err => this.notificationsService.error('Error', err.text) + ) + } + ) + } + deleteVideo (video: Video) { this.confirmService.confirm(`Do you really want to delete ${video.name}?`, 'Delete').subscribe( res => { @@ -40,8 +81,7 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit .subscribe( status => { this.notificationsService.success('Success', `Video ${video.name} deleted.`) - const index = this.videos.findIndex(v => v.id === video.id) - this.videos.splice(index, 1) + this.spliceVideosById(video.id) }, error => this.notificationsService.error('Error', error.text) @@ -49,4 +89,9 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit } ) } + + private spliceVideosById (id: number) { + const index = this.videos.findIndex(v => v.id === id) + this.videos.splice(index, 1) + } } -- cgit v1.2.3