2edee99a3a3ee2d5d4520910bf30e0a202b19e65
[oweals/peertube.git] / client / src / app / +admin / follows / video-redundancies-list / video-redundancies-list.component.ts
1 import { Component, OnInit } from '@angular/core'
2 import { Notifier, ServerService } from '@app/core'
3 import { SortMeta } from 'primeng/api'
4 import { ConfirmService } from '../../../core/confirm/confirm.service'
5 import { RestPagination, RestTable } from '../../../shared'
6 import { I18n } from '@ngx-translate/i18n-polyfill'
7 import { VideoRedundanciesTarget, VideoRedundancy } from '@shared/models'
8 import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage'
9 import { VideosRedundancyStats } from '@shared/models/server'
10 import { BytesPipe } from 'ngx-pipes'
11 import { RedundancyService } from '@app/shared/video/redundancy.service'
12
13 @Component({
14   selector: 'my-video-redundancies-list',
15   templateUrl: './video-redundancies-list.component.html',
16   styleUrls: [ './video-redundancies-list.component.scss' ]
17 })
18 export class VideoRedundanciesListComponent extends RestTable implements OnInit {
19   private static LOCAL_STORAGE_DISPLAY_TYPE = 'video-redundancies-list-display-type'
20
21   videoRedundancies: VideoRedundancy[] = []
22   totalRecords = 0
23   rowsPerPage = 10
24
25   sort: SortMeta = { field: 'name', order: 1 }
26   pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
27   displayType: VideoRedundanciesTarget = 'my-videos'
28
29   redundanciesGraphsData: { stats: VideosRedundancyStats, graphData: object, options: object }[] = []
30
31   noRedundancies = false
32
33   private bytesPipe: BytesPipe
34
35   constructor (
36     private notifier: Notifier,
37     private confirmService: ConfirmService,
38     private redundancyService: RedundancyService,
39     private serverService: ServerService,
40     private i18n: I18n
41   ) {
42     super()
43
44     this.bytesPipe = new BytesPipe()
45   }
46
47   getIdentifier () {
48     return 'VideoRedundanciesListComponent'
49   }
50
51   ngOnInit () {
52     this.loadSelectLocalStorage()
53
54     this.initialize()
55
56     this.serverService.getServerStats()
57         .subscribe(res => {
58           const redundancies = res.videosRedundancy
59
60           if (redundancies.length === 0) this.noRedundancies = true
61
62           for (const r of redundancies) {
63             this.buildPieData(r)
64           }
65         })
66   }
67
68   isDisplayingRemoteVideos () {
69     return this.displayType === 'remote-videos'
70   }
71
72   getTotalSize (redundancy: VideoRedundancy) {
73     return redundancy.redundancies.files.reduce((a, b) => a + b.size, 0) +
74       redundancy.redundancies.streamingPlaylists.reduce((a, b) => a + b.size, 0)
75   }
76
77   onDisplayTypeChanged () {
78     this.pagination.start = 0
79     this.saveSelectLocalStorage()
80
81     this.loadData()
82   }
83
84   getRedundancyStrategy (redundancy: VideoRedundancy) {
85     if (redundancy.redundancies.files.length !== 0) return redundancy.redundancies.files[0].strategy
86     if (redundancy.redundancies.streamingPlaylists.length !== 0) return redundancy.redundancies.streamingPlaylists[0].strategy
87
88     return ''
89   }
90
91   buildPieData (stats: VideosRedundancyStats) {
92     const totalSize = stats.totalSize
93       ? stats.totalSize - stats.totalUsed
94       : stats.totalUsed
95
96     if (totalSize === 0) return
97
98     this.redundanciesGraphsData.push({
99       stats,
100       graphData: {
101         labels: [ this.i18n('Used'), this.i18n('Available') ],
102         datasets: [
103           {
104             data: [ stats.totalUsed, totalSize ],
105             backgroundColor: [
106               '#FF6384',
107               '#36A2EB'
108             ],
109             hoverBackgroundColor: [
110               '#FF6384',
111               '#36A2EB'
112             ]
113           }
114         ]
115       },
116       options: {
117         title: {
118           display: true,
119           text: stats.strategy
120         },
121
122         tooltips: {
123           callbacks: {
124             label: (tooltipItem: any, data: any) => {
125               const dataset = data.datasets[tooltipItem.datasetIndex]
126               let label = data.labels[tooltipItem.index]
127               if (label) label += ': '
128               else label = ''
129
130               label += this.bytesPipe.transform(dataset.data[tooltipItem.index], 1)
131               return label
132             }
133           }
134         }
135       }
136     })
137   }
138
139   async removeRedundancy (redundancy: VideoRedundancy) {
140     const message = this.i18n('Do you really want to remove this video redundancy?')
141     const res = await this.confirmService.confirm(message, this.i18n('Remove redundancy'))
142     if (res === false) return
143
144     this.redundancyService.removeVideoRedundancies(redundancy)
145       .subscribe(
146         () => {
147           this.notifier.success(this.i18n('Video redundancies removed!'))
148           this.loadData()
149         },
150
151         err => this.notifier.error(err.message)
152       )
153
154   }
155
156   protected loadData () {
157     const options = {
158       pagination: this.pagination,
159       sort: this.sort,
160       target: this.displayType
161     }
162
163     this.redundancyService.listVideoRedundancies(options)
164                       .subscribe(
165                         resultList => {
166                           this.videoRedundancies = resultList.data
167                           this.totalRecords = resultList.total
168                         },
169
170                         err => this.notifier.error(err.message)
171                       )
172   }
173
174   private loadSelectLocalStorage () {
175     const displayType = peertubeLocalStorage.getItem(VideoRedundanciesListComponent.LOCAL_STORAGE_DISPLAY_TYPE)
176     if (displayType) this.displayType = displayType as VideoRedundanciesTarget
177   }
178
179   private saveSelectLocalStorage () {
180     peertubeLocalStorage.setItem(VideoRedundanciesListComponent.LOCAL_STORAGE_DISPLAY_TYPE, this.displayType)
181   }
182 }