Localization for routes and permissions, added compression for language/getEntries
This commit is contained in:
parent
12b8a0b386
commit
0e3d27fa10
@ -115,7 +115,8 @@ namespace Core\API\Language {
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, [
|
||||
"code" => new StringType("code", 5, true, NULL),
|
||||
"modules" => new ArrayType("modules", Parameter::TYPE_STRING, true, false)
|
||||
"modules" => new ArrayType("modules", Parameter::TYPE_STRING, true, false),
|
||||
"compression" => new StringType("compression", -1, true, NULL, ["gzip", "zlib"])
|
||||
]);
|
||||
$this->loginRequired = false;
|
||||
$this->csrfTokenRequired = false;
|
||||
@ -156,7 +157,23 @@ namespace Core\API\Language {
|
||||
}
|
||||
|
||||
$this->result["code"] = $code;
|
||||
|
||||
$compression = $this->getParam("compression");
|
||||
if ($compression) {
|
||||
switch ($compression) {
|
||||
case "gzip":
|
||||
$this->result["compressed"] = base64_encode(gzencode(json_encode($entries), 9));
|
||||
break;
|
||||
case "zlib":
|
||||
$this->result["compressed"] = base64_encode(gzcompress(json_encode($entries), 9, ZLIB_ENCODING_DEFLATE));
|
||||
break;
|
||||
default:
|
||||
http_response_code(400);
|
||||
return $this->createError("Invalid compression method: $compression");
|
||||
}
|
||||
} else {
|
||||
$this->result["entries"] = $entries;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ return [
|
||||
"cancel" => "Abbrechen",
|
||||
"confirm" => "Bestätigen",
|
||||
"add" => "Hinzufügen",
|
||||
"select" => "Auswählen",
|
||||
"ok" => "OK",
|
||||
"id" => "ID",
|
||||
"user" => "Benutzer",
|
||||
|
20
Core/Localization/de_DE/permissions.php
Normal file
20
Core/Localization/de_DE/permissions.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
"title" => "Berechtigungen",
|
||||
"title_short" => "ACL",
|
||||
"query" => "Suchanfrage",
|
||||
"add_permission" => "Berechtigung hinzufügen",
|
||||
"permission" => "Berechtigung",
|
||||
"everyone" => "Alle",
|
||||
"method" => "Methode",
|
||||
"description" => "Beschreibung",
|
||||
|
||||
# dialog
|
||||
"delete_permission_confirm" => "Diese Berechtigung wirklich löschen?",
|
||||
"edit_permission" => "Berechtigung bearbeiten",
|
||||
"update_permission_error" => "Fehler beim Aktualisieren der Berechtigung",
|
||||
"delete_permission_error" => "Fehler beim Löschen der Berechtigung",
|
||||
"fetch_permission_error" => "Fehler beim Holen der Berechtigungen",
|
||||
"fetch_group_error" => "Fehler beim Holen der Gruppen",
|
||||
];
|
41
Core/Localization/de_DE/routes.php
Normal file
41
Core/Localization/de_DE/routes.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
"title" => "Routen",
|
||||
"regenerating_cache" => "Lade Cache neu",
|
||||
"regenerate_cache" => "Cache neuladen",
|
||||
|
||||
# table
|
||||
"route" => "Route",
|
||||
"type" => "Typ",
|
||||
"target" => "Ziel",
|
||||
"extra" => "Extra",
|
||||
"active" => "Aktiv",
|
||||
"exact" => "Exakt",
|
||||
|
||||
# form
|
||||
"edit_route_title" => "Route bearbeiten",
|
||||
"create_route_title" => "Neue Route erstellen",
|
||||
"pattern" => "Pattern",
|
||||
"arguments" => "Argumente",
|
||||
"status_code" => "Status Code",
|
||||
"json_ok" => "JSON ok!",
|
||||
"json_err" => "Ungültiger JSON-string!",
|
||||
"json_not_object" => "Das JSON muss ein Array oder Objekt sein!",
|
||||
"validate_route" => "Route validieren",
|
||||
"validate_route_placeholder" => "Einen Pfad eingeben um die Route zu testen",
|
||||
|
||||
# data
|
||||
"type_dynamic" => "Dynamisch",
|
||||
"type_static" => "Statisch",
|
||||
"type_redirect_permanently" => "Dauerhaft weiterleiten",
|
||||
"type_redirect_temporary" => "Temporär weiterleiten",
|
||||
|
||||
# dialogs
|
||||
"fetch_routes_error" => "Fehler beim Holen der Routen",
|
||||
"enable_route_error" => "Fehler beim Aktivieren der Route",
|
||||
"disable_route_error" => "Fehler beim Deaktivieren der Route",
|
||||
"remove_route_error" => "Fehler beim Entfernen der Route",
|
||||
"regenerate_router_cache_error" => "Fehler beim Erzeugen des Router Caches",
|
||||
"regenerate_router_cache_success" => "Router Cache erfolgreich erzeugt",
|
||||
];
|
@ -30,6 +30,7 @@ return [
|
||||
"cancel" => "Cancel",
|
||||
"confirm" => "Confirm",
|
||||
"add" => "Add",
|
||||
"select" => "Select",
|
||||
"close" => "Close",
|
||||
"ok" => "OK",
|
||||
"id" => "ID",
|
||||
|
20
Core/Localization/en_US/permissions.php
Normal file
20
Core/Localization/en_US/permissions.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
"title" => "Permissions",
|
||||
"title_short" => "ACL",
|
||||
"query" => "Search query",
|
||||
"add_permission" => "Add permission",
|
||||
"permission" => "Permission",
|
||||
"everyone" => "Everyone",
|
||||
"method" => "Method",
|
||||
"description" => "Description",
|
||||
|
||||
# dialog
|
||||
"delete_permission_confirm" => "Do you really want to delete this permission?",
|
||||
"edit_permission" => "Edit Permission",
|
||||
"update_permission_error" => "Error updating permission",
|
||||
"delete_permission_error" => "Error deleting permission",
|
||||
"fetch_permission_error" => "Error fetching permissions",
|
||||
"fetch_group_error" => "Error fetching groups",
|
||||
];
|
41
Core/Localization/en_US/routes.php
Normal file
41
Core/Localization/en_US/routes.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
"title" => "Routes",
|
||||
"regenerating_cache" => "Regenerating Cache",
|
||||
"regenerate_cache" => "Regenerate Cache",
|
||||
|
||||
# table
|
||||
"route" => "Route",
|
||||
"type" => "Type",
|
||||
"target" => "Target",
|
||||
"extra" => "Extra",
|
||||
"active" => "Active",
|
||||
"exact" => "Exact",
|
||||
|
||||
# form
|
||||
"edit_route_title" => "Edit Route",
|
||||
"create_route_title" => "Create new Route",
|
||||
"pattern" => "Pattern",
|
||||
"arguments" => "Arguments",
|
||||
"status_code" => "Status Code",
|
||||
"json_ok" => "JSON ok!",
|
||||
"json_err" => "Invalid JSON-string!",
|
||||
"json_not_object" => "JSON must be Array or Object!",
|
||||
"validate_route" => "Validate Route",
|
||||
"validate_route_placeholder" => "Enter a path to test the route",
|
||||
|
||||
# data
|
||||
"type_dynamic" => "Dynamic",
|
||||
"type_static" => "Static",
|
||||
"type_redirect_permanently" => "Redirect permanently",
|
||||
"type_redirect_temporary" => "Redirect temporary",
|
||||
|
||||
# dialogs
|
||||
"fetch_routes_error" => "Error fetching routes",
|
||||
"enable_route_error" => "Error enabling route",
|
||||
"disable_route_error" => "Error disabling route",
|
||||
"remove_route_error" => "Error removing route",
|
||||
"regenerate_router_cache_error" => "Error regenerating router cache",
|
||||
"regenerate_router_cache_success" => "Router cache successfully regenerated",
|
||||
];
|
@ -45,13 +45,13 @@ export default function AccessControlList(props) {
|
||||
setFetchACL(false);
|
||||
props.api.fetchGroups().then(res => {
|
||||
if (!res.success) {
|
||||
props.showDialog(res.msg, "Error fetching groups");
|
||||
props.showDialog(res.msg, L("permissions.fetch_group_error"));
|
||||
navigate("/admin/dashboard");
|
||||
} else {
|
||||
setGroups(res.groups);
|
||||
props.api.fetchPermissions().then(res => {
|
||||
if (!res.success) {
|
||||
props.showDialog(res.msg, "Error fetching permissions");
|
||||
props.showDialog(res.msg, L("permissions.fetch_permission_error"));
|
||||
navigate("/admin/dashboard");
|
||||
} else {
|
||||
setACL(res.permissions);
|
||||
@ -67,7 +67,7 @@ export default function AccessControlList(props) {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
requestModules(props.api, ["general"], currentLocale).then(data => {
|
||||
requestModules(props.api, ["general", "permissions"], currentLocale).then(data => {
|
||||
if (!data.success) {
|
||||
props.showDialog("Error fetching translations: " + data.msg);
|
||||
}
|
||||
@ -103,7 +103,7 @@ export default function AccessControlList(props) {
|
||||
setACL(newACL);
|
||||
props.api.fetchUser();
|
||||
} else {
|
||||
props.showDialog("Error updating permission: " + data.msg);
|
||||
props.showDialog(data.msg, L("permissions.update_permission_error"));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -116,7 +116,7 @@ export default function AccessControlList(props) {
|
||||
setACL(newACL);
|
||||
props.api.fetchUser();
|
||||
} else {
|
||||
props.showDialog("Error deleting permission: " + data.msg);
|
||||
props.showDialog(data.msg, L("permissions.delete_permission_error"));
|
||||
}
|
||||
})
|
||||
}, [acl]);
|
||||
@ -130,7 +130,7 @@ export default function AccessControlList(props) {
|
||||
setACL(newACL);
|
||||
props.api.fetchUser();
|
||||
} else {
|
||||
props.showDialog("Error updating permission: " + data.msg);
|
||||
props.showDialog(data.msg, L("permissions.update_permission_error"));
|
||||
}
|
||||
})
|
||||
}, [acl]);
|
||||
@ -162,11 +162,11 @@ export default function AccessControlList(props) {
|
||||
disabled={isRestricted(permission.method)}
|
||||
onClick={() => setDialogData({
|
||||
open: true,
|
||||
title: L("Edit permission"),
|
||||
title: L("permissions.edit_permission"),
|
||||
inputs: [
|
||||
{ type: "label", value: L("general.method") + ":" },
|
||||
{ type: "label", value: L("permissions.method") + ":" },
|
||||
{ type: "text", name: "method", value: permission.method, disabled: true },
|
||||
{ type: "label", value: L("general.description") + ":" },
|
||||
{ type: "label", value: L("permissions.description") + ":" },
|
||||
{ type: "text", name: "description", value: permission.description, maxLength: 128 }
|
||||
],
|
||||
onOption: (option, inputData) => option === 0 && onUpdatePermission(inputData, permission.groups)
|
||||
@ -177,8 +177,8 @@ export default function AccessControlList(props) {
|
||||
disabled={isRestricted(permission.method)}
|
||||
onClick={() => setDialogData({
|
||||
open: true,
|
||||
title: L("Do you really want to delete this permission?"),
|
||||
message: "Method: " + permission.method,
|
||||
title: L("permissions.delete_permission_confirm"),
|
||||
message: L("permissions.method") + ": " + permission.method,
|
||||
onOption: (option) => option === 0 && onDeletePermission(permission.method)
|
||||
})} >
|
||||
<Delete />
|
||||
@ -212,12 +212,12 @@ export default function AccessControlList(props) {
|
||||
<div className={"container-fluid"}>
|
||||
<div className={"row mb-2"}>
|
||||
<div className={"col-sm-6"}>
|
||||
<h1 className={"m-0 text-dark"}>Access Control List</h1>
|
||||
<h1 className={"m-0 text-dark"}>{L("permissions.title")}</h1>
|
||||
</div>
|
||||
<div className={"col-sm-6"}>
|
||||
<ol className={"breadcrumb float-sm-right"}>
|
||||
<li className={"breadcrumb-item"}><Link to={"/admin/dashboard"}>Home</Link></li>
|
||||
<li className="breadcrumb-item active">ACL</li>
|
||||
<li className="breadcrumb-item active">{L("permissions.title_short")}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
@ -226,10 +226,10 @@ export default function AccessControlList(props) {
|
||||
<div className={"row"}>
|
||||
<div className={"col-6"}>
|
||||
<div className={"form-group"}>
|
||||
<label>{L("query")}</label>
|
||||
<label>{L("permissions.query")}</label>
|
||||
<TextField
|
||||
className={"form-control"}
|
||||
placeholder={L("search_query") + "…"}
|
||||
placeholder={L("permissions.query") + "…"}
|
||||
value={query}
|
||||
onChange={e => setQuery(e.target.value)}
|
||||
variant={"outlined"}
|
||||
@ -245,7 +245,7 @@ export default function AccessControlList(props) {
|
||||
<Button variant={"outlined"} className={"m-1"} startIcon={<Add />} disabled={!props.api.hasGroup(USER_GROUP_ADMIN)}
|
||||
onClick={() => setDialogData({
|
||||
open: true,
|
||||
title: L("Add permission"),
|
||||
title: L("permissions.add_permission"),
|
||||
inputs: [
|
||||
{ type: "label", value: L("general.method") + ":" },
|
||||
{ type: "text", name: "method", value: "", placeholder: L("general.method") },
|
||||
@ -263,8 +263,8 @@ export default function AccessControlList(props) {
|
||||
<Table stickyHeader size={"small"} className={"table-striped"}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>{L("permission")}</TableCell>
|
||||
<BorderedColumn align={"center"}><i>{L("everyone")}</i></BorderedColumn>
|
||||
<TableCell>{L("permissions.permission")}</TableCell>
|
||||
<BorderedColumn align={"center"}><i>{L("permissions.everyone")}</i></BorderedColumn>
|
||||
{ groups.map(group => <TableCell key={"group-" + group.id} align={"center"}>
|
||||
{group.name}
|
||||
</TableCell>) }
|
||||
|
@ -48,7 +48,7 @@ export default function RouteEditView(props) {
|
||||
const [isSaving, setSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
requestModules(props.api, ["general"], currentLocale).then(data => {
|
||||
requestModules(props.api, ["general", "routes"], currentLocale).then(data => {
|
||||
if (!data.success) {
|
||||
props.showDialog("Error fetching translations: " + data.msg);
|
||||
}
|
||||
@ -122,15 +122,13 @@ export default function RouteEditView(props) {
|
||||
<div className={"container-fluid"}>
|
||||
<ol className={"breadcrumb"}>
|
||||
<li className={"breadcrumb-item"}><Link to={"/admin/dashboard"}>Home</Link></li>
|
||||
<li className="breadcrumb-item active"><Link to={"/admin/routes"}>Routes</Link></li>
|
||||
<li className="breadcrumb-item active">{isNewRoute ? "New" : "Edit"}</li>
|
||||
<li className="breadcrumb-item active"><Link to={"/admin/routes"}>{L("routes.title")}</Link></li>
|
||||
<li className="breadcrumb-item active">{isNewRoute ? L("general.new") : L("general.edit")}</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div className={"content"}>
|
||||
<div className={"container-fluid"}>
|
||||
<h3>{L(isNewRoute ? "Create new Route" : "Edit Route")}</h3>
|
||||
<div className={"col-sm-12 col-lg-6"}>
|
||||
</div>
|
||||
<h3>{L(isNewRoute ? "routes.create_route_title" : "routes.edit_route_title")}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<RouteForm route={route} setRoute={setRoute} />
|
||||
@ -147,10 +145,10 @@ export default function RouteEditView(props) {
|
||||
</Button>
|
||||
</ButtonBar>
|
||||
<Box mt={3}>
|
||||
<h5>{L("Validate Route")}</h5>
|
||||
<h5>{L("routes.validate_route")}</h5>
|
||||
<MonoSpaceTextField value={routeTest} onChange={e => setRouteTest(e.target.value)}
|
||||
variant={"outlined"} size={"small"} fullWidth={true}
|
||||
placeholder={L("Enter a path to test the route…")} />
|
||||
placeholder={L("routes.validate_route_placeholder") + "…"} />
|
||||
<pre>
|
||||
Match: {JSON.stringify(routeTestResult)}
|
||||
</pre>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Box, Checkbox, FormControl, FormControlLabel, FormGroup, Select, styled, TextField} from "@material-ui/core";
|
||||
import {Checkbox, FormControl, FormControlLabel, Select, styled, TextField} from "@material-ui/core";
|
||||
import * as React from "react";
|
||||
import {useCallback, useContext, useEffect, useRef} from "react";
|
||||
import {LocaleContext} from "shared/locale";
|
||||
@ -38,30 +38,30 @@ export default function RouteForm(props) {
|
||||
|
||||
const elements = [
|
||||
<RouteFormControl key={"form-control-pattern"} fullWidth={true}>
|
||||
<label htmlFor={"route-pattern"}>{L("Pattern")}</label>
|
||||
<label htmlFor={"route-pattern"}>{L("routes.pattern")}</label>
|
||||
<TextField id={"route-pattern"} variant={"outlined"} size={"small"}
|
||||
value={route.pattern}
|
||||
onChange={e => setRoute({...route, pattern: e.target.value})} />
|
||||
</RouteFormControl>,
|
||||
<FormGroup key={"form-control-exact"}>
|
||||
<FormControlLabel label={L("Exact")} control={<Checkbox
|
||||
<RouteFormControl key={"form-control-exact"}>
|
||||
<FormControlLabel label={L("routes.exact")} control={<Checkbox
|
||||
checked={route.exact}
|
||||
onChange={e => setRoute({...route, exact: e.target.checked})} />} />
|
||||
</FormGroup>,
|
||||
<FormGroup key={"form-control-active"}>
|
||||
<FormControlLabel label={L("Active")} control={<Checkbox
|
||||
</RouteFormControl>,
|
||||
<RouteFormControl key={"form-control-active"}>
|
||||
<FormControlLabel label={L("routes.active")} control={<Checkbox
|
||||
checked={route.active}
|
||||
onChange={e => setRoute({...route, active: e.target.checked})} />} />
|
||||
</FormGroup>,
|
||||
</RouteFormControl>,
|
||||
<RouteFormControl key={"form-control-type"} fullWidth={true} size={"small"}>
|
||||
<label htmlFor={"route-type"}>{L("Type")}</label>
|
||||
<label htmlFor={"route-type"}>{L("routes.type")}</label>
|
||||
<Select value={route.type} variant={"outlined"} size={"small"} labelId={"route-type"}
|
||||
onChange={e => onChangeRouteType(e.target.value)} native>
|
||||
<option value={""}>Select…</option>
|
||||
<option value={"dynamic"}>Dynamic</option>
|
||||
<option value={"static"}>Static</option>
|
||||
<option value={"redirect_permanently"}>Redirect Permanently</option>
|
||||
<option value={"redirect_temporary"}>Redirect Temporary</option>
|
||||
<option value={""}>{L("general.select")}…</option>
|
||||
<option value={"dynamic"}>{L("routes.type_dynamic")}</option>
|
||||
<option value={"static"}>{L("routes.type_static")}</option>
|
||||
<option value={"redirect_permanently"}>{L("routes.type_redirect_permanently")}</option>
|
||||
<option value={"redirect_temporary"}>{L("routes.type_redirect_temporary")}</option>
|
||||
</Select>
|
||||
</RouteFormControl>,
|
||||
];
|
||||
@ -77,7 +77,7 @@ export default function RouteForm(props) {
|
||||
if (route.type) {
|
||||
elements.push(
|
||||
<RouteFormControl key={"form-control-target"} fullWidth={true}>
|
||||
<label htmlFor={"route-target"}>{L("Target")}</label>
|
||||
<label htmlFor={"route-target"}>{L("routes.target")}</label>
|
||||
<TextField id={"route-target"} variant={"outlined"} size={"small"}
|
||||
value={route.target}
|
||||
onChange={e => setRoute({...route, target: e.target.value})}/>
|
||||
@ -95,23 +95,22 @@ export default function RouteForm(props) {
|
||||
}
|
||||
elements.push(
|
||||
<RouteFormControl key={"form-control-extra"} fullWidth={true}>
|
||||
<label htmlFor={"route-extra"}>{L("Arguments")}</label>
|
||||
<label htmlFor={"route-extra"}>{L("routes.arguments")}</label>
|
||||
<textarea id={"route-extra"}
|
||||
ref={extraRef}
|
||||
value={extraArgs ?? route.extra}
|
||||
onChange={e => setRoute({...route, extra: minifyJson(e.target.value)})}/>
|
||||
<i>{
|
||||
extraArgs === null ?
|
||||
"Invalid JSON-string" :
|
||||
(type !== "object" ?
|
||||
"JSON must be Array or Object" : "JSON ok!")
|
||||
L("routes.json_err") :
|
||||
(type !== "object" ? L("routes.json_not_obj") : L("routes.json_ok"))
|
||||
}</i>
|
||||
</RouteFormControl>
|
||||
);
|
||||
} else if (route.type === "static") {
|
||||
elements.push(
|
||||
<RouteFormControl key={"form-control-extra"} fullWidth={true}>
|
||||
<label htmlFor={"route-extra"}>{L("Status Code")}</label>
|
||||
<label htmlFor={"route-extra"}>{L("routes.status_code")}</label>
|
||||
<TextField id={"route-extra"} variant={"outlined"} size={"small"}
|
||||
type={"number"} value={route.extra}
|
||||
onChange={e => setRoute({...route, extra: parseInt(e.target.value) || 200})} />
|
||||
|
@ -42,7 +42,7 @@ export default function RouteListView(props) {
|
||||
setFetchRoutes(false);
|
||||
props.api.fetchRoutes().then(res => {
|
||||
if (!res.success) {
|
||||
props.showDialog(res.msg, "Error fetching routes");
|
||||
props.showDialog(res.msg, L("routes.fetch_routes_error"));
|
||||
navigate("/admin/dashboard");
|
||||
} else {
|
||||
setRoutes(res.routes);
|
||||
@ -56,7 +56,7 @@ export default function RouteListView(props) {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
requestModules(props.api, ["general"], currentLocale).then(data => {
|
||||
requestModules(props.api, ["general", "routes"], currentLocale).then(data => {
|
||||
if (!data.success) {
|
||||
props.showDialog("Error fetching translations: " + data.msg);
|
||||
}
|
||||
@ -67,7 +67,7 @@ export default function RouteListView(props) {
|
||||
if (active) {
|
||||
props.api.enableRoute(id).then(data => {
|
||||
if (!data.success) {
|
||||
props.showDialog(data.msg, L("Error enabling route"));
|
||||
props.showDialog(data.msg, L("routes.enable_route_error"));
|
||||
} else {
|
||||
setRoutes({...routes, [id]: { ...routes[id], active: true }});
|
||||
}
|
||||
@ -75,7 +75,7 @@ export default function RouteListView(props) {
|
||||
} else {
|
||||
props.api.disableRoute(id).then(data => {
|
||||
if (!data.success) {
|
||||
props.showDialog(data.msg, L("Error enabling route"));
|
||||
props.showDialog(data.msg, L("routes.disable_route_error"));
|
||||
} else {
|
||||
setRoutes({...routes, [id]: { ...routes[id], active: false }});
|
||||
}
|
||||
@ -86,7 +86,7 @@ export default function RouteListView(props) {
|
||||
const onDeleteRoute = useCallback(id => {
|
||||
props.api.deleteRoute(id).then(data => {
|
||||
if (!data.success) {
|
||||
props.showDialog(data.msg, L("Error removing route"));
|
||||
props.showDialog(data.msg, L("routes.remove_route_error"));
|
||||
} else {
|
||||
let newRoutes = { ...routes };
|
||||
delete newRoutes[id];
|
||||
@ -100,13 +100,13 @@ export default function RouteListView(props) {
|
||||
setGeneratingCache(true);
|
||||
props.api.regenerateRouterCache().then(data => {
|
||||
if (!data.success) {
|
||||
props.showDialog(data.msg, L("Error regenerating router cache"));
|
||||
props.showDialog(data.msg, L("routes.regenerate_router_cache_error"));
|
||||
setGeneratingCache(false);
|
||||
} else {
|
||||
setDialogData({
|
||||
open: true,
|
||||
title: L("general.success"),
|
||||
message: L("Router cache successfully regenerated"),
|
||||
message: L("routes.regenerate_router_cache_success"),
|
||||
onClose: () => setGeneratingCache(false)
|
||||
})
|
||||
}
|
||||
@ -121,12 +121,12 @@ export default function RouteListView(props) {
|
||||
<div className={"container-fluid"}>
|
||||
<div className={"row mb-2"}>
|
||||
<div className={"col-sm-6"}>
|
||||
<h1 className={"m-0 text-dark"}>Routes</h1>
|
||||
<h1 className={"m-0 text-dark"}>{L("routes.title")}</h1>
|
||||
</div>
|
||||
<div className={"col-sm-6"}>
|
||||
<ol className={"breadcrumb float-sm-right"}>
|
||||
<li className={"breadcrumb-item"}><Link to={"/admin/dashboard"}>Home</Link></li>
|
||||
<li className="breadcrumb-item active">Routes</li>
|
||||
<li className="breadcrumb-item active">{L("routes.title")}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
@ -147,7 +147,7 @@ export default function RouteListView(props) {
|
||||
<Button variant={"outlined"} className={"m-1"} startIcon={<Cached />}
|
||||
disabled={!props.api.hasPermission("routes/generateCache") || isGeneratingCache}
|
||||
onClick={onRegenerateCache} >
|
||||
{isGeneratingCache ? L("regenerating_cache") + "…" : L("regenerate_cache")}
|
||||
{isGeneratingCache ? L("routes.regenerating_cache") + "…" : L("routes.regenerate_cache")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -157,12 +157,12 @@ export default function RouteListView(props) {
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>{L("general.id")}</TableCell>
|
||||
<TableCell>{L("Route")}</TableCell>
|
||||
<TableCell>{L("Type")}</TableCell>
|
||||
<TableCell>{L("Target")}</TableCell>
|
||||
<TableCell>{L("Extra")}</TableCell>
|
||||
<TableCell align={"center"}>{L("Active")}</TableCell>
|
||||
<TableCell align={"center"}>{L("Exact")}</TableCell>
|
||||
<TableCell>{L("routes.route")}</TableCell>
|
||||
<TableCell>{L("routes.type")}</TableCell>
|
||||
<TableCell>{L("routes.target")}</TableCell>
|
||||
<TableCell>{L("routes.extra")}</TableCell>
|
||||
<TableCell align={"center"}>{L("routes.active")}</TableCell>
|
||||
<TableCell align={"center"}>{L("routes.exact")}</TableCell>
|
||||
<TableCell align={"center"}>{L("general.controls")}</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
|
@ -45,6 +45,7 @@
|
||||
"date-fns": "^2.29.3",
|
||||
"material-ui-color-picker": "^3.5.1",
|
||||
"mini-css-extract-plugin": "^2.7.1",
|
||||
"pako": "^2.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^5.0.1",
|
||||
"react-collapse": "^5.1.1",
|
||||
|
@ -308,12 +308,12 @@ export default class API {
|
||||
return res;
|
||||
}
|
||||
|
||||
async getLanguageEntries(modules, code=null, useCache=false) {
|
||||
async getLanguageEntries(modules, code=null, compression=null) {
|
||||
if (!Array.isArray(modules)) {
|
||||
modules = [modules];
|
||||
}
|
||||
|
||||
return this.apiCall("language/getEntries", {code: code, modules: modules});
|
||||
return this.apiCall("language/getEntries", {code: code, modules: modules, compression: compression});
|
||||
}
|
||||
|
||||
/** ApiKeyAPI **/
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React, {useReducer} from 'react';
|
||||
import {createContext, useCallback, useState} from "react";
|
||||
import { enUS as dateFnsEN, de as dateFnsDE } from 'date-fns/locale';
|
||||
import {getCookie, getParameter} from "./util";
|
||||
import {encodeText, getCookie, getParameter} from "./util";
|
||||
import pako from "pako";
|
||||
|
||||
const LocaleContext = createContext(null);
|
||||
|
||||
@ -109,7 +110,13 @@ function LocaleProvider(props) {
|
||||
}
|
||||
|
||||
if (modules.length > 0) {
|
||||
let data = await api.apiCall("language/getEntries", { code: code, modules: modules });
|
||||
let compression = "zlib";
|
||||
|
||||
let data = await api.getLanguageEntries(modules, code, compression);
|
||||
|
||||
if (compression && data.success) {
|
||||
data.entries = JSON.parse(pako.inflate(encodeText(atob(data.compressed)), { to: 'string' }));
|
||||
}
|
||||
|
||||
if (useCache) {
|
||||
if (data && data.success) {
|
||||
|
@ -4858,11 +4858,6 @@ date-fns@^2.29.3:
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.21.0"
|
||||
|
||||
dayjs@^1.11.10:
|
||||
version "1.11.10"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
|
||||
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
|
||||
|
||||
debug@2.6.9, debug@^2.6.0:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
@ -8392,6 +8387,11 @@ p-try@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||
|
||||
pako@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86"
|
||||
integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==
|
||||
|
||||
param-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
|
||||
|
Loading…
Reference in New Issue
Block a user