Merge branch 'frontend-fixes' into 'develop'
Frontend fixes / improvements See merge request funkwhale/funkwhale!644
This commit is contained in:
commit
b75e30763c
|
@ -5,7 +5,7 @@
|
||||||
</header>
|
</header>
|
||||||
<section class="scrolling content">
|
<section class="scrolling content">
|
||||||
<table
|
<table
|
||||||
class="ui compact collapsing basic fixed single line table"
|
class="ui compact collapsing basic table"
|
||||||
v-for="section in sections"
|
v-for="section in sections"
|
||||||
:key="section.title">
|
:key="section.title">
|
||||||
<caption>{{ section.title }}</caption>
|
<caption>{{ section.title }}</caption>
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<td colspan="4" v-else>
|
<td colspan="4" v-else>
|
||||||
<translate :translate-context="'*/*/*'">N/A</translate>
|
<translate :translate-context="'*/*/*'">N/A</translate>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="2">
|
<td colspan="2" class="align right">
|
||||||
<track-favorite-icon class="favorite-icon" :track="track"></track-favorite-icon>
|
<track-favorite-icon class="favorite-icon" :track="track"></track-favorite-icon>
|
||||||
<track-playlist-icon
|
<track-playlist-icon
|
||||||
v-if="$store.state.auth.authenticated"
|
v-if="$store.state.auth.authenticated"
|
||||||
|
|
|
@ -1,26 +1,28 @@
|
||||||
<template>
|
<template>
|
||||||
<table class="ui compact very basic fixed single line unstackable table">
|
<div class="table-wrapper">
|
||||||
<thead>
|
<table class="ui compact very basic unstackable table">
|
||||||
<tr>
|
<thead>
|
||||||
<th></th>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th colspan="6"><translate :translate-context="'Content/Track/Table.Label'">Title</translate></th>
|
<th></th>
|
||||||
<th colspan="4"><translate :translate-context="'Content/Track/Table.Label'">Artist</translate></th>
|
<th colspan="6"><translate :translate-context="'Content/Track/Table.Label'">Title</translate></th>
|
||||||
<th colspan="4"><translate :translate-context="'Content/Track/Table.Label'">Album</translate></th>
|
<th colspan="4"><translate :translate-context="'Content/Track/Table.Label'">Artist</translate></th>
|
||||||
<th colspan="4"><translate :translate-context="'Content/Track/Table.Label'">Duration</translate></th>
|
<th colspan="4"><translate :translate-context="'Content/Track/Table.Label'">Album</translate></th>
|
||||||
<th colspan="2"></th>
|
<th colspan="4"><translate :translate-context="'Content/Track/Table.Label'">Duration</translate></th>
|
||||||
</tr>
|
<th colspan="2"></th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
<track-row
|
<tbody>
|
||||||
:playable="playable"
|
<track-row
|
||||||
:display-position="displayPosition"
|
:playable="playable"
|
||||||
:track="track"
|
:display-position="displayPosition"
|
||||||
:artist="artist"
|
:track="track"
|
||||||
:key="index + '-' + track.id"
|
:artist="artist"
|
||||||
v-for="(track, index) in tracks"></track-row>
|
:key="index + '-' + track.id"
|
||||||
</tbody>
|
v-for="(track, index) in tracks"></track-row>
|
||||||
</table>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
<section class="ui small text container">
|
<section class="ui small text container">
|
||||||
<div class="ui divider"></div>
|
<div class="ui hidden divider"></div>
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate :translate-context="'Content/Settings/Title'">Avatar</translate>
|
<translate :translate-context="'Content/Settings/Title'">Avatar</translate>
|
||||||
</h2>
|
</h2>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="ui small text container">
|
<section class="ui small text container">
|
||||||
<div class="ui divider"></div>
|
<div class="ui hidden divider"></div>
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate :translate-context="'Content/Settings/Title/Verb'">Change my password</translate>
|
<translate :translate-context="'Content/Settings/Title/Verb'">Change my password</translate>
|
||||||
</h2>
|
</h2>
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="ui small text container" id="content-filters">
|
<section class="ui small text container" id="content-filters">
|
||||||
<div class="ui divider"></div>
|
<div class="ui hidden divider"></div>
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="eye slash outline icon"></i>
|
<i class="eye slash outline icon"></i>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
<h3 class="ui header">
|
<h3 class="ui header">
|
||||||
<translate>Hidden artists</translate>
|
<translate>Hidden artists</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<table class="ui compact very basic fixed single line unstackable table">
|
<table class="ui compact very basic unstackable table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th><translate :translate-context="'Content/*/Table.Label'">Name</translate></th>
|
<th><translate :translate-context="'Content/*/Table.Label'">Name</translate></th>
|
||||||
|
|
|
@ -1,142 +1,144 @@
|
||||||
<template>
|
<template>
|
||||||
<table class="ui compact very basic single line unstackable table">
|
<div class="table-wrapper">
|
||||||
<thead>
|
<table class="ui compact very basic unstackable table">
|
||||||
<tr>
|
<thead>
|
||||||
<th colspan="1000">
|
<tr>
|
||||||
<div v-if="refreshable" class="right floated">
|
<th colspan="1000">
|
||||||
<span v-if="needsRefresh">
|
<div v-if="refreshable" class="right floated">
|
||||||
<translate :translate-context="'Content/*/Button.Help text.Paragraph'">Content have been updated, click refresh to see up-to-date content</translate>
|
<span v-if="needsRefresh">
|
||||||
</span>
|
<translate :translate-context="'Content/*/Button.Help text.Paragraph'">Content have been updated, click refresh to see up-to-date content</translate>
|
||||||
<button
|
</span>
|
||||||
@click="$emit('refresh')"
|
<button
|
||||||
class="ui basic icon button"
|
@click="$emit('refresh')"
|
||||||
:title="labels.refresh"
|
class="ui basic icon button"
|
||||||
:aria-label="labels.refresh">
|
:title="labels.refresh"
|
||||||
<i class="refresh icon"></i>
|
:aria-label="labels.refresh">
|
||||||
</button>
|
<i class="refresh icon"></i>
|
||||||
</div>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="ui small left floated form" v-if="actionUrl && actions.length > 0">
|
<div class="ui small left floated form" v-if="actionUrl && actions.length > 0">
|
||||||
<div class="ui inline fields">
|
<div class="ui inline fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label><translate :translate-context="'Content/*/Dropdown.Label/Noun'">Actions</translate></label>
|
<label><translate :translate-context="'Content/*/Dropdown.Label/Noun'">Actions</translate></label>
|
||||||
<select class="ui dropdown" v-model="currentActionName">
|
<select class="ui dropdown" v-model="currentActionName">
|
||||||
<option v-for="action in actions" :value="action.name">
|
<option v-for="action in actions" :value="action.name">
|
||||||
{{ action.label }}
|
{{ action.label }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<dangerous-button
|
||||||
|
v-if="selectAll || currentAction.isDangerous" :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']"
|
||||||
|
confirm-color="green"
|
||||||
|
color=""
|
||||||
|
@confirm="launchAction">
|
||||||
|
<translate :translate-context="'Content/*/Button.Label/Short, Verb'">Go</translate>
|
||||||
|
<p slot="modal-header">
|
||||||
|
<translate :translate-context="'Modal/*/Title'"
|
||||||
|
key="1"
|
||||||
|
:translate-n="affectedObjectsCount"
|
||||||
|
:translate-params="{count: affectedObjectsCount, action: currentActionName}"
|
||||||
|
translate-plural="Do you want to launch %{ action } on %{ count } elements?">
|
||||||
|
Do you want to launch %{ action } on %{ count } element?
|
||||||
|
</translate>
|
||||||
|
</p>
|
||||||
|
<p slot="modal-content">
|
||||||
|
<translate :translate-context="'Modal/*/Paragraph'">This may affect a lot of elements or have irreversible consequences, please double check this is really what you want.</translate>
|
||||||
|
</p>
|
||||||
|
<div slot="modal-confirm"><translate :translate-context="'Modal/*/Button.Label/Short, Verb'">Launch</translate></div>
|
||||||
|
</dangerous-button>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
@click="launchAction"
|
||||||
|
:disabled="checked.length === 0"
|
||||||
|
:class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']">
|
||||||
|
<translate :translate-context="'Content/*/Button.Label/Short, Verb'">Go</translate></div>
|
||||||
|
</div>
|
||||||
|
<div class="count field">
|
||||||
|
<translate :translate-context="'Content/*/Paragraph'"
|
||||||
|
tag="span"
|
||||||
|
v-if="selectAll"
|
||||||
|
key="1"
|
||||||
|
:translate-n="objectsData.count"
|
||||||
|
:translate-params="{count: objectsData.count, total: objectsData.count}"
|
||||||
|
translate-plural="All %{ count } elements selected">
|
||||||
|
All %{ count } element selected
|
||||||
|
</translate>
|
||||||
|
<translate :translate-context="'Content/*/Paragraph'"
|
||||||
|
tag="span"
|
||||||
|
v-else
|
||||||
|
key="2"
|
||||||
|
:translate-n="checked.length"
|
||||||
|
:translate-params="{count: checked.length, total: objectsData.count}"
|
||||||
|
translate-plural="%{ count } on %{ total } selected">
|
||||||
|
%{ count } on %{ total } selected
|
||||||
|
</translate>
|
||||||
|
<template v-if="currentAction.allowAll && checkable.length > 0 && checkable.length === checked.length">
|
||||||
|
<a @click="selectAll = true" v-if="!selectAll">
|
||||||
|
<translate :translate-context="'Content/*/Link/Verb'"
|
||||||
|
key="3"
|
||||||
|
:translate-n="objectsData.count"
|
||||||
|
:translate-params="{total: objectsData.count}"
|
||||||
|
translate-plural="Select all %{ total } elements">
|
||||||
|
Select all %{ total } elements
|
||||||
|
</translate>
|
||||||
|
</a>
|
||||||
|
<a @click="selectAll = false" v-else>
|
||||||
|
<translate :translate-context="'Content/*/Link/Verb'" key="4">Select only current page</translate>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div v-if="actionErrors.length > 0" class="ui negative message">
|
||||||
<dangerous-button
|
<div class="header"><translate :translate-context="'Content/*/Error message/Header'">Error while applying action</translate></div>
|
||||||
v-if="selectAll || currentAction.isDangerous" :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']"
|
<ul class="list">
|
||||||
confirm-color="green"
|
<li v-for="error in actionErrors">{{ error }}</li>
|
||||||
color=""
|
</ul>
|
||||||
@confirm="launchAction">
|
|
||||||
<translate :translate-context="'Content/*/Button.Label/Short, Verb'">Go</translate>
|
|
||||||
<p slot="modal-header">
|
|
||||||
<translate :translate-context="'Modal/*/Title'"
|
|
||||||
key="1"
|
|
||||||
:translate-n="affectedObjectsCount"
|
|
||||||
:translate-params="{count: affectedObjectsCount, action: currentActionName}"
|
|
||||||
translate-plural="Do you want to launch %{ action } on %{ count } elements?">
|
|
||||||
Do you want to launch %{ action } on %{ count } element?
|
|
||||||
</translate>
|
|
||||||
</p>
|
|
||||||
<p slot="modal-content">
|
|
||||||
<translate :translate-context="'Modal/*/Paragraph'">This may affect a lot of elements or have irreversible consequences, please double check this is really what you want.</translate>
|
|
||||||
</p>
|
|
||||||
<div slot="modal-confirm"><translate :translate-context="'Modal/*/Button.Label/Short, Verb'">Launch</translate></div>
|
|
||||||
</dangerous-button>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
@click="launchAction"
|
|
||||||
:disabled="checked.length === 0"
|
|
||||||
:class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']">
|
|
||||||
<translate :translate-context="'Content/*/Button.Label/Short, Verb'">Go</translate></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="count field">
|
<div v-if="actionResult" class="ui positive message">
|
||||||
<translate :translate-context="'Content/*/Paragraph'"
|
<p>
|
||||||
tag="span"
|
<translate :translate-context="'Content/*/Paragraph'"
|
||||||
v-if="selectAll"
|
:translate-n="actionResult.updated"
|
||||||
key="1"
|
:translate-params="{count: actionResult.updated, action: actionResult.action}"
|
||||||
:translate-n="objectsData.count"
|
translate-plural="Action %{ action } was launched successfully on %{ count } elements">
|
||||||
:translate-params="{count: objectsData.count, total: objectsData.count}"
|
Action %{ action } was launched successfully on %{ count } element
|
||||||
translate-plural="All %{ count } elements selected">
|
</translate>
|
||||||
All %{ count } element selected
|
</p>
|
||||||
</translate>
|
|
||||||
<translate :translate-context="'Content/*/Paragraph'"
|
|
||||||
tag="span"
|
|
||||||
v-else
|
|
||||||
key="2"
|
|
||||||
:translate-n="checked.length"
|
|
||||||
:translate-params="{count: checked.length, total: objectsData.count}"
|
|
||||||
translate-plural="%{ count } on %{ total } selected">
|
|
||||||
%{ count } on %{ total } selected
|
|
||||||
</translate>
|
|
||||||
<template v-if="currentAction.allowAll && checkable.length > 0 && checkable.length === checked.length">
|
|
||||||
<a @click="selectAll = true" v-if="!selectAll">
|
|
||||||
<translate :translate-context="'Content/*/Link/Verb'"
|
|
||||||
key="3"
|
|
||||||
:translate-n="objectsData.count"
|
|
||||||
:translate-params="{total: objectsData.count}"
|
|
||||||
translate-plural="Select all %{ total } elements">
|
|
||||||
Select all %{ total } elements
|
|
||||||
</translate>
|
|
||||||
</a>
|
|
||||||
<a @click="selectAll = false" v-else>
|
|
||||||
<translate :translate-context="'Content/*/Link/Verb'" key="4">Select only current page</translate>
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="actionErrors.length > 0" class="ui negative message">
|
|
||||||
<div class="header"><translate :translate-context="'Content/*/Error message/Header'">Error while applying action</translate></div>
|
|
||||||
<ul class="list">
|
|
||||||
<li v-for="error in actionErrors">{{ error }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div v-if="actionResult" class="ui positive message">
|
|
||||||
<p>
|
|
||||||
<translate :translate-context="'Content/*/Paragraph'"
|
|
||||||
:translate-n="actionResult.updated"
|
|
||||||
:translate-params="{count: actionResult.updated, action: actionResult.action}"
|
|
||||||
translate-plural="Action %{ action } was launched successfully on %{ count } elements">
|
|
||||||
Action %{ action } was launched successfully on %{ count } element
|
|
||||||
</translate>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<slot name="action-success-footer" :result="actionResult">
|
<slot name="action-success-footer" :result="actionResult">
|
||||||
</slot>
|
</slot>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</th>
|
||||||
</th>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<th v-if="actions.length > 0">
|
||||||
<th v-if="actions.length > 0">
|
<div class="ui checkbox">
|
||||||
<div class="ui checkbox">
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
@change="toggleCheckAll"
|
||||||
|
:disabled="checkable.length === 0"
|
||||||
|
:checked="checkable.length > 0 && checked.length === checkable.length"><label> </label>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<slot name="header-cells"></slot>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody v-if="objectsData.count > 0">
|
||||||
|
<tr v-for="(obj, index) in objects">
|
||||||
|
<td v-if="actions.length > 0" class="collapsing">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@change="toggleCheckAll"
|
:disabled="checkable.indexOf(getId(obj)) === -1"
|
||||||
:disabled="checkable.length === 0"
|
@click="toggleCheck($event, getId(obj), index)"
|
||||||
:checked="checkable.length > 0 && checked.length === checkable.length"><label> </label>
|
:checked="checked.indexOf(getId(obj)) > -1"><label> </label>
|
||||||
</div>
|
</td>
|
||||||
</th>
|
<slot name="row-cells" :obj="obj"></slot>
|
||||||
<slot name="header-cells"></slot>
|
</tr>
|
||||||
</tr>
|
</tbody>
|
||||||
</thead>
|
</table>
|
||||||
<tbody v-if="objectsData.count > 0">
|
</div>
|
||||||
<tr v-for="(obj, index) in objects">
|
|
||||||
<td v-if="actions.length > 0" class="collapsing">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
:disabled="checkable.indexOf(getId(obj)) === -1"
|
|
||||||
@click="toggleCheck($event, getId(obj), index)"
|
|
||||||
:checked="checked.indexOf(getId(obj)) > -1"><label> </label>
|
|
||||||
</td>
|
|
||||||
<slot name="row-cells" :obj="obj"></slot>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
|
@ -79,39 +79,42 @@
|
||||||
<i><translate :translate-context="'Content/Library/Paragraph'" :translate-params="{extensions: supportedExtensions.join(', ')}">Supported extensions: %{ extensions }</translate></i>
|
<i><translate :translate-context="'Content/Library/Paragraph'" :translate-params="{extensions: supportedExtensions.join(', ')}">Supported extensions: %{ extensions }</translate></i>
|
||||||
</file-upload-widget>
|
</file-upload-widget>
|
||||||
</div>
|
</div>
|
||||||
<table v-if="files.length > 0" class="ui single line table">
|
<div v-if="files.length > 0" class="table-wrapper">
|
||||||
<thead>
|
<div class="ui hidden divider"></div>
|
||||||
<tr>
|
<table class="ui unstackable table">
|
||||||
<th><translate :translate-context="'Content/Library/Table.Label'">Filename</translate></th>
|
<thead>
|
||||||
<th><translate :translate-context="'Content/Library/Table.Label'">Size</translate></th>
|
<tr>
|
||||||
<th><translate :translate-context="'Content/Library/Table.Label'">Status</translate></th>
|
<th><translate :translate-context="'Content/Library/Table.Label'">Filename</translate></th>
|
||||||
</tr>
|
<th><translate :translate-context="'Content/Library/Table.Label'">Size</translate></th>
|
||||||
</thead>
|
<th><translate :translate-context="'Content/Library/Table.Label'">Status</translate></th>
|
||||||
<tbody>
|
</tr>
|
||||||
<tr v-for="(file, index) in sortedFiles" :key="file.id">
|
</thead>
|
||||||
<td :title="file.name">{{ file.name | truncate(60) }}</td>
|
<tbody>
|
||||||
<td>{{ file.size | humanSize }}</td>
|
<tr v-for="(file, index) in sortedFiles" :key="file.id">
|
||||||
<td>
|
<td :title="file.name">{{ file.name | truncate(60) }}</td>
|
||||||
<span v-if="file.error" class="ui tooltip" :data-tooltip="labels.tooltips[file.error]">
|
<td>{{ file.size | humanSize }}</td>
|
||||||
<span class="ui red icon label">
|
<td>
|
||||||
<i class="question circle outline icon" /> {{ file.error }}
|
<span v-if="file.error" class="ui tooltip" :data-tooltip="labels.tooltips[file.error]">
|
||||||
|
<span class="ui red icon label">
|
||||||
|
<i class="question circle outline icon" /> {{ file.error }}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
<span v-else-if="file.success" class="ui green label">
|
||||||
<span v-else-if="file.success" class="ui green label">
|
<translate :translate-context="'Content/Library/Table'" key="1">Uploaded</translate>
|
||||||
<translate :translate-context="'Content/Library/Table'" key="1">Uploaded</translate>
|
</span>
|
||||||
</span>
|
<span v-else-if="file.active" class="ui yellow label">
|
||||||
<span v-else-if="file.active" class="ui yellow label">
|
<translate :translate-context="'Content/Library/Table'" key="2">Uploading…</translate>
|
||||||
<translate :translate-context="'Content/Library/Table'" key="2">Uploading…</translate>
|
({{ parseInt(file.progress) }}%)
|
||||||
({{ parseInt(file.progress) }}%)
|
</span>
|
||||||
</span>
|
<template v-else>
|
||||||
<template v-else>
|
<span class="ui label"><translate :translate-context="'Content/Library/Table'" key="3">Pending</translate></span>
|
||||||
<span class="ui label"><translate :translate-context="'Content/Library/Table'" key="3">Pending</translate></span>
|
<button class="ui tiny basic red icon button" @click.prevent="$refs.upload.remove(file)"><i class="delete icon"></i></button>
|
||||||
<button class="ui tiny basic red icon button" @click.prevent="$refs.upload.remove(file)"><i class="delete icon"></i></button>
|
</template>
|
||||||
</template>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
</tr>
|
</tbody>
|
||||||
</tbody>
|
</table>
|
||||||
</table>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'processing'}]">
|
<div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'processing'}]">
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui section hidden divider"></div>
|
<div class="ui section hidden divider"></div>
|
||||||
<div class="ui grid">
|
<div class="ui stackable one column grid">
|
||||||
<div class="ui row">
|
<div class="column">
|
||||||
<album-widget :filters="{playable: true, ordering: '-creation_date'}">
|
<album-widget :filters="{playable: true, ordering: '-creation_date'}">
|
||||||
<template slot="title"><translate :translate-context="'Content/Home/Title'">Recently added</translate></template>
|
<template slot="title"><translate :translate-context="'Content/Home/Title'">Recently added</translate></template>
|
||||||
</album-widget>
|
</album-widget>
|
||||||
|
|
|
@ -48,24 +48,27 @@
|
||||||
<div class="ui hidden divider"></div>
|
<div class="ui hidden divider"></div>
|
||||||
<template v-if="plts.length > 0">
|
<template v-if="plts.length > 0">
|
||||||
<p><translate :translate-context="'Content/Playlist/Paragraph/Call to action'">Drag and drop rows to reorder tracks in the playlist</translate></p>
|
<p><translate :translate-context="'Content/Playlist/Paragraph/Call to action'">Drag and drop rows to reorder tracks in the playlist</translate></p>
|
||||||
<table class="ui compact very basic fixed single line unstackable table">
|
<div class="table-wrapper">
|
||||||
<draggable v-model="plts" element="tbody" @update="reorder">
|
<table class="ui compact very basic unstackable table">
|
||||||
<tr v-for="(plt, index) in plts" :key="plt.id">
|
<draggable v-model="plts" element="tbody" @update="reorder">
|
||||||
<td class="left aligned">{{ plt.index + 1}}</td>
|
<tr v-for="(plt, index) in plts" :key="plt.id">
|
||||||
<td class="center aligned">
|
<td class="left aligned">{{ plt.index + 1}}</td>
|
||||||
<img class="ui mini image" v-if="plt.track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.small_square_crop)">
|
<td class="center aligned">
|
||||||
<img class="ui mini image" v-else src="../../assets/audio/default-cover.png">
|
<img class="ui mini image" v-if="plt.track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.small_square_crop)">
|
||||||
</td>
|
<img class="ui mini image" v-else src="../../assets/audio/default-cover.png">
|
||||||
<td colspan="4">
|
</td>
|
||||||
<strong>{{ plt.track.title }}</strong><br />
|
<td colspan="4">
|
||||||
{{ plt.track.artist.name }}
|
<strong>{{ plt.track.title }}</strong><br />
|
||||||
</td>
|
{{ plt.track.artist.name }}
|
||||||
<td class="right aligned">
|
</td>
|
||||||
<i @click.stop="removePlt(index)" class="circular red trash icon"></i>
|
<td class="right aligned">
|
||||||
</td>
|
<i @click.stop="removePlt(index)" class="circular red trash icon"></i>
|
||||||
</tr>
|
</td>
|
||||||
</draggable>
|
</tr>
|
||||||
</table>
|
</draggable>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,7 +17,15 @@ export function ago (date, locale) {
|
||||||
locale = locale || 'en'
|
locale = locale || 'en'
|
||||||
const m = moment(date)
|
const m = moment(date)
|
||||||
m.locale(locale)
|
m.locale(locale)
|
||||||
return m.fromNow()
|
return m.calendar(null, {
|
||||||
|
sameDay: 'LT',
|
||||||
|
nextDay: 'L',
|
||||||
|
nextWeek: 'L',
|
||||||
|
lastDay: 'L',
|
||||||
|
lastWeek: 'L',
|
||||||
|
sameElse: 'L'
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.filter('ago', ago)
|
Vue.filter('ago', ago)
|
||||||
|
|
|
@ -75,6 +75,9 @@
|
||||||
// see https://github.com/webpack/webpack/issues/215
|
// see https://github.com/webpack/webpack/issues/215
|
||||||
@import "./vendor/media";
|
@import "./vendor/media";
|
||||||
|
|
||||||
|
$desktop-sidebar-width: 300px;
|
||||||
|
$widedesktop-sidebar-width: 350px;
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
@include media("<desktop") {
|
@include media("<desktop") {
|
||||||
|
@ -91,12 +94,25 @@ body {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ui.wide.left.sidebar {
|
||||||
|
@include media(">desktop") {
|
||||||
|
width: $desktop-sidebar-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media(">widedesktop") {
|
||||||
|
width: $widedesktop-sidebar-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
.main.pusher,
|
.main.pusher,
|
||||||
.footer {
|
.footer {
|
||||||
@include media(">desktop") {
|
@include media(">desktop") {
|
||||||
margin-left: 350px !important;
|
margin-left: $desktop-sidebar-width !important;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include media(">widedesktop") {
|
||||||
|
margin-left: $widedesktop-sidebar-width !important;;
|
||||||
|
}
|
||||||
transform: none !important;
|
transform: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,11 +134,14 @@ body {
|
||||||
}
|
}
|
||||||
@include media(">desktop") {
|
@include media(">desktop") {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 350px;
|
left: $desktop-sidebar-width;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
@include media(">widedesktop") {
|
||||||
|
left: $widedesktop-sidebar-width;
|
||||||
|
}
|
||||||
background-color: white;
|
background-color: white;
|
||||||
.item {
|
.item {
|
||||||
padding-top: 1.5em;
|
padding-top: 1.5em;
|
||||||
|
@ -135,7 +154,10 @@ body {
|
||||||
bottom: 1em;
|
bottom: 1em;
|
||||||
left: 1em;
|
left: 1em;
|
||||||
@include media(">desktop") {
|
@include media(">desktop") {
|
||||||
left: 350px;
|
left: $desktop-sidebar-width;
|
||||||
|
}
|
||||||
|
@include media(">widedesktop") {
|
||||||
|
left: $widedesktop-sidebar-width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.main-pusher {
|
.main-pusher {
|
||||||
|
@ -143,9 +165,12 @@ body {
|
||||||
}
|
}
|
||||||
.ui.stripe.segment,
|
.ui.stripe.segment,
|
||||||
#footer {
|
#footer {
|
||||||
padding: 2em;
|
padding: 1em;
|
||||||
@include media(">tablet") {
|
@include media(">tablet") {
|
||||||
padding: 4em;
|
padding: 2em;
|
||||||
|
}
|
||||||
|
@include media(">widedesktop") {
|
||||||
|
padding: 3em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,3 +310,19 @@ span.diff.added {
|
||||||
span.diff.removed {
|
span.diff.removed {
|
||||||
background-color: rgba(255, 0, 0, 0.25);
|
background-color: rgba(255, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.align.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.pagination.menu {
|
||||||
|
margin-top: 1em;
|
||||||
|
+ span {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
$breakpoints: (
|
$breakpoints: (
|
||||||
'phone': 320px,
|
'phone': 320px,
|
||||||
'tablet': 768px,
|
'tablet': 768px,
|
||||||
'desktop': 1024px
|
'desktop': 1024px,
|
||||||
|
'widedesktop': 1200px
|
||||||
) !default;
|
) !default;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="ui stackable grid">
|
<div class="ui two column row">
|
||||||
<div class="five wide column">
|
<div class="column">
|
||||||
<h3 class="ui header"><translate :translate-context="'Content/Library/Title'">Current library</translate></h3>
|
<h3 class="ui header"><translate :translate-context="'Content/Library/Title'">Current library</translate></h3>
|
||||||
<library-card :library="library" />
|
<library-card :library="library" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {expect} from 'chai'
|
import {expect} from 'chai'
|
||||||
|
import moment from 'moment'
|
||||||
import {truncate, ago, capitalize, year} from '@/filters'
|
import {truncate, ago, capitalize, year} from '@/filters'
|
||||||
|
|
||||||
describe('filters', () => {
|
describe('filters', () => {
|
||||||
|
@ -24,7 +24,15 @@ describe('filters', () => {
|
||||||
it('works', () => {
|
it('works', () => {
|
||||||
const input = new Date()
|
const input = new Date()
|
||||||
let output = ago(input)
|
let output = ago(input)
|
||||||
expect(output).to.equal('a few seconds ago')
|
let expected = moment(input).calendar(input, {
|
||||||
|
sameDay: 'LT',
|
||||||
|
nextDay: 'L',
|
||||||
|
nextWeek: 'L',
|
||||||
|
lastDay: 'L',
|
||||||
|
lastWeek: 'L',
|
||||||
|
sameElse: 'L'
|
||||||
|
})
|
||||||
|
expect(output).to.equal(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('year', () => {
|
describe('year', () => {
|
||||||
|
|
Loading…
Reference in New Issue