mirror of
https://github.com/getredash/redash.git
synced 2026-03-22 10:00:17 -04:00
* Migrate router and <app-view> to React: skeleton * Update layout on route change * Start moving page routes from angular to react * Move page routes to react except of public dashboard and visualization embed) * Move public dashboard and visualization embed routes to React * Replace $route/$routeParams usages * Some cleanup * Replace AngularJS $location service with implementation based on history library * Minor fix to how ApplicationView handles route change * Explicitly use global layout for each page instead of handling related stuff in ApplicationArea component * Error handling * Remove AngularJS and related dependencies * Move Parameter factory method to a separate file * Fix CSS (replace custom components with classes) * Fix: keep other url parts when updating location partially; refine code * Fix tests * Make router work in multi-org mode (respect <base> tag) * Optimzation: don't resolve route if path didn't change * Fix search input in header; error handling improvement (handle more errors in pages; global error handler for unhandled errors; dialog dismiss 'unhandled rejection' errors) * Fix page keys; fix navigateTo calls (third parameter not available) * Use relative links * Router: ignore location REPLACE events, resolve only on PUSH/POP * Fix tests * Remove unused jQuery reference * Show error from backend when creating Destination * Remove route.resolve where not necessary (used constant values) * New Query page: keep state on saving, reload when creating another new query * Use currentRoute.key instead of hard-coded keys for page components * Tidy up Router * Tidy up location service * Fix tests * Don't add parameters changes to browser's history * Fix test (improved fix) Co-authored-by: Gabriel Dutra <nesk.frz@gmail.com>
160 lines
3.0 KiB
JavaScript
160 lines
3.0 KiB
JavaScript
import moment from "moment";
|
|
import { clientConfig } from "@/services/auth";
|
|
|
|
export const IntervalEnum = {
|
|
NEVER: "Never",
|
|
SECONDS: "second",
|
|
MINUTES: "minute",
|
|
HOURS: "hour",
|
|
DAYS: "day",
|
|
WEEKS: "week",
|
|
};
|
|
|
|
export function formatDateTime(value) {
|
|
if (!value) {
|
|
return "";
|
|
}
|
|
|
|
const parsed = moment(value);
|
|
if (!parsed.isValid()) {
|
|
return "-";
|
|
}
|
|
|
|
return parsed.format(clientConfig.dateTimeFormat);
|
|
}
|
|
|
|
export function formatDate(value) {
|
|
if (!value) {
|
|
return "";
|
|
}
|
|
|
|
const parsed = moment(value);
|
|
if (!parsed.isValid()) {
|
|
return "-";
|
|
}
|
|
|
|
return parsed.format(clientConfig.dateFormat);
|
|
}
|
|
|
|
export function localizeTime(time) {
|
|
const [hrs, mins] = time.split(":");
|
|
return moment
|
|
.utc()
|
|
.hour(hrs)
|
|
.minute(mins)
|
|
.local()
|
|
.format("HH:mm");
|
|
}
|
|
|
|
export function secondsToInterval(count) {
|
|
if (!count) {
|
|
return { interval: IntervalEnum.NEVER };
|
|
}
|
|
|
|
let interval = IntervalEnum.SECONDS;
|
|
if (count >= 60) {
|
|
count /= 60;
|
|
interval = IntervalEnum.MINUTES;
|
|
}
|
|
if (count >= 60) {
|
|
count /= 60;
|
|
interval = IntervalEnum.HOURS;
|
|
}
|
|
if (count >= 24 && interval === IntervalEnum.HOURS) {
|
|
count /= 24;
|
|
interval = IntervalEnum.DAYS;
|
|
}
|
|
if (count >= 7 && !(count % 7) && interval === IntervalEnum.DAYS) {
|
|
count /= 7;
|
|
interval = IntervalEnum.WEEKS;
|
|
}
|
|
return { count, interval };
|
|
}
|
|
|
|
export function pluralize(text, count) {
|
|
const should = count !== 1;
|
|
return text + (should ? "s" : "");
|
|
}
|
|
|
|
export function durationHumanize(duration, options = {}) {
|
|
if (!duration) {
|
|
return "-";
|
|
}
|
|
let ret = "";
|
|
const { interval, count } = secondsToInterval(duration);
|
|
const rounded = Math.round(count);
|
|
if (rounded !== 1 || !options.omitSingleValueNumber) {
|
|
ret = `${rounded} `;
|
|
}
|
|
ret += pluralize(interval, rounded);
|
|
return ret;
|
|
}
|
|
|
|
export function toHuman(text) {
|
|
return text.replace(/_/g, " ").replace(/(?:^|\s)\S/g, a => a.toUpperCase());
|
|
}
|
|
|
|
export function remove(items, item) {
|
|
if (items === undefined) {
|
|
return items;
|
|
}
|
|
|
|
let notEquals;
|
|
|
|
if (item instanceof Array) {
|
|
notEquals = other => item.indexOf(other) === -1;
|
|
} else {
|
|
notEquals = other => item !== other;
|
|
}
|
|
|
|
const filtered = [];
|
|
|
|
for (let i = 0; i < items.length; i += 1) {
|
|
if (notEquals(items[i])) {
|
|
filtered.push(items[i]);
|
|
}
|
|
}
|
|
|
|
return filtered;
|
|
}
|
|
|
|
const units = ["bytes", "KB", "MB", "GB", "TB", "PB"];
|
|
|
|
export function prettySize(bytes) {
|
|
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) {
|
|
return "?";
|
|
}
|
|
|
|
let unit = 0;
|
|
|
|
while (bytes >= 1024) {
|
|
bytes /= 1024;
|
|
unit += 1;
|
|
}
|
|
|
|
return bytes.toFixed(3) + " " + units[unit];
|
|
}
|
|
|
|
export function join(arr) {
|
|
if (arr === undefined || arr === null) {
|
|
return "";
|
|
}
|
|
|
|
return arr.join(" / ");
|
|
}
|
|
|
|
export function formatColumnValue(value, columnType = null) {
|
|
if (moment.isMoment(value)) {
|
|
if (columnType === "date") {
|
|
return formatDate(value);
|
|
}
|
|
return formatDateTime(value);
|
|
}
|
|
|
|
if (typeof value === "boolean") {
|
|
return value.toString();
|
|
}
|
|
|
|
return value;
|
|
}
|