mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-15 00:03:28 +01:00
Make final pywb 2.7 UI tweaks
- Remove redundant icon title - Fix display date in TimelineLinear tooltip - Adjust calendar spacing, add border and shadow - Remove tooltip scroll - Auto-size calendar to contents - Make display date consistent across browsers - Render calendar for all months regardless of captures - Fix weekday labels to avoid off-by-one - Grey out calendar days without captures
This commit is contained in:
parent
373eca641c
commit
91cf74a2a9
File diff suppressed because one or more lines are too long
@ -61,7 +61,7 @@
|
|||||||
:aria-pressed="(showFullView ? true : false)"
|
:aria-pressed="(showFullView ? true : false)"
|
||||||
@click="showFullView = !showFullView"
|
@click="showFullView = !showFullView"
|
||||||
:title="(showFullView ? _('Hide calendar') : _('Show calendar'))">
|
:title="(showFullView ? _('Hide calendar') : _('Show calendar'))">
|
||||||
<i class="far fa-calendar-alt" :title="_('Calendar')"></i>
|
<i class="far fa-calendar-alt"></i>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
@ -71,7 +71,7 @@
|
|||||||
:aria-pressed="showTimelineView"
|
:aria-pressed="showTimelineView"
|
||||||
@click="showTimelineView = !showTimelineView"
|
@click="showTimelineView = !showTimelineView"
|
||||||
:title="(showTimelineView ? _('Hide timeline') : _('Show timeline'))">
|
:title="(showTimelineView ? _('Hide timeline') : _('Show timeline'))">
|
||||||
<i class="far fa-chart-bar" :title="_('Timeline')"></i>
|
<i class="far fa-chart-bar"></i>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown" v-if="localesAreSet">
|
<li class="nav-item dropdown" v-if="localesAreSet">
|
||||||
@ -142,8 +142,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Calendar -->
|
<!-- Calendar -->
|
||||||
<div class="card border-0" v-if="currentPeriod && showFullView && currentPeriod.children.length">
|
<div class="card" v-if="currentPeriod && showFullView && currentPeriod.children.length">
|
||||||
<div class="card-body">
|
<div class="card-body" id="calendar-card-body">
|
||||||
<CalendarYear
|
<CalendarYear
|
||||||
:period="currentPeriod"
|
:period="currentPeriod"
|
||||||
:current-snapshot="currentSnapshot"
|
:current-snapshot="currentSnapshot"
|
||||||
@ -453,6 +453,9 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
#calendar-card-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
.strong {
|
.strong {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,9 @@
|
|||||||
|
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
.calendar-month .day .day-id.empty {
|
||||||
|
color: #454545 !important;
|
||||||
|
}
|
||||||
.calendar-month .day:hover .size {
|
.calendar-month .day:hover .size {
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
@ -92,11 +95,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="calendar-month" :class="{current: isCurrent, 'contains-current-snapshot': containsCurrentSnapshot}">
|
<div class="calendar-month" :class="{current: isCurrent, 'contains-current-snapshot': containsCurrentSnapshot}">
|
||||||
<h3>{{getLongMonthName(month.id)}} <span v-if="month.snapshotCount">({{ month.snapshotCount }})</span></h3>
|
<h3>{{getLongMonthName(month.id)}} <span v-if="month.snapshotCount">({{ month.snapshotCount }})</span></h3>
|
||||||
<div v-if="month.snapshotCount">
|
<span v-for="(dayInitial) in dayInitials" class="day" :style="dayStyle">{{dayInitial}}</span><br/>
|
||||||
<span v-for="(dayInitial) in dayInitials" class="day" :style="dayStyle">{{dayInitial}}</span><br/>
|
<span v-for="(day,i) in days"><br v-if="i && i % 7===0"/><span class="day" :class="{empty: !day || !day.snapshotCount, 'contains-current-snapshot':dayContainsCurrentSnapshot(day)}" :style="dayStyle" @click="gotoDay(day, $event)" @keyup.13="gotoDay(day, $event)"><template v-if="day"><span class="size" v-if="day.snapshotCount" :style="getDayCountCircleStyle(day.snapshotCount)" tabindex="0"> </span><span class="day-id" :class="{empty: !day.snapshotCount}">{{day.id}}</span><span v-if="day.snapshotCount" class="count">{{ $root._(day.snapshotCount !== 1 ? '{count} captures':'{count} capture', {count: day.snapshotCount}) }}</span></template><template v-else v-html="' '"></template></span></span>
|
||||||
<span v-for="(day,i) in days"><br v-if="i && i % 7===0"/><span class="day" :class="{empty: !day || !day.snapshotCount, 'contains-current-snapshot':dayContainsCurrentSnapshot(day)}" :style="dayStyle" @click="gotoDay(day, $event)" @keyup.13="gotoDay(day, $event)"><template v-if="day"><span class="size" v-if="day.snapshotCount" :style="getDayCountCircleStyle(day.snapshotCount)" tabindex="0"> </span><span class="day-id">{{day.id}}</span><span v-if="day.snapshotCount" class="count">{{ $root._(day.snapshotCount !== 1 ? '{count} captures':'{count} capture', {count: day.snapshotCount}) }}</span></template><template v-else v-html="' '"></template></span></span>
|
|
||||||
</div>
|
|
||||||
<div v-else class="empty">{{ _('no captures') }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ export default {
|
|||||||
return `height: ${s}px; width: ${s}px; line-height: ${s}px`;
|
return `height: ${s}px; width: ${s}px; line-height: ${s}px`;
|
||||||
},
|
},
|
||||||
days() {
|
days() {
|
||||||
if (!this.month || !this.month.snapshotCount) {
|
if (!this.month) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const days = [];
|
const days = [];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="full-view">
|
<div class="full-view border-top-0 border-left-0 border-right-0 border-bottom border-dark shadow">
|
||||||
<h2>
|
<h2>
|
||||||
<i
|
<i
|
||||||
class="fas fa-arrow-left year-arrow"
|
class="fas fa-arrow-left year-arrow"
|
||||||
@ -159,12 +159,15 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.full-view {
|
.full-view {
|
||||||
position: fixed;
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-wrap: wrap;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
height: 80vh;
|
overflow-y: scroll;
|
||||||
overflow: scroll;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.full-view .months {
|
.full-view .months {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="timeline-linear">
|
<div class="timeline-linear">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<div>{{ period.getFullReadableId() }}</div>
|
<div>{{ displayDate }}</div>
|
||||||
<div>{{ $root._(period.snapshotCount !== 1 ? '{count} captures':'{count} capture', {count: period.snapshotCount}) }}</div>
|
<div>{{ $root._(period.snapshotCount !== 1 ? '{count} captures':'{count} capture', {count: period.snapshotCount}) }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -21,6 +21,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { PywbI18N } from "../i18n";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TimelineLinear",
|
name: "TimelineLinear",
|
||||||
props: ['period', 'currentSnapshot'],
|
props: ['period', 'currentSnapshot'],
|
||||||
@ -31,6 +33,11 @@ export default {
|
|||||||
containsCurrentSnapshot() {
|
containsCurrentSnapshot() {
|
||||||
return this.currentSnapshot &&
|
return this.currentSnapshot &&
|
||||||
this.period.contains(this.currentSnapshot);
|
this.period.contains(this.currentSnapshot);
|
||||||
|
},
|
||||||
|
displayDate() {
|
||||||
|
// replace '-' in date string with '/' so firefox and chrome will return same result
|
||||||
|
let dateStringNoSlashes = this.period.fullId.replace(/-/g,'/');
|
||||||
|
return new Date(dateStringNoSlashes).toLocaleDateString(PywbI18N.getLocale());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -59,7 +66,8 @@ export default {
|
|||||||
.timeline-linear .list {
|
.timeline-linear .list {
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
min-height: 50px;
|
min-height: 50px;
|
||||||
overflow: scroll;
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.timeline-linear .title {
|
.timeline-linear .title {
|
||||||
border-bottom: 1px solid black;
|
border-bottom: 1px solid black;
|
||||||
|
@ -36,7 +36,7 @@ export class PywbI18N {
|
|||||||
return decodeURIComponent(this.config[id+'_'+type])
|
return decodeURIComponent(this.config[id+'_'+type])
|
||||||
}
|
}
|
||||||
getWeekDays(type='long') {
|
getWeekDays(type='long') {
|
||||||
return ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].map(d => this.getWeekDay(d, type));
|
return ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'].map(d => this.getWeekDay(d, type));
|
||||||
}
|
}
|
||||||
getText(id, embeddedVariableStrings=null) {
|
getText(id, embeddedVariableStrings=null) {
|
||||||
const translated = decodeURIComponent(this.config[id] || id);
|
const translated = decodeURIComponent(this.config[id] || id);
|
||||||
|
@ -278,7 +278,7 @@ PywbPeriod.prototype.getChildrenRange = function() {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
PywbPeriod.prototype.fillEmptyGrancChildPeriods = function() {
|
PywbPeriod.prototype.fillEmptyGrandChildPeriods = function() {
|
||||||
if (this.hasFilledEmptyGrandchildPeriods) {
|
if (this.hasFilledEmptyGrandchildPeriods) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -289,19 +289,10 @@ PywbPeriod.prototype.fillEmptyGrancChildPeriods = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PywbPeriod.prototype.fillEmptyChildPeriods = function(isFillEmptyGrandChildrenPeriods=false) {
|
PywbPeriod.prototype.fillEmptyChildPeriods = function(isFillEmptyGrandChildrenPeriods=false) {
|
||||||
if (this.snapshotCount === 0 || this.type > PywbPeriod.Type.day) {
|
if (this.type > PywbPeriod.Type.day) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFillEmptyGrandChildrenPeriods) {
|
|
||||||
this.fillEmptyGrancChildPeriods();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.hasFilledEmptyChildPeriods) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.hasFilledEmptyChildPeriods = true;
|
|
||||||
|
|
||||||
const idRange = this.getChildrenRange();
|
const idRange = this.getChildrenRange();
|
||||||
if (!idRange) {
|
if (!idRange) {
|
||||||
return;
|
return;
|
||||||
@ -321,15 +312,13 @@ PywbPeriod.prototype.fillEmptyChildPeriods = function(isFillEmptyGrandChildrenPe
|
|||||||
// insert new after existing
|
// insert new after existing
|
||||||
this.children.splice(i+1, 0, empty);
|
this.children.splice(i+1, 0, empty);
|
||||||
}
|
}
|
||||||
// manually push children (no need to reverse link parent
|
empty.parent = this;
|
||||||
//empty.parent = this;
|
empty.initFullId();
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
const empty = new PywbPeriod({type: this.type + 1, id: newId});
|
const empty = new PywbPeriod({type: this.type + 1, id: newId});
|
||||||
this.children.push(empty);
|
let result = this.addChild(empty);
|
||||||
// manually push children (no need to reverse link parent
|
|
||||||
//empty.parent = this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,6 +327,10 @@ PywbPeriod.prototype.fillEmptyChildPeriods = function(isFillEmptyGrandChildrenPe
|
|||||||
this.childrenIds[this.children[i].id] = i;
|
this.childrenIds[this.children[i].id] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFillEmptyGrandChildrenPeriods) {
|
||||||
|
this.fillEmptyGrandChildPeriods();
|
||||||
|
}
|
||||||
|
|
||||||
return idRange;
|
return idRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user