You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
5.6 KiB
138 lines
5.6 KiB
import { Box, LinearProgress, Typography } from '@material-ui/core'; |
|
import React, { useCallback, useEffect, useReducer, useState } from 'react'; |
|
import { $enum } from 'ts-enum-util'; |
|
import { ItemType, QueryElemProperty, QueryResponseType } from '../../../api'; |
|
import { queryItems } from '../../../lib/backend/queries'; |
|
import { QueryElem, QueryLeafBy, QueryLeafOp } from '../../../lib/query/Query'; |
|
import StoreLinkIcon, { ExternalStore, StoreURLIdentifiers } from '../../common/StoreLinkIcon'; |
|
|
|
var _ = require('lodash'); |
|
|
|
export default function LinksStatusWidget(props: { |
|
|
|
}) { |
|
type Counts = { |
|
songs: number | undefined, |
|
albums: number | undefined, |
|
artists: number | undefined, |
|
}; |
|
|
|
let [totalCounts, setTotalCounts] = useState<Counts | undefined>(undefined); |
|
let [linkedCounts, setLinkedCounts] = useState<Record<string, Counts>>({}); |
|
|
|
let queryStoreCount = async (store: ExternalStore, type: ItemType) => { |
|
let whichProp: any = { |
|
[ItemType.Song]: QueryLeafBy.SongStoreLinks, |
|
[ItemType.Artist]: QueryLeafBy.ArtistStoreLinks, |
|
[ItemType.Album]: QueryLeafBy.AlbumStoreLinks, |
|
} |
|
let whichElem: any = { |
|
[ItemType.Song]: 'songs', |
|
[ItemType.Artist]: 'artists', |
|
[ItemType.Album]: 'albums', |
|
} |
|
let r: any = await queryItems( |
|
[type], |
|
{ |
|
a: whichProp[type], |
|
leafOp: QueryLeafOp.Like, |
|
b: `%${StoreURLIdentifiers[store]}%`, |
|
}, |
|
undefined, |
|
undefined, |
|
QueryResponseType.Count |
|
); |
|
return r[whichElem[type]]; |
|
} |
|
|
|
// Start retrieving total counts |
|
useEffect(() => { |
|
(async () => { |
|
let counts: any = await queryItems( |
|
[ItemType.Song, ItemType.Artist, ItemType.Album], |
|
undefined, |
|
undefined, |
|
undefined, |
|
QueryResponseType.Count |
|
); |
|
setTotalCounts(counts); |
|
} |
|
)(); |
|
}, []); |
|
|
|
// Start retrieving counts per store |
|
useEffect(() => { |
|
(async () => { |
|
let promises = $enum(ExternalStore).getValues().map((s: ExternalStore) => { |
|
let songsPromise: Promise<number> = queryStoreCount(s, ItemType.Song); |
|
let albumsPromise: Promise<number> = queryStoreCount(s, ItemType.Album); |
|
let artistsPromise: Promise<number> = queryStoreCount(s, ItemType.Artist); |
|
let updatePromise = Promise.all([songsPromise, albumsPromise, artistsPromise]).then( |
|
(r: any[]) => { |
|
setLinkedCounts((prev: Record<string, Counts>) => { |
|
return { |
|
...prev, |
|
[s]: { |
|
songs: r[0], |
|
artists: r[2], |
|
albums: r[1], |
|
} |
|
} |
|
}); |
|
} |
|
) |
|
console.log(s); |
|
return updatePromise; |
|
}) |
|
return Promise.all(promises); |
|
} |
|
)(); |
|
}, [setLinkedCounts]); |
|
|
|
let storeReady = (s: ExternalStore) => { |
|
return s in linkedCounts; |
|
} |
|
|
|
return <Box display="flex" flexDirection="column" alignItems="left"> |
|
<table> |
|
{$enum(ExternalStore).getValues().map((s: ExternalStore) => { |
|
if (!totalCounts) { return <></>; } |
|
if (!storeReady(s)) { return <></>; } |
|
let tot = totalCounts; |
|
let lin = linkedCounts[s]; |
|
let perc = { |
|
songs: Math.round((lin.songs || 0) / (tot.songs || 1) * 100), |
|
artists: Math.round((lin.artists || 0) / (tot.artists || 1) * 100), |
|
albums: Math.round((lin.albums || 0) / (tot.albums || 1) * 100), |
|
} |
|
return <> |
|
{totalCounts && storeReady(s) && <> |
|
<tr> |
|
<td rowSpan={3}> |
|
<Box display="flex" flexDirection="column" alignItems="center"> |
|
<StoreLinkIcon whichStore={s} /> |
|
<Typography>{s}</Typography> |
|
</Box> |
|
</td> |
|
<td><Typography>Linked artists:</Typography></td> |
|
<td><Box minWidth="200px"><LinearProgress variant="determinate" color="secondary" value={perc.artists} /></Box></td> |
|
<td><Typography>{lin.artists} / {tot.artists}</Typography></td> |
|
</tr> |
|
<tr> |
|
<td><Typography>Linked albums:</Typography></td> |
|
<td><Box minWidth="200px"><LinearProgress variant="determinate" color="secondary" value={perc.albums} /></Box></td> |
|
<td><Typography>{lin.albums} / {tot.albums}</Typography></td> |
|
</tr> |
|
<tr> |
|
<td><Typography>Linked songs:</Typography></td> |
|
<td><Box minWidth="200px"><LinearProgress variant="determinate" color="secondary" value={perc.songs} /></Box></td> |
|
<td><Typography>{lin.songs} / {tot.songs}</Typography></td> |
|
</tr> |
|
<tr><td colSpan={4}> </td></tr> |
|
</> |
|
} |
|
</>; |
|
})} |
|
</table> |
|
</Box > |
|
} |