UX: tooltips and improvements to new dashboard
- tooltips - revert chart title UI - reduce period chooser font-size - localize dates of data points - fix a bug where multiple reports were loaded at the same time - fix a bug where % was not showing anymore - remove spacing at the top - remove loadingTitle feature (Loading...%report name%) incompatible with new hijack design
This commit is contained in:
parent
131b7f5da5
commit
9554d9c56a
|
@ -6,8 +6,6 @@ export default Ember.Component.extend(AsyncReport, {
|
|||
classNames: ["dashboard-table", "dashboard-inline-table", "fixed"],
|
||||
help: null,
|
||||
helpPage: null,
|
||||
title: null,
|
||||
loadingTitle: null,
|
||||
|
||||
loadReport(report_json) {
|
||||
return Report.create(report_json);
|
||||
|
@ -30,12 +28,10 @@ export default Ember.Component.extend(AsyncReport, {
|
|||
payload.data.limit = this.get("limit");
|
||||
}
|
||||
|
||||
this.set("reports", Ember.Object.create());
|
||||
|
||||
return Ember.RSVP.Promise.all(this.get("dataSources").map(dataSource => {
|
||||
return ajax(dataSource, payload)
|
||||
.then(response => {
|
||||
this.set(`reports.${response.report.report_key}`, this.loadReport(response.report));
|
||||
this.get("reports").pushObject(this.loadReport(response.report));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import AsyncReport from "admin/mixins/async-report";
|
|||
import Report from "admin/models/report";
|
||||
import { number } from 'discourse/lib/formatter';
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import { registerTooltip, unregisterTooltip } from "discourse/lib/tooltip";
|
||||
|
||||
function collapseWeekly(data, average) {
|
||||
let aggregate = [];
|
||||
|
@ -25,7 +26,7 @@ function collapseWeekly(data, average) {
|
|||
}
|
||||
|
||||
export default Ember.Component.extend(AsyncReport, {
|
||||
classNames: ["dashboard-mini-chart"],
|
||||
classNames: ["chart", "dashboard-mini-chart"],
|
||||
total: 0,
|
||||
|
||||
init() {
|
||||
|
@ -34,6 +35,18 @@ export default Ember.Component.extend(AsyncReport, {
|
|||
this._colorsPool = ["rgb(0,136,204)", "rgb(235,83,148)"];
|
||||
},
|
||||
|
||||
didRender() {
|
||||
this._super();
|
||||
|
||||
registerTooltip($(this.element).find("[data-tooltip]"));
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this._super();
|
||||
|
||||
unregisterTooltip($(this.element).find("[data-tooltip]"));
|
||||
},
|
||||
|
||||
pickColorAtIndex(index) {
|
||||
return this._colorsPool[index] || this._colorsPool[0];
|
||||
},
|
||||
|
@ -58,12 +71,10 @@ export default Ember.Component.extend(AsyncReport, {
|
|||
this._chart = null;
|
||||
}
|
||||
|
||||
this.set("reports", Ember.Object.create());
|
||||
|
||||
return Ember.RSVP.Promise.all(this.get("dataSources").map(dataSource => {
|
||||
return ajax(dataSource, payload)
|
||||
.then(response => {
|
||||
this.set(`reports.${response.report.report_key}`, this.loadReport(response.report));
|
||||
this.get("reports").pushObject(this.loadReport(response.report));
|
||||
});
|
||||
}));
|
||||
},
|
||||
|
@ -93,13 +104,13 @@ export default Ember.Component.extend(AsyncReport, {
|
|||
if (!$chartCanvas.length) return;
|
||||
const context = $chartCanvas[0].getContext("2d");
|
||||
|
||||
const reports = _.values(this.get("reports"));
|
||||
const reportsForPeriod = this.get("reportsForPeriod");
|
||||
|
||||
const labels = Ember.makeArray(reports.get("firstObject.data")).map(d => d.x);
|
||||
const labels = Ember.makeArray(reportsForPeriod.get("firstObject.data")).map(d => d.x);
|
||||
|
||||
const data = {
|
||||
labels,
|
||||
datasets: reports.map(report => {
|
||||
datasets: reportsForPeriod.map(report => {
|
||||
return {
|
||||
data: Ember.makeArray(report.data).map(d => d.y),
|
||||
backgroundColor: "rgba(200,220,240,0.3)",
|
||||
|
@ -127,6 +138,11 @@ export default Ember.Component.extend(AsyncReport, {
|
|||
type: "line",
|
||||
data,
|
||||
options: {
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
title: (context) => moment(context[0].xLabel, "YYYY-MM-DD").format("LL")
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
|
|
|
@ -100,7 +100,7 @@ export default Ember.Controller.extend({
|
|||
return fullDay.subtract(1, "month").startOf("day");
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
return fullDay.subtract(1, "month").startOf("day");
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@ import computed from "ember-addons/ember-computed-decorators";
|
|||
|
||||
export default Ember.Mixin.create({
|
||||
classNameBindings: ["isLoading"],
|
||||
|
||||
reports: null,
|
||||
isLoading: false,
|
||||
dataSourceNames: "",
|
||||
title: null,
|
||||
|
||||
init() {
|
||||
this._super();
|
||||
this.set("reports", Ember.Object.create());
|
||||
this.set("reports", []);
|
||||
},
|
||||
|
||||
@computed("dataSourceNames")
|
||||
|
@ -17,8 +17,27 @@ export default Ember.Mixin.create({
|
|||
return dataSourceNames.split(",").map(source => `/admin/reports/${source}`);
|
||||
},
|
||||
|
||||
@computed("reports.[]", "startDate", "endDate")
|
||||
reportsForPeriod(reports, startDate, endDate) {
|
||||
// on a slow network fetchReport could be called multiple times between
|
||||
// T and T+x, and all the ajax responses would occur after T+(x+y)
|
||||
// to avoid any inconsistencies we filter by period and make sure
|
||||
// the array contains only unique values
|
||||
reports = reports.uniqBy("report_key");
|
||||
|
||||
if (!startDate || !endDate) {
|
||||
return reports;
|
||||
}
|
||||
|
||||
return reports.filter(report => {
|
||||
return report.report_key.includes(startDate.format("YYYYMMDD")) &&
|
||||
report.report_key.includes(endDate.format("YYYYMMDD"));
|
||||
});
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super();
|
||||
|
||||
this.fetchReport()
|
||||
.finally(() => {
|
||||
this.renderReport();
|
||||
|
@ -27,6 +46,7 @@ export default Ember.Mixin.create({
|
|||
|
||||
didUpdateAttrs() {
|
||||
this._super();
|
||||
|
||||
this.fetchReport()
|
||||
.finally(() => {
|
||||
this.renderReport();
|
||||
|
@ -35,26 +55,14 @@ export default Ember.Mixin.create({
|
|||
|
||||
renderReport() {
|
||||
if (!this.element || this.isDestroying || this.isDestroyed) return;
|
||||
|
||||
const reports = _.values(this.get("reports"));
|
||||
|
||||
if (!reports.length) return;
|
||||
|
||||
const title = reports.map(report => report.title).join(", ");
|
||||
|
||||
if (reports.map(report => report.processing).includes(true)) {
|
||||
const loading = I18n.t("conditional_loading_section.loading");
|
||||
this.set("loadingTitle", `${loading}\n\n${title}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setProperties({ title, isLoading: false});
|
||||
this.set("title", this.get("reportsForPeriod").map(r => r.title).join(", "));
|
||||
this.set("isLoading", false);
|
||||
},
|
||||
|
||||
loadReport() {},
|
||||
|
||||
fetchReport() {
|
||||
this.set("reports", []);
|
||||
this.set("isLoading", true);
|
||||
this.set("loadingTitle", I18n.t("conditional_loading_section.loading"));
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{#conditional-loading-section isLoading=isLoading title=loadingTitle}}
|
||||
{{#conditional-loading-section isLoading=isLoading}}
|
||||
<div class="table-title">
|
||||
<h3>{{title}}</h3>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#each-in reports as |key report|}}
|
||||
{{#each reportsForPeriod as |report|}}
|
||||
<div class="table-container">
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -36,5 +36,5 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{/each-in}}
|
||||
{{/each}}
|
||||
{{/conditional-loading-section}}
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
{{#conditional-loading-section isLoading=isLoading title=loadingTitle}}
|
||||
<div class="dashboard-mini-statuses">
|
||||
{{#each-in reports as |key report|}}
|
||||
<div class="dashboard-mini-status" title="{{report.trendTitle}}">
|
||||
<span class="indicator" style="background-color:{{report.color}}"></span>
|
||||
<div class="legend">
|
||||
<h4 class="title">
|
||||
<a href="{{report.reportUrl}}">
|
||||
{{report.title}}
|
||||
</a>
|
||||
</h4>
|
||||
{{#conditional-loading-section isLoading=isLoading}}
|
||||
{{#each reportsForPeriod as |report|}}
|
||||
<div class="status">
|
||||
<h4 class="title">
|
||||
<a href="{{report.reportUrl}}">
|
||||
{{report.title}}
|
||||
</a>
|
||||
|
||||
<div class="trend">
|
||||
<span class="value" title="{{report.trendTitle}}">
|
||||
{{#if report.average}}
|
||||
{{report.currentAverage}}
|
||||
{{else}}
|
||||
{{number report.currentTotal noTitle="true"}}
|
||||
{{/if}}
|
||||
</span>
|
||||
{{#if report.trendIcon}}
|
||||
{{d-icon report.trendIcon}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<span class="info" data-tooltip="{{report.description}}">
|
||||
{{d-icon "question-circle"}}
|
||||
</span>
|
||||
</h4>
|
||||
|
||||
<div class="trend {{report.trend}}">
|
||||
<span class="trend-value" title="{{report.trendTitle}}">
|
||||
{{#if report.average}}
|
||||
{{number report.currentAverage}}{{#if report.percent}}%{{/if}}
|
||||
{{else}}
|
||||
{{number report.currentTotal noTitle="true"}}{{#if report.percent}}%{{/if}}
|
||||
{{/if}}
|
||||
</span>
|
||||
|
||||
{{#if report.trendIcon}}
|
||||
{{d-icon report.trendIcon class="trend-icon"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/each-in}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
<div class="chart-canvas-container">
|
||||
<canvas class="chart-canvas"></canvas>
|
||||
|
|
|
@ -3,5 +3,7 @@ export default Ember.Component.extend({
|
|||
|
||||
classNameBindings: ["isLoading"],
|
||||
|
||||
isLoading: false
|
||||
isLoading: false,
|
||||
|
||||
title: I18n.t("conditional_loading_section.loading")
|
||||
});
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
export function showTooltip() {
|
||||
const fadeSpeed = 300;
|
||||
const tooltipID = "#discourse-tooltip";
|
||||
const $this = $(this);
|
||||
const $parent = $this.offsetParent();
|
||||
const content = $this.attr("data-tooltip");
|
||||
const retina = window.devicePixelRatio && window.devicePixelRatio > 1 ? "class='retina'" : "";
|
||||
|
||||
let pos = $this.offset();
|
||||
const delta = $parent.offset();
|
||||
pos.top -= delta.top;
|
||||
pos.left -= delta.left;
|
||||
|
||||
$(tooltipID).fadeOut(fadeSpeed).remove();
|
||||
|
||||
$(this).after(`
|
||||
<div id="discourse-tooltip" ${retina}>
|
||||
<div class="tooltip-pointer"></div>
|
||||
<div class="tooltip-content">${content}</div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
$(window).on("click.discourse", (event) => {
|
||||
if ($(event.target).closest(tooltipID).length === 0) {
|
||||
$(tooltipID).remove();
|
||||
$(window).off("click.discourse");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const $tooltip = $(tooltipID);
|
||||
$tooltip.css({top: 0, left: 0});
|
||||
|
||||
let left = (pos.left - ($tooltip.width() / 2) + $this.width()/2);
|
||||
if (left < 0) {
|
||||
$tooltip.find(".tooltip-pointer").css({
|
||||
"margin-left": left*2 + "px"
|
||||
});
|
||||
left = 0;
|
||||
}
|
||||
|
||||
// also do a right margin fix
|
||||
const parentWidth = $parent.width();
|
||||
if (left + $tooltip.width() > parentWidth) {
|
||||
let oldLeft = left;
|
||||
left = parentWidth - $tooltip.width();
|
||||
|
||||
$tooltip.find(".tooltip-pointer").css({
|
||||
"margin-left": (oldLeft - left) * 2 + "px"
|
||||
});
|
||||
}
|
||||
|
||||
$tooltip.css({
|
||||
top: pos.top + 5 + "px",
|
||||
left: left + "px"
|
||||
});
|
||||
|
||||
$tooltip.fadeIn(fadeSpeed);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function registerTooltip(jqueryContext) {
|
||||
if (jqueryContext.length) {
|
||||
jqueryContext.on('click', showTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
export function unregisterTooltip(jqueryContext) {
|
||||
if (jqueryContext.length) {
|
||||
jqueryContext.off('click');
|
||||
}
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
.dashboard-next {
|
||||
|
||||
&.admin-contents {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.section-top {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.section-columns {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
@ -62,223 +65,26 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dashboard-table {
|
||||
margin-bottom: 1em;
|
||||
|
||||
&.is-disabled {
|
||||
background: $primary-low;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
@include small-width {
|
||||
table {
|
||||
tbody tr td {
|
||||
font-size: $font-down-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.table-title {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
h3 {
|
||||
margin: .5em 0;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
|
||||
thead {
|
||||
border: 1px solid $primary-low;
|
||||
tr {
|
||||
background: $primary-low;
|
||||
th {
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
tr {
|
||||
td:first-child {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid $primary-low;
|
||||
text-align: center;
|
||||
}
|
||||
td.left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td.value {
|
||||
i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.high-trending-up, &.trending-up {
|
||||
i.up {
|
||||
color: $success;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
&.high-trending-down, &.trending-down {
|
||||
i.down {
|
||||
color: $danger;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
&.no-change {
|
||||
i.down {
|
||||
display: inline;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.charts {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.dashboard-mini-statuses {
|
||||
margin-bottom: 1em;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.dashboard-mini-status {
|
||||
flex-direction: row;
|
||||
margin-right: 1em;
|
||||
display: flex;
|
||||
|
||||
.indicator {
|
||||
margin-right: .5em;
|
||||
width: .33em;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.legend {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
a {color: black;}
|
||||
|
||||
font-size: $font-down-2;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.trend {
|
||||
flex-direction: row;
|
||||
|
||||
.d-icon {
|
||||
font-weight: 700;
|
||||
|
||||
&.d-icon-angle-down, &.d-icon-angle-double-down {
|
||||
color: $danger;
|
||||
}
|
||||
|
||||
&.d-icon-angle-up, &.d-icon-angle-double-up {
|
||||
color: rgb(17, 141, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-mini-chart {
|
||||
.chart {
|
||||
max-width: calc(100% * 1/3);
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
flex-basis: 100%;
|
||||
display: flex;
|
||||
margin-bottom: 1em;
|
||||
|
||||
.conditional-loading-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@include small-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.loading-container.visible {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.d-icon-question-circle {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
h3 {
|
||||
margin: 1em 0;
|
||||
a, a:visited {
|
||||
color: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.high-trending-up, &.trending-up {
|
||||
.chart-trend, .data-point {
|
||||
color: rgb(17, 141, 0);
|
||||
}
|
||||
}
|
||||
|
||||
&.high-trending-down, &.trending-down {
|
||||
.chart-trend, .data-point {
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include small-width {
|
||||
.dashboard-mini-chart {
|
||||
width: 100%;
|
||||
.chart {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-trend {
|
||||
font-size: $font-up-3;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.chart-canvas-container {
|
||||
position: relative;
|
||||
padding: 0 1em 0 0;
|
||||
|
@ -300,4 +106,204 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.community-health {
|
||||
.period-chooser .period-chooser-header {
|
||||
.selected-name, .d-icon {
|
||||
font-size: $font-up-1;
|
||||
}
|
||||
|
||||
.d-icon {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.dashboard-mini-chart {
|
||||
.status {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1em;
|
||||
|
||||
.title {
|
||||
font-size: $font-0;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
|
||||
a { color: $primary; }
|
||||
|
||||
.info {
|
||||
cursor: pointer;
|
||||
margin-left: .25em;
|
||||
color: $primary-medium;
|
||||
}
|
||||
}
|
||||
|
||||
.trend {
|
||||
margin-right: 1em;
|
||||
align-items: center;
|
||||
|
||||
&.trending-down, &.high-trending-down {
|
||||
color: $danger;
|
||||
}
|
||||
|
||||
&.trending-up, &.high-trending-up {
|
||||
color: $success;
|
||||
}
|
||||
|
||||
.trend-value {
|
||||
font-size: $font-up-1;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.trend-icon {
|
||||
font-size: $font-up-1;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.conditional-loading-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@include small-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.loading-container.visible {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.d-icon-question-circle {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
h3 {
|
||||
margin: 1em 0;
|
||||
a, a:visited {
|
||||
color: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.high-trending-up, &.trending-up {
|
||||
.chart-trend, .data-point {
|
||||
color: $success;
|
||||
}
|
||||
}
|
||||
|
||||
&.high-trending-down, &.trending-down {
|
||||
.chart-trend, .data-point {
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-table {
|
||||
margin-bottom: 1em;
|
||||
|
||||
&.is-disabled {
|
||||
background: $primary-low;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
@include small-width {
|
||||
table {
|
||||
tbody tr td {
|
||||
font-size: $font-down-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.table-title {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
h3 {
|
||||
margin: .5em 0;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
|
||||
thead {
|
||||
border: 1px solid $primary-low;
|
||||
tr {
|
||||
background: $primary-low;
|
||||
th {
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
tr {
|
||||
td:first-child {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid $primary-low;
|
||||
text-align: center;
|
||||
}
|
||||
td.left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td.value {
|
||||
i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.high-trending-up, &.trending-up {
|
||||
i.up {
|
||||
color: $success;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
&.high-trending-down, &.trending-down {
|
||||
i.down {
|
||||
color: $danger;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
&.no-change {
|
||||
i.down {
|
||||
display: inline;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
$discourse-tooltip-background: $secondary;
|
||||
$discourse-tooltip-border: $primary-medium;
|
||||
|
||||
#discourse-tooltip {
|
||||
background-color: $discourse-tooltip-background;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
border: 1px solid $discourse-tooltip-border;
|
||||
max-width: 400px;
|
||||
margin-top: 25px;
|
||||
overflow-wrap: break-word;
|
||||
display: none;
|
||||
font-size: $font-0;
|
||||
font-weight: 500;
|
||||
|
||||
&.retina {
|
||||
border: 0.5px solid $discourse-tooltip-border;
|
||||
}
|
||||
|
||||
.tooltip-pointer {
|
||||
position: relative;
|
||||
background: $discourse-tooltip-background;
|
||||
}
|
||||
|
||||
.tooltip-pointer:before, .tooltip-pointer:after {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: solid transparent;
|
||||
bottom: 100%;
|
||||
content: "";
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.tooltip-pointer:after
|
||||
{
|
||||
border-bottom-color: $discourse-tooltip-background;
|
||||
border-width: 8px;
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
margin-bottom: -0.5px;
|
||||
}
|
||||
|
||||
.tooltip-pointer:before {
|
||||
border-bottom-color: $discourse-tooltip-border;
|
||||
border-width: 9px;
|
||||
left: 50%;
|
||||
margin-left: -9px;
|
||||
margin-bottom: -0.5px;
|
||||
}
|
||||
|
||||
.tooltip-content {
|
||||
padding: 0 0.5em;
|
||||
font-size: $font-down-1;
|
||||
color: $primary-medium;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": null,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,7 +13,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": 46,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -42,7 +42,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": null,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,7 +12,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": 0,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -39,7 +39,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": 0,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,7 +12,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": 0,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,7 +12,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": null,
|
||||
"labels": ["Term", "Searches", "Unique"]
|
||||
"labels": ["Term", "Searches", "Unique"],
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,7 +13,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": null,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,7 +13,8 @@ export default {
|
|||
"category_id": null,
|
||||
"group_id": null,
|
||||
"prev30Days": null,
|
||||
"labels": null
|
||||
"labels": null,
|
||||
"report_key": ""
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue