2b62d30a389c7bf619c7a5edb5ee716565e5d5aa
[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   getColspan () {
69     if (this.isDisplayingRemoteVideos()) return 5
70
71     return 4
72   }
73
74   isDisplayingRemoteVideos () {
75     return this.displayType === 'remote-videos'
76   }
77
78   getTotalSize (redundancy: VideoRedundancy) {
79     return redundancy.redundancies.files.reduce((a, b) => a + b.size, 0) +
80       redundancy.redundancies.streamingPlaylists.reduce((a, b) => a + b.size, 0)
81   }
82
83   onDisplayTypeChanged () {
84     this.pagination.start = 0
85     this.saveSelectLocalStorage()
86
87     this.loadData()
88   }
89
90   getRedundancyStrategy (redundancy: VideoRedundancy) {
91     if (redundancy.redundancies.files.length !== 0) return redundancy.redundancies.files[0].strategy
92     if (redundancy.redundancies.streamingPlaylists.length !== 0) return redundancy.redundancies.streamingPlaylists[0].strategy
93
94     return ''
95   }
96
97   buildPieData (stats: VideosRedundancyStats) {
98     const totalSize = stats.totalSize
99       ? stats.totalSize - stats.totalUsed
100       : stats.totalUsed
101
102     if (totalSize === 0) return
103
104     this.redundanciesGraphsData.push({
105       stats,
106       graphData: {
107         labels: [ this.i18n('Used'), this.i18n('Available') ],
108         datasets: [
109           {
110             data: [ stats.totalUsed, totalSize ],
111             backgroundColor: [
112               '#FF6384',
113               '#36A2EB'
114             ],
115             hoverBackgroundColor: [
116               '#FF6384',
117               '#36A2EB'
118             ]
119           }
120         ]
121       },
122       options: {
123         title: {
124           display: true,
125           text: stats.strategy
126         },
127
128         tooltips: {
129           callbacks: {
130             label: (tooltipItem: any, data: any) => {
131               const dataset = data.datasets[tooltipItem.datasetIndex]
132               let label = data.labels[tooltipItem.index]
133               if (label) label += ': '
134               else label = ''
135
136               label += this.bytesPipe.transform(dataset.data[tooltipItem.index], 1)
137               return label
138             }
139           }
140         }
141       }
142     })
143   }
144
145   async removeRedundancy (redundancy: VideoRedundancy) {
146     const message = this.i18n('Do you really want to remove this video redundancy?')
147     const res = await this.confirmService.confirm(message, this.i18n('Remove redundancy'))
148     if (res === false) return
149
150     this.redundancyService.removeVideoRedundancies(redundancy)
151       .subscribe(
152         () => {
153           this.notifier.success(this.i18n('Video redundancies removed!'))
154           this.loadData()
155         },
156
157         err => this.notifier.error(err.message)
158       )
159
160   }
161
162   protected loadData () {
163     const options = {
164       pagination: this.pagination,
165       sort: this.sort,
166       target: this.displayType
167     }
168
169     this.redundancyService.listVideoRedundancies(options)
170                       .subscribe(
171                         resultList => {
172                           this.videoRedundancies = resultList.data
173                           this.totalRecords = resultList.total
174                         },
175
176                         err => this.notifier.error(err.message)
177                       )
178   }
179
180   private loadSelectLocalStorage () {
181     const displayType = peertubeLocalStorage.getItem(VideoRedundanciesListComponent.LOCAL_STORAGE_DISPLAY_TYPE)
182     if (displayType) this.displayType = displayType as VideoRedundanciesTarget
183   }
184
185   private saveSelectLocalStorage () {
186     peertubeLocalStorage.setItem(VideoRedundanciesListComponent.LOCAL_STORAGE_DISPLAY_TYPE, this.displayType)
187   }
188 }