route bugfix, localization
This commit is contained in:
parent
e4e2511d1c
commit
8a09fc1f2d
@ -1259,7 +1259,7 @@ namespace Core\API\User {
|
|||||||
$settings = $this->context->getSettings();
|
$settings = $this->context->getSettings();
|
||||||
$baseUrl = htmlspecialchars($settings->getBaseUrl());
|
$baseUrl = htmlspecialchars($settings->getBaseUrl());
|
||||||
$token = htmlspecialchars(urlencode($token));
|
$token = htmlspecialchars(urlencode($token));
|
||||||
$url = "$baseUrl/settings?confirmGPG&token=$token"; // TODO: fix this url
|
$url = "$baseUrl/confirmGPG?token=$token";
|
||||||
$mailBody = "Hello $name,<br><br>" .
|
$mailBody = "Hello $name,<br><br>" .
|
||||||
"you imported a GPG public key for end-to-end encrypted mail communication. " .
|
"you imported a GPG public key for end-to-end encrypted mail communication. " .
|
||||||
"To confirm the key and verify, you own the corresponding private key, please click on the following link. " .
|
"To confirm the key and verify, you own the corresponding private key, please click on the following link. " .
|
||||||
|
@ -8,6 +8,9 @@ return [
|
|||||||
"accept_invite_description" => "Schließen Sie die Registrierung ab indem Sie ein Passwort wählen",
|
"accept_invite_description" => "Schließen Sie die Registrierung ab indem Sie ein Passwort wählen",
|
||||||
"confirm_email_title" => "E-Mail Adresse bestätigen",
|
"confirm_email_title" => "E-Mail Adresse bestätigen",
|
||||||
"confirm_email_description" => "Schließen Sie die Registrierung ab indem Sie Ihre E-Mail Adresse bestätigen",
|
"confirm_email_description" => "Schließen Sie die Registrierung ab indem Sie Ihre E-Mail Adresse bestätigen",
|
||||||
|
"confirm_gpg_title" => "GPG-Schlüssel bestätigen",
|
||||||
|
"confirm_gpg_error" => "Fehler beim Bestätigen des GPG-Schlüssels",
|
||||||
|
"confirm_gpg_success" => "GPG-Schlüssel erfolgreich bestätigt",
|
||||||
"registration_title" => "Registration",
|
"registration_title" => "Registration",
|
||||||
"registration_description" => "Erstelle einen neuen Account",
|
"registration_description" => "Erstelle einen neuen Account",
|
||||||
"resend_confirm_email_title" => "Bestätigungsmail erneut senden",
|
"resend_confirm_email_title" => "Bestätigungsmail erneut senden",
|
||||||
@ -43,7 +46,15 @@ return [
|
|||||||
"confirm_success" => "Ihre E-Mail Adresse wurde erfolgreich bestätigt, Sie können sich jetzt einloggen",
|
"confirm_success" => "Ihre E-Mail Adresse wurde erfolgreich bestätigt, Sie können sich jetzt einloggen",
|
||||||
"confirm_error" => "Fehler beim Bestätigen der E-Mail Adresse",
|
"confirm_error" => "Fehler beim Bestätigen der E-Mail Adresse",
|
||||||
"gpg_key" => "GPG-Schlüssel",
|
"gpg_key" => "GPG-Schlüssel",
|
||||||
|
"no_gpg_key_added" => "Kein GPG-Schlüssel hinzugefügt",
|
||||||
|
"download_gpg_key" => "GPG-Schlüssel herunterladen",
|
||||||
"2fa_token" => "Zwei-Faktor Authentifizierung (2FA)",
|
"2fa_token" => "Zwei-Faktor Authentifizierung (2FA)",
|
||||||
"profile_picture_of" => "Profilbild von",
|
"profile_picture_of" => "Profilbild von",
|
||||||
|
"profile_of" => "Profil von",
|
||||||
"language" => "Sprache",
|
"language" => "Sprache",
|
||||||
|
"profile" => "Benutzerprofil",
|
||||||
|
"loading_profile" => "Lade Benutzerprofil",
|
||||||
|
"error_profile_get" => "Fehler beim Laden des Benutzerprofils",
|
||||||
|
"registered_at" => "Registriert am",
|
||||||
|
"last_online" => "Zuletzt online",
|
||||||
];
|
];
|
@ -6,10 +6,12 @@ return [
|
|||||||
"retry" => "Erneut versuchen",
|
"retry" => "Erneut versuchen",
|
||||||
"go_back" => "Zurück",
|
"go_back" => "Zurück",
|
||||||
"save" => "Speichern",
|
"save" => "Speichern",
|
||||||
|
"save_only" => "Nur Speichern",
|
||||||
"saving" => "Speichere",
|
"saving" => "Speichere",
|
||||||
"unsaved_changes" => "Du hast nicht gespeicherte Änderungen",
|
"unsaved_changes" => "Du hast nicht gespeicherte Änderungen",
|
||||||
"new" => "Neu",
|
"new" => "Neu",
|
||||||
"edit" => "Bearbeiten",
|
"edit" => "Bearbeiten",
|
||||||
|
"apply" => "Übernehmen",
|
||||||
"submitting" => "Übermittle",
|
"submitting" => "Übermittle",
|
||||||
"submit" => "Absenden",
|
"submit" => "Absenden",
|
||||||
"request" => "Anfordern",
|
"request" => "Anfordern",
|
||||||
|
@ -8,6 +8,9 @@ return [
|
|||||||
"accept_invite_description" => "Complete your account registration by choosing a password",
|
"accept_invite_description" => "Complete your account registration by choosing a password",
|
||||||
"confirm_email_title" => "Confirm Email",
|
"confirm_email_title" => "Confirm Email",
|
||||||
"confirm_email_description" => "Complete your registration by confirming the e-mail address",
|
"confirm_email_description" => "Complete your registration by confirming the e-mail address",
|
||||||
|
"confirm_gpg_title" => "Confirm GPG Key",
|
||||||
|
"confirm_gpg_error" => "Error confirming GPG Key",
|
||||||
|
"confirm_gpg_success" => "Successfully confirmed GPG Key",
|
||||||
"registration_title" => "Registration",
|
"registration_title" => "Registration",
|
||||||
"registration_description" => "Create a new account",
|
"registration_description" => "Create a new account",
|
||||||
"resend_confirm_email_title" => "Resend Confirm Email",
|
"resend_confirm_email_title" => "Resend Confirm Email",
|
||||||
@ -43,7 +46,15 @@ return [
|
|||||||
"confirm_success" => "Your e-mail address was successfully confirmed, you may now log in",
|
"confirm_success" => "Your e-mail address was successfully confirmed, you may now log in",
|
||||||
"confirm_error" => "Error confirming e-mail address",
|
"confirm_error" => "Error confirming e-mail address",
|
||||||
"gpg_key" => "GPG Key",
|
"gpg_key" => "GPG Key",
|
||||||
|
"no_gpg_key_added" => "No GPG key added",
|
||||||
|
"download_gpg_key" => "Download GPG Key",
|
||||||
"2fa_token" => "Two-Factor Authentication (2FA)",
|
"2fa_token" => "Two-Factor Authentication (2FA)",
|
||||||
"profile_picture_of" => "Profile Picture of",
|
"profile_picture_of" => "Profile Picture of",
|
||||||
|
"profile_of" => "Profile of",
|
||||||
"language" => "Language",
|
"language" => "Language",
|
||||||
|
"profile" => "User Profile",
|
||||||
|
"loading_profile" => "Loading Profile",
|
||||||
|
"error_profile_get" => "Error retrieving user profile",
|
||||||
|
"registered_at" => "Registered At",
|
||||||
|
"last_online" => "Last Online",
|
||||||
];
|
];
|
@ -24,6 +24,7 @@ return [
|
|||||||
"edit" => "Edit",
|
"edit" => "Edit",
|
||||||
"submitting" => "Submitting",
|
"submitting" => "Submitting",
|
||||||
"submit" => "Submit",
|
"submit" => "Submit",
|
||||||
|
"apply" => "Apply",
|
||||||
"request" => "Request",
|
"request" => "Request",
|
||||||
"cancel" => "Cancel",
|
"cancel" => "Cancel",
|
||||||
"confirm" => "Confirm",
|
"confirm" => "Confirm",
|
||||||
@ -36,6 +37,7 @@ return [
|
|||||||
"retry" => "Retry",
|
"retry" => "Retry",
|
||||||
"go_back" => "Go Back",
|
"go_back" => "Go Back",
|
||||||
"save" => "Save",
|
"save" => "Save",
|
||||||
|
"save_only" => "Save Only",
|
||||||
"saving" => "Saving",
|
"saving" => "Saving",
|
||||||
"delete" => "Delete",
|
"delete" => "Delete",
|
||||||
"info" => "Info",
|
"info" => "Info",
|
||||||
|
@ -105,6 +105,7 @@ class DatabaseEntityQuery extends Select {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fix cycle detection + rather use deterministic aliases instead of t1, t2, t3...?
|
||||||
private function fetchRelation(string $propertyName, string $tableName, DatabaseEntityHandler $src, DatabaseEntityHandler $relationHandler,
|
private function fetchRelation(string $propertyName, string $tableName, DatabaseEntityHandler $src, DatabaseEntityHandler $relationHandler,
|
||||||
bool $recursive = false, string $relationColumnPrefix = "", array &$visited = []) {
|
bool $recursive = false, string $relationColumnPrefix = "", array &$visited = []) {
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace Core\Objects\DatabaseEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Language(1, "en_US", "American English");
|
return self::getPredefinedValues()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEntries(?string $module = null): ?array {
|
public function getEntries(?string $module = null): ?array {
|
||||||
@ -101,7 +101,7 @@ namespace Core\Objects\DatabaseEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "[$key]";
|
return $key ? "[$key]" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addModule(string $module, array $entries) {
|
public function addModule(string $module, array $entries) {
|
||||||
@ -143,8 +143,8 @@ namespace Core\Objects\DatabaseEntity {
|
|||||||
|
|
||||||
public static function getPredefinedValues(): array {
|
public static function getPredefinedValues(): array {
|
||||||
return [
|
return [
|
||||||
new Language(Language::AMERICAN_ENGLISH, "en_US", 'American English'),
|
new Language(Language::AMERICAN_ENGLISH, "en_US", 'English (US)'),
|
||||||
new Language(Language::GERMAN_STANDARD, "de_DE", 'Deutsch Standard'),
|
new Language(Language::GERMAN_STANDARD, "de_DE", 'Deutsch (Standard)'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ namespace Core\Objects\DatabaseEntity {
|
|||||||
namespace {
|
namespace {
|
||||||
function L(string $key): string {
|
function L(string $key): string {
|
||||||
if (!array_key_exists('LANGUAGE', $GLOBALS)) {
|
if (!array_key_exists('LANGUAGE', $GLOBALS)) {
|
||||||
return "[$key]";
|
return $key ? "[$key]" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
global $LANGUAGE;
|
global $LANGUAGE;
|
||||||
|
@ -107,15 +107,23 @@ abstract class Route extends DatabaseEntity {
|
|||||||
return "new $className($args)";
|
return "new $className($args)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function getParts(string $url): array {
|
||||||
|
if ($url === "/" || $url === "") {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
return explode("/", $url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function match(string $url) {
|
public function match(string $url) {
|
||||||
|
|
||||||
# /test/{abc}/{param:?}/{xyz:int}/{aaa:int?}
|
# /test/{abc}/{param:?}/{xyz:int}/{aaa:int?}
|
||||||
$patternParts = explode("/", Router::cleanURL($this->pattern, false));
|
$patternParts = self::getParts(Router::cleanURL($this->pattern, false));
|
||||||
$countPattern = count($patternParts);
|
$countPattern = count($patternParts);
|
||||||
$patternOffset = 0;
|
$patternOffset = 0;
|
||||||
|
|
||||||
# /test/param/optional/123
|
# /test/param/optional/123
|
||||||
$urlParts = explode("/", Router::cleanURL($url));
|
$urlParts = self::getParts(Router::cleanURL($url));
|
||||||
$countUrl = count($urlParts);
|
$countUrl = count($urlParts);
|
||||||
$urlOffset = 0;
|
$urlOffset = 0;
|
||||||
|
|
||||||
@ -235,6 +243,7 @@ abstract class Route extends DatabaseEntity {
|
|||||||
new DocumentRoute("/admin", false, \Core\Documents\Admin::class),
|
new DocumentRoute("/admin", false, \Core\Documents\Admin::class),
|
||||||
new DocumentRoute("/register", true, \Core\Documents\Account::class, "account/register.twig"),
|
new DocumentRoute("/register", true, \Core\Documents\Account::class, "account/register.twig"),
|
||||||
new DocumentRoute("/confirmEmail", true, \Core\Documents\Account::class, "account/confirm_email.twig"),
|
new DocumentRoute("/confirmEmail", true, \Core\Documents\Account::class, "account/confirm_email.twig"),
|
||||||
|
new DocumentRoute("/confirmGPG", true, \Core\Documents\Account::class, "account/confirm_gpg.twig"),
|
||||||
new DocumentRoute("/acceptInvite", true, \Core\Documents\Account::class, "account/accept_invite.twig"),
|
new DocumentRoute("/acceptInvite", true, \Core\Documents\Account::class, "account/accept_invite.twig"),
|
||||||
new DocumentRoute("/resetPassword", true, \Core\Documents\Account::class, "account/reset_password.twig"),
|
new DocumentRoute("/resetPassword", true, \Core\Documents\Account::class, "account/reset_password.twig"),
|
||||||
new DocumentRoute("/login", true, \Core\Documents\Account::class, "account/login.twig"),
|
new DocumentRoute("/login", true, \Core\Documents\Account::class, "account/login.twig"),
|
||||||
|
36
Core/Templates/account/confirm_gpg.twig
Normal file
36
Core/Templates/account/confirm_gpg.twig
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{% extends "account/account_base.twig" %}
|
||||||
|
|
||||||
|
{% set view_title = 'account.confirm_gpg_title' %}
|
||||||
|
{% set view_icon = 'user-check' %}
|
||||||
|
{% set view_description = '' %}
|
||||||
|
|
||||||
|
{% block view_content %}
|
||||||
|
<noscript>
|
||||||
|
<div class="alert alert-danger">{{ L('general.noscript') }}</div>
|
||||||
|
</noscript>
|
||||||
|
<div class="alert alert-info" id="confirm-status">
|
||||||
|
{{ L('account.confirming_gpg') }}… <i class="fas fa-spinner fa-spin"></i>
|
||||||
|
</div>
|
||||||
|
<script nonce="{{ site.csp.nonce }}">
|
||||||
|
$(document).ready(function() {
|
||||||
|
let token = jsCore.getParameter("token");
|
||||||
|
let confirmStatus = $("#confirm-status");
|
||||||
|
if (token) {
|
||||||
|
jsCore.apiCall("/user/confirmGPG", { token: token, csrfToken: '{{ user.session.csrfToken }}' }, (res) => {
|
||||||
|
confirmStatus.removeClass("alert-info");
|
||||||
|
if (!res.success) {
|
||||||
|
confirmStatus.addClass("alert-danger");
|
||||||
|
confirmStatus.text("{{ L('account.confirm_gpg_error') }}: " + res.msg);
|
||||||
|
} else {
|
||||||
|
confirmStatus.addClass("alert-success");
|
||||||
|
confirmStatus.text("{{ L('account.confirm_gpg_success') }}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
confirmStatus.removeClass("alert-info");
|
||||||
|
confirmStatus.addClass("alert-danger");
|
||||||
|
confirmStatus.text("{{ L('account.invalid_link') }}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
8
cli.php
8
cli.php
@ -480,6 +480,12 @@ function onRoutes(array $argv) {
|
|||||||
|
|
||||||
printTable($head, $tableRows);
|
printTable($head, $tableRows);
|
||||||
}
|
}
|
||||||
|
} else if ($action === "generate_cache") {
|
||||||
|
$req = new \Core\API\Routes\GenerateCache($context);
|
||||||
|
$success = $req->execute();
|
||||||
|
if (!$success) {
|
||||||
|
_exit("Error generating cache: " . $req->getLastError());
|
||||||
|
}
|
||||||
} else if ($action === "add") {
|
} else if ($action === "add") {
|
||||||
if (count($argv) < 7) {
|
if (count($argv) < 7) {
|
||||||
_exit("Usage: cli.php routes add <pattern> <type> <target> <exact> [extra]");
|
_exit("Usage: cli.php routes add <pattern> <type> <target> <exact> [extra]");
|
||||||
@ -543,7 +549,7 @@ function onRoutes(array $argv) {
|
|||||||
_exit("Route updated successfully");
|
_exit("Route updated successfully");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_exit("Usage: cli.php routes <list|enable|disable|add|remove|modify> [options...]");
|
_exit("Usage: cli.php routes <list|enable|disable|add|remove|modify|generate_cache> [options...]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ server {
|
|||||||
error_log /var/log/nginx/error.log;
|
error_log /var/log/nginx/error.log;
|
||||||
access_log /var/log/nginx/access.log;
|
access_log /var/log/nginx/access.log;
|
||||||
root /application;
|
root /application;
|
||||||
|
client_max_body_size 1G;
|
||||||
|
|
||||||
# rewrite error codes
|
# rewrite error codes
|
||||||
error_page 400 /index.php?error=400;
|
error_page 400 /index.php?error=400;
|
||||||
|
@ -101,8 +101,8 @@ let Core = function () {
|
|||||||
var param = split[i];
|
var param = split[i];
|
||||||
var index = param.indexOf('=');
|
var index = param.indexOf('=');
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
var key = param.substr(0, index);
|
var key = param.substring(0, index);
|
||||||
var val = param.substr(index + 1);
|
var val = param.substring(index + 1);
|
||||||
this.parameters[key] = val;
|
this.parameters[key] = val;
|
||||||
} else
|
} else
|
||||||
this.parameters[param] = '';
|
this.parameters[param] = '';
|
||||||
|
@ -10,7 +10,7 @@ export default class API {
|
|||||||
this.loggedIn = false;
|
this.loggedIn = false;
|
||||||
this.user = null;
|
this.user = null;
|
||||||
this.session = null;
|
this.session = null;
|
||||||
this.language = { id: 1, code: "en_US", shortCode: "en", name: "American English" };
|
this.language = { id: 1, code: "en_US", shortCode: "en", name: "English (US)" };
|
||||||
this.permissions = [];
|
this.permissions = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
.data-table th {
|
.data-table th {
|
||||||
background-color: #bbb;
|
background-color: #bbb;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-table th > svg {
|
.data-table th > svg {
|
||||||
@ -34,3 +35,13 @@
|
|||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.data-table-buttons {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table-buttons > svg {
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
@ -293,7 +293,6 @@ export class ControlsColumn extends DataColumn {
|
|||||||
...buttonProps,
|
...buttonProps,
|
||||||
key: "button-" + index,
|
key: "button-" + index,
|
||||||
onClick: (e) => { e.stopPropagation(); button.onClick(entry, index); },
|
onClick: (e) => { e.stopPropagation(); button.onClick(entry, index); },
|
||||||
className: "data-table-clickable",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button.hasOwnProperty("disabled")) {
|
if (button.hasOwnProperty("disabled")) {
|
||||||
@ -309,8 +308,8 @@ export class ControlsColumn extends DataColumn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <>
|
return <Box className={"data-table-buttons"}>
|
||||||
{buttonElements}
|
{buttonElements}
|
||||||
</>
|
</Box>
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,8 @@ export default function useAsyncSearch(callback, minLength = 1) {
|
|||||||
const [results, setResults] = useState(null);
|
const [results, setResults] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!searchString || searchString.length < minLength) {
|
console.log("searchString:", searchString);
|
||||||
|
if (minLength > 0 && (!searchString || searchString.length < minLength)) {
|
||||||
setResults([]);
|
setResults([]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {format, parse} from "date-fns";
|
import {format, parse, formatDistance as formatDistanceDateFns } from "date-fns";
|
||||||
import {API_DATE_FORMAT, API_DATETIME_FORMAT} from "./constants";
|
import {API_DATE_FORMAT, API_DATETIME_FORMAT} from "./constants";
|
||||||
|
|
||||||
function createDownload(name, data) {
|
function createDownload(name, data) {
|
||||||
@ -58,33 +58,36 @@ const getBaseUrl = () => {
|
|||||||
return window.location.protocol + "//" + window.location.host;
|
return window.location.protocol + "//" + window.location.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatDate = (L, apiDate) => {
|
const toDate = (apiDate, apiFormat = API_DATETIME_FORMAT) => {
|
||||||
if (!(apiDate instanceof Date)) {
|
if (apiDate === null) {
|
||||||
|
return "";
|
||||||
|
} else if (!(apiDate instanceof Date)) {
|
||||||
if (!isNaN(apiDate)) {
|
if (!isNaN(apiDate)) {
|
||||||
apiDate = new Date(apiDate * 1000);
|
apiDate = new Date(apiDate * 1000);
|
||||||
} else {
|
} else {
|
||||||
apiDate = parse(apiDate, API_DATE_FORMAT, new Date());
|
apiDate = parse(apiDate, apiFormat, new Date());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return format(apiDate, L("general.datefns_date_format", "YYY/MM/dd"));
|
return apiDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDate = (L, apiDate) => {
|
||||||
|
return format(toDate(apiDate), L("general.datefns_date_format", "YYY/MM/dd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatDateTime = (L, apiDate, precise=false) => {
|
const formatDateTime = (L, apiDate, precise=false) => {
|
||||||
if (!(apiDate instanceof Date)) {
|
|
||||||
if (!isNaN(apiDate)) {
|
|
||||||
apiDate = new Date(apiDate * 1000);
|
|
||||||
} else {
|
|
||||||
apiDate = parse(apiDate, API_DATETIME_FORMAT, new Date());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dateFormat = precise ?
|
let dateFormat = precise ?
|
||||||
L("general.datefns_date_time_format_precise", "YYY/MM/dd HH:mm:ss") :
|
L("general.datefns_datetime_format_precise", "YYY/MM/dd HH:mm:ss") :
|
||||||
L("general.datefns_date_time_format", "YYY/MM/dd HH:mm");
|
L("general.datefns_datetime_format", "YYY/MM/dd HH:mm");
|
||||||
return format(apiDate, dateFormat);
|
return format(toDate(apiDate), dateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatDistance(dateFns, apiDate) {
|
||||||
|
return formatDistanceDateFns(toDate(apiDate), new Date(), { addSuffix: true, locale: dateFns });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const upperFirstChars = (str) => {
|
const upperFirstChars = (str) => {
|
||||||
return str.split(" ")
|
return str.split(" ")
|
||||||
.map(block => block.charAt(0).toUpperCase() + block.substring(1))
|
.map(block => block.charAt(0).toUpperCase() + block.substring(1))
|
||||||
@ -97,5 +100,7 @@ const isInt = (value) => {
|
|||||||
!isNaN(parseInt(value, 10));
|
!isNaN(parseInt(value, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
export { humanReadableSize, removeParameter, getParameter, encodeText, decodeText, getBaseUrl,
|
export { humanReadableSize, removeParameter, getParameter,
|
||||||
formatDate, formatDateTime, upperFirstChars, isInt, createDownload };
|
encodeText, decodeText, getBaseUrl,
|
||||||
|
formatDate, formatDateTime, formatDistance,
|
||||||
|
upperFirstChars, isInt, createDownload };
|
@ -15,7 +15,6 @@ import React, {useCallback, useContext, useEffect, useState} from "react";
|
|||||||
import ReplayIcon from '@material-ui/icons/Replay';
|
import ReplayIcon from '@material-ui/icons/Replay';
|
||||||
import LanguageSelection from "../elements/language-selection";
|
import LanguageSelection from "../elements/language-selection";
|
||||||
import {decodeText, encodeText, getParameter, removeParameter} from "shared/util";
|
import {decodeText, encodeText, getParameter, removeParameter} from "shared/util";
|
||||||
import Icon from "shared/elements/icon";
|
|
||||||
import {LocaleContext} from "shared/locale";
|
import {LocaleContext} from "shared/locale";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
Loading…
Reference in New Issue
Block a user