Update all library admin views

This commit is contained in:
Ciarán Ainsworth 2022-09-18 13:05:26 +00:00 committed by Kasper Seweryn
parent ef757e1854
commit 5e1e260606
12 changed files with 490 additions and 237 deletions

View File

@ -1659,6 +1659,17 @@
}
}
},
"embed": {
"EmbedFrame": {
"badResource": "idget improperly configured (bad resource type {type}).",
"missingResourceId": "Widget improperly configured (missing resource id).",
"trackNotFound": "Track not found.",
"unauthenticated": "You need to login to access this resource.",
"unknownServerError": "An unknown error occurred while loading track data from server.",
"trackUnavailable": "This track is unavailable.",
"unknownTrackError": "An unknown error occurred while loading track data."
}
},
"views": {
"Notifications": {
"title": "Notifications",
@ -1701,9 +1712,251 @@
"submitSearchLabel": "Submit Search Query",
"searchHeader": "Search"
},
"library": {
"LibraryBase": {
"admin": {
"ChannelDetail": {
"statsWarning": "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object",
"localLabel": "Local",
"localProfileLink": "Open local profile",
"djangoLink": "View in Django's admin",
"refreshButton": "Refresh from remote server",
"openRemoteButton": "Open remote profile",
"deleteButton": "Delete",
"deleteModalHeader": "Delete this channel?",
"deleteModalMessage": "The channel will be removed, as well as associated uploads, tracks, and albums. This action is irreversible.",
"channelDataHeader": "Channel data",
"nameLabel": "Name",
"categoryLabel": "Category",
"accountLabel": "Account",
"domainLabel": "Domain",
"descriptionLabel": "Description",
"urlLabel": "URL",
"rssLabel": "RSS feed",
"activityHeader": "Activity ",
"firstSeenLabel": "First seen",
"listeningsLabel": "Listenings",
"favoritedLabel": "Favorited tracks",
"playlistsLabel": "Playlists",
"linkedReportsLabel": "Linked reports",
"editsLabel": "Edits",
"audioContentHeader": "Audio content ",
"cachedSizeLabel": "Cached size",
"totalSizeLabel": "Total size",
"uploadsLabel": "Uploads",
"albumsLabel": "Albums",
"tracksLabel": "Tracks"
},
"CommonList": {
"accountsLabel": "Accounts",
"albumsLabel": "Albums",
"artistsLabel": "Artists",
"channelsLabel": "Channels",
"invitationsLabel": "Invitations",
"librariesLabel": "Libraries",
"tagsLabel": "Tags",
"tracksLabel": "Tracks",
"uploadsLabel": "Uploads",
"usersLabel": "Users"
},
"Settings": {
"settingsLabel": "Instance Settings",
"instanceInfoLabel": "Instance Information",
"signupsLabel": "Sign-ups",
"securityLabel": "Security",
"musicLabel": "Music",
"channelsLabel": "Channels",
"playlistsLabel": "Playlists",
"moderationLabel": "Moderation",
"federationLabel": "Federation",
"subsonicLabel": "Subsonic",
"statsLabel": "Statistics",
"uiLabel": "User Interface",
"sectionsHeader": "Sections"
},
"library": {
"AlbumDetail": {
"statsWarning": "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object",
"localLabel": "Local",
"localProfileLink": "Open local profile",
"djangoLink": "View in Django's admin",
"musicbrainzLink": "Open on MusicBrainz",
"remoteRefreshButton": "Refresh from remote server",
"remoteProfileLink": "Open remote profile",
"editButton": "Edit",
"deleteButton": "Delete",
"deleteModalHeader": "Delete this album?",
"deleteModalMessage": "The album will be deleted, as well as associated uploads, tracks, favorites and listening history. This action is irreversible.",
"albumDataHeader": "Album data",
"titleLabel": "Title",
"artistLabel": "Artist",
"domainLabel": "Domain",
"descriptionLabel": "Description",
"activityHeader": "Activity ",
"firstSeenLabel": "First seen",
"listeningsLabel": "Listenings",
"favoritedLabel": "Favorited tracks",
"playlistsLabel": "Playlists",
"linkedReportsLabel": "Linked reports",
"editsLabel": "Edits",
"audioContentHeader": "Audio content ",
"cachedSizeLabel": "Cached size",
"totalSizeLabel": "Total size",
"librariesLabel": "Libraries",
"uploadsLabel": "Uploads",
"tracksLabel": "Tracks"
},
"ArtistDetail": {
"statsWarning":"Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object",
"localLabel": "Local",
"localProfileLink": "Open local profile",
"djangoLink": "View in Django's admin",
"musicbrainzLink": "Open on MusicBrainz",
"remoteRefreshButton": "Refresh from remote server",
"remoteProfileLink": "Open remote profile",
"editButton": "Edit",
"deleteButton": "Delete",
"deleteModalHeader": "Delete this artist?",
"deleteModalMessage": "The artist will be deleted, as well as associated uploads, tracks, favorites and listening history. This action is irreversible.",
"artistDataHeader": "Artist data",
"nameLabel": "Name",
"categoryLabel": "Category",
"domainLabel": "Domain",
"descriptionLabel": "Description",
"activityHeader": "Activity ",
"firstSeenLabel": "First seen",
"listeningsLabel": "Listenings",
"favoritedLabel": "Favorited tracks",
"playlistsLabel": "Playlists",
"linkedReportsLabel": "Linked reports",
"editsLabel": "Edits",
"audioContentHeader": "Audio content ",
"cachedSizeLabel": "Cached size",
"totalSizeLabel": "Total size",
"librariesLabel": "Libraries",
"uploadsLabel": "Uploads",
"albumsLabel": "Albums",
"tracksLabel": "Tracks"
},
"Base": {
"title": "Manage Library",
"secondaryMenu": "Secondary menu",
"editsLink": "Edits",
"channelsLink": "Channels",
"artistsLink": "Artists",
"albumsLink": "Albums",
"tracksLink": "Tracks",
"librariesLink": "Libraries",
"uploadsLink": "Uploads",
"tagsLink": "Tags"
},
"EditsList": {
"title": "Edits",
"libraryEditsHeader": "Library edits"
},
"LibraryDetail": {
"statsWarning": "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object",
"localLabel": "Local",
"djangoLink": "View in Django's admin",
"remoteProfileLink": "Open remote profile",
"deleteButton": "Delete",
"deleteModalHeader": "Delete this library?",
"deleteModalMessage": "The library will be deleted, as well as associated uploads, tracks, favorites and listening history. This action is irreversible.",
"libraryDataHeader": "Library data",
"nameLabel": "Name",
"visibilityLabel": "Visibility",
"accountLabel": "Account",
"domainLabel": "Domain",
"descriptionLabel": "Description",
"activityHeader": "Activity ",
"firstSeenLabel": "First seen",
"followersLabel": "Followers",
"linkedReportsLabel": "Linked reports",
"audioContentHeader": "Audio content ",
"cachedSizeLabel": "Cached size",
"totalSizeLabel": "Total size",
"artistsLabel": "Artists",
"albumsLabel": "Albums",
"tracksLabel": "Tracks",
"uploadsLabel": "Uploads"
},
"TagDetail": {
"localProfileLink": "Open local profile",
"djangoLink": "View in Django's admin",
"deleteButton": "Delete",
"deleteModalHeader": "Delete this tag?",
"deleteModalMessage": "The tag will be removed and unlinked from any existing entity. This action is irreversible.",
"tagDataHeader": "Tag data",
"nameLabel": "Name",
"activityHeader": "Activity ",
"firstSeenLabel": "First seen",
"audioContentHeader": "Audio content ",
"artistsLabel": "Artists",
"albumsLabel": "Albums",
"tracksLabel": "Tracks"
},
"TrackDetail": {
"statsWarning": "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object",
"localLabel": "Local",
"localProfileLink": "Open local profile",
"djangoLink": "View in Django's admin",
"musicbrainzLink": "Open on MusicBrainz",
"remoteRefreshButton": "Refresh from remote server",
"remoteProfileLink": "Open remote profile",
"editButton": "Edit",
"deleteButton": "Delete",
"deleteModalHeader": "Delete this track?",
"deleteModalMessage": "The track will be deleted, as well as associated uploads, favorites and listening history. This action is irreversible.",
"trackDataHeader": "Track data",
"titleLabel": "Title",
"albumLabel": "Album",
"artistLabel": "Artist",
"albumArtistLabel": "Album artist",
"positionLabel": "Position",
"discNumberLabel": "Disc number",
"copyrightLabel": "Copyright",
"licenseLabel": "License",
"domainLabel": "Domain",
"descriptionLabel": "Description",
"activityHeader": "Activity ",
"firstSeenLabel": "First seen",
"listeningsLabel": "Listenings",
"favoritedLabel": "Favorited tracks",
"playlistsLabel": "Playlists",
"linkedReportsLabel": "Linked reports",
"editsLabel": "Edits",
"audioContentHeader": "Audio content ",
"cachedSizeLabel": "Cached size",
"totalSizeLabel": "Total size",
"librariesLabel": "Libraries",
"uploadsLabel": "Uploads"
},
"UploadDetail": {
"localLabel": "Local",
"djangoLink": "View in Django's admin",
"remoteProfileLink": "Open remote profile",
"downloadButton": "Download",
"deleteButton": "Delete",
"deleteModalHeader": "Delete this upload?",
"deleteModalMessage": "The upload will be removed. This action is irreversible.",
"uploadDataHeader": "Upload data",
"nameLabel": "Name",
"visibilityLabel": "Visibility",
"accountLabel": "Account",
"domainLabel": "Domain",
"importStatusLabel": "Import status",
"libraryLabel": "Library",
"activityHeader": "Activity ",
"firstSeenLabel": "First seen",
"accessedDateLabel": "Accessed date",
"notApplicable": "N/A",
"audioContentHeader": "Audio content ",
"trackLabel": "Track",
"cachedSizeLabel": "Cached size",
"sizeLabel": "Size",
"bitrateLabel": "Bitrate",
"bitrateValue": "{bitrate}/s",
"durationLabel": "Duration",
"typeLabel": "Type"
}
}
}
}

View File

@ -21,7 +21,7 @@ const { t } = useI18n()
const router = useRouter()
const labels = computed(() => ({
statsWarning: t('Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object')
statsWarning: t('views.admin.ChannelDetail.statsWarning')
}))
const isLoading = ref(false)
@ -106,7 +106,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<template v-if="object.artist.is_local">
<span class="ui tiny accent label">
<i class="home icon" />
Local
{{ $t('views.admin.ChannelDetail.localLabel') }}
</span>
&nbsp;
</template>
@ -129,7 +129,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:to="{name: 'channels.detail', params: {id: object.uuid }}"
>
<i class="info icon" />
Open local profile&nbsp;
{{ $t('views.admin.ChannelDetail.localProfileLink') }}
</router-link>
<button
v-dropdown
@ -145,7 +145,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.ChannelDetail.djangoLink') }}
</a>
<fetch-button
v-if="!object.actor.is_local"
@ -154,7 +154,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
@refresh="fetchData"
>
<i class="refresh icon" />&nbsp;
Refresh from remote server&nbsp;
{{ $t('views.admin.ChannelDetail.refreshButton') }}
</fetch-button>
<a
class="basic item"
@ -163,7 +163,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="external icon" />
Open remote profile&nbsp;
{{ $t('views.admin.ChannelDetail.openRemoteButton') }}
</a>
</div>
</button>
@ -173,22 +173,22 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:class="['ui', {loading: isLoading}, 'basic danger button']"
:action="remove"
>
Delete
{{ $t('views.admin.ChannelDetail.deleteButton') }}
<template #modal-header>
<p>
Delete this channel?
{{ $t('views.admin.ChannelDetail.deleteModalHeader') }}
</p>
</template>
<template #modal-content>
<div>
<p>
The channel will be removed, as well as associated uploads, tracks, and albums. This action is irreversible.
{{ $t('views.admin.ChannelDetail.deleteModalMessage') }}
</p>
</div>
</template>
<template #modal-confirm>
<p>
Delete
{{ $t('views.admin.ChannelDetail.deleteButton') }}
</p>
</template>
</dangerous-button>
@ -205,14 +205,14 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="info icon" />
<div class="content">
Channel data
{{ $t('views.admin.ChannelDetail.channelDataHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
Name
{{ $t('views.admin.ChannelDetail.nameLabel') }}
</td>
<td>
{{ object.artist.name }}
@ -221,7 +221,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.channels', query: {q: getQuery('category', object.artist.content_category) }}">
Category
{{ $t('views.admin.ChannelDetail.categoryLabel') }}
</router-link>
</td>
<td>
@ -231,7 +231,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: object.attributed_to.full_username }}">
Account
{{ $t('views.admin.ChannelDetail.accountLabel') }}
</router-link>
</td>
<td>
@ -241,7 +241,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr v-if="!object.actor.is_local">
<td>
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.actor.domain }}">
Domain
{{ $t('views.admin.ChannelDetail.domainLabel') }}
</router-link>
</td>
<td>
@ -250,7 +250,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="object.artist.description">
<td>
Description
{{ $t('views.admin.ChannelDetail.descriptionLabel') }}
</td>
<sanitized-html
tag="td"
@ -259,7 +259,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="object.actor.url">
<td>
URL
{{ $t('views.admin.ChannelDetail.urlLabel') }}
</td>
<td>
<a
@ -271,7 +271,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="object.rss_url">
<td>
RSS Feed
{{ $t('views.admin.ChannelDetail.rssLabel') }}
</td>
<td>
<a
@ -290,7 +290,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="feed icon" />
<div class="content">
Activity&nbsp;
{{ $t('views.admin.ChannelDetail.activityHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -310,7 +310,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
First seen
{{ $t('views.admin.ChannelDetail.firstSeenLabel') }}
</td>
<td>
<human-date :date="object.creation_date" />
@ -318,7 +318,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Listenings
{{ $t('views.admin.ChannelDetail.listeningsLabel') }}
</td>
<td>
{{ stats.listenings }}
@ -326,7 +326,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Favorited tracks
{{ $t('views.admin.ChannelDetail.favoritedLabel') }}
</td>
<td>
{{ stats.track_favorites }}
@ -334,7 +334,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Playlists
{{ $t('views.admin.ChannelDetail.playlistsLabel') }}
</td>
<td>
{{ stats.playlists }}
@ -343,7 +343,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.moderation.reports.list', query: {q: getQuery('target', `channel:${object.uuid}`) }}">
Linked reports
{{ $t('views.admin.ChannelDetail.linkedReportsLabel') }}
</router-link>
</td>
<td>
@ -353,7 +353,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.edits', query: {q: getQuery('target', 'artist ' + object.artist.id)}}">
Edits
{{ $t('views.admin.ChannelDetail.editsLabel') }}
</router-link>
</td>
<td>
@ -369,7 +369,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="music icon" />
<div class="content">
Audio content&nbsp;
{{ $t('views.admin.ChannelDetail.audioContentHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -389,7 +389,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
Cached size
{{ $t('views.admin.ChannelDetail.cachedSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_downloaded_size) }}
@ -397,7 +397,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Total size
{{ $t('views.admin.ChannelDetail.totalSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_total_size) }}
@ -406,7 +406,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('channel_id', object.uuid) }}">
Uploads
{{ $t('views.admin.ChannelDetail.uploadsLabel') }}
</router-link>
</td>
<td>
@ -416,7 +416,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.albums', query: {q: getQuery('channel_id', object.uuid) }}">
Albums
{{ $t('views.admin.ChannelDetail.albumsLabel') }}
</router-link>
</td>
<td>
@ -426,7 +426,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('channel_id', object.uuid) }}">
Tracks
{{ $t('views.admin.ChannelDetail.tracksLabel') }}
</router-link>
</td>
<td>

View File

@ -27,16 +27,16 @@ const props = withDefaults(defineProps<Props>(), {
const { t } = useI18n()
const labels = computed(() => ({
accounts: t('Accounts'),
albums: t('Albums'),
artists: t('Artists'),
channels: t('Channels'),
invitations: t('Invitations'),
libraries: t('Libraries'),
tags: t('Tags'),
tracks: t('Tracks'),
uploads: t('Uploads'),
users: t('Users')
accounts: t('views.admin.CommonList.accountsLabel'),
albums: t('views.admin.CommonList.albumsLabel'),
artists: t('views.admin.CommonList.artistsLabel'),
channels: t('views.admin.CommonList.channelsLabel'),
invitations: t('views.admin.CommonList.invitationsLabel'),
libraries: t('views.admin.CommonList.librariesLabel'),
tags: t('views.admin.CommonList.tagsLabel'),
tracks: t('views.admin.CommonList.tracksLabel'),
uploads: t('views.admin.CommonList.uploadsLabel'),
users: t('views.admin.CommonList.usersLabel')
}))
const title = computed(() => labels.value[props.type])

View File

@ -20,7 +20,7 @@ const { t } = useI18n()
const groups = computed(() => [
{
label: t('Instance information'),
label: t('views.admin.Settings.instanceInfoLabel'),
id: 'instance',
settings: [
{ name: 'instance__name' },
@ -34,7 +34,7 @@ const groups = computed(() => [
]
},
{
label: t('Sign-ups'),
label: t('views.admin.Settings.signupsLabel'),
id: 'signup',
settings: [
{ name: 'users__registration_enabled' },
@ -43,7 +43,7 @@ const groups = computed(() => [
]
},
{
label: t('Security'),
label: t('views.admin.Settings.securityLabel'),
id: 'security',
settings: [
{ name: 'common__api_authentication_required' },
@ -52,7 +52,7 @@ const groups = computed(() => [
]
},
{
label: t('Music'),
label: t('views.admin.Settings.musicLabel'),
id: 'music',
settings: [
{ name: 'music__transcoding_enabled' },
@ -60,7 +60,7 @@ const groups = computed(() => [
]
},
{
label: t('Channels'),
label: t('views.admin.Settings.channelsLabel'),
id: 'channels',
settings: [
{ name: 'audio__channels_enabled' },
@ -68,14 +68,14 @@ const groups = computed(() => [
]
},
{
label: t('Playlists'),
label: t('views.admin.Settings.playlistsLabel'),
id: 'playlists',
settings: [
{ name: 'playlists__max_tracks' }
]
},
{
label: t('Moderation'),
label: t('views.admin.Settings.moderationLabel'),
id: 'moderation',
settings: [
{ name: 'moderation__allow_list_enabled' },
@ -84,7 +84,7 @@ const groups = computed(() => [
]
},
{
label: t('Federation'),
label: t('views.admin.Settings.federationLabel'),
id: 'federation',
settings: [
{ name: 'federation__enabled' },
@ -95,14 +95,14 @@ const groups = computed(() => [
]
},
{
label: t('Subsonic'),
label: t('views.admin.Settings.subsonicLabel'),
id: 'subsonic',
settings: [
{ name: 'subsonic__enabled' }
]
},
{
label: t('Statistics'),
label: t('views.admin.Settings.statsLabel'),
id: 'ui',
settings: [
{ name: 'ui__custom_css' },
@ -110,7 +110,7 @@ const groups = computed(() => [
]
},
{
label: t('User Interface'),
label: t('views.admin.Settings.uiLabel'),
id: 'statistics',
settings: [
{ name: 'instance__nodeinfo_stats_enabled' },
@ -120,7 +120,7 @@ const groups = computed(() => [
] as SettingsGroupType[])
const labels = computed(() => ({
settings: t('Instance settings')
settings: t('views.admin.Settings.settingsLabel')
}))
const scrollTo = (id: string) => {
@ -186,7 +186,7 @@ await nextTick()
<div class="four wide column">
<div class="ui sticky vertical secondary menu">
<div class="header item">
Sections
{{ $t('views.admin.Settings.sectionsHeader') }}
</div>
<a
v-for="(group, key) in groups"

View File

@ -21,7 +21,7 @@ const { t } = useI18n()
const router = useRouter()
const labels = computed(() => ({
statsWarning: t('Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object')
statsWarning: t('views.admin.library.AlbumDetail.statsWarning')
}))
const isLoading = ref(false)
@ -106,7 +106,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<template v-if="object.is_local">
<span class="ui tiny accent label">
<i class="home icon" />
Local
{{ $t('views.admin.library.AlbumDetail.localLabel') }}
</span>
&nbsp;
</template>
@ -130,7 +130,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:to="{name: 'library.albums.detail', params: {id: object.id }}"
>
<i class="info icon" />
Open local profile&nbsp;
{{ $t('views.admin.library.AlbumDetail.localProfileLink') }}
</router-link>
<button
v-dropdown
@ -146,7 +146,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.AlbumDetail.djangoLink') }}
</a>
<a
v-if="object.mbid"
@ -156,7 +156,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="external icon" />
Open on MusicBrainz&nbsp;
{{ $t('views.admin.library.AlbumDetail.musicbrainzLink') }}
</a>
<fetch-button
v-if="!object.is_local"
@ -165,7 +165,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
@refresh="fetchData"
>
<i class="refresh icon" />&nbsp;
Refresh from remote server&nbsp;
{{ $t('views.admin.library.AlbumDetail.remoteRefreshButton') }}
</fetch-button>
<a
class="basic item"
@ -174,7 +174,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="external icon" />
Open remote profile&nbsp;
{{ $t('views.admin.library.AlbumDetail.remoteProfileLink') }}
</a>
</div>
</button>
@ -186,7 +186,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
class="ui labeled icon button"
>
<i class="edit icon" />
Edit
{{ $t('views.admin.library.AlbumDetail.editButton') }}
</router-link>
</div>
<div class="ui buttons">
@ -194,22 +194,22 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:class="['ui', {loading: isLoading}, 'basic danger button']"
:action="remove"
>
Delete
{{ $t('views.admin.library.AlbumDetail.deleteButton') }}
<template #modal-header>
<p>
Delete this album?
{{ $t('views.admin.library.AlbumDetail.deleteModalHeader') }}
</p>
</template>
<template #modal-content>
<div>
<p>
The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible.
{{ $t('views.admin.library.AlbumDetail.deleteModalMessage') }}
</p>
</div>
</template>
<template #modal-confirm>
<p>
Delete
{{ $t('views.admin.library.AlbumDetail.deleteButton') }}
</p>
</template>
</dangerous-button>
@ -226,14 +226,14 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="info icon" />
<div class="content">
Album data
{{ $t('views.admin.library.AlbumDetail.albumDataHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
Title
{{ $t('views.admin.library.AlbumDetail.titleLabel') }}
</td>
<td>
{{ object.title }}
@ -242,7 +242,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.artists.detail', params: {id: object.artist.id }}">
Artist
{{ $t('views.admin.library.AlbumDetail.artistLabel') }}
</router-link>
</td>
<td>
@ -252,7 +252,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr v-if="!object.is_local">
<td>
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
Domain
{{ $t('views.admin.library.AlbumDetail.domainLabel') }}
</router-link>
</td>
<td>
@ -261,7 +261,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="object.description">
<td>
Description
{{ $t('views.admin.library.AlbumDetail.descriptionLabel') }}
</td>
<sanitized-html
tag="td"
@ -277,7 +277,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="feed icon" />
<div class="content">
Activity&nbsp;
{{ $t('views.admin.library.AlbumDetail.activityHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -297,7 +297,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
First seen
{{ $t('views.admin.library.AlbumDetail.firstSeenLabel') }}
</td>
<td>
<human-date :date="object.creation_date" />
@ -305,7 +305,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Listenings
{{ $t('views.admin.library.AlbumDetail.listeningsLabel') }}
</td>
<td>
{{ stats.listenings }}
@ -313,7 +313,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Favorited tracks
{{ $t('views.admin.library.AlbumDetail.favoritedLabel') }}
</td>
<td>
{{ stats.track_favorites }}
@ -321,7 +321,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Playlists
{{ $t('views.admin.library.AlbumDetail.playlistsLabel') }}
</td>
<td>
{{ stats.playlists }}
@ -330,7 +330,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.moderation.reports.list', query: {q: getQuery('target', `album:${object.id}`) }}">
Linked reports
{{ $t('views.admin.library.AlbumDetail.linkedReportsLabel') }}
</router-link>
</td>
<td>
@ -340,7 +340,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.edits', query: {q: getQuery('target', 'album ' + object.id)}}">
Edits
{{ $t('views.admin.library.AlbumDetail.editsLabel') }}
</router-link>
</td>
<td>
@ -356,7 +356,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="music icon" />
<div class="content">
Audio content&nbsp;
{{ $t('views.admin.library.AlbumDetail.audioContentHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -376,7 +376,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
Cached size
{{ $t('views.admin.library.AlbumDetail.cachedSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_downloaded_size) }}
@ -384,7 +384,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Total size
{{ $t('views.admin.library.AlbumDetail.totalSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_total_size) }}
@ -394,7 +394,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('album_id', object.id) }}">
Libraries
{{ $t('views.admin.library.AlbumDetail.librariesLabel') }}
</router-link>
</td>
<td>
@ -404,7 +404,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('album_id', object.id) }}">
Uploads
{{ $t('views.admin.library.AlbumDetail.uploadsLabel') }}
</router-link>
</td>
<td>
@ -414,7 +414,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('album_id', object.id) }}">
Tracks
{{ $t('views.admin.library.AlbumDetail.tracksLabel') }}
</router-link>
</td>
<td>

View File

@ -21,7 +21,7 @@ const { t } = useI18n()
const router = useRouter()
const labels = computed(() => ({
statsWarning: t('Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object')
statsWarning: t('views.admin.library.ArtistDetail.statsWarning')
}))
const isLoading = ref(false)
@ -106,7 +106,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<template v-if="object.is_local">
<span class="ui tiny accent label">
<i class="home icon" />
Local
{{ $t('views.admin.library.ArtistDetail.localLabel') }}
</span>
&nbsp;
</template>
@ -129,7 +129,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:to="{name: 'library.artists.detail', params: {id: object.id }}"
>
<i class="info icon" />
Open local profile&nbsp;
{{ $t('views.admin.library.ArtistDetail.localProfileLink') }}
</router-link>
<button
v-dropdown
@ -145,7 +145,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.ArtistDetail.djangoLink') }}
</a>
<a
v-if="object.mbid"
@ -155,7 +155,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="external icon" />
Open on MusicBrainz&nbsp;
{{ $t('views.admin.library.ArtistDetail.musicbrainzLink') }}
</a>
<fetch-button
v-if="!object.is_local"
@ -164,7 +164,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
@refresh="fetchData"
>
<i class="refresh icon" />&nbsp;
Refresh from remote server&nbsp;
{{ $t('views.admin.library.ArtistDetail.remoteRefreshButton') }}
</fetch-button>
<a
class="basic item"
@ -173,7 +173,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="external icon" />
Open remote profile&nbsp;
{{ $t('views.admin.library.ArtistDetail.remoteProfileLink') }}
</a>
</div>
</button>
@ -185,7 +185,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
class="ui labeled icon button"
>
<i class="edit icon" />
Edit
{{ $t('views.admin.library.ArtistDetail.editButton') }}
</router-link>
</div>
<div class="ui buttons">
@ -193,22 +193,22 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:class="['ui', {loading: isLoading}, 'basic danger button']"
:action="remove"
>
Delete
{{ $t('views.admin.library.ArtistDetail.deleteButton') }}
<template #modal-header>
<p>
Delete this artist?
{{ $t('views.admin.library.ArtistDetail.deleteModalHeader') }}
</p>
</template>
<template #modal-content>
<div>
<p>
The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible.
{{ $t('views.admin.library.ArtistDetail.deleteModalMessage') }}
</p>
</div>
</template>
<template #modal-confirm>
<p>
Delete
{{ $t('views.admin.library.ArtistDetail.deleteButton') }}
</p>
</template>
</dangerous-button>
@ -225,14 +225,14 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="info icon" />
<div class="content">
Artist data
{{ $t('views.admin.library.ArtistDetail.artistDataHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
Name
{{ $t('views.admin.library.ArtistDetail.nameLabel') }}
</td>
<td>
{{ object.name }}
@ -241,7 +241,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.artists', query: {q: getQuery('category', object.content_category) }}">
Category
{{ $t('views.admin.library.ArtistDetail.categoryLabel') }}
</router-link>
</td>
<td>
@ -251,7 +251,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr v-if="!object.is_local">
<td>
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
Domain
{{ $t('views.admin.library.ArtistDetail.domainLabel') }}
</router-link>
</td>
<td>
@ -260,7 +260,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="object.description">
<td>
Description
{{ $t('views.admin.library.ArtistDetail.descriptionLabel') }}
</td>
<sanitized-html
tag="td"
@ -276,7 +276,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="feed icon" />
<div class="content">
Activity&nbsp;
{{ $t('views.admin.library.ArtistDetail.activityHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -296,7 +296,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
First seen
{{ $t('views.admin.library.ArtistDetail.firstSeenLabel') }}
</td>
<td>
<human-date :date="object.creation_date" />
@ -304,7 +304,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Listenings
{{ $t('views.admin.library.ArtistDetail.listeningsLabel') }}
</td>
<td>
{{ stats.listenings }}
@ -312,7 +312,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Favorited tracks
{{ $t('views.admin.library.ArtistDetail.favoritedLabel') }}
</td>
<td>
{{ stats.track_favorites }}
@ -320,7 +320,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Playlists
{{ $t('views.admin.library.ArtistDetail.playlistsLabel') }}
</td>
<td>
{{ stats.playlists }}
@ -329,7 +329,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.moderation.reports.list', query: {q: getQuery('target', `artist:${object.id}`) }}">
Linked reports
{{ $t('views.admin.library.ArtistDetail.linkedReportsLabel') }}
</router-link>
</td>
<td>
@ -339,7 +339,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.edits', query: {q: getQuery('target', 'artist ' + object.id)}}">
Edits
{{ $t('views.admin.library.ArtistDetail.editsLabel') }}
</router-link>
</td>
<td>
@ -355,7 +355,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="music icon" />
<div class="content">
Audio content&nbsp;
{{ $t('views.admin.library.ArtistDetail.audioContentHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -375,7 +375,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
Cached size
{{ $t('views.admin.library.ArtistDetail.cachedSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_downloaded_size) }}
@ -383,7 +383,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Total size
{{ $t('views.admin.library.ArtistDetail.totalSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_total_size) }}
@ -393,7 +393,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('artist_id', object.id) }}">
Libraries
{{ $t('views.admin.library.ArtistDetail.librariesLabel') }}
</router-link>
</td>
<td>
@ -403,7 +403,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('artist_id', object.id) }}">
Uploads
{{ $t('views.admin.library.ArtistDetail.uploadsLabel') }}
</router-link>
</td>
<td>
@ -413,7 +413,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.albums', query: {q: getQuery('artist_id', object.id) }}">
Albums
{{ $t('views.admin.library.ArtistDetail.albumsLabel') }}
</router-link>
</td>
<td>
@ -423,7 +423,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('artist_id', object.id) }}">
Tracks
{{ $t('views.admin.library.ArtistDetail.tracksLabel') }}
</router-link>
</td>
<td>

View File

@ -4,8 +4,8 @@ import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const labels = computed(() => ({
title: t('Manage library'),
secondaryMenu: t('Secondary menu')
title: t('views.admin.library.Base.title'),
secondaryMenu: t('views.admin.library.Base.secondaryMenu')
}))
</script>
@ -23,49 +23,49 @@ const labels = computed(() => ({
class="ui item"
:to="{name: 'manage.library.edits'}"
>
Edits
{{ $t('views.admin.library.Base.editsLink') }}
</router-link>
<router-link
class="ui item"
:to="{name: 'manage.channels'}"
>
Channels
{{ $t('views.admin.library.Base.channelsLink') }}
</router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.artists'}"
>
Artists
{{ $t('views.admin.library.Base.artistsLink') }}
</router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.albums'}"
>
Albums
{{ $t('views.admin.library.Base.albumsLink') }}
</router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.tracks'}"
>
Tracks
{{ $t('views.admin.library.Base.tracksLink') }}
</router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.libraries'}"
>
Libraries
{{ $t('views.admin.library.Base.librariesLink') }}
</router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.uploads'}"
>
Uploads
{{ $t('views.admin.library.Base.uploadsLink') }}
</router-link>
<router-link
class="ui item"
:to="{name: 'manage.library.tags'}"
>
Tags
{{ $t('views.admin.library.Base.tagsLink') }}
</router-link>
</nav>
<router-view :key="$route.fullPath" />

View File

@ -14,7 +14,7 @@ withDefaults(defineProps<Props>(), {
const { t } = useI18n()
const labels = computed(() => ({
title: t('Edits')
title: t('views.admin.library.EditsList.title')
}))
</script>
@ -26,7 +26,7 @@ const labels = computed(() => ({
:default-query="defaultQuery"
>
<h2 class="ui header">
Library edits
{{ $t('views.admin.library.EditsList.libraryEditsHeader') }}
</h2>
</edits-card-list>
</section>

View File

@ -27,7 +27,7 @@ const router = useRouter()
const logger = useLogger()
const labels = computed(() => ({
statsWarning: t('Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object')
statsWarning: t('views.admin.library.LibraryDetail.statsWarning')
}))
const isLoading = ref(false)
@ -117,7 +117,7 @@ const updateObj = async (attr: string) => {
<template v-if="object.is_local">
<span class="ui tiny accent label">
<i class="home icon" />
Local
{{ $t('views.admin.library.LibraryDetail.localLabel') }}
</span>
&nbsp;
</template>
@ -134,7 +134,7 @@ const updateObj = async (attr: string) => {
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.LibraryDetail.djangoLink') }}
</a>
<button
v-dropdown
@ -150,7 +150,7 @@ const updateObj = async (attr: string) => {
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.LibraryDetail.djangoLink') }}
</a>
<a
class="basic item"
@ -159,7 +159,7 @@ const updateObj = async (attr: string) => {
rel="noopener noreferrer"
>
<i class="external icon" />
Open remote profile&nbsp;
{{ $t('views.admin.library.LibraryDetail.remoteProfileLink') }}
</a>
</div>
</button>
@ -169,22 +169,22 @@ const updateObj = async (attr: string) => {
:class="['ui', {loading: isLoading}, 'basic danger button']"
:action="remove"
>
Delete
{{ $t('views.admin.library.LibraryDetail.deleteButton') }}
<template #modal-header>
<p>
Delete this library?
{{ $t('views.admin.library.LibraryDetail.deleteModalHeader') }}
</p>
</template>
<template #modal-content>
<div>
<p>
The library will be removed, as well as associated uploads, and follows. This action is irreversible.
{{ $t('views.admin.library.LibraryDetail.deleteModalMessage') }}
</p>
</div>
</template>
<template #modal-confirm>
<p>
Delete
{{ $t('views.admin.library.LibraryDetail.deleteButton') }}
</p>
</template>
</dangerous-button>
@ -201,14 +201,14 @@ const updateObj = async (attr: string) => {
<h3 class="ui header">
<i class="info icon" />
<div class="content">
Library data
{{ $t('views.admin.library.LibraryDetail.libraryDataHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
Name
{{ $t('views.admin.library.LibraryDetail.nameLabel') }}
</td>
<td>
{{ object.name }}
@ -217,7 +217,7 @@ const updateObj = async (attr: string) => {
<tr>
<td>
<router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('privacy_level', object.privacy_level) }}">
Visibility
{{ $t('views.admin.library.LibraryDetail.visibilityLabel') }}
</router-link>
</td>
<td>
@ -244,7 +244,7 @@ const updateObj = async (attr: string) => {
<tr>
<td>
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: object.actor.full_username }}">
Account
{{ $t('views.admin.library.LibraryDetail.accountLabel') }}
</router-link>
</td>
<td>
@ -254,7 +254,7 @@ const updateObj = async (attr: string) => {
<tr v-if="!object.is_local">
<td>
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
Domain
{{ $t('views.admin.library.LibraryDetail.domainLabel') }}
</router-link>
</td>
<td>
@ -263,7 +263,7 @@ const updateObj = async (attr: string) => {
</tr>
<tr>
<td>
Description
{{ $t('views.admin.library.LibraryDetail.descriptionLabel') }}
</td>
<td>
{{ object.description }}
@ -278,7 +278,7 @@ const updateObj = async (attr: string) => {
<h3 class="ui header">
<i class="feed icon" />
<div class="content">
Activity&nbsp;
{{ $t('views.admin.library.LibraryDetail.activityHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -298,7 +298,7 @@ const updateObj = async (attr: string) => {
<tbody>
<tr>
<td>
First seen
{{ $t('views.admin.library.LibraryDetail.firstSeenLabel') }}
</td>
<td>
<human-date :date="object.creation_date" />
@ -306,7 +306,7 @@ const updateObj = async (attr: string) => {
</tr>
<tr>
<td>
Followers
{{ $t('views.admin.library.LibraryDetail.followersLabel') }}
</td>
<td>
{{ stats.followers }}
@ -315,7 +315,7 @@ const updateObj = async (attr: string) => {
<tr>
<td>
<router-link :to="{name: 'manage.moderation.reports.list', query: {q: getQuery('target', `library:${object.uuid}`) }}">
Linked reports
{{ $t('views.admin.library.LibraryDetail.linkedReportsLabel') }}
</router-link>
</td>
<td>
@ -331,7 +331,7 @@ const updateObj = async (attr: string) => {
<h3 class="ui header">
<i class="music icon" />
<div class="content">
Audio content&nbsp;
{{ $t('views.admin.library.LibraryDetail.audioContentHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -351,7 +351,7 @@ const updateObj = async (attr: string) => {
<tbody>
<tr>
<td>
Cached size
{{ $t('views.admin.library.LibraryDetail.cachedSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_downloaded_size) }}
@ -359,7 +359,7 @@ const updateObj = async (attr: string) => {
</tr>
<tr>
<td>
Total size
{{ $t('views.admin.library.LibraryDetail.totalSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_total_size) }}
@ -368,7 +368,7 @@ const updateObj = async (attr: string) => {
<tr>
<td>
<router-link :to="{name: 'manage.library.artists', query: {q: getQuery('library_id', object.id) }}">
Artists
{{ $t('views.admin.library.LibraryDetail.artistsLabel') }}
</router-link>
</td>
<td>
@ -378,7 +378,7 @@ const updateObj = async (attr: string) => {
<tr>
<td>
<router-link :to="{name: 'manage.library.albums', query: {q: getQuery('library_id', object.id) }}">
Albums
{{ $t('views.admin.library.LibraryDetail.albumsLabel') }}
</router-link>
</td>
<td>
@ -388,7 +388,7 @@ const updateObj = async (attr: string) => {
<tr>
<td>
<router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('library_id', object.id) }}">
Tracks
{{ $t('views.admin.library.LibraryDetail.tracksLabel') }}
</router-link>
</td>
<td>
@ -398,7 +398,7 @@ const updateObj = async (attr: string) => {
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('library_id', object.id) }}">
Uploads
{{ $t('views.admin.library.LibraryDetail.uploadsLabel') }}
</router-link>
</td>
<td>

View File

@ -77,7 +77,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:to="{name: 'library.tags.detail', params: {id: object.name }}"
>
<i class="info icon" />
Open local profile&nbsp;
{{ $t('views.admin.library.TagDetail.localProfileLink') }}
</router-link>
<button
v-dropdown
@ -93,7 +93,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.TagDetail.djangoLink') }}
</a>
</div>
</button>
@ -103,22 +103,22 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:class="['ui', {loading: isLoading}, 'basic danger button']"
:action="remove"
>
Delete
{{ $t('views.admin.library.TagDetail.deleteButton') }}
<template #modal-header>
<p>
Delete this tag?
{{ $t('views.admin.library.TagDetail.deleteModalHeader') }}
</p>
</template>
<template #modal-content>
<div>
<p>
The tag will be removed and unlinked from any existing entity. This action is irreversible.
{{ $t('views.admin.library.TagDetail.deleteModalMessage') }}
</p>
</div>
</template>
<template #modal-confirm>
<p>
Delete
{{ $t('views.admin.library.TagDetail.deleteButton') }}
</p>
</template>
</dangerous-button>
@ -135,14 +135,14 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="info icon" />
<div class="content">
Tag data
{{ $t('views.admin.library.TagDetail.tagDataHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
Name
{{ $t('views.admin.library.TagDetail.nameLabel') }}
</td>
<td>
{{ object.name }}
@ -157,14 +157,14 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="feed icon" />
<div class="content">
Activity&nbsp;
{{ $t('views.admin.library.TagDetail.activityHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
First seen
{{ $t('views.admin.library.TagDetail.firstSeenLabel') }}
</td>
<td>
<human-date :date="object.creation_date" />
@ -179,7 +179,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="music icon" />
<div class="content">
Audio content&nbsp;
{{ $t('views.admin.library.TagDetail.audioContentHeader') }}
</div>
</h3>
<table class="ui very basic table">
@ -187,7 +187,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.artists', query: {q: getQuery('tag', object.name) }}">
Artists
{{ $t('views.admin.library.TagDetail.artistsLabel') }}
</router-link>
</td>
<td>
@ -197,7 +197,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.albums', query: {q: getQuery('tag', object.name) }}">
Albums
{{ $t('views.admin.library.TagDetail.albumsLabel') }}
</router-link>
</td>
<td>
@ -207,7 +207,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('tag', object.name) }}">
Tracks
{{ $t('views.admin.library.TagDetail.tracksLabel') }}
</router-link>
</td>
<td>

View File

@ -19,7 +19,7 @@ const props = defineProps<Props>()
const { t } = useI18n()
const labels = computed(() => ({
statsWarning: t('Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object')
statsWarning: t('views.admin.library.TrackDetail.statsWarning')
}))
const track = ref()
@ -105,7 +105,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<template v-if="track.is_local">
<span class="ui tiny accent label">
<i class="home icon" />
Local
{{ $t('views.admin.library.TrackDetail.localLabel') }}
</span>
&nbsp;
</template>
@ -129,7 +129,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:to="{name: 'library.tracks.detail', params: {id: track.id }}"
>
<i class="info icon" />
Open local profile&nbsp;
{{ $t('views.admin.library.TrackDetail.localProfileLink') }}
</router-link>
<button
v-dropdown
@ -145,7 +145,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.TrackDetail.djangoLink') }}
</a>
<a
v-if="track.mbid"
@ -155,7 +155,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="external icon" />
Open on MusicBrainz&nbsp;
{{ $t('views.admin.library.TrackDetail.musicbrainzLink') }}
</a>
<fetch-button
v-if="!track.is_local"
@ -164,7 +164,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
@refresh="fetchData"
>
<i class="refresh icon" />&nbsp;
Refresh from remote server&nbsp;
{{ $t('views.admin.library.TrackDetail.remoteRefreshButton') }}
</fetch-button>
<a
class="basic item"
@ -173,7 +173,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
rel="noopener noreferrer"
>
<i class="external icon" />
Open remote profile&nbsp;
{{ $t('views.admin.library.TrackDetail.remoteProfileLink') }}
</a>
</div>
</button>
@ -185,7 +185,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
class="ui labeled icon button"
>
<i class="edit icon" />
Edit
{{ $t('views.admin.library.TrackDetail.editButton') }}
</router-link>
</div>
<div class="ui buttons">
@ -193,22 +193,22 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
:class="['ui', {loading: isLoading}, 'basic danger button']"
:action="remove"
>
Delete
{{ $t('views.admin.library.TrackDetail.deleteButton') }}
<template #modal-header>
<p>
Delete this track?
{{ $t('views.admin.library.TrackDetail.deleteModalHeader') }}
</p>
</template>
<template #modal-content>
<div>
<p>
The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible.
{{ $t('views.admin.library.TrackDetail.deleteModalMessage') }}
</p>
</div>
</template>
<template #modal-confirm>
<p>
Delete
{{ $t('views.admin.library.TrackDetail.deleteButton') }}
</p>
</template>
</dangerous-button>
@ -225,14 +225,14 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="info icon" />
<div class="content">
Track data
{{ $t('views.admin.library.TrackDetail.trackDataHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
Title
{{ $t('views.admin.library.TrackDetail.titleLabel') }}
</td>
<td>
{{ track.title }}
@ -241,7 +241,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr v-if="track.album">
<td>
<router-link :to="{name: 'manage.library.albums.detail', params: {id: track.album.id }}">
Album
{{ $t('views.admin.library.TrackDetail.albumLabel') }}
</router-link>
</td>
<td>
@ -252,7 +252,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.artists.detail', params: {id: track.artist.id }}">
Artist
{{ $t('views.admin.library.TrackDetail.artistLabel') }}
</router-link>
</td>
<td>
@ -262,7 +262,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr v-if="track.album">
<td>
<router-link :to="{name: 'manage.library.artists.detail', params: {id: track.album.artist.id }}">
Album artist
{{ $t('views.admin.library.TrackDetail.albumArtistLabel') }}
</router-link>
</td>
<td>
@ -271,7 +271,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Position
{{ $t('views.admin.library.TrackDetail.positionLabel') }}
</td>
<td>
{{ track.position }}
@ -279,7 +279,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="track.disc_number">
<td>
Disc number
{{ $t('views.admin.library.TrackDetail.discNumberLabel') }}
</td>
<td>
{{ track.disc_number }}
@ -287,13 +287,13 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="track.copyright">
<td>
Copyright
{{ $t('views.admin.library.TrackDetail.copyrightLabel') }}
</td>
<td>{{ track.copyright }}</td>
</tr>
<tr v-if="track.license">
<td>
License
{{ $t('views.admin.library.TrackDetail.licenseLabel') }}
</td>
<td>
<router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('license', track.license)}}">
@ -304,7 +304,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr v-if="!track.is_local">
<td>
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: track.domain }}">
Domain
{{ $t('views.admin.library.TrackDetail.domainLabel') }}
</router-link>
</td>
<td>
@ -313,7 +313,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr v-if="track.description">
<td>
Description
{{ $t('views.admin.library.TrackDetail.descriptionLabel') }}
</td>
<sanitized-html
tag="td"
@ -329,7 +329,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="feed icon" />
<div class="content">
Activity&nbsp;
{{ $t('views.admin.library.TrackDetail.activityHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -349,7 +349,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
First seen
{{ $t('views.admin.library.TrackDetail.firstSeenLabel') }}
</td>
<td>
<human-date :date="track.creation_date" />
@ -357,7 +357,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Listenings
{{ $t('views.admin.library.TrackDetail.listeningsLabel') }}
</td>
<td>
{{ stats.listenings }}
@ -365,7 +365,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Favorited tracks
{{ $t('views.admin.library.TrackDetail.favoritedLabel') }}
</td>
<td>
{{ stats.track_favorites }}
@ -373,7 +373,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Playlists
{{ $t('views.admin.library.TrackDetail.playlistsLabel') }}
</td>
<td>
{{ stats.playlists }}
@ -382,7 +382,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.moderation.reports.list', query: {q: getQuery('target', `track:${track.id}`) }}">
Linked reports
{{ $t('views.admin.library.TrackDetail.linkedReportsLabel') }}
</router-link>
</td>
<td>
@ -392,7 +392,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.edits', query: {q: getQuery('target', 'track ' + track.id)}}">
Edits
{{ $t('views.admin.library.TrackDetail.editsLabel') }}
</router-link>
</td>
<td>
@ -408,7 +408,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<h3 class="ui header">
<i class="music icon" />
<div class="content">
Audio content&nbsp;
{{ $t('views.admin.library.TrackDetail.trackDataHeader') }}
<span :data-tooltip="labels.statsWarning"><i class="question circle icon" /></span>
</div>
</h3>
@ -428,7 +428,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tbody>
<tr>
<td>
Cached size
{{ $t('views.admin.library.TrackDetail.cachedSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_downloaded_size) }}
@ -436,7 +436,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
</tr>
<tr>
<td>
Total size
{{ $t('views.admin.library.TrackDetail.totalSizeLabel') }}
</td>
<td>
{{ humanSize(stats.media_total_size) }}
@ -446,7 +446,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('track_id', track.id) }}">
Libraries
{{ $t('views.admin.library.TrackDetail.librariesLabel') }}
</router-link>
</td>
<td>
@ -456,7 +456,7 @@ const getQuery = (field: string, value: string) => `${field}:"${value}"`
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('track_id', track.id) }}">
Uploads
{{ $t('views.admin.library.TrackDetail.uploadsLabel') }}
</router-link>
</td>
<td>

View File

@ -89,7 +89,7 @@ const showUploadDetailModal = ref(false)
<template v-if="object.is_local">
<span class="ui tiny accent label">
<i class="home icon" />
Local
{{ $t('views.admin.library.UploadDetail.localLabel') }}
</span>
&nbsp;
</template>
@ -106,7 +106,7 @@ const showUploadDetailModal = ref(false)
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.UploadDetail.djangoLink') }}
</a>
<button
v-dropdown
@ -122,7 +122,7 @@ const showUploadDetailModal = ref(false)
rel="noopener noreferrer"
>
<i class="wrench icon" />
View in Django's admin&nbsp;
{{ $t('views.admin.library.UploadDetail.djangoLink') }}
</a>
<a
class="basic item"
@ -131,7 +131,7 @@ const showUploadDetailModal = ref(false)
rel="noopener noreferrer"
>
<i class="external icon" />
Open remote profile&nbsp;
{{ $t('views.admin.library.UploadDetail.remoteProfileLink') }}
</a>
</div>
</button>
@ -145,7 +145,7 @@ const showUploadDetailModal = ref(false)
rel="noopener noreferrer"
>
<i class="download icon" />
Download
{{ $t('views.admin.library.UploadDetail.downloadButton') }}
</a>
</div>
<div class="ui buttons">
@ -153,22 +153,22 @@ const showUploadDetailModal = ref(false)
:class="['ui', {loading: isLoading}, 'basic danger button']"
:action="remove"
>
Delete
{{ $t('views.admin.library.UploadDetail.deleteButton') }}
<template #modal-header>
<p>
Delete this upload?
{{ $t('views.admin.library.UploadDetail.deleteModalHeader') }}
</p>
</template>
<template #modal-content>
<div>
<p>
The upload will be removed. This action is irreversible.
{{ $t('views.admin.library.UploadDetail.deleteModalMessage') }}
</p>
</div>
</template>
<template #modal-confirm>
<p>
Delete
{{ $t('views.admin.library.UploadDetail.deleteButton') }}
</p>
</template>
</dangerous-button>
@ -185,14 +185,14 @@ const showUploadDetailModal = ref(false)
<h3 class="ui header">
<i class="info icon" />
<div class="content">
Upload data
{{ $t('views.admin.library.UploadDetail.uploadDataHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
Name
{{ $t('views.admin.library.UploadDetail.nameLabel') }}
</td>
<td>
{{ displayName(object) }}
@ -201,7 +201,7 @@ const showUploadDetailModal = ref(false)
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('privacy_level', object.library.privacy_level) }}">
Visibility
{{ $t('views.admin.library.UploadDetail.visibilityLabel') }}
</router-link>
</td>
<td>
@ -211,7 +211,7 @@ const showUploadDetailModal = ref(false)
<tr>
<td>
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: object.library.actor.full_username }}">
Account
{{ $t('views.admin.library.UploadDetail.accountLabel') }}
</router-link>
</td>
<td>
@ -221,7 +221,7 @@ const showUploadDetailModal = ref(false)
<tr v-if="!object.is_local">
<td>
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
Domain
{{ $t('views.admin.library.UploadDetail.domainLabel') }}
</router-link>
</td>
<td>
@ -231,7 +231,7 @@ const showUploadDetailModal = ref(false)
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('status', object.import_status) }}">
Import status
{{ $t('views.admin.library.UploadDetail.importStatusLabel') }}
</router-link>
</td>
<td>
@ -248,7 +248,7 @@ const showUploadDetailModal = ref(false)
<tr>
<td>
<router-link :to="{name: 'manage.library.libraries.detail', params: {id: object.library.uuid }}">
Library
{{ $t('views.admin.library.UploadDetail.libraryLabel') }}
</router-link>
</td>
<td>
@ -264,14 +264,14 @@ const showUploadDetailModal = ref(false)
<h3 class="ui header">
<i class="feed icon" />
<div class="content">
Activity&nbsp;
{{ $t('views.admin.library.UploadDetail.activityHeader') }}
</div>
</h3>
<table class="ui very basic table">
<tbody>
<tr>
<td>
First seen
{{ $t('views.admin.library.UploadDetail.firstSeenLabel') }}
</td>
<td>
<human-date :date="object.creation_date" />
@ -279,7 +279,7 @@ const showUploadDetailModal = ref(false)
</tr>
<tr>
<td>
Accessed date
{{ $t('views.admin.library.UploadDetail.accessedDateLabel') }}
</td>
<td>
<human-date
@ -289,7 +289,7 @@ const showUploadDetailModal = ref(false)
<translate
v-else
>
N/A
{{ $t('views.admin.library.UploadDetail.notApplicable') }}
</translate>
</td>
</tr>
@ -302,7 +302,7 @@ const showUploadDetailModal = ref(false)
<h3 class="ui header">
<i class="music icon" />
<div class="content">
Audio content&nbsp;
{{ $t('views.admin.library.UploadDetail.audioContentHeader') }}
</div>
</h3>
<table class="ui very basic table">
@ -310,7 +310,7 @@ const showUploadDetailModal = ref(false)
<tr v-if="object.track">
<td>
<router-link :to="{name: 'manage.library.tracks.detail', params: {id: object.track.id }}">
Track
{{ $t('views.admin.library.UploadDetail.trackLabel') }}
</router-link>
</td>
<td>
@ -319,7 +319,7 @@ const showUploadDetailModal = ref(false)
</tr>
<tr>
<td>
Cached size
{{ $t('views.admin.library.UploadDetail.cachedSizeLabel') }}
</td>
<td>
<template v-if="object.audio_file">
@ -328,13 +328,13 @@ const showUploadDetailModal = ref(false)
<translate
v-else
>
N/A
{{ $t('views.admin.library.UploadDetail.notApplicable') }}
</translate>
</td>
</tr>
<tr>
<td>
Size
{{ $t('views.admin.library.UploadDetail.sizeLabel') }}
</td>
<td>
{{ humanSize(object.size) }}
@ -342,22 +342,22 @@ const showUploadDetailModal = ref(false)
</tr>
<tr>
<td>
Bitrate
{{ $t('views.admin.library.UploadDetail.bitrateLabel') }}
</td>
<td>
<template v-if="object.bitrate">
{{ humanSize(object.bitrate) }}/s
{{ $t('views.admin.library.UploadDetail.bitrateValue', {bitrate: humanSize(object.bitrate)}) }}
</template>
<translate
v-else
>
N/A
{{ $t('views.admin.library.UploadDetail.notApplicable') }}
</translate>
</td>
</tr>
<tr>
<td>
Duration
{{ $t('views.admin.library.UploadDetail.durationLabel') }}
</td>
<td>
<template v-if="object.duration">
@ -366,14 +366,14 @@ const showUploadDetailModal = ref(false)
<translate
v-else
>
N/A
{{ $t('views.admin.library.UploadDetail.notApplicable') }}
</translate>
</td>
</tr>
<tr>
<td>
<router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('type', object.mimetype) }}">
Type
{{ $t('views.admin.library.UploadDetail.typeLabel') }}
</router-link>
</td>
<td>
@ -383,7 +383,7 @@ const showUploadDetailModal = ref(false)
<translate
v-else
>
N/A
{{ $t('views.admin.library.UploadDetail.notApplicable') }}
</translate>
</td>
</tr>