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