Merge pull request #691 from BeryJu/web-intl

This commit is contained in:
Jens L 2021-04-03 21:32:57 +02:00 committed by GitHub
commit e8dc6b259f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
165 changed files with 11779 additions and 2071 deletions

View File

@ -1,10 +1,8 @@
"""authentik api urls"""
from django.urls import include, path
from django.views.i18n import JavaScriptCatalog
from authentik.api.v2.urls import urlpatterns as v2_urls
urlpatterns = [
path("v2beta/", include(v2_urls)),
path("jsi18n/", JavaScriptCatalog.as_view(), name="javascript-catalog"),
]

View File

@ -61,23 +61,23 @@ class UserMetricsSerializer(PassiveSerializer):
@swagger_serializer_method(serializer_or_field=CoordinateSerializer(many=True))
def get_logins_per_1h(self, _):
"""Get successful logins per hour for the last 24 hours"""
request = self.context["request"]._request
return get_events_per_1h(action=EventAction.LOGIN, user__pk=request.user.pk)
user = self.context["user"]
return get_events_per_1h(action=EventAction.LOGIN, user__pk=user.pk)
@swagger_serializer_method(serializer_or_field=CoordinateSerializer(many=True))
def get_logins_failed_per_1h(self, _):
"""Get failed logins per hour for the last 24 hours"""
request = self.context["request"]._request
user = self.context["user"]
return get_events_per_1h(
action=EventAction.LOGIN_FAILED, context__username=request.user.username
action=EventAction.LOGIN_FAILED, context__username=user.username
)
@swagger_serializer_method(serializer_or_field=CoordinateSerializer(many=True))
def get_authorizations_per_1h(self, _):
"""Get failed logins per hour for the last 24 hours"""
request = self.context["request"]._request
user = self.context["user"]
return get_events_per_1h(
action=EventAction.AUTHORIZE_APPLICATION, user__pk=request.user.pk
action=EventAction.AUTHORIZE_APPLICATION, user__pk=user.pk
)
@ -109,11 +109,13 @@ class UserViewSet(ModelViewSet):
@permission_required("authentik_core.view_user", ["authentik_events.view_event"])
@swagger_auto_schema(responses={200: UserMetricsSerializer(many=False)})
@action(detail=False, pagination_class=None, filter_backends=[])
def metrics(self, request: Request) -> Response:
@action(detail=True, pagination_class=None, filter_backends=[])
# pylint: disable=invalid-name, unused-argument
def metrics(self, request: Request, pk: int) -> Response:
"""User metrics per 1h"""
user: User = self.get_object()
serializer = UserMetricsSerializer(True)
serializer.context["request"] = request
serializer.context["user"] = user
return Response(serializer.data)
@permission_required("authentik_core.reset_user_password")

View File

@ -12,8 +12,7 @@
<link rel="shortcut icon" type="image/png" href="{% static 'dist/assets/icons/icon.png' %}?v={{ ak_version }}">
<link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly.min.css' %}?v={{ ak_version }}">
<link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}?v={{ ak_version }}">
<script src="{% url 'authentik_api:javascript-catalog' %}?v={{ ak_version }}"></script>
<script src="{% static 'dist/adoptedStyleSheets.js' %}?v={{ ak_version }}" type="module"></script>
<script src="{% static 'dist/poly.js' %}?v={{ ak_version }}" type="module"></script>
{% block head %}
{% endblock %}
</head>

View File

@ -1,5 +1,4 @@
"""NotificationTransport API Views"""
from django.http.response import Http404
from drf_yasg.utils import no_body, swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.fields import CharField, ListField, SerializerMethodField
@ -68,10 +67,7 @@ class NotificationTransportViewSet(ModelViewSet):
def test(self, request: Request, pk=None) -> Response:
"""Send example notification using selected transport. Requires
Modify permissions."""
transports = self.get_object()
if not transports.exists():
raise Http404
transport: NotificationTransport = transports.first()
transport: NotificationTransport = self.get_object()
notification = Notification(
severity=NotificationSeverity.NOTICE,
body=f"Test Notification from transport {transport.name}",

View File

@ -109,14 +109,14 @@ class PolicyViewSet(
)
return Response(TypeCreateSerializer(data, many=True).data)
@permission_required("authentik_policies.view_policy_cache")
@permission_required(None, ["authentik_policies.view_policy_cache"])
@swagger_auto_schema(responses={200: CacheSerializer(many=False)})
@action(detail=False, pagination_class=None, filter_backends=[])
def cache_info(self, request: Request) -> Response:
"""Info about cached policies"""
return Response(data={"count": len(cache.keys("policy_*"))})
@permission_required("authentik_policies.clear_policy_cache")
@permission_required(None, ["authentik_policies.clear_policy_cache"])
@swagger_auto_schema(
request_body=no_body,
responses={204: "Successfully cleared cache", 400: "Bad request"},

View File

@ -2087,23 +2087,6 @@ paths:
tags:
- core
parameters: []
/core/users/metrics/:
get:
operationId: core_users_metrics
description: User metrics per 1h
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/UserMetrics'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags:
- core
parameters: []
/core/users/{id}/:
get:
operationId: core_users_read
@ -2207,6 +2190,33 @@ paths:
description: A unique integer value identifying this User.
required: true
type: integer
/core/users/{id}/metrics/:
get:
operationId: core_users_metrics
description: User metrics per 1h
parameters: []
responses:
'200':
description: ''
schema:
$ref: '#/definitions/UserMetrics'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404':
description: Object does not exist or caller has insufficient permissions
to access it.
schema:
$ref: '#/definitions/APIException'
tags:
- core
parameters:
- name: id
in: path
description: A unique integer value identifying this User.
required: true
type: integer
/core/users/{id}/recovery/:
get:
operationId: core_users_recovery

27
web/.babelrc Normal file
View File

@ -0,0 +1,27 @@
{
"presets": [
"@babel/env",
"@babel/typescript"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"decoratorsBeforeExport": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
],
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
],
"macros"
]
}

3153
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,51 +4,81 @@
"private": true,
"license": "GNU GPLv3",
"scripts": {
"build": "rollup -c ./rollup.config.js",
"watch": "rollup -c -w",
"extract": "lingui extract",
"build": "lingui compile && rollup -c ./rollup.config.js",
"watch": "lingui compile && rollup -c -w",
"lint": "eslint . --max-warnings 0",
"lit-analyse": "lit-analyzer src"
},
"lingui": {
"sourceLocale": "en",
"locales": ["en", "pseudo-LOCALE"],
"pseudoLocale": "pseudo-LOCALE",
"fallbackLocales": {
"pseudo-LOCALE": "en"
},
"compileNamespace": "ts",
"catalogs": [
{
"path": "src/locales/{locale}",
"include": [
"src"
],
"exclude": [
"**/node_modules/**",
"**/dist/**"
]
}
]
},
"dependencies": {
"@babel/core": "^7.13.14",
"@babel/plugin-proposal-decorators": "^7.13.5",
"@babel/plugin-transform-runtime": "^7.13.10",
"@babel/preset-env": "^7.13.12",
"@babel/preset-typescript": "^7.13.0",
"@fortawesome/fontawesome-free": "^5.15.3",
"@lingui/cli": "^3.8.2",
"@lingui/core": "^3.8.2",
"@lingui/macro": "^3.8.2",
"@patternfly/patternfly": "^4.96.2",
"@polymer/iron-form": "^3.0.1",
"@polymer/paper-input": "^3.2.1",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-replace": "^2.4.2",
"@rollup/plugin-typescript": "^8.2.1",
"@sentry/browser": "^6.2.5",
"@sentry/tracing": "^6.2.5",
"@types/chart.js": "^2.9.31",
"@types/codemirror": "0.0.108",
"@types/grecaptcha": "^3.0.1",
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"authentik-api": "file:api",
"babel-plugin-macros": "^3.0.1",
"base64-js": "^1.5.1",
"chart.js": "^2.9.4",
"codemirror": "^5.60.0",
"construct-style-sheets-polyfill": "^2.4.16",
"eslint-config-google": "^0.14.0",
"eslint-plugin-lit": "^1.3.0",
"eslint": "^7.23.0",
"flowchart.js": "^1.15.0",
"lit-element": "^2.4.0",
"lit-html": "^1.3.0",
"rapidoc": "^8.4.9",
"rollup": "^2.44.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-cssimport": "^1.0.2",
"rollup-plugin-external-globals": "^0.6.1",
"tslib": "^2.1.0",
"webcomponent-qr-code": "^1.0.5",
"yaml": "^1.10.2"
},
"devDependencies": {
"@rollup/plugin-typescript": "^8.2.1",
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"eslint": "^7.23.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-lit": "^1.3.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-minify-html-literals": "^1.2.6",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-sourcemaps": "^0.6.3",
"rollup-plugin-terser": "^7.0.2",
"rollup": "^2.44.0",
"ts-lit-plugin": "^1.2.1",
"typescript": "^4.2.3"
"tslib": "^2.1.0",
"typescript": "^4.2.3",
"webcomponent-qr-code": "^1.0.5",
"yaml": "^1.10.2"
}
}

View File

@ -5,7 +5,12 @@ import sourcemaps from "rollup-plugin-sourcemaps";
import typescript from "@rollup/plugin-typescript";
import cssimport from "rollup-plugin-cssimport";
import copy from "rollup-plugin-copy";
import externalGlobals from "rollup-plugin-external-globals";
import babel from "@rollup/plugin-babel";
import replace from "@rollup/plugin-replace";
const extensions = [
".js", ".jsx", ".ts", ".tsx",
];
const resources = [
{ src: "node_modules/rapidoc/dist/rapidoc-min.js", dest: "dist/" },
@ -26,6 +31,11 @@ const resources = [
const isProdBuild = process.env.NODE_ENV === "production";
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function manualChunks(id) {
if (id.includes("locales")) {
const parts = id.split("/");
const file = parts[parts.length - 1];
return "locale-" + file.replace(".ts", "");
}
if (id.includes("node_modules")) {
if (id.includes("codemirror")) {
return "vendor-cm";
@ -67,20 +77,15 @@ export default [
],
output: [
{
format: "es",
dir: "dist",
format: "iife",
file: "dist/poly.js",
sourcemap: true,
}
],
plugins: [
cssimport(),
typescript(),
externalGlobals({
django: "django",
}),
resolve({ browser: true }),
commonjs(),
sourcemaps(),
isProdBuild && terser(),
].filter(p => p),
watch: {
@ -100,19 +105,23 @@ export default [
],
plugins: [
cssimport(),
typescript(),
externalGlobals({
django: "django",
}),
resolve({ browser: true }),
resolve({ extensions, browser: true }),
commonjs(),
babel({
extensions,
babelHelpers: "runtime",
include: ["src/**/*"],
}),
replace({
"process.env.NODE_ENV": JSON.stringify(isProdBuild ? "production" : "development"),
preventAssignment: true
}),
sourcemaps(),
isProdBuild && terser(),
].filter(p => p),
watch: {
clearScreen: false,
},
external: ["django"]
},
// Flow executor
{
@ -127,18 +136,22 @@ export default [
],
plugins: [
cssimport(),
typescript(),
externalGlobals({
django: "django"
}),
resolve({ browser: true }),
resolve({ extensions, browser: true }),
commonjs(),
babel({
extensions,
babelHelpers: "runtime",
include: ["src/**/*"],
}),
replace({
"process.env.NODE_ENV": JSON.stringify(isProdBuild ? "production" : "development"),
preventAssignment: true
}),
sourcemaps(),
isProdBuild && terser(),
].filter(p => p),
watch: {
clearScreen: false,
},
external: ["django"]
},
];

10
web/src/django.d.ts vendored
View File

@ -1,10 +0,0 @@
declare module "django" {
export = django;
}
declare namespace django {
function gettext(name: string): string;
function ngettext(singular: string, plural: string, count: number): string;
function gettext_noop(msgid: string): string;
function pgettext(context: string, msgid: string): string;
function interpolate(fmt: string, obj: unknown, named: boolean): string;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import PFExpandableSection from "../../node_modules/@patternfly/patternfly/components/ExpandableSection/expandable-section.css";
@ -26,7 +26,7 @@ export class Expand extends LitElement {
<span class="pf-c-expandable-section__toggle-icon">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
<span class="pf-c-expandable-section__toggle-text">${gettext(this.expanded ? this.textOpen : this.textClosed)}</span>
<span class="pf-c-expandable-section__toggle-text">${this.expanded ? t`${this.textOpen}` : t`${this.textClosed}`}</span>
</button>
<slot ?hidden=${!this.expanded} class="pf-c-expandable-section__content"></slot>
</div>`;

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { LitElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
@ -15,9 +15,9 @@ export abstract class Page extends LitElement {
<div class="pf-c-content">
<h1>
<i class="${this.pageIcon()}"></i>
${gettext(this.pageTitle())}
${t`${this.pageTitle()}`}
</h1>
${description ? html`<p>${gettext(description)}</p>` : html``}
${description ? html`<p>${t`${description}`}</p>` : html``}
</div>
</section>
${this.renderContent()}`;

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import PFSpinner from "@patternfly/patternfly/components/Spinner/spinner.css";
@ -22,7 +22,7 @@ export class Spinner extends LitElement {
return html`<span
class="pf-c-spinner ${this.size.toString()}"
role="progressbar"
aria-valuetext="${gettext("Loading...")}">
aria-valuetext="${t`Loading...`}">
<span class="pf-c-spinner__clipper"></span>
<span class="pf-c-spinner__lead-ball"></span>
<span class="pf-c-spinner__tail-ball"></span>

View File

@ -4,7 +4,7 @@ import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css";
import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import AKGlobal from "../authentik.css";
import { CURRENT_CLASS } from "../constants";
import { gettext } from "django";
import { t } from "@lingui/macro";
@customElement("ak-tabs")
export class Tabs extends LitElement {
@ -62,7 +62,7 @@ export class Tabs extends LitElement {
const pages = Array.from(this.querySelectorAll("[slot^='page-']"));
if (!this.currentPage) {
if (pages.length < 1) {
return html`<h1>${gettext("no tabs defined")}</h1>`;
return html`<h1>${t`no tabs defined`}</h1>`;
}
this.currentPage = pages[0].attributes.getNamedItem("slot")?.value;
}

View File

@ -1,4 +1,3 @@
import { gettext } from "django";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { ifDefined } from "lit-html/directives/if-defined";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
@ -47,7 +46,7 @@ export class AggregateCard extends LitElement {
return html`<div class="pf-c-card pf-c-card-aggregate">
<div class="pf-c-card__header pf-l-flex pf-m-justify-content-space-between">
<div class="pf-c-card__header-main">
<i class="${ifDefined(this.icon)}"></i> ${this.header ? gettext(this.header) : ""}
<i class="${ifDefined(this.icon)}"></i> ${this.header ? this.header : ""}
</div>
${this.renderHeaderLink()}
</div>

View File

@ -1,4 +1,4 @@
import { customElement } from "lit-element";
import { customElement, property } from "lit-element";
import Chart from "chart.js";
import { CoreApi, UserMetrics } from "authentik-api";
import { AKChart } from "./Chart";
@ -7,8 +7,13 @@ import { DEFAULT_CONFIG } from "../../api/Config";
@customElement("ak-charts-user")
export class UserChart extends AKChart<UserMetrics> {
@property({type: Number})
userId?: number;
apiRequest(): Promise<UserMetrics> {
return new CoreApi(DEFAULT_CONFIG).coreUsersMetrics();
return new CoreApi(DEFAULT_CONFIG).coreUsersMetrics({
id: this.userId || 0,
});
}
getDatasets(data: UserMetrics): Chart.ChartDataSets[] {

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../table/Table";
@ -44,10 +44,10 @@ export class ObjectChangelog extends Table<Event> {
columns(): TableColumn[] {
return [
new TableColumn("Action", "action"),
new TableColumn("User", "enabled"),
new TableColumn("Creation Date", "created"),
new TableColumn("Client IP", "client_ip"),
new TableColumn(t`Action`, t`action`),
new TableColumn(t`User`, t`enabled`),
new TableColumn(t`Creation Date`, t`created`),
new TableColumn(t`Client IP`, t`client_ip`),
];
}
@ -56,7 +56,7 @@ export class ObjectChangelog extends Table<Event> {
html`${item.action}`,
html`<div>${item.user?.username}</div>
${item.user.on_behalf_of ? html`<small>
${gettext(`On behalf of ${item.user.on_behalf_of.username}`)}
${t`On behalf of ${item.user.on_behalf_of.username}`}
</small>` : html``}`,
html`<span>${item.created?.toLocaleString()}</span>`,
html`<span>${item.clientIp}</span>`,
@ -76,9 +76,9 @@ export class ObjectChangelog extends Table<Event> {
}
renderEmpty(): TemplateResult {
return super.renderEmpty(html`<ak-empty-state header=${gettext("No Events found.")} icon="pf-icon-module">
return super.renderEmpty(html`<ak-empty-state header=${t`No Events found.`} icon="pf-icon-module">
<div slot="body">
${gettext("No matching events could be found.")}
${t`No matching events could be found.`}
</div>
</ak-empty-state>`);
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { EVENT_REFRESH } from "../../constants";
import { ModalButton } from "../buttons/ModalButton";
@ -37,14 +37,14 @@ export class ConfirmationForm extends ModalButton {
onSuccess(): void {
showMessage({
message: gettext(this.successMessage),
message: this.successMessage,
level: MessageLevel.success,
});
}
onError(e: Error): void {
showMessage({
message: gettext(`${this.errorMessage}: ${e.toString()}`),
message: t`${this.errorMessage}: ${e.toString()}`,
level: MessageLevel.error,
});
}
@ -76,14 +76,14 @@ export class ConfirmationForm extends ModalButton {
this.confirm();
}}
class="pf-m-danger">
${gettext(this.action)}
${this.action}
</ak-spinner-button>&nbsp;
<ak-spinner-button
.callAction=${() => {
this.open = false;
}}
class="pf-m-secondary">
${gettext("Cancel")}
${t`Cancel`}
</ak-spinner-button>
</footer>`;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { EVENT_REFRESH } from "../../constants";
import { ModalButton } from "../buttons/ModalButton";
@ -35,14 +35,14 @@ export class DeleteForm extends ModalButton {
onSuccess(): void {
showMessage({
message: gettext(`Successfully deleted ${this.objectLabel} ${ this.obj?.name }`),
message: t`Successfully deleted ${this.objectLabel} ${ this.obj?.name }`,
level: MessageLevel.success,
});
}
onError(e: Error): void {
showMessage({
message: gettext(`Failed to delete ${this.objectLabel}: ${e.toString()}`),
message: t`Failed to delete ${this.objectLabel}: ${e.toString()}`,
level: MessageLevel.error,
});
}
@ -51,7 +51,7 @@ export class DeleteForm extends ModalButton {
return html`<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1 class="pf-c-title pf-m-2xl">
${gettext(`Delete ${this.objectLabel}`)}
${t`Delete ${this.objectLabel}`}
</h1>
</div>
</section>
@ -62,9 +62,7 @@ export class DeleteForm extends ModalButton {
<div class="pf-c-card__body">
<form class="pf-c-form pf-m-horizontal">
<p>
${gettext(
`Are you sure you want to delete ${this.objectLabel} '${this.obj?.name}'?`
)}
${t`Are you sure you want to delete ${this.objectLabel} '${this.obj?.name}'?`}
</p>
</form>
</div>
@ -78,14 +76,14 @@ export class DeleteForm extends ModalButton {
this.confirm();
}}
class="pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</ak-spinner-button>&nbsp;
<ak-spinner-button
.callAction=${() => {
this.open = false;
}}
class="pf-m-secondary">
${gettext("Cancel")}
${t`Cancel`}
</ak-spinner-button>
</footer>`;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { EVENT_REFRESH } from "../../constants";
import { ModalButton } from "../buttons/ModalButton";
@ -66,7 +66,7 @@ export class ModalForm extends ModalButton {
this.open = false;
}}
class="pf-m-secondary">
${gettext("Cancel")}
${t`Cancel`}
</ak-spinner-button>
</footer>`;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { LitElement, html, customElement, TemplateResult, property, CSSResult, css } from "lit-element";
import "./Message";
import { APIMessage, MessageLevel } from "./Message";
@ -64,7 +64,7 @@ export class MessageContainer extends LitElement {
if (this.retryDelay > 3000) {
showMessage({
level: MessageLevel.error,
message: gettext("Connection error, reconnecting...")
message: t`Connection error, reconnecting...`
});
}
setTimeout(() => {

View File

@ -1,5 +1,5 @@
import { Middleware, ResponseContext } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { MessageLevel } from "./Message";
import { showMessage } from "./MessageContainer";
@ -9,7 +9,7 @@ export class MessageMiddleware implements Middleware {
if (context.response.status >= 500) {
showMessage({
level: MessageLevel.error,
message: gettext("API request failed"),
message: t`API request failed`,
description: `${context.init.method} ${context.url}: ${context.response.status}`
});
}

View File

@ -5,7 +5,7 @@ import PFNotificationDrawer from "@patternfly/patternfly/components/Notification
import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";
import AKGlobal from "../../authentik.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { EVENT_API_DRAWER_REFRESH } from "../../constants";
export interface RequestInfo {
@ -71,7 +71,7 @@ export class APIDrawer extends LitElement {
<div class="pf-c-notification-drawer">
<div class="pf-c-notification-drawer__header pf-c-content">
<h1>
${gettext("API Requests")}
${t`API Requests`}
</h1>
</div>
<div class="pf-c-notification-drawer__body">

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { EventsApi, Notification } from "authentik-api";
import { AKResponse } from "../../api/Client";
@ -100,10 +100,10 @@ export class NotificationDrawer extends LitElement {
<div class="pf-c-notification-drawer">
<div class="pf-c-notification-drawer__header pf-c-content">
<h1>
${gettext("Notifications")}
${t`Notifications`}
</h1>
<p>
${gettext(`${this.unread} unread`)}
${t`${this.unread} unread`}
</p>
</div>
<div class="pf-c-notification-drawer__body">

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../table/Table";
@ -26,9 +26,9 @@ export class UserOAuthCodeList extends Table<ExpiringBaseGrantModel> {
columns(): TableColumn[] {
return [
new TableColumn("Provider", "provider"),
new TableColumn("Expires", "expires"),
new TableColumn("Scopes", "scope"),
new TableColumn(t`Provider`, t`provider`),
new TableColumn(t`Expires`, t`expires`),
new TableColumn(t`Scopes`, t`scope`),
new TableColumn(""),
];
}
@ -41,14 +41,14 @@ export class UserOAuthCodeList extends Table<ExpiringBaseGrantModel> {
html`
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Authorization Code")}
objectLabel=${t`Authorization Code`}
.delete=${() => {
return new Oauth2Api(DEFAULT_CONFIG).oauth2AuthorizationCodesDelete({
id: item.pk || 0,
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete Authorization Code")}
${t`Delete Authorization Code`}
</button>
</ak-forms-delete>`,
];

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../table/Table";
@ -26,9 +26,9 @@ export class UserOAuthRefreshList extends Table<ExpiringBaseGrantModel> {
columns(): TableColumn[] {
return [
new TableColumn("Provider", "provider"),
new TableColumn("Expires", "expires"),
new TableColumn("Scopes", "scope"),
new TableColumn(t`Provider`, t`provider`),
new TableColumn(t`Expires`, t`expires`),
new TableColumn(t`Scopes`, t`scope`),
new TableColumn(""),
];
}
@ -41,14 +41,14 @@ export class UserOAuthRefreshList extends Table<ExpiringBaseGrantModel> {
html`
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Refresh Code")}
objectLabel=${t`Refresh Code`}
.delete=${() => {
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensDelete({
id: item.pk || 0,
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete Refresh Code")}
${t`Delete Refresh Code`}
</button>
</ak-forms-delete>`,
];

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import PFEmptyState from "@patternfly/patternfly/components/EmptyState/empty-state.css";
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
@ -18,11 +18,11 @@ export class Router404 extends LitElement {
return html`<div class="pf-c-empty-state pf-m-full-height">
<div class="pf-c-empty-state__content">
<i class="fas fa-question-circle pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">${gettext("Not found")}</h1>
<h1 class="pf-c-title pf-m-lg">${t`Not found`}</h1>
<div class="pf-c-empty-state__body">
${gettext(`The URL '${this.url}' was not found.`)}
${t`The URL '${this.url}' was not found.`}
</div>
<a href="#/" class="pf-c-button pf-m-primary" type="button">${gettext("Return home")}</a>
<a href="#/" class="pf-c-button pf-m-primary" type="button">${t`Return home`}</a>
</div>
</div>`;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, html, LitElement, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
@ -54,7 +54,7 @@ export class TableColumn {
return html`
<button class="pf-c-table__button" @click=${() => this.headerClickHandler(table)}>
<div class="pf-c-table__button-content">
<span class="pf-c-table__text">${gettext(this.title)}</span>
<span class="pf-c-table__text">${this.title}</span>
<span class="pf-c-table__sort-indicator">
<i class="fas ${this.getSortIndicator(table)}"></i>
</span>
@ -70,7 +70,7 @@ export class TableColumn {
${this.orderBy ? "pf-c-table__sort " : " "}
${(table.order === this.orderBy || table.order === `-${this.orderBy}`) ? "pf-m-selected " : ""}
">
${this.orderBy ? this.renderSortable(table) : html`${gettext(this.title)}`}
${this.orderBy ? this.renderSortable(table) : html`${this.title}`}
</th>`;
}
@ -147,7 +147,7 @@ export abstract class Table<T> extends LitElement {
<div class="pf-l-bullseye">
<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>
</div>
</td>
@ -159,7 +159,7 @@ export abstract class Table<T> extends LitElement {
<tr role="row">
<td role="cell" colspan="8">
<div class="pf-l-bullseye">
${inner ? inner : html`<ak-empty-state header="${gettext("No elements found.")}"></ak-empty-state>`}
${inner ? inner : html`<ak-empty-state header="${t`No elements found.`}"></ak-empty-state>`}
</div>
</td>
</tr>
@ -218,7 +218,7 @@ export abstract class Table<T> extends LitElement {
return html`<button
@click=${() => { this.fetch(); }}
class="pf-c-button pf-m-primary">
${gettext("Refresh")}
${t`Refresh`}
</button>`;
}
@ -253,7 +253,7 @@ export abstract class Table<T> extends LitElement {
<thead>
<tr role="row">
${this.checkbox ? html`<td class="pf-c-table__check" role="cell">
<input type="checkbox" aria-label=${gettext("Select all rows")} @input=${(ev: InputEvent) => {
<input type="checkbox" aria-label=${t`Select all rows`} @input=${(ev: InputEvent) => {
if ((ev.target as HTMLInputElement).checked) {
this.selectedElements = this.data?.results || [];
} else {

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { ifDefined } from "lit-html/directives/if-defined";
@ -34,9 +34,9 @@ export abstract class TablePage<T> extends Table<T> {
<div class="pf-c-content">
<h1>
<i class="${this.pageIcon()}"></i>
${gettext(this.pageTitle())}
${t`${this.pageTitle()}`}
</h1>
${description ? html`<p>${gettext(description)}</p>` : html``}
${description ? html`<p>${t`${description}`}</p>` : html``}
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">

View File

@ -1,6 +1,6 @@
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { AKPagination } from "../../api/Client";
import { gettext } from "django";
import { t } from "@lingui/macro";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
@ -25,9 +25,7 @@ export class TablePagination extends LitElement {
<div class="pf-c-options-menu">
<div class="pf-c-options-menu__toggle pf-m-text pf-m-plain">
<span class="pf-c-options-menu__toggle-text">
${this.pages?.startIndex} -
${this.pages?.endIndex} of
${this.pages?.count}
${t`${this.pages?.startIndex} - ${this.pages?.endIndex} of ${this.pages?.count}`}
</span>
</div>
</div>
@ -37,7 +35,7 @@ export class TablePagination extends LitElement {
class="pf-c-button pf-m-plain"
@click=${() => { this.pageChangeHandler(this.pages?.previous || 0); }}
?disabled="${(this.pages?.previous || 0) < 1}"
aria-label="${gettext("Go to previous page")}"
aria-label="${t`Go to previous page`}"
>
<i class="fas fa-angle-left" aria-hidden="true"></i>
</button>
@ -47,7 +45,7 @@ export class TablePagination extends LitElement {
class="pf-c-button pf-m-plain"
@click=${() => { this.pageChangeHandler(this.pages?.next || 0); }}
?disabled="${(this.pages?.next || 0) <= 0}"
aria-label="${gettext("Go to next page")}"
aria-label="${t`Go to next page`}"
>
<i class="fas fa-angle-right" aria-hidden="true"></i>
</button>

View File

@ -6,6 +6,7 @@ import PFToolbar from "@patternfly/patternfly/components/Toolbar/toolbar.css";
import PFInputGroup from "@patternfly/patternfly/components/InputGroup/input-group.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import AKGlobal from "../../authentik.css";
import { t } from "@lingui/macro";
@customElement("ak-table-search")
export class TableSearch extends LitElement {
@ -31,7 +32,7 @@ export class TableSearch extends LitElement {
if (el.value === "") return;
this.onSearch(el?.value);
}}>
<input class="pf-c-form-control" name="search" type="search" placeholder="Search..." value="${ifDefined(this.value)}" @search=${(ev: Event) => {
<input class="pf-c-form-control" name="search" type="search" placeholder=${t`Search...`} value="${ifDefined(this.value)}" @search=${(ev: Event) => {
if (!this.onSearch) return;
this.onSearch((ev.target as HTMLInputElement).value);
}}>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../table/Table";
@ -26,8 +26,8 @@ export class UserConsentList extends Table<UserConsent> {
columns(): TableColumn[] {
return [
new TableColumn("Application", "application"),
new TableColumn("Expires", "expires"),
new TableColumn(t`Application`, t`application`),
new TableColumn(t`Expires`, t`expires`),
new TableColumn(""),
];
}
@ -39,14 +39,14 @@ export class UserConsentList extends Table<UserConsent> {
html`
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Consent")}
objectLabel=${t`Consent`}
.delete=${() => {
return new CoreApi(DEFAULT_CONFIG).coreUserConsentDelete({
id: item.pk || 0,
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete Consent")}
${t`Delete Consent`}
</button>
</ak-forms-delete>`,
];

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { LitElement, html, customElement, property, TemplateResult, CSSResult, css } from "lit-element";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -152,11 +152,11 @@ export class FlowExecutor extends LitElement implements StageHost {
type: ChallengeTypeEnum.Shell,
body: `<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">
${gettext("Whoops!")}
${t`Whoops!`}
</h1>
</header>
<div class="pf-c-login__main-body">
<h3>${gettext("Something went wrong! Please try again later.")}</h3>
<h3>${t`Something went wrong! Please try again later.`}</h3>
<pre class="ak-exception">${error}</pre>
</div>`
};
@ -178,7 +178,7 @@ export class FlowExecutor extends LitElement implements StageHost {
window.location.assign((this.challenge as RedirectChallenge).to);
return html`<ak-empty-state
?loading=${true}
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
case ChallengeTypeEnum.Shell:
return html`${unsafeHTML((this.challenge as ShellChallenge).body)}`;
@ -225,7 +225,7 @@ export class FlowExecutor extends LitElement implements StageHost {
if (!this.challenge) {
return html`<ak-empty-state
?loading=${true}
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`
@ -267,7 +267,7 @@ export class FlowExecutor extends LitElement implements StageHost {
</li>`;
}))}
${this.config?.brandingTitle != "authentik" ? html`
<li><a href="https://goauthentik.io">${gettext("Powered by authentik")}</a></li>
<li><a href="https://goauthentik.io">${t`Powered by authentik`}</a></li>
` : html``}
</ul>
</footer>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
import { ifDefined } from "lit-html/directives/if-defined";
@ -40,7 +40,7 @@ export class FormStatic extends LitElement {
return html`
<div class="form-control-static">
<div class="avatar">
<img class="pf-c-avatar" src="${ifDefined(this.userAvatar)}" alt="${gettext("User's avatar")}">
<img class="pf-c-avatar" src="${ifDefined(this.userAvatar)}" alt="${t`User's avatar`}">
${this.user}
</div>
<slot name="link"></slot>

View File

@ -8,7 +8,7 @@ import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFList from "@patternfly/patternfly/components/List/list.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import AKGlobal from "../../authentik.css";
import { gettext } from "django";
import { t } from "@lingui/macro";
import "../../elements/EmptyState";
@ -30,7 +30,7 @@ export class FlowAccessDenied extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -43,7 +43,7 @@ export class FlowAccessDenied extends BaseStage {
<div class="pf-c-form__group">
<p>
<i class="pf-icon pf-icon-error-circle-o"></i>
${gettext("Request has been denied.")}
${t`Request has been denied.`}
</p>
${this.challenge?.error_message &&
html`<hr>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -47,7 +47,7 @@ export class AuthenticatorStaticStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -62,11 +62,11 @@ export class AuthenticatorStaticStage extends BaseStage {
userAvatar="${this.challenge.pending_user_avatar}"
user=${this.challenge.pending_user}>
<div slot="link">
<a href="${FlowURLManager.cancel()}">${gettext("Not you?")}</a>
<a href="${FlowURLManager.cancel()}">${t`Not you?`}</a>
</div>
</ak-form-static>
<ak-form-element
label="${gettext("Tokens")}"
label="${t`Tokens`}"
?required="${true}"
class="pf-c-form__group">
<ul class="ak-otp-tokens">
@ -78,7 +78,7 @@ export class AuthenticatorStaticStage extends BaseStage {
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -35,7 +35,7 @@ export class AuthenticatorTOTPStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -50,7 +50,7 @@ export class AuthenticatorTOTPStage extends BaseStage {
userAvatar="${this.challenge.pending_user_avatar}"
user=${this.challenge.pending_user}>
<div slot="link">
<a href="${FlowURLManager.cancel()}">${gettext("Not you?")}</a>
<a href="${FlowURLManager.cancel()}">${t`Not you?`}</a>
</div>
</ak-form-static>
<input type="hidden" name="otp_uri" value=${this.challenge.config_url} />
@ -63,16 +63,16 @@ export class AuthenticatorTOTPStage extends BaseStage {
navigator.clipboard.writeText(this.challenge?.config_url).then(() => {
showMessage({
level: MessageLevel.success,
message: gettext("Successfully copied TOTP Config.")
message: t`Successfully copied TOTP Config.`
});
});
}}>
<span class="pf-c-button__progress"><i class="fas fa-copy"></i></span>
${gettext("Copy")}
${t`Copy`}
</button>
</ak-form-element>
<ak-form-element
label="${gettext("Code")}"
label="${t`Code`}"
?required="${true}"
class="pf-c-form__group"
.errors=${(this.challenge?.response_errors || {})["code"]}>
@ -81,7 +81,7 @@ export class AuthenticatorTOTPStage extends BaseStage {
name="code"
inputmode="numeric"
pattern="[0-9]*"
placeholder="${gettext("Please enter your TOTP Code")}"
placeholder="${t`Please enter your TOTP Code`}"
autofocus=""
autocomplete="one-time-code"
class="pf-c-form-control"
@ -90,7 +90,7 @@ export class AuthenticatorTOTPStage extends BaseStage {
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -80,8 +80,8 @@ export class AuthenticatorValidateStage extends BaseStage implements StageHost {
case DeviceClasses.WEBAUTHN:
return html`<i class="fas fa-mobile-alt"></i>
<div class="right">
<p>${gettext("Authenticator")}</p>
<small>${gettext("Use a security key to prove your identity.")}</small>
<p>${t`Authenticator`}</p>
<small>${t`Use a security key to prove your identity.`}</small>
</div>`;
case DeviceClasses.TOTP:
// TOTP is a bit special, assuming that TOTP is allowed from the backend,
@ -97,14 +97,14 @@ export class AuthenticatorValidateStage extends BaseStage implements StageHost {
}
return html`<i class="fas fa-clock"></i>
<div class="right">
<p>${gettext("Traditional authenticator")}</p>
<small>${gettext("Use a code-based authenticator.")}</small>
<p>${t`Traditional authenticator`}</p>
<small>${t`Use a code-based authenticator.`}</small>
</div>`;
case DeviceClasses.STATIC:
return html`<i class="fas fa-key"></i>
<div class="right">
<p>${gettext("Recovery keys")}</p>
<small>${gettext("In case you can't access any other method.")}</small>
<p>${t`Recovery keys`}</p>
<small>${t`In case you can't access any other method.`}</small>
</div>`;
default:
break;
@ -154,7 +154,7 @@ export class AuthenticatorValidateStage extends BaseStage implements StageHost {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
// User only has a single device class, so we don't show a picker
@ -166,7 +166,7 @@ export class AuthenticatorValidateStage extends BaseStage implements StageHost {
${this.challenge.title}
</h1>
${this.selectedDeviceChallenge ? "" : html`<p class="pf-c-login__main-header-desc">
${gettext("Select an identification method.")}
${t`Select an identification method.`}
</p>`}
</header>
${this.selectedDeviceChallenge ?

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
@ -35,7 +35,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<div class="pf-c-login__main-body">
@ -45,11 +45,11 @@ export class AuthenticatorValidateStageWebCode extends BaseStage {
userAvatar="${this.challenge.pending_user_avatar}"
user=${this.challenge.pending_user}>
<div slot="link">
<a href="${FlowURLManager.cancel()}">${gettext("Not you?")}</a>
<a href="${FlowURLManager.cancel()}">${t`Not you?`}</a>
</div>
</ak-form-static>
<ak-form-element
label="${gettext("Code")}"
label="${t`Code`}"
?required="${true}"
class="pf-c-form__group"
.errors=${(this.challenge?.response_errors || {})["code"]}>
@ -58,7 +58,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage {
name="code"
inputmode="numeric"
pattern="[0-9]*"
placeholder="${gettext("Please enter your TOTP Code")}"
placeholder="${t`Please enter your TOTP Code`}"
autofocus=""
autocomplete="one-time-code"
class="pf-c-form-control"
@ -68,7 +68,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage {
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>
@ -81,7 +81,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage {
if (!this.host) return;
(this.host as AuthenticatorValidateStage).selectedDeviceChallenge = undefined;
}}>
${gettext("Return to device picker")}
${t`Return to device picker`}
</button>
</li>`:
html``}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
@ -48,10 +48,10 @@ export class AuthenticatorValidateStageWebAuthn extends BaseStage {
publicKey: transformedCredentialRequestOptions,
});
if (!assertion) {
throw new Error(gettext("Assertions is empty"));
throw new Error(t`Assertions is empty`);
}
} catch (err) {
throw new Error(gettext(`Error when creating credential: ${err}`));
throw new Error(t`Error when creating credential: ${err}`);
}
// we now have an authentication assertion! encode the byte arrays contained
@ -64,7 +64,7 @@ export class AuthenticatorValidateStageWebAuthn extends BaseStage {
formData.set("webauthn", JSON.stringify(transformedAssertionForServer));
await this.host?.submit(formData);
} catch (err) {
throw new Error(gettext(`Error when validating assertion on server: ${err}`));
throw new Error(t`Error when validating assertion on server: ${err}`);
}
}
@ -78,7 +78,7 @@ export class AuthenticatorValidateStageWebAuthn extends BaseStage {
}
this.authenticateRunning = true;
this.authenticate().catch((e) => {
console.error(gettext(e));
console.error(e);
this.authenticateMessage = e.toString();
}).finally(() => {
this.authenticateRunning = false;
@ -101,7 +101,7 @@ export class AuthenticatorValidateStageWebAuthn extends BaseStage {
<button class="pf-c-button pf-m-primary pf-m-block" @click=${() => {
this.authenticateWrapper();
}}>
${gettext("Retry authentication")}
${t`Retry authentication`}
</button>
</div>`}
</div>
@ -113,7 +113,7 @@ export class AuthenticatorValidateStageWebAuthn extends BaseStage {
if (!this.host) return;
(this.host as AuthenticatorValidateStage).selectedDeviceChallenge = undefined;
}}>
${gettext("Return to device picker")}
${t`Return to device picker`}
</button>
</li>`:
html``}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -54,7 +54,7 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage {
throw new Error("Credential is empty");
}
} catch (err) {
throw new Error(gettext(`Error creating credential: ${err}`));
throw new Error(t`Error creating credential: ${err}`);
}
// we now have a new credential! We now need to encode the byte arrays
@ -68,7 +68,7 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage {
response: newAssertionForServer
});
} catch (err) {
throw new Error(gettext(`Server validation of credential failed: ${err}`));
throw new Error(t`Server validation of credential failed: ${err}`);
}
}
@ -113,7 +113,7 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage {
<button class="pf-c-button pf-m-primary pf-m-block" @click=${() => {
this.registerWrapper();
}}>
${gettext("Register device")}
${t`Register device`}
</button>
</div>`}
</div>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -34,7 +34,7 @@ export class AutosubmitStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -52,7 +52,7 @@ export class AutosubmitStage extends BaseStage {
</ak-empty-state>
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -64,7 +64,7 @@ export class CaptchaStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -79,7 +79,7 @@ export class CaptchaStage extends BaseStage {
userAvatar="${this.challenge.pending_user_avatar}"
user=${this.challenge.pending_user}>
<div slot="link">
<a href="${FlowURLManager.cancel()}">${gettext("Not you?")}</a>
<a href="${FlowURLManager.cancel()}">${t`Not you?`}</a>
</div>
</ak-form-static>
<div class="ak-loading">

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -39,7 +39,7 @@ export class ConsentStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -54,14 +54,14 @@ export class ConsentStage extends BaseStage {
userAvatar="${this.challenge.pending_user_avatar}"
user=${this.challenge.pending_user}>
<div slot="link">
<a href="${FlowURLManager.cancel()}">${gettext("Not you?")}</a>
<a href="${FlowURLManager.cancel()}">${t`Not you?`}</a>
</div>
</ak-form-static>
<div class="pf-c-form__group">
<p id="header-text">
${this.challenge.header_text}
</p>
<p>${gettext("Application requires following permissions")}</p>
<p>${t`Application requires following permissions`}</p>
<ul class="pf-c-list" id="permmissions">
${(this.challenge.permissions || []).map((permission) => {
return html`<li data-permission-code="${permission.id}">${permission.name}</li>`;
@ -71,7 +71,7 @@ export class ConsentStage extends BaseStage {
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { Challenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -26,7 +26,7 @@ export class DummyStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -38,7 +38,7 @@ export class DummyStage extends BaseStage {
<form class="pf-c-form" @submit=${(e: Event) => { this.submitForm(e); }}>
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { Challenge } from "authentik-api";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -27,7 +27,7 @@ export class EmailStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -39,13 +39,13 @@ export class EmailStage extends BaseStage {
<form class="pf-c-form" @submit=${(e: Event) => { this.submitForm(e); }}>
<div class="pf-c-form__group">
<p>
${gettext("Check your Emails for a password reset link.")}
${t`Check your Emails for a password reset link.`}
</p>
</div>
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Send Email again.")}
${t`Send Email again.`}
</button>
</div>
</form>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { BaseStage } from "../base";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -144,13 +144,13 @@ export class IdentificationStage extends BaseStage {
return html`<div class="pf-c-login__main-footer-band">
${this.challenge.enroll_url ? html`
<p class="pf-c-login__main-footer-band-item">
${gettext("Need an account?")}
<a id="enroll" href="${this.challenge.enroll_url}">${gettext("Sign up.")}</a>
${t`Need an account?`}
<a id="enroll" href="${this.challenge.enroll_url}">${t`Sign up.`}</a>
</p>` : html``}
${this.challenge.recovery_url ? html`
<p class="pf-c-login__main-footer-band-item">
${gettext("Need an account?")}
<a id="recovery" href="${this.challenge.recovery_url}">${gettext("Forgot username or password?")}</a>
${t`Need an account?`}
<a id="recovery" href="${this.challenge.recovery_url}">${t`Forgot username or password?`}</a>
</p>` : html``}
</div>`;
}
@ -159,7 +159,7 @@ export class IdentificationStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -171,12 +171,12 @@ export class IdentificationStage extends BaseStage {
<form class="pf-c-form" @submit=${(e: Event) => {this.submitForm(e);}}>
${this.challenge.application_pre ?
html`<p>
${gettext(`Login to continue to ${this.challenge.application_pre}.`)}
${t`Login to continue to ${this.challenge.application_pre}.`}
</p>`:
html``}
<ak-form-element
label="${gettext("Email or Username")}"
label="${t`Email or Username`}"
?required="${true}"
class="pf-c-form__group"
.errors=${(this.challenge?.response_errors || {})["uid_field"]}>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { WithUserInfoChallenge } from "../../../api/Flows";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -33,7 +33,7 @@ export class PasswordStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -48,18 +48,18 @@ export class PasswordStage extends BaseStage {
userAvatar="${this.challenge.pending_user_avatar}"
user=${this.challenge.pending_user}>
<div slot="link">
<a href="${FlowURLManager.cancel()}">${gettext("Not you?")}</a>
<a href="${FlowURLManager.cancel()}">${t`Not you?`}</a>
</div>
</ak-form-static>
<input name="username" autocomplete="username" type="hidden" value="${this.challenge.pending_user}">
<ak-form-element
label="${gettext("Password")}"
label="${t`Password`}"
?required="${true}"
class="pf-c-form__group"
.errors=${(this.challenge?.response_errors || {})["password"]}>
<input type="password"
name="password"
placeholder="${gettext("Please enter your password")}"
placeholder="${t`Please enter your password`}"
autofocus=""
autocomplete="current-password"
class="pf-c-form-control"
@ -69,11 +69,11 @@ export class PasswordStage extends BaseStage {
${this.challenge.recovery_url ?
html`<a href="${this.challenge.recovery_url}">
${gettext("Forgot password?")}</a>` : ""}
${t`Forgot password?`}</a>` : ""}
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { unsafeHTML } from "lit-html/directives/unsafe-html";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -121,7 +121,7 @@ export class PromptStage extends BaseStage {
if (!this.challenge) {
return html`<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
@ -142,7 +142,7 @@ export class PromptStage extends BaseStage {
})}
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${gettext("Continue")}
${t`Continue`}
</button>
</div>
</form>

View File

@ -4,58 +4,60 @@ import { me } from "../api/Users";
import { SidebarItem } from "../elements/sidebar/Sidebar";
import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "../elements/router/Route";
import { Interface } from "./Interface";
import "./locale";
import { t } from "@lingui/macro";
export const SIDEBAR_ITEMS: SidebarItem[] = [
new SidebarItem("Library", "/library"),
new SidebarItem("Monitor").children(
new SidebarItem("Overview", "/administration/overview"),
new SidebarItem("System Tasks", "/administration/system-tasks"),
new SidebarItem(t`Library`, "/library"),
new SidebarItem(t`Monitor`).children(
new SidebarItem(t`Overview`, "/administration/overview"),
new SidebarItem(t`System Tasks`, "/administration/system-tasks"),
).when((): Promise<boolean> => {
return me().then(u => u.user.isSuperuser||false);
}),
new SidebarItem("Resources").children(
new SidebarItem("Applications", "/core/applications").activeWhen(
new SidebarItem(t`Resources`).children(
new SidebarItem(t`Applications`, "/core/applications").activeWhen(
`^/core/applications/(?<slug>${SLUG_REGEX})$`
),
new SidebarItem("Sources", "/core/sources").activeWhen(
new SidebarItem(t`Sources`, "/core/sources").activeWhen(
`^/core/sources/(?<slug>${SLUG_REGEX})$`,
),
new SidebarItem("Providers", "/core/providers").activeWhen(
new SidebarItem(t`Providers`, "/core/providers").activeWhen(
`^/core/providers/(?<id>${ID_REGEX})$`,
),
new SidebarItem("Outposts", "/outpost/outposts"),
new SidebarItem("Outpost Service Connections", "/outpost/service-connections"),
new SidebarItem(t`Outposts`, "/outpost/outposts"),
new SidebarItem(t`Outpost Service Connections`, "/outpost/service-connections"),
).when((): Promise<boolean> => {
return me().then(u => u.user.isSuperuser||false);
}),
new SidebarItem("Events").children(
new SidebarItem("Logs", "/events/log").activeWhen(
new SidebarItem(t`Events`).children(
new SidebarItem(t`Logs`, "/events/log").activeWhen(
`^/events/log/(?<id>${UUID_REGEX})$`
),
new SidebarItem("Notification Rules", "/events/rules"),
new SidebarItem("Notification Transports", "/events/transports"),
new SidebarItem(t`Notification Rules`, "/events/rules"),
new SidebarItem(t`Notification Transports`, "/events/transports"),
).when((): Promise<boolean> => {
return me().then(u => u.user.isSuperuser || false);
}),
new SidebarItem("Customisation").children(
new SidebarItem("Policies", "/policy/policies"),
new SidebarItem("Property Mappings", "/core/property-mappings"),
new SidebarItem(t`Customisation`).children(
new SidebarItem(t`Policies`, "/policy/policies"),
new SidebarItem(t`Property Mappings`, "/core/property-mappings"),
).when((): Promise<boolean> => {
return me().then(u => u.user.isSuperuser||false);
}),
new SidebarItem("Flows").children(
new SidebarItem("Flows", "/flow/flows").activeWhen(`^/flow/flows/(?<slug>${SLUG_REGEX})$`),
new SidebarItem("Stages", "/flow/stages"),
new SidebarItem("Prompts", "/flow/stages/prompts"),
new SidebarItem("Invitations", "/flow/stages/invitations"),
new SidebarItem(t`Flows`).children(
new SidebarItem(t`Flows`, "/flow/flows").activeWhen(`^/flow/flows/(?<slug>${SLUG_REGEX})$`),
new SidebarItem(t`Stages`, "/flow/stages"),
new SidebarItem(t`Prompts`, "/flow/stages/prompts"),
new SidebarItem(t`Invitations`, "/flow/stages/invitations"),
).when((): Promise<boolean> => {
return me().then(u => u.user.isSuperuser||false);
}),
new SidebarItem("Identity & Cryptography").children(
new SidebarItem("Users", "/identity/users").activeWhen(`^/identity/users/(?<id>${ID_REGEX})$`),
new SidebarItem("Groups", "/identity/groups"),
new SidebarItem("Certificates", "/crypto/certificates"),
new SidebarItem("Tokens", "/core/tokens"),
new SidebarItem(t`Identity & Cryptography`).children(
new SidebarItem(t`Users`, "/identity/users").activeWhen(`^/identity/users/(?<id>${ID_REGEX})$`),
new SidebarItem(t`Groups`, "/identity/groups"),
new SidebarItem(t`Certificates`, "/crypto/certificates"),
new SidebarItem(t`Tokens`, "/core/tokens"),
).when((): Promise<boolean> => {
return me().then(u => u.user.isSuperuser||false);
}),

View File

@ -1,4 +1,3 @@
import "construct-style-sheets-polyfill";
import "./locale";
import "../elements/messages/MessageContainer";
import "../flows/FlowExecutor";

View File

@ -13,7 +13,7 @@ import "../elements/notifications/NotificationDrawer";
import "../elements/Banner";
import { until } from "lit-html/directives/until";
import { me } from "../api/Users";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { EVENT_NOTIFICATION_TOGGLE, EVENT_SIDEBAR_TOGGLE } from "../constants";
export abstract class Interface extends LitElement {
@ -52,9 +52,9 @@ export abstract class Interface extends LitElement {
${until(me().then((u) => {
if (u.original) {
return html`<ak-banner>
${gettext(`You're currently impersonating ${u.user.username}.`)}
${t`You're currently impersonating ${u.user.username}.`}
<a href=${`/-/impersonation/end/?back=${window.location.pathname}%23${window.location.hash}`}>
${gettext("Stop impersonation")}
${t`Stop impersonation`}
</a>
</ak-banner>`;
}

View File

@ -7,8 +7,7 @@
<link rel="shortcut icon" type="image/png" href="/static/dist/assets/icons/icon.png">
<link rel="stylesheet" type="text/css" href="/static/dist/patternfly-base.css">
<link rel="stylesheet" type="text/css" href="/static/dist/authentik.css">
<script src="/api/jsi18n/"></script>
<script src="/static/dist/adoptedStyleSheets.js" type="module"></script>
<script src="/static/dist/poly.js" type="module"></script>
<script src="/static/dist/AdminInterface.js" type="module"></script>
<title>authentik</title>
</head>

View File

@ -7,8 +7,7 @@
<link rel="shortcut icon" type="image/png" href="/static/dist/assets/icons/icon.png">
<link rel="stylesheet" type="text/css" href="/static/dist/patternfly-base.css">
<link rel="stylesheet" type="text/css" href="/static/dist/authentik.css">
<script src="/api/jsi18n/"></script>
<script src="/static/dist/adoptedStyleSheets.js" type="module"></script>
<script src="/static/dist/poly.js" type="module"></script>
<script src="/static/dist/FlowInterface.js" type="module"></script>
<title>authentik</title>
</head>

View File

@ -0,0 +1,14 @@
import { i18n } from "@lingui/core";
import { en } from "make-plural/plurals";
import { messages as localeEN } from "../locales/en";
import { messages as localeDEBUG } from "../locales/pseudo-LOCALE";
i18n.loadLocaleData("en", { plurals: en });
i18n.loadLocaleData("debug", { plurals: en });
i18n.load("en", localeEN);
i18n.load("debug", localeDEBUG);
i18n.activate("en");
if (window.location.search.includes("debugLocale")) {
i18n.activate("debug");
}

1
web/src/locales/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.ts

3725
web/src/locales/en.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { ifDefined } from "lit-html/directives/if-defined";
import { until } from "lit-html/directives/until";
@ -87,7 +87,7 @@ export class LibraryPage extends LitElement {
apps?: AKResponse<Application>;
pageTitle(): string {
return gettext("Applications");
return t`Applications`;
}
static get styles(): CSSResult[] {
@ -109,9 +109,9 @@ export class LibraryPage extends LitElement {
return html` <div class="pf-c-empty-state pf-m-full-height">
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">${gettext("No Applications available.")}</h1>
<h1 class="pf-c-title pf-m-lg">${t`No Applications available.`}</h1>
<div class="pf-c-empty-state__body">
${gettext("Either no applications are defined, or you don't have access to any.")}
${t`Either no applications are defined, or you don't have access to any.`}
</div>
</div>
</div>`;
@ -129,7 +129,7 @@ export class LibraryPage extends LitElement {
<div class="pf-c-content">
<h1>
<i class="pf-icon pf-icon-applications"></i>
${gettext("Applications")}
${t`Applications`}
</h1>
</div>
</section>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, LitElement, TemplateResult } from "lit-element";
import "../../elements/charts/AdminLoginsChart";
@ -28,30 +28,30 @@ export class AdminOverviewPage extends LitElement {
render(): TemplateResult {
return html`<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>${gettext("System Overview")}</h1>
<h1>${t`System Overview`}</h1>
</div>
</section>
<section class="pf-c-page__main-section">
<div class="pf-l-gallery pf-m-gutter">
<ak-aggregate-card class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header="Logins over the last 24 hours" style="grid-column-end: span 3;grid-row-end: span 2;">
<ak-aggregate-card class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header=${t`Logins over the last 24 hours`} style="grid-column-end: span 3;grid-row-end: span 2;">
<ak-charts-admin-login></ak-charts-admin-login>
</ak-aggregate-card>
<ak-aggregate-card class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header="Apps with most usage" style="grid-column-end: span 2;grid-row-end: span 3;">
<ak-aggregate-card class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header=${t`Apps with most usage`} style="grid-column-end: span 2;grid-row-end: span 3;">
<ak-top-applications-table></ak-top-applications-table>
</ak-aggregate-card>
<ak-admin-status-card-provider class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-plugged" header="Providers" headerLink="#/core/providers/">
<ak-admin-status-card-provider class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-plugged" header=${t`Providers`} headerLink="#/core/providers/">
</ak-admin-status-card-provider>
<ak-admin-status-card-policy-unbound class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-infrastructure" header="Policies" headerLink="#/policy/policies">
<ak-admin-status-card-policy-unbound class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-infrastructure" header=${t`Policies`} headerLink="#/policy/policies">
</ak-admin-status-card-policy-unbound>
<ak-admin-status-card-user-count class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-user" header="Users" headerLink="#/identity/users">
<ak-admin-status-card-user-count class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-user" header=${t`Users`} headerLink="#/identity/users">
</ak-admin-status-card-user-count>
<ak-admin-status-version class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-bundle" header="Version" headerLink="https://github.com/BeryJu/authentik/releases">
<ak-admin-status-version class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-bundle" header=${t`Version`} headerLink="https://github.com/BeryJu/authentik/releases">
</ak-admin-status-version>
<ak-admin-status-card-workers class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header="Workers">
<ak-admin-status-card-workers class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header=${t`Workers`}>
</ak-admin-status-card-workers>
<ak-admin-status-card-policy-cache class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header="Cached Policies">
<ak-admin-status-card-policy-cache class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header=${t`Cached Policies`}>
</ak-admin-status-card-policy-cache>
<ak-admin-status-card-flow-cache class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header="Cached Flows">
<ak-admin-status-card-flow-cache class="pf-l-gallery__item pf-m-4-col" icon="pf-icon pf-icon-server" header=${t`Cached Flows`}>
</ak-admin-status-card-flow-cache>
</div>
</section>`;

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { EventsApi, EventTopPerUser } from "authentik-api";
import PFTable from "@patternfly/patternfly/components/Table/table.css";
@ -43,8 +43,8 @@ export class TopApplicationsTable extends LitElement {
return html`<table class="pf-c-table pf-m-compact" role="grid">
<thead>
<tr role="row">
<th role="columnheader" scope="col">${gettext("Application")}</th>
<th role="columnheader" scope="col">${gettext("Logins")}</th>
<th role="columnheader" scope="col">${t`Application`}</th>
<th role="columnheader" scope="col">${t`Logins`}</th>
<th role="columnheader" scope="col"></th>
</tr>
</thead>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, TemplateResult } from "lit-element";
import { AdminStatus, AdminStatusCard } from "./AdminStatusCard";
import { FlowsApi } from "authentik-api";
@ -18,7 +18,7 @@ export class FlowCacheStatusCard extends AdminStatusCard<number> {
if (value < 1) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning",
message: gettext("No flows cached."),
message: t`No flows cached.`,
});
} else {
return Promise.resolve<AdminStatus>({
@ -29,18 +29,18 @@ export class FlowCacheStatusCard extends AdminStatusCard<number> {
renderHeaderLink(): TemplateResult {
return html`<ak-forms-confirm
successMessage="Successfully cleared flow cache"
errorMessage="Failed to delete flow cache"
action="Clear cache"
successMessage=${t`Successfully cleared flow cache`}
errorMessage=${t`Failed to delete flow cache`}
action=${t`Clear cache`}
.onConfirm=${() => {
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesCacheClear();
}}>
<span slot="header">
${gettext("Clear Flow cache")}
${t`Clear Flow cache`}
</span>
<p slot="body">
${gettext(`Are you sure you want to clear the flow cache?
This will cause all flows to be re-evaluated on their next usage.`)}
${t`Are you sure you want to clear the flow cache?
This will cause all flows to be re-evaluated on their next usage.`}
</p>
<a slot="trigger">
<i class="fa fa-trash"> </i>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement } from "lit-element";
import { TemplateResult, html } from "lit-html";
import { AdminStatusCard, AdminStatus } from "./AdminStatusCard";
@ -19,7 +19,7 @@ export class PolicyCacheStatusCard extends AdminStatusCard<number> {
if (value < 1) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning",
message: gettext("No policies cached. Users may experience slow response times."),
message: t`No policies cached. Users may experience slow response times.`,
});
} else {
return Promise.resolve<AdminStatus>({
@ -30,18 +30,18 @@ export class PolicyCacheStatusCard extends AdminStatusCard<number> {
renderHeaderLink(): TemplateResult {
return html`<ak-forms-confirm
successMessage="Successfully cleared policy cache"
errorMessage="Failed to delete policy cache"
action="Clear cache"
successMessage=${t`Successfully cleared policy cache`}
errorMessage=${t`Failed to delete policy cache`}
action=${t`Clear cache`}
.onConfirm=${() => {
return new PoliciesApi(DEFAULT_CONFIG).policiesAllCacheClear();
}}>
<span slot="header">
${gettext("Clear Policy cache")}
${t`Clear Policy cache`}
</span>
<p slot="body">
${gettext(`Are you sure you want to clear the policy cache?
This will cause all policies to be re-evaluated on their next usage.`)}
${t`Are you sure you want to clear the policy cache?
This will cause all policies to be re-evaluated on their next usage.`}
</p>
<a slot="trigger">
<i class="fa fa-trash"> </i>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement } from "lit-element";
import { PoliciesApi } from "authentik-api";
import { DEFAULT_CONFIG } from "../../../api/Config";
@ -20,7 +20,7 @@ export class PolicyUnboundStatusCard extends AdminStatusCard<number> {
if (value > 0) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning",
message: gettext("Policies without binding exist."),
message: t`Policies without binding exist.`,
});
} else {
return Promise.resolve<AdminStatus>({

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement } from "lit-element";
import { ProvidersApi } from "authentik-api";
import { DEFAULT_CONFIG } from "../../../api/Config";
@ -19,7 +19,7 @@ export class ProviderStatusCard extends AdminStatusCard<number> {
if (value > 0) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning",
message: gettext("Warning: At least one Provider has no application assigned."),
message: t`Warning: At least one Provider has no application assigned.`,
});
} else {
return Promise.resolve<AdminStatus>({

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, TemplateResult } from "lit-element";
import { AdminApi, Version } from "authentik-api";
import { DEFAULT_CONFIG } from "../../../api/Config";
@ -15,18 +15,18 @@ export class VersionStatusCard extends AdminStatusCard<Version> {
if (value.buildHash) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-check-circle pf-m-success",
message: gettext(`Build hash: ${value.buildHash?.substring(0, 10)}`),
message: t`Build hash: ${value.buildHash?.substring(0, 10)}`,
});
}
if (value.outdated) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning",
message: gettext(`${value.versionLatest} is available!`),
message: t`${value.versionLatest} is available!`,
});
}
return Promise.resolve<AdminStatus>({
icon: "fa fa-check-circle pf-m-success",
message: gettext("Up-to-date!")
message: t`Up-to-date!`
});
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement } from "lit-element";
import { AdminApi } from "authentik-api";
import { DEFAULT_CONFIG } from "../../../api/Config";
@ -17,7 +17,7 @@ export class WorkersStatusCard extends AdminStatusCard<number> {
if (value < 1) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning",
message: gettext("No workers connected. Background tasks will not run."),
message: t`No workers connected. Background tasks will not run.`,
});
} else {
return Promise.resolve<AdminStatus>({

View File

@ -1,5 +1,5 @@
import { CoreApi, Application, ProvidersApi, Provider, ApplicationPolicyEngineModeEnum } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -20,9 +20,9 @@ export class ApplicationForm extends Form<Application> {
getSuccessMessage(): string {
if (this.application) {
return gettext("Successfully updated application.");
return t`Successfully updated application.`;
} else {
return gettext("Successfully created application.");
return t`Successfully created application.`;
}
}
@ -74,21 +74,21 @@ export class ApplicationForm extends Form<Application> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.application?.name)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${gettext("Application's display Name.")}</p>
<p class="pf-c-form__helper-text">${t`Application's display Name.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Slug")}
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.application?.slug)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${gettext("Internal application name, used in URLs.")}</p>
<p class="pf-c-form__helper-text">${t`Internal application name, used in URLs.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Provider")}
label=${t`Provider`}
name="parent">
<select class="pf-c-form-control">
<option value="" ?selected=${this.application?.provider === undefined}>---------</option>
@ -98,36 +98,36 @@ export class ApplicationForm extends Form<Application> {
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Policy engine mode")}
label=${t`Policy engine mode`}
?required=${true}
name="policyEngineMode">
<select class="pf-c-form-control">
<option value=${ApplicationPolicyEngineModeEnum.Any} ?selected=${this.application?.policyEngineMode === ApplicationPolicyEngineModeEnum.Any}>
${gettext("ANY, any policy must match to grant access.")}
${t`ANY, any policy must match to grant access.`}
</option>
<option value=${ApplicationPolicyEngineModeEnum.All} ?selected=${this.application?.policyEngineMode === ApplicationPolicyEngineModeEnum.All}>
${gettext("ALL, all policies must match to grant access.")}
${t`ALL, all policies must match to grant access.`}
</option>
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Launch URL")}
label=${t`Launch URL`}
name="launchUrl">
<input type="text" value="${ifDefined(this.application?.launchUrl)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${gettext("If left empty, authentik will try to extract the launch URL based on the selected provider.")}</p>
<p class="pf-c-form__helper-text">${t`If left empty, authentik will try to extract the launch URL based on the selected provider.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Icon")}
label=${t`Icon`}
name="metaIcon">
<input type="file" value="${ifDefined(this.application?.metaIcon)}" class="pf-c-form-control">
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Description")}
label=${t`Description`}
name="metaDescription">
<textarea class="pf-c-form-control">${ifDefined(this.application?.metaDescription)}</textarea>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Publisher")}
label=${t`Publisher`}
name="metaPublisher">
<input type="text" value="${ifDefined(this.application?.metaPublisher)}" class="pf-c-form-control">
</ak-form-element-horizontal>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
import { AKResponse } from "../../api/Client";
@ -19,10 +19,10 @@ export class ApplicationListPage extends TablePage<Application> {
return true;
}
pageTitle(): string {
return gettext("Applications");
return t`Applications`;
}
pageDescription(): string {
return gettext("External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML.");
return t`External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML.`;
}
pageIcon(): string {
return "pf-icon pf-icon-applications";
@ -54,8 +54,8 @@ export class ApplicationListPage extends TablePage<Application> {
columns(): TableColumn[] {
return [
new TableColumn(""),
new TableColumn("Name", "name"),
new TableColumn("Slug", "slug"),
new TableColumn(t`Name`, t`name`),
new TableColumn(t`Slug`, t`slug`),
new TableColumn("Provider"),
new TableColumn("Provider Type"),
new TableColumn(""),
@ -65,7 +65,7 @@ export class ApplicationListPage extends TablePage<Application> {
row(item: Application): TemplateResult[] {
return [
item.metaIcon ?
html`<img class="app-icon pf-c-avatar" src="${item.metaIcon}" alt="${gettext("Application Icon")}">` :
html`<img class="app-icon pf-c-avatar" src="${item.metaIcon}" alt="${t`Application Icon`}">` :
html`<i class="fas fas fa-share-square"></i>`,
html`<a href="#/core/applications/${item.slug}">
<div>
@ -79,27 +79,27 @@ export class ApplicationListPage extends TablePage<Application> {
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Application")}
${t`Update Application`}
</span>
<ak-application-form slot="form" .application=${item}>
</ak-application-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Application")}
objectLabel=${t`Application`}
.delete=${() => {
return new CoreApi(DEFAULT_CONFIG).coreApplicationsDelete({
slug: item.slug || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>`,
];
@ -109,15 +109,15 @@ export class ApplicationListPage extends TablePage<Application> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Application")}
${t`Create Application`}
</span>
<ak-application-form slot="form">
</ak-application-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create")}
${t`Create`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import "../../elements/Tabs";
@ -49,13 +49,13 @@ export class ApplicationViewPage extends LitElement {
return html`<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>
${gettext("Loading...")}
${t`Loading...`}
</h1>
</div>
</section>
<ak-empty-state
?loading="${true}"
header=${gettext("Loading")}>
header=${t`Loading`}>
</ak-empty-state>`;
}
return html`<section class="pf-c-page__main-section pf-m-light">
@ -68,10 +68,10 @@ export class ApplicationViewPage extends LitElement {
</div>
</section>
<ak-tabs>
<section slot="page-1" data-tab-title="${gettext("Overview")}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<section slot="page-1" data-tab-title="${t`Overview`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-l-gallery pf-m-gutter">
<div class="pf-c-card pf-l-gallery__item" style="grid-column-end: span 3;grid-row-end: span 2;">
<div class="pf-c-card__title">${gettext("Logins over the last 24 hours")}</div>
<div class="pf-c-card__title">${t`Logins over the last 24 hours`}</div>
<div class="pf-c-card__body">
${this.application && html`
<ak-charts-application-authorize applicationSlug=${this.application.slug}>
@ -79,13 +79,13 @@ export class ApplicationViewPage extends LitElement {
</div>
</div>
<div class="pf-c-card pf-l-gallery__item">
<div class="pf-c-card__title">${gettext("Related")}</div>
<div class="pf-c-card__title">${t`Related`}</div>
<div class="pf-c-card__body">
<dl class="pf-c-description-list">
${this.application.provider ?
html`<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("Provider")}</span>
<span class="pf-c-description-list__text">${t`Provider`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
@ -100,7 +100,7 @@ export class ApplicationViewPage extends LitElement {
</div>
</div>
<div class="pf-c-card pf-l-gallery__item" style="grid-column-end: span 3;grid-row-end: span 2;">
<div class="pf-c-card__title">${gettext("Changelog")}</div>
<div class="pf-c-card__title">${t`Changelog`}</div>
<div class="pf-c-card__body">
<ak-object-changelog
targetModelPk=${this.application.pk || ""}
@ -111,9 +111,9 @@ export class ApplicationViewPage extends LitElement {
</div>
</div>
</section>
<div slot="page-2" data-tab-title="${gettext("Policy Bindings")}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div slot="page-2" data-tab-title="${t`Policy Bindings`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__title">${gettext("These policies control which users can access this application.")}</div>
<div class="pf-c-card__title">${t`These policies control which users can access this application.`}</div>
<ak-bound-policies-list .target=${this.application.pk}>
</ak-bound-policies-list>
</div>

View File

@ -1,6 +1,6 @@
import { CertificateGeneration, CryptoApi } from "authentik-api";
import { CertificateKeyPair } from "authentik-api/src";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -11,7 +11,7 @@ import "../../elements/forms/HorizontalFormElement";
export class CertificateKeyPairForm extends Form<CertificateGeneration> {
getSuccessMessage(): string {
return gettext("Successfully generated certificate-key pair.");
return t`Successfully generated certificate-key pair.`;
}
send = (data: CertificateGeneration): Promise<CertificateKeyPair> => {
@ -23,19 +23,19 @@ export class CertificateKeyPairForm extends Form<CertificateGeneration> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Common Name")}
label=${t`Common Name`}
name="commonName"
?required=${true}>
<input type="text" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Subject-alt name")}
label=${t`Subject-alt name`}
name="subjectAltName">
<input class="pf-c-form-control" type="text">
<p class="pf-c-form__helper-text">${gettext("Optional, comma-separated SubjectAlt Names.")}</p>
<p class="pf-c-form__helper-text">${t`Optional, comma-separated SubjectAlt Names.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Validity days")}
label=${t`Validity days`}
name="validityDays"
?required=${true}>
<input class="pf-c-form-control" type="number" value="365">

View File

@ -1,5 +1,5 @@
import { CertificateKeyPair, CryptoApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -17,9 +17,9 @@ export class CertificateKeyPairForm extends Form<CertificateKeyPair> {
getSuccessMessage(): string {
if (this.keyPair) {
return gettext("Successfully updated certificate-key pair.");
return t`Successfully updated certificate-key pair.`;
} else {
return gettext("Successfully created certificate-key pair.");
return t`Successfully created certificate-key pair.`;
}
}
@ -39,24 +39,24 @@ export class CertificateKeyPairForm extends Form<CertificateKeyPair> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
name="name"
?required=${true}>
<input type="text" value="${ifDefined(this.keyPair?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
${this.keyPair ? html`<ak-divider>${gettext("Only change the fields below if you want to overwrite their values.")}</ak-divider>` : html``}
${this.keyPair ? html`<ak-divider>${t`Only change the fields below if you want to overwrite their values.`}</ak-divider>` : html``}
<ak-form-element-horizontal
label=${gettext("Certificate")}
label=${t`Certificate`}
name="certificateData"
?required=${true}>
<textarea class="pf-c-form-control" required>${ifDefined(this.keyPair?.certificateData)}</textarea>
<p class="pf-c-form__helper-text">${gettext("PEM-encoded Certificate data.")}</p>
<p class="pf-c-form__helper-text">${t`PEM-encoded Certificate data.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
name="keyData"
label=${gettext("Private Key")}>
label=${t`Private Key`}>
<textarea class="pf-c-form-control" >${ifDefined(this.keyPair?.keyData)}</textarea>
<p class="pf-c-form__helper-text">${gettext("Optional Private Key. If this is set, you can use this keypair for encryption.")}</p>
<p class="pf-c-form__helper-text">${t`Optional Private Key. If this is set, you can use this keypair for encryption.`}</p>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage";
@ -23,10 +23,10 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
return true;
}
pageTitle(): string {
return gettext("Certificate-Key Pairs");
return t`Certificate-Key Pairs`;
}
pageDescription(): string {
return gettext("Import certificates of external providers or create certificates to sign requests with.");
return t`Import certificates of external providers or create certificates to sign requests with.`;
}
pageIcon(): string {
return "pf-icon pf-icon-key";
@ -50,7 +50,7 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn(t`Name`, t`name`),
new TableColumn("Private key available?"),
new TableColumn("Expiry date"),
new TableColumn(""),
@ -60,32 +60,32 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
row(item: CertificateKeyPair): TemplateResult[] {
return [
html`${item.name}`,
html`${gettext(item.privateKeyAvailable ? "Yes" : "No")}`,
html`${item.privateKeyAvailable ? t`Yes` : t`No`}`,
html`${item.certExpiry?.toLocaleString()}`,
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Certificate-Key Pair")}
${t`Update Certificate-Key Pair`}
</span>
<ak-crypto-certificate-form slot="form" .keyPair=${item}>
</ak-crypto-certificate-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Certificate-Key Pair")}
objectLabel=${t`Certificate-Key Pair`}
.delete=${() => {
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsDelete({
kpUuid: item.pk || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>`,
];
@ -98,7 +98,7 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
<dl class="pf-c-description-list pf-m-horizontal">
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("Certificate Fingerprint")}</span>
<span class="pf-c-description-list__text">${t`Certificate Fingerprint`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">${item.fingerprint}</div>
@ -106,7 +106,7 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("Certificate Subjet")}</span>
<span class="pf-c-description-list__text">${t`Certificate Subjet`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">${item.certSubject}</div>
@ -123,28 +123,28 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Certificate-Key Pair")}
${t`Create Certificate-Key Pair`}
</span>
<ak-crypto-certificate-form slot="form">
</ak-crypto-certificate-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create")}
${t`Create`}
</button>
</ak-forms-modal>
<ak-forms-modal>
<span slot="submit">
${gettext("Generate")}
${t`Generate`}
</span>
<span slot="header">
${gettext("Generate Certificate-Key Pair")}
${t`Generate Certificate-Key Pair`}
</span>
<ak-crypto-certificate-generate-form slot="form">
</ak-crypto-certificate-generate-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Generate")}
${t`Generate`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { until } from "lit-html/directives/until";
import { FlowsApi } from "authentik-api";
@ -43,7 +43,7 @@ export class EventInfo extends LitElement {
return html`<dl class="pf-c-description-list pf-m-horizontal">
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("UID")}</span>
<span class="pf-c-description-list__text">${t`UID`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">${context.pk as string}</div>
@ -51,7 +51,7 @@ export class EventInfo extends LitElement {
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("Name")}</span>
<span class="pf-c-description-list__text">${t`Name`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">${context.name as string}</div>
@ -59,7 +59,7 @@ export class EventInfo extends LitElement {
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("App")}</span>
<span class="pf-c-description-list__text">${t`App`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">${context.app as string}</div>
@ -67,7 +67,7 @@ export class EventInfo extends LitElement {
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("Model Name")}</span>
<span class="pf-c-description-list__text">${t`Model Name`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">${context.model_name as string}</div>
@ -79,11 +79,11 @@ export class EventInfo extends LitElement {
defaultResponse(): TemplateResult {
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${gettext("Context")}</h3>
<h3>${t`Context`}</h3>
<code>${JSON.stringify(this.event?.context, null, 4)}</code>
</div>
<div class="pf-l-flex__item">
<h3>${gettext("User")}</h3>
<h3>${t`User`}</h3>
<code>${JSON.stringify(this.event?.user, null, 4)}</code>
</div>
</div>`;
@ -98,17 +98,17 @@ export class EventInfo extends LitElement {
case "model_updated":
case "model_deleted":
return html`
<h3>${gettext("Affected model:")}</h3>
<h3>${t`Affected model:`}</h3>
${this.getModelInfo(this.event.context?.model as EventContext)}
`;
case "authorize_application":
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${gettext("Authorized application:")}</h3>
<h3>${t`Authorized application:`}</h3>
${this.getModelInfo(this.event.context.authorized_application as EventContext)}
</div>
<div class="pf-l-flex__item">
<h3>${gettext("Using flow")}</h3>
<h3>${t`Using flow`}</h3>
<span>${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
flowUuid: this.event.context.flow as string,
}).then(resp => {
@ -120,20 +120,20 @@ export class EventInfo extends LitElement {
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "login_failed":
return html`
<h3>${gettext(`Attempted to log in as ${this.event.context.username}`)}</h3>
<h3>${t`Attempted to log in as ${this.event.context.username}`}</h3>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "secret_view":
return html`
<h3>${gettext("Secret:")}</h3>
<h3>${t`Secret:`}</h3>
${this.getModelInfo(this.event.context.secret as EventContext)}`;
case "property_mapping_exception":
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${gettext("Exception")}</h3>
<h3>${t`Exception`}</h3>
<code>${this.event.context.message || this.event.context.error}</code>
</div>
<div class="pf-l-flex__item">
<h3>${gettext("Expression")}</h3>
<h3>${t`Expression`}</h3>
<code>${this.event.context.expression}</code>
</div>
</div>
@ -141,18 +141,18 @@ export class EventInfo extends LitElement {
case "policy_exception":
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${gettext("Binding")}</h3>
<h3>${t`Binding`}</h3>
${this.getModelInfo(this.event.context.binding as EventContext)}
</div>
<div class="pf-l-flex__item">
<h3>${gettext("Request")}</h3>
<h3>${t`Request`}</h3>
<ul class="pf-c-list">
<li>${gettext("Object")}: ${this.getModelInfo((this.event.context.request as EventContext).obj as EventContext)}</li>
<li><span>${gettext("Context")}: <code>${JSON.stringify((this.event.context.request as EventContext).context, null, 4)}</code></span></li>
<li>${t`Object`}: ${this.getModelInfo((this.event.context.request as EventContext).obj as EventContext)}</li>
<li><span>${t`Context`}: <code>${JSON.stringify((this.event.context.request as EventContext).context, null, 4)}</code></span></li>
</ul>
</div>
<div class="pf-l-flex__item">
<h3>${gettext("Exception")}</h3>
<h3>${t`Exception`}</h3>
<code>${this.event.context.message || this.event.context.error}</code>
</div>
</div>
@ -160,21 +160,21 @@ export class EventInfo extends LitElement {
case "policy_execution":
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${gettext("Binding")}</h3>
<h3>${t`Binding`}</h3>
${this.getModelInfo(this.event.context.binding as EventContext)}
</div>
<div class="pf-l-flex__item">
<h3>${gettext("Request")}</h3>
<h3>${t`Request`}</h3>
<ul class="pf-c-list">
<li>${gettext("Object")}: ${this.getModelInfo((this.event.context.request as EventContext).obj as EventContext)}</li>
<li><span>${gettext("Context")}: <code>${JSON.stringify((this.event.context.request as EventContext).context, null, 4)}</code></span></li>
<li>${t`Object`}: ${this.getModelInfo((this.event.context.request as EventContext).obj as EventContext)}</li>
<li><span>${t`Context`}: <code>${JSON.stringify((this.event.context.request as EventContext).context, null, 4)}</code></span></li>
</ul>
</div>
<div class="pf-l-flex__item">
<h3>${gettext("Result")}</h3>
<h3>${t`Result`}</h3>
<ul class="pf-c-list">
<li>${gettext("Passing")}: ${(this.event.context.result as EventContext).passing}</li>
<li>${gettext("Messages")}:
<li>${t`Passing`}: ${(this.event.context.result as EventContext).passing}</li>
<li>${t`Messages`}:
<ul class="pf-c-list">
${((this.event.context.result as EventContext).messages as string[]).map(msg => {
return html`<li>${msg}</li>`;
@ -189,7 +189,7 @@ export class EventInfo extends LitElement {
return html`<h3>${this.event.context.message}</h3>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "update_available":
return html`<h3>${gettext("New version available!")}</h3>
return html`<h3>${t`New version available!`}</h3>
<a target="_blank" href="https://github.com/BeryJu/authentik/releases/tag/version%2F${this.event.context.new_version}">${this.event.context.new_version}</a>
`;
// Action types which typically don't record any extra context.
@ -198,7 +198,7 @@ export class EventInfo extends LitElement {
if ("using_source" in this.event.context) {
return html`<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${gettext("Using source")}</h3>
<h3>${t`Using source`}</h3>
${this.getModelInfo(this.event.context.using_source as EventContext)}
</div>
</div>`;
@ -206,7 +206,7 @@ export class EventInfo extends LitElement {
return this.defaultResponse();
case "logout":
if (this.event.context === {}) {
return html`<span>${gettext("No additional data available.")}</span>`;
return html`<span>${t`No additional data available.`}</span>`;
}
return this.defaultResponse();
default:

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { EventsApi } from "authentik-api";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -37,7 +37,7 @@ export class EventInfoPage extends LitElement {
<div class="pf-c-content">
<h1>
<i class="pf-icon pf-icon-catalog"></i>
${gettext(`Event ${this.event?.pk || ""}`)}
${t`Event ${this.event?.pk || ""}`}
</h1>
</div>
</section>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { Event, EventsApi } from "authentik-api";
import { AKResponse } from "../../api/Client";
@ -40,10 +40,10 @@ export class EventListPage extends TablePage<Event> {
columns(): TableColumn[] {
return [
new TableColumn("Action", "action"),
new TableColumn("User", "user"),
new TableColumn("Creation Date", "created"),
new TableColumn("Client IP", "client_ip"),
new TableColumn(t`Action`, t`action`),
new TableColumn(t`User`, t`user`),
new TableColumn(t`Creation Date`, t`created`),
new TableColumn(t`Client IP`, t`client_ip`),
];
}
row(item: EventWithContext): TemplateResult[] {
@ -52,7 +52,7 @@ export class EventListPage extends TablePage<Event> {
<small>${item.app}</small>`,
html`<div>${item.user?.username}</div>
${item.user.on_behalf_of ? html`<small>
${gettext(`On behalf of ${item.user.on_behalf_of.username}`)}
${t`On behalf of ${item.user.on_behalf_of.username}`}
</small>` : html``}`,
html`<span>${item.created?.toLocaleString()}</span>`,
html`<span>${item.clientIp}</span>`,

View File

@ -1,5 +1,5 @@
import { CoreApi, EventsApi, NotificationRule, NotificationRuleSeverityEnum } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -16,9 +16,9 @@ export class RuleForm extends Form<NotificationRule> {
getSuccessMessage(): string {
if (this.rule) {
return gettext("Successfully updated rule.");
return t`Successfully updated rule.`;
} else {
return gettext("Successfully created rule.");
return t`Successfully created rule.`;
}
}
@ -38,13 +38,13 @@ export class RuleForm extends Form<NotificationRule> {
renderSeverity(): TemplateResult {
return html`
<option value=${NotificationRuleSeverityEnum.Alert} ?selected=${this.rule?.severity === NotificationRuleSeverityEnum.Alert}>
${gettext("Alert")}
${t`Alert`}
</option>
<option value=${NotificationRuleSeverityEnum.Warning} ?selected=${this.rule?.severity === NotificationRuleSeverityEnum.Warning}>
${gettext("Warning")}
${t`Warning`}
</option>
<option value=${NotificationRuleSeverityEnum.Notice} ?selected=${this.rule?.severity === NotificationRuleSeverityEnum.Notice}>
${gettext("Notice")}
${t`Notice`}
</option>
`;
}
@ -52,13 +52,13 @@ export class RuleForm extends Form<NotificationRule> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.rule?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Group")}
label=${t`Group`}
name="group">
<select class="pf-c-form-control">
<option value="" ?selected=${this.rule?.group === undefined}>---------</option>
@ -70,7 +70,7 @@ export class RuleForm extends Form<NotificationRule> {
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Transports")}
label=${t`Transports`}
?required=${true}
name="transports">
<select name="users" class="pf-c-form-control" multiple>
@ -83,11 +83,11 @@ export class RuleForm extends Form<NotificationRule> {
});
}))}
</select>
<p class="pf-c-form__helper-text">${gettext("Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI.")}</p>
<p class="pf-c-form__helper-text">${gettext("Hold control/command to select multiple items.")}</p>
<p class="pf-c-form__helper-text">${t`Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI.`}</p>
<p class="pf-c-form__helper-text">${t`Hold control/command to select multiple items.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Severity")}
label=${t`Severity`}
?required=${true}
name="severity">
<select class="pf-c-form-control">

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage";
@ -21,10 +21,10 @@ export class RuleListPage extends TablePage<NotificationRule> {
return true;
}
pageTitle(): string {
return gettext("Notification Rules");
return t`Notification Rules`;
}
pageDescription(): string {
return gettext("Send notifications whenever a specific Event is created and matched by policies.");
return t`Send notifications whenever a specific Event is created and matched by policies.`;
}
pageIcon(): string {
return "pf-icon pf-icon-attention-bell";
@ -44,9 +44,9 @@ export class RuleListPage extends TablePage<NotificationRule> {
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn("Severity", "severity"),
new TableColumn("Sent to group", "group"),
new TableColumn(t`Name`, t`name`),
new TableColumn(t`Severity`, t`severity`),
new TableColumn(t`Sent to group`, t`group`),
new TableColumn(""),
];
}
@ -55,31 +55,31 @@ export class RuleListPage extends TablePage<NotificationRule> {
return [
html`${item.name}`,
html`${item.severity}`,
html`${item.group?.name || gettext("None (rule disabled)")}`,
html`${item.group?.name || t`None (rule disabled)`}`,
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Notification Rule")}
${t`Update Notification Rule`}
</span>
<ak-event-rule-form slot="form" .rule=${item}>
</ak-event-rule-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Notification rule")}
objectLabel=${t`Notification rule`}
.delete=${() => {
return new EventsApi(DEFAULT_CONFIG).eventsRulesDelete({
pbmUuid: item.pk || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>`,
];
@ -89,15 +89,15 @@ export class RuleListPage extends TablePage<NotificationRule> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Notification Rule")}
${t`Create Notification Rule`}
</span>
<ak-event-rule-form slot="form">
</ak-event-rule-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create")}
${t`Create`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,5 +1,5 @@
import { EventsApi, NotificationTransport, NotificationTransportModeEnum } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -18,9 +18,9 @@ export class TransportForm extends Form<NotificationTransport> {
getSuccessMessage(): string {
if (this.transport) {
return gettext("Successfully updated transport.");
return t`Successfully updated transport.`;
} else {
return gettext("Successfully created transport.");
return t`Successfully created transport.`;
}
}
@ -40,13 +40,13 @@ export class TransportForm extends Form<NotificationTransport> {
renderTransportModes(): TemplateResult {
return html`
<option value=${NotificationTransportModeEnum.Email} ?selected=${this.transport?.mode === NotificationTransportModeEnum.Email}>
${gettext("Email")}
${t`Email`}
</option>
<option value=${NotificationTransportModeEnum.Webhook} ?selected=${this.transport?.mode === NotificationTransportModeEnum.Webhook}>
${gettext("Webhook (generic)")}
${t`Webhook (generic)`}
</option>
<option value=${NotificationTransportModeEnum.WebhookSlack} ?selected=${this.transport?.mode === NotificationTransportModeEnum.WebhookSlack}>
${gettext("Webhook (Slack/Discord)")}
${t`Webhook (Slack/Discord)`}
</option>
`;
}
@ -68,13 +68,13 @@ export class TransportForm extends Form<NotificationTransport> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.transport?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Mode")}
label=${t`Mode`}
?required=${true}
name="mode">
<select class="pf-c-form-control" @change=${(ev: Event) => {
@ -86,7 +86,7 @@ export class TransportForm extends Form<NotificationTransport> {
</ak-form-element-horizontal>
<ak-form-element-horizontal
?hidden=${!this.showWebhook}
label=${gettext("Webhook URL")}
label=${t`Webhook URL`}
name="webhookUrl">
<input type="text" value="${ifDefined(this.transport?.webhookUrl)}" class="pf-c-form-control">
</ak-form-element-horizontal>
@ -94,10 +94,10 @@ export class TransportForm extends Form<NotificationTransport> {
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.transport?.sendOnce || false}>
<label class="pf-c-check__label">
${gettext("Send once")}
${t`Send once`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("Only send notification once, for example when sending a webhook into a chat channel.")}</p>
<p class="pf-c-form__helper-text">${t`Only send notification once, for example when sending a webhook into a chat channel.`}</p>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage";
@ -19,10 +19,10 @@ export class TransportListPage extends TablePage<NotificationTransport> {
return true;
}
pageTitle(): string {
return gettext("Notification Transports");
return t`Notification Transports`;
}
pageDescription(): string {
return gettext("Define how notifications are sent to users, like Email or Webhook.");
return t`Define how notifications are sent to users, like Email or Webhook.`;
}
pageIcon(): string {
return "pf-icon pf-icon-export";
@ -42,8 +42,8 @@ export class TransportListPage extends TablePage<NotificationTransport> {
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn("Mode", "mode"),
new TableColumn(t`Name`, t`name`),
new TableColumn(t`Mode`, t`mode`),
new TableColumn(""),
];
}
@ -59,31 +59,31 @@ export class TransportListPage extends TablePage<NotificationTransport> {
uuid: item.pk || "",
});
}}>
${gettext("Test")}
${t`Test`}
</ak-action-button>
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Notification Transport")}
${t`Update Notification Transport`}
</span>
<ak-event-transport-form slot="form" .transport=${item}>
</ak-event-transport-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Notifications Transport")}
objectLabel=${t`Notifications Transport`}
.delete=${() => {
return new EventsApi(DEFAULT_CONFIG).eventsTransportsDelete({
uuid: item.pk || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>`,
];
@ -93,15 +93,15 @@ export class TransportListPage extends TablePage<NotificationTransport> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Notification Transport")}
${t`Create Notification Transport`}
</span>
<ak-event-transport-form slot="form">
</ak-event-transport-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create")}
${t`Create`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../../elements/table/Table";
@ -50,10 +50,10 @@ export class BoundStagesList extends Table<FlowStageBinding> {
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext(`Update ${item.stageObj?.verboseName}`)}
${t`Update ${item.stageObj?.verboseName}`}
</span>
<ak-proxy-form
slot="form"
@ -63,32 +63,32 @@ export class BoundStagesList extends Table<FlowStageBinding> {
type=${ifDefined(item.stageObj?.component)}>
</ak-proxy-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit Stage")}
${t`Edit Stage`}
</button>
</ak-forms-modal>
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Stage binding")}
${t`Update Stage binding`}
</span>
<ak-stage-binding-form slot="form" .fsb=${item}>
</ak-stage-binding-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit Binding")}
${t`Edit Binding`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Stage binding")}
objectLabel=${t`Stage binding`}
.delete=${() => {
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsDelete({
fsbUuid: item.pk || "",
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete Binding")}
${t`Delete Binding`}
</button>
</ak-forms-delete>`,
];
@ -100,7 +100,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
<td role="cell" colspan="3">
<div class="pf-c-table__expandable-row-content">
<div class="pf-c-content">
<p>${gettext("These policies control when this stage will be applied to the flow.")}</p>
<p>${t`These policies control when this stage will be applied to the flow.`}</p>
<ak-bound-policies-list .target=${item.policybindingmodelPtrId}>
</ak-bound-policies-list>
</div>
@ -111,22 +111,22 @@ export class BoundStagesList extends Table<FlowStageBinding> {
}
renderEmpty(): TemplateResult {
return super.renderEmpty(html`<ak-empty-state header=${gettext("No Stages bound")} icon="pf-icon-module">
return super.renderEmpty(html`<ak-empty-state header=${t`No Stages bound`} icon="pf-icon-module">
<div slot="body">
${gettext("No stages are currently bound to this flow.")}
${t`No stages are currently bound to this flow.`}
</div>
<div slot="primary">
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Stage binding")}
${t`Create Stage binding`}
</span>
<ak-stage-binding-form slot="form" targetPk=${ifDefined(this.target)}>
</ak-stage-binding-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Bind stage")}
${t`Bind stage`}
</button>
</ak-forms-modal>
</div>
@ -137,7 +137,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
return html`
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">${gettext("Create Stage")}</span>
<span class="pf-c-dropdown__toggle-text">${t`Create Stage`}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
@ -146,10 +146,10 @@ export class BoundStagesList extends Table<FlowStageBinding> {
return html`<li>
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext(`Create ${type.name}`)}
${t`Create ${type.name}`}
</span>
<ak-proxy-form
slot="form"
@ -167,15 +167,15 @@ export class BoundStagesList extends Table<FlowStageBinding> {
</ak-dropdown>
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Stage binding")}
${t`Create Stage binding`}
</span>
<ak-stage-binding-form slot="form" targetPk=${ifDefined(this.target)}>
</ak-stage-binding-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Bind stage")}
${t`Bind stage`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,5 +1,5 @@
import { Flow, FlowDesignationEnum, FlowPolicyEngineModeEnum, FlowsApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -15,9 +15,9 @@ export class FlowForm extends Form<Flow> {
getSuccessMessage(): string {
if (this.flow) {
return gettext("Successfully updated flow.");
return t`Successfully updated flow.`;
} else {
return gettext("Successfully created flow.");
return t`Successfully created flow.`;
}
}
@ -48,25 +48,25 @@ export class FlowForm extends Form<Flow> {
renderDesignations(): TemplateResult {
return html`
<option value=${FlowDesignationEnum.Authentication} ?selected=${this.flow?.designation === FlowDesignationEnum.Authentication}>
${gettext("Authentication")}
${t`Authentication`}
</option>
<option value=${FlowDesignationEnum.Authorization} ?selected=${this.flow?.designation === FlowDesignationEnum.Authorization}>
${gettext("Authorization")}
${t`Authorization`}
</option>
<option value=${FlowDesignationEnum.Enrollment} ?selected=${this.flow?.designation === FlowDesignationEnum.Enrollment}>
${gettext("Enrollment")}
${t`Enrollment`}
</option>
<option value=${FlowDesignationEnum.Invalidation} ?selected=${this.flow?.designation === FlowDesignationEnum.Invalidation}>
${gettext("Invalidation")}
${t`Invalidation`}
</option>
<option value=${FlowDesignationEnum.Recovery} ?selected=${this.flow?.designation === FlowDesignationEnum.Recovery}>
${gettext("Recovery")}
${t`Recovery`}
</option>
<option value=${FlowDesignationEnum.StageConfiguration} ?selected=${this.flow?.designation === FlowDesignationEnum.StageConfiguration}>
${gettext("Stage Configuration")}
${t`Stage Configuration`}
</option>
<option value=${FlowDesignationEnum.Unenrollment} ?selected=${this.flow?.designation === FlowDesignationEnum.Unenrollment}>
${gettext("Unenrollment")}
${t`Unenrollment`}
</option>
`;
}
@ -74,53 +74,53 @@ export class FlowForm extends Form<Flow> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.flow?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Title")}
label=${t`Title`}
?required=${true}
name="title">
<input type="text" value="${ifDefined(this.flow?.title)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${gettext("Shown as the Title in Flow pages.")}</p>
<p class="pf-c-form__helper-text">${t`Shown as the Title in Flow pages.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.flow?.slug)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${gettext("Visible in the URL.")}</p>
<p class="pf-c-form__helper-text">${t`Visible in the URL.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Policy engine mode")}
label=${t`Policy engine mode`}
?required=${true}
name="policyEngineMode">
<select class="pf-c-form-control">
<option value=${FlowPolicyEngineModeEnum.Any} ?selected=${this.flow?.policyEngineMode === FlowPolicyEngineModeEnum.Any}>
${gettext("ANY, any policy must match to grant access.")}
${t`ANY, any policy must match to grant access.`}
</option>
<option value=${FlowPolicyEngineModeEnum.All} ?selected=${this.flow?.policyEngineMode === FlowPolicyEngineModeEnum.All}>
${gettext("ALL, all policies must match to grant access.")}
${t`ALL, all policies must match to grant access.`}
</option>
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Designation")}
label=${t`Designation`}
?required=${true}
name="designation">
<select class="pf-c-form-control">
<option value="" ?selected=${this.flow?.designation === undefined}>---------</option>
${this.renderDesignations()}
</select>
<p class="pf-c-form__helper-text">${gettext("Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik.")}</p>
<p class="pf-c-form__helper-text">${t`Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Background")}
label=${t`Background`}
name="background">
<input type="file" value="${ifDefined(this.flow?.background)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${gettext("Background shown during execution.")}</p>
<p class="pf-c-form__helper-text">${t`Background shown during execution.`}</p>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,5 +1,5 @@
import { Flow, FlowsApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -10,7 +10,7 @@ import "../../elements/forms/HorizontalFormElement";
export class FlowImportForm extends Form<Flow> {
getSuccessMessage(): string {
return gettext("Successfully imported flow.");
return t`Successfully imported flow.`;
}
// eslint-disable-next-line
@ -27,10 +27,10 @@ export class FlowImportForm extends Form<Flow> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Flow")}
label=${t`Flow`}
name="flow">
<input type="file" value="" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${gettext("Background shown during execution.")}</p>
<p class="pf-c-form__helper-text">${t`Background shown during execution.`}</p>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage";
@ -19,10 +19,10 @@ export class FlowListPage extends TablePage<Flow> {
return true;
}
pageTitle(): string {
return gettext("Flows");
return t`Flows`;
}
pageDescription(): string {
return gettext("Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them.");
return t`Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them.`;
}
pageIcon(): string {
return "pf-icon pf-icon-process-automation";
@ -42,9 +42,9 @@ export class FlowListPage extends TablePage<Flow> {
columns(): TableColumn[] {
return [
new TableColumn("Identifier", "slug"),
new TableColumn("Name", "name"),
new TableColumn("Designation", "designation"),
new TableColumn(t`Identifier`, t`slug`),
new TableColumn(t`Name`, t`name`),
new TableColumn(t`Designation`, t`designation`),
new TableColumn("Stages"),
new TableColumn("Policies"),
new TableColumn(""),
@ -63,27 +63,27 @@ export class FlowListPage extends TablePage<Flow> {
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Flow")}
${t`Update Flow`}
</span>
<ak-flow-form slot="form" .flow=${item}>
</ak-flow-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Flow")}
objectLabel=${t`Flow`}
.delete=${() => {
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesDelete({
slug: item.slug
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>
<button
@ -95,10 +95,10 @@ export class FlowListPage extends TablePage<Flow> {
window.location.assign(`${link.link}?next=/%23${window.location.href}`);
});
}}>
${gettext("Execute")}
${t`Execute`}
</button>
<a class="pf-c-button pf-m-secondary" href="${`${DEFAULT_CONFIG.basePath}/flows/instances/${item.slug}/export/`}">
${gettext("Export")}
${t`Export`}
</a>`,
];
}
@ -107,28 +107,28 @@ export class FlowListPage extends TablePage<Flow> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Flow")}
${t`Create Flow`}
</span>
<ak-flow-form slot="form">
</ak-flow-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create")}
${t`Create`}
</button>
</ak-forms-modal>
<ak-forms-modal>
<span slot="submit">
${gettext("Import")}
${t`Import`}
</span>
<span slot="header">
${gettext("Import Flow")}
${t`Import Flow`}
</span>
<ak-flow-import-form slot="form">
</ak-flow-import-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Import")}
${t`Import`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import "../../elements/Tabs";
@ -59,7 +59,7 @@ export class FlowViewPage extends LitElement {
</div>
</section>
<ak-tabs>
<div slot="page-1" data-tab-title="${gettext("Flow Overview")}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div slot="page-1" data-tab-title="${t`Flow Overview`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-l-gallery pf-m-gutter">
<div class="pf-c-card pf-l-gallery__item" style="grid-column-end: span 3;grid-row-end: span 2;">
<div class="pf-c-card">
@ -70,12 +70,12 @@ export class FlowViewPage extends LitElement {
</div>
</div>
<div class="pf-c-card pf-l-gallery__item">
<div class="pf-c-card__title">${gettext("Related")}</div>
<div class="pf-c-card__title">${t`Related`}</div>
<div class="pf-c-card__body">
<dl class="pf-c-description-list">
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${gettext("Execute flow")}</span>
<span class="pf-c-description-list__text">${t`Execute flow`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
@ -88,7 +88,7 @@ export class FlowViewPage extends LitElement {
window.location.assign(`${link.link}?next=/%23${window.location.href}`);
});
}}>
${gettext("Execute")}
${t`Execute`}
</button>
</div>
</dd>
@ -98,7 +98,7 @@ export class FlowViewPage extends LitElement {
</div>
</div>
</div>
<div slot="page-2" data-tab-title="${gettext("Stage Bindings")}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div slot="page-2" data-tab-title="${t`Stage Bindings`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-bound-stages-list .target=${this.flow.pk}>
@ -106,16 +106,16 @@ export class FlowViewPage extends LitElement {
</div>
</div>
</div>
<div slot="page-3" data-tab-title="${gettext("Policy Bindings")}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div slot="page-3" data-tab-title="${t`Policy Bindings`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__title">${gettext("These policies control which users can access this flow.")}</div>
<div class="pf-c-card__title">${t`These policies control which users can access this flow.`}</div>
<div class="pf-c-card__body">
<ak-bound-policies-list .target=${this.flow.policybindingmodelPtrId}>
</ak-bound-policies-list>
</div>
</div>
</div>
<div slot="page-4" data-tab-title="${gettext("Changelog")}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div slot="page-4" data-tab-title="${t`Changelog`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-object-changelog

View File

@ -1,5 +1,5 @@
import { FlowsApi, FlowStageBinding, FlowStageBindingPolicyEngineModeEnum, Stage, StagesApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -20,9 +20,9 @@ export class StageBindingForm extends Form<FlowStageBinding> {
getSuccessMessage(): string {
if (this.fsb) {
return gettext("Successfully updated binding.");
return t`Successfully updated binding.`;
} else {
return gettext("Successfully created binding.");
return t`Successfully created binding.`;
}
}
@ -71,7 +71,7 @@ export class StageBindingForm extends Form<FlowStageBinding> {
`;
}
return html`<ak-form-element-horizontal
label=${gettext("Target")}
label=${t`Target`}
?required=${true}
name="target">
<select class="pf-c-form-control">
@ -91,7 +91,7 @@ export class StageBindingForm extends Form<FlowStageBinding> {
return html`<form class="pf-c-form pf-m-horizontal">
${this.renderTarget()}
<ak-form-element-horizontal
label=${gettext("Stage")}
label=${t`Stage`}
?required=${true}
name="stage">
<select class="pf-c-form-control">
@ -106,36 +106,36 @@ export class StageBindingForm extends Form<FlowStageBinding> {
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.fsb?.evaluateOnPlan || true}>
<label class="pf-c-check__label">
${gettext("Evaluate on plan")}
${t`Evaluate on plan`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("Evaluate policies during the Flow planning process. Disable this for input-based policies.")}</p>
<p class="pf-c-form__helper-text">${t`Evaluate policies during the Flow planning process. Disable this for input-based policies.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="reEvaluatePolicies">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.fsb?.reEvaluatePolicies || false}>
<label class="pf-c-check__label">
${gettext("Re-evaluate policies")}
${t`Re-evaluate policies`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("Evaluate policies when the Stage is present to the user.")}</p>
<p class="pf-c-form__helper-text">${t`Evaluate policies when the Stage is present to the user.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Order")}
label=${t`Order`}
?required=${true}
name="order">
<input type="number" value="${until(this.getOrder(), this.fsb?.order)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Policy engine mode")}
label=${t`Policy engine mode`}
?required=${true}
name="policyEngineMode">
<select class="pf-c-form-control">
<option value=${FlowStageBindingPolicyEngineModeEnum.Any} ?selected=${this.fsb?.policyEngineMode === FlowStageBindingPolicyEngineModeEnum.Any}>
${gettext("ANY, any policy must match to grant access.")}
${t`ANY, any policy must match to grant access.`}
</option>
<option value=${FlowStageBindingPolicyEngineModeEnum.All} ?selected=${this.fsb?.policyEngineMode === FlowStageBindingPolicyEngineModeEnum.All}>
${gettext("ALL, all policies must match to grant access.")}
${t`ALL, all policies must match to grant access.`}
</option>
</select>
</ak-form-element-horizontal>

View File

@ -1,5 +1,5 @@
import { CoreApi, Group } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -18,9 +18,9 @@ export class GroupForm extends Form<Group> {
getSuccessMessage(): string {
if (this.group) {
return gettext("Successfully updated group.");
return t`Successfully updated group.`;
} else {
return gettext("Successfully created group.");
return t`Successfully created group.`;
}
}
@ -40,7 +40,7 @@ export class GroupForm extends Form<Group> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.group?.name)}" class="pf-c-form-control" required>
@ -49,13 +49,13 @@ export class GroupForm extends Form<Group> {
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.group?.isSuperuser || false}>
<label class="pf-c-check__label">
${gettext("Is superuser")}
${t`Is superuser`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("Users added to this group will be superusers.")}</p>
<p class="pf-c-form__helper-text">${t`Users added to this group will be superusers.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Parent")}
label=${t`Parent`}
?required=${true}
name="parent">
<select class="pf-c-form-control">
@ -68,7 +68,7 @@ export class GroupForm extends Form<Group> {
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Members")}
label=${t`Members`}
?required=${true}
name="users">
<select class="pf-c-form-control" multiple>
@ -83,10 +83,10 @@ export class GroupForm extends Form<Group> {
});
}))}
</select>
<p class="pf-c-form__helper-text">${gettext("Hold control/command to select multiple items.")}</p>
<p class="pf-c-form__helper-text">${t`Hold control/command to select multiple items.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Attributes")}
label=${t`Attributes`}
name="attributes">
<ak-codemirror mode="yaml" value="${YAML.stringify(this.group?.attributes)}">
</ak-codemirror>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage";
@ -18,10 +18,10 @@ export class GroupListPage extends TablePage<Group> {
return true;
}
pageTitle(): string {
return gettext("Groups");
return t`Groups`;
}
pageDescription(): string {
return gettext("Group users together and give them permissions based on the membership.");
return t`Group users together and give them permissions based on the membership.`;
}
pageIcon(): string {
return "pf-icon pf-icon-users";
@ -41,8 +41,8 @@ export class GroupListPage extends TablePage<Group> {
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn("Parent", "parent"),
new TableColumn(t`Name`, t`name`),
new TableColumn(t`Parent`, t`parent`),
new TableColumn("Members"),
new TableColumn("Superuser privileges?"),
new TableColumn(""),
@ -54,31 +54,31 @@ export class GroupListPage extends TablePage<Group> {
html`${item.name}`,
html`${item.parent || "-"}`,
html`${item.users?.keys.length}`,
html`${item.isSuperuser ? "Yes" : "No"}`,
html`${item.isSuperuser ? t`Yes` : t`No`}`,
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Group")}
${t`Update Group`}
</span>
<ak-group-form slot="form" .group=${item}>
</ak-group-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Group")}
objectLabel=${t`Group`}
.delete=${() => {
return new CoreApi(DEFAULT_CONFIG).coreGroupsDelete({
groupUuid: item.pk || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>`,
];
@ -88,15 +88,15 @@ export class GroupListPage extends TablePage<Group> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Group")}
${t`Create Group`}
</span>
<ak-group-form slot="form">
</ak-group-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create")}
${t`Create`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,5 +1,5 @@
import { Outpost, OutpostsApi, ProvidersApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -18,9 +18,9 @@ export class OutpostForm extends Form<Outpost> {
getSuccessMessage(): string {
if (this.outpost) {
return gettext("Successfully updated outpost.");
return t`Successfully updated outpost.`;
} else {
return gettext("Successfully created outpost.");
return t`Successfully created outpost.`;
}
}
@ -40,21 +40,21 @@ export class OutpostForm extends Form<Outpost> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.outpost?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Type")}
label=${t`Type`}
?required=${true}
name="type">
<select class="pf-c-form-control">
<option value="proxy" ?selected=${true}>${gettext("Proxy")}</option>s
<option value="proxy" ?selected=${true}>${t`Proxy`}</option>s
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Service connection")}
label=${t`Service connection`}
name="serviceConnection">
<select class="pf-c-form-control">
<option value="" ?selected=${this.outpost?.serviceConnection === undefined}>---------</option>
@ -66,13 +66,13 @@ export class OutpostForm extends Form<Outpost> {
});
}), html``)}
</select>
<p class="pf-c-form__helper-text">${gettext("Selecting a service-connection enables the management of the outpost by authentik.")}</p>
<p class="pf-c-form__helper-text">${t`Selecting a service-connection enables the management of the outpost by authentik.`}</p>
<p class="pf-c-form__helper-text">
See <a _target="blank" href="https://goauthentik.io/docs/outposts/outposts">documentation</a>.
See <a target="_blank" href="https://goauthentik.io/docs/outposts/outposts">documentation</a>.
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Providers")}
label=${t`Providers`}
?required=${true}
name="providers">
<select class="pf-c-form-control" multiple>
@ -87,7 +87,7 @@ export class OutpostForm extends Form<Outpost> {
});
}))}
</select>
<p class="pf-c-form__helper-text">${gettext("Hold control/command to select multiple items.")}</p>
<p class="pf-c-form__helper-text">${t`Hold control/command to select multiple items.`}</p>
</ak-form-element-horizontal>
${until(new OutpostsApi(DEFAULT_CONFIG).outpostsOutpostsDefaultSettings({}).then(config => {
let fc = config.config;
@ -95,7 +95,7 @@ export class OutpostForm extends Form<Outpost> {
fc = this.outpost.config;
}
return html`<ak-form-element-horizontal
label=${gettext("Configuration")}
label=${t`Configuration`}
name="config">
<ak-codemirror mode="yaml" value="${YAML.stringify(fc)}"></ak-codemirror>
</ak-form-element-horizontal>`;

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { until } from "lit-html/directives/until";
import { OutpostsApi } from "authentik-api";
@ -28,7 +28,7 @@ export class OutpostHealth extends LitElement {
return html`<li>
<ul>
<li role="cell">
<i class="fas fa-question-circle"></i>${gettext("Not available")}
<i class="fas fa-question-circle"></i>${t`Not available`}
</li>
</ul>
</li>`;
@ -37,13 +37,13 @@ export class OutpostHealth extends LitElement {
return html`<li>
<ul>
<li role="cell">
<i class="fas fa-check pf-m-success"></i>${gettext(`Last seen: ${h.lastSeen?.toLocaleTimeString()}`)}
<i class="fas fa-check pf-m-success"></i>${t`Last seen: ${h.lastSeen?.toLocaleTimeString()}`}
</li>
<li role="cell">
${h.versionOutdated ?
html`<i class="fas fa-times pf-m-danger"></i>
${gettext(`${h.version}, should be ${h.versionShould}`)}` :
html`<i class="fas fa-check pf-m-success"></i>${gettext(`Version: ${h.version || ""}`)}`}
${t`${h.version}, should be ${h.versionShould}`}` :
html`<i class="fas fa-check pf-m-success"></i>${t`Version: ${h.version || ""}`}`}
</li>
</ul>
</li>`;

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { AKResponse } from "../../api/Client";
@ -40,7 +40,7 @@ export class OutpostListPage extends TablePage<Outpost> {
}
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn(t`Name`, t`name`),
new TableColumn("Providers"),
new TableColumn("Health and Version"),
new TableColumn(""),
@ -60,39 +60,39 @@ export class OutpostListPage extends TablePage<Outpost> {
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Outpost")}
${t`Update Outpost`}
</span>
<ak-outpost-form slot="form" .outpost=${item}>
</ak-outpost-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Outpost")}
objectLabel=${t`Outpost`}
.delete=${() => {
return new OutpostsApi(DEFAULT_CONFIG).outpostsOutpostsDelete({
uuid: item.pk || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>
<ak-modal-button>
<button slot="trigger" class="pf-c-button pf-m-tertiary">
${gettext("View Deployment Info")}
${t`View Deployment Info`}
</button>
<div slot="modal">
<div class="pf-c-modal-box__header">
<h1 class="pf-c-title pf-m-2xl" id="modal-title">${gettext("Outpost Deployment Info")}</h1>
<h1 class="pf-c-title pf-m-2xl" id="modal-title">${t`Outpost Deployment Info`}</h1>
</div>
<div class="pf-c-modal-box__body" id="modal-description">
<p><a href="https://goauthentik.io/docs/outposts/outposts/#deploy">${gettext("View deployment documentation")}</a></p>
<p><a href="https://goauthentik.io/docs/outposts/outposts/#deploy">${t`View deployment documentation`}</a></p>
<form class="pf-c-form">
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
@ -106,11 +106,11 @@ export class OutpostListPage extends TablePage<Outpost> {
</label>
<div>
<ak-token-copy-button identifier="${ifDefined(item.tokenIdentifier)}">
${gettext("Click to copy token")}
${t`Click to copy token`}
</ak-token-copy-button>
</div>
</div>
<h3>${gettext("If your authentik Instance is using a self-signed certificate, set this value.")}</h3>
<h3>${t`If your authentik Instance is using a self-signed certificate, set this value.`}</h3>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">AUTHENTIK_INSECURE</span>
@ -120,7 +120,7 @@ export class OutpostListPage extends TablePage<Outpost> {
</form>
</div>
<footer class="pf-c-modal-box__footer pf-m-align-left">
<a class="pf-c-button pf-m-primary">${gettext("Close")}</a>
<a class="pf-c-button pf-m-primary">${t`Close`}</a>
</footer>
</div>
</ak-modal-button>`,
@ -131,15 +131,15 @@ export class OutpostListPage extends TablePage<Outpost> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Outpost")}
${t`Create Outpost`}
</span>
<ak-outpost-form slot="form">
</ak-outpost-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create")}
${t`Create`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,5 +1,5 @@
import { CryptoApi, DockerServiceConnection, OutpostsApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -24,9 +24,9 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
getSuccessMessage(): string {
if (this.sc) {
return gettext("Successfully updated service-connection.");
return t`Successfully updated service-connection.`;
} else {
return gettext("Successfully created service-connection.");
return t`Successfully created service-connection.`;
}
}
@ -46,7 +46,7 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.sc?.name)}" class="pf-c-form-control" required>
@ -55,20 +55,20 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.sc?.local || false}>
<label class="pf-c-check__label">
${gettext("Local")}
${t`Local`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("If enabled, use the local connection. Required Docker socket/Kubernetes Integration.")}</p>
<p class="pf-c-form__helper-text">${t`If enabled, use the local connection. Required Docker socket/Kubernetes Integration.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Docker URL")}
label=${t`Docker URL`}
?required=${true}
name="url">
<input type="text" value="${ifDefined(this.sc?.url)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${gettext("Can be in the format of 'unix://' when connecting to a local docker daemon, or 'https://:2376' when connecting to a remote system.")}</p>
<p class="pf-c-form__helper-text">${t`Can be in the format of 'unix://' when connecting to a local docker daemon, or 'https://:2376' when connecting to a remote system.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("TLS Verification Certificate")}
label=${t`TLS Verification Certificate`}
?required=${true}
name="tlsVerification">
<select class="pf-c-form-control">
@ -81,10 +81,10 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
});
}))}
</select>
<p class="pf-c-form__helper-text">${gettext("CA which the endpoint's Certificate is verified against. Can be left empty for no validation.")}</p>
<p class="pf-c-form__helper-text">${t`CA which the endpoint's Certificate is verified against. Can be left empty for no validation.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("TLS Authentication Certificate")}
label=${t`TLS Authentication Certificate`}
?required=${true}
name="tlsAuthentication">
<select class="pf-c-form-control">
@ -97,7 +97,7 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
});
}))}
</select>
<p class="pf-c-form__helper-text">${gettext("Certificate/Key used for authentication. Can be left empty for no authentication.")}</p>
<p class="pf-c-form__helper-text">${t`Certificate/Key used for authentication. Can be left empty for no authentication.`}</p>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,5 +1,5 @@
import { KubernetesServiceConnection, OutpostsApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -25,9 +25,9 @@ export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConne
getSuccessMessage(): string {
if (this.sc) {
return gettext("Successfully updated service-connection.");
return t`Successfully updated service-connection.`;
} else {
return gettext("Successfully created service-connection.");
return t`Successfully created service-connection.`;
}
}
@ -47,7 +47,7 @@ export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConne
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.sc?.name)}" class="pf-c-form-control" required>
@ -56,13 +56,13 @@ export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConne
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.sc?.local || false}>
<label class="pf-c-check__label">
${gettext("Local")}
${t`Local`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("If enabled, use the local connection. Required Docker socket/Kubernetes Integration.")}</p>
<p class="pf-c-form__helper-text">${t`If enabled, use the local connection. Required Docker socket/Kubernetes Integration.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Kubeconfig")}
label=${t`Kubeconfig`}
name="kubeconfig">
<ak-codemirror mode="yaml" value="${YAML.stringify(this.sc?.kubeconfig)}">
</ak-codemirror>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { AKResponse } from "../../api/Client";
@ -45,9 +45,9 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn(t`Name`, t`name`),
new TableColumn("Type"),
new TableColumn("Local", "local"),
new TableColumn(t`Local`, t`local`),
new TableColumn("State"),
new TableColumn(""),
];
@ -60,7 +60,7 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
return [
html`${item.name}`,
html`${item.verboseName}`,
html`${item.local ? "Yes" : "No"}`,
html`${item.local ? t`Yes` : t`No`}`,
html`${until(
new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsAllState({
uuid: item.pk || ""
@ -68,15 +68,15 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
if (state.healthy) {
return html`<i class="fas fa-check pf-m-success"></i> ${state.version}`;
}
return html`<i class="fas fa-times pf-m-danger"></i> ${gettext("Unhealthy")}`;
return html`<i class="fas fa-times pf-m-danger"></i> ${t`Unhealthy`}`;
}), html`<ak-spinner></ak-spinner>`)}`,
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext(`Update ${item.verboseName}`)}
${t`Update ${item.verboseName}`}
</span>
<ak-proxy-form
slot="form"
@ -86,19 +86,19 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
type=${ifDefined(item.component)}>
</ak-proxy-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Outpost Service-connection")}
objectLabel=${t`Outpost Service-connection`}
.delete=${() => {
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsAllDelete({
uuid: item.pk || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>`,
];
@ -108,7 +108,7 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
return html`
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">${gettext("Create")}</span>
<span class="pf-c-dropdown__toggle-text">${t`Create`}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
@ -117,10 +117,10 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
return html`<li>
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext(`Create ${type.name}`)}
${t`Create ${type.name}`}
</span>
<ak-proxy-form
slot="form"

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { Table, TableColumn } from "../../elements/table/Table";
@ -36,22 +36,22 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
columns(): TableColumn[] {
return [
new TableColumn("Policy / User / Group"),
new TableColumn("Enabled", "enabled"),
new TableColumn("Order", "order"),
new TableColumn("Timeout", "timeout"),
new TableColumn(t`Enabled`, t`enabled`),
new TableColumn(t`Order`, t`order`),
new TableColumn(t`Timeout`, t`timeout`),
new TableColumn(""),
];
}
getPolicyUserGroupRow(item: PolicyBinding): string {
if (item.policy) {
return gettext(`Policy ${item.policyObj?.name}`);
return t`Policy ${item.policyObj?.name}`;
} else if (item.group) {
return gettext(`Group ${item.groupObj?.name}`);
return t`Group ${item.groupObj?.name}`;
} else if (item.user) {
return gettext(`User ${item.userObj?.name}`);
return t`User ${item.userObj?.name}`;
} else {
return gettext("");
return t`-`;
}
}
@ -60,10 +60,10 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
return html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext(`Update ${item.policyObj?.name}`)}
${t`Update ${item.policyObj?.name}`}
</span>
<ak-proxy-form
slot="form"
@ -73,35 +73,35 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
type=${ifDefined(item.policyObj?.component)}>
</ak-proxy-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>`;
} else if (item.group) {
return html`<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Group")}
${t`Update Group`}
</span>
<ak-group-form slot="form" .group=${item.groupObj}>
</ak-group-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Edit Group")}
${t`Edit Group`}
</button>
</ak-forms-modal>`;
} else if (item.user) {
return html`<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update User")}
${t`Update User`}
</span>
<ak-user-form slot="form" .user=${item.userObj}>
</ak-user-form>
<button slot="trigger" class="pf-m-secondary pf-c-button">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>`;
} else {
@ -112,56 +112,56 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
row(item: PolicyBinding): TemplateResult[] {
return [
html`${this.getPolicyUserGroupRow(item)}`,
html`${item.enabled ? "Yes" : "No"}`,
html`${item.enabled ? t`Yes` : t`No`}`,
html`${item.order}`,
html`${item.timeout}`,
html`
${this.getObjectEditButton(item)}
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext("Update Binding")}
${t`Update Binding`}
</span>
<ak-policy-binding-form slot="form" .binding=${item} targetPk=${ifDefined(this.target)}>
</ak-policy-binding-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit Binding")}
${t`Edit Binding`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Policy binding")}
objectLabel=${t`Policy binding`}
.delete=${() => {
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsDelete({
policyBindingUuid: item.pk || "",
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete Binding")}
${t`Delete Binding`}
</button>
</ak-forms-delete>`,
];
}
renderEmpty(): TemplateResult {
return super.renderEmpty(html`<ak-empty-state header=${gettext("No Policies bound.")} icon="pf-icon-module">
return super.renderEmpty(html`<ak-empty-state header=${t`No Policies bound.`} icon="pf-icon-module">
<div slot="body">
${gettext("No policies are currently bound to this object.")}
${t`No policies are currently bound to this object.`}
</div>
<div slot="primary">
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Binding")}
${t`Create Binding`}
</span>
<ak-policy-binding-form slot="form" targetPk=${ifDefined(this.target)}>
</ak-policy-binding-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create Binding")}
${t`Create Binding`}
</button>
</ak-forms-modal>
</div>
@ -172,7 +172,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
return html`
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">${gettext("Create Policy")}</span>
<span class="pf-c-dropdown__toggle-text">${t`Create Policy`}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
@ -181,10 +181,10 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
return html`<li>
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext(`Create ${type.name}`)}
${t`Create ${type.name}`}
</span>
<ak-proxy-form
slot="form"
@ -202,15 +202,15 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
</ak-dropdown>
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext("Create Binding")}
${t`Create Binding`}
</span>
<ak-policy-binding-form slot="form" targetPk=${ifDefined(this.target)}>
</ak-policy-binding-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${gettext("Create Binding")}
${t`Create Binding`}
</button>
</ak-forms-modal>
${super.renderToolbar()}

View File

@ -1,5 +1,5 @@
import { CoreApi, PoliciesApi, Policy, PolicyBinding } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -20,9 +20,9 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
getSuccessMessage(): string {
if (this.binding) {
return gettext("Successfully updated binding.");
return t`Successfully updated binding.`;
} else {
return gettext("Successfully created binding.");
return t`Successfully created binding.`;
}
}
@ -72,7 +72,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Policy")}
label=${t`Policy`}
name="policy">
<select class="pf-c-form-control">
<option value="" ?selected=${this.binding?.policy === undefined}>---------</option>
@ -84,7 +84,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Group")}
label=${t`Group`}
name="group">
<select class="pf-c-form-control">
<option value="" ?selected=${this.binding?.group === undefined}>---------</option>
@ -98,7 +98,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("User")}
label=${t`User`}
name="user">
<select class="pf-c-form-control">
<option value="" ?selected=${this.binding?.user === undefined}>---------</option>
@ -116,18 +116,18 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.binding?.enabled || true}>
<label class="pf-c-check__label">
${gettext("Enabled")}
${t`Enabled`}
</label>
</div>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Order")}
label=${t`Order`}
?required=${true}
name="order">
<input type="number" value="${until(this.getOrder(), this.binding?.order)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Timeout")}
label=${t`Timeout`}
?required=${true}
name="timeout">
<input type="number" value="${first(this.binding?.timeout, 30)}" class="pf-c-form-control" required>

View File

@ -1,4 +1,4 @@
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element";
import { AKResponse } from "../../api/Client";
import { TablePage } from "../../elements/table/TablePage";
@ -29,10 +29,10 @@ export class PolicyListPage extends TablePage<Policy> {
return true;
}
pageTitle(): string {
return gettext("Policies");
return t`Policies`;
}
pageDescription(): string {
return gettext("Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages.");
return t`Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages.`;
}
pageIcon(): string {
return "pf-icon pf-icon-infrastructure";
@ -52,7 +52,7 @@ export class PolicyListPage extends TablePage<Policy> {
columns(): TableColumn[] {
return [
new TableColumn("Name", "name"),
new TableColumn(t`Name`, t`name`),
new TableColumn("Type"),
new TableColumn(""),
];
@ -65,19 +65,19 @@ export class PolicyListPage extends TablePage<Policy> {
${(item.boundTo || 0) > 0 ?
html`<i class="pf-icon pf-icon-ok"></i>
<small>
${gettext(`Assigned to ${item.boundTo} objects.`)}
${t`Assigned to ${item.boundTo} objects.`}
</small>`:
html`<i class="pf-icon pf-icon-warning-triangle"></i>
<small>${gettext("Warning: Policy is not assigned.")}</small>`}
<small>${t`Warning: Policy is not assigned.`}</small>`}
</div>`,
html`${item.verboseName}`,
html`
<ak-forms-modal>
<span slot="submit">
${gettext("Update")}
${t`Update`}
</span>
<span slot="header">
${gettext(`Update ${item.verboseName}`)}
${t`Update ${item.verboseName}`}
</span>
<ak-proxy-form
slot="form"
@ -87,32 +87,32 @@ export class PolicyListPage extends TablePage<Policy> {
type=${ifDefined(item.component)}>
</ak-proxy-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Edit")}
${t`Edit`}
</button>
</ak-forms-modal>
<ak-forms-modal .closeAfterSuccessfulSubmit=${false}>
<span slot="submit">
${gettext("Test")}
${t`Test`}
</span>
<span slot="header">
${gettext("Test Policy")}
${t`Test Policy`}
</span>
<ak-policy-test-form slot="form" .policy=${item}>
</ak-policy-test-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${gettext("Test")}
${t`Test`}
</button>
</ak-forms-modal>
<ak-forms-delete
.obj=${item}
objectLabel=${gettext("Policy")}
objectLabel=${t`Policy`}
.delete=${() => {
return new PoliciesApi(DEFAULT_CONFIG).policiesAllDelete({
policyUuid: item.pk || ""
});
}}>
<button slot="trigger" class="pf-c-button pf-m-danger">
${gettext("Delete")}
${t`Delete`}
</button>
</ak-forms-delete>`,
];
@ -122,7 +122,7 @@ export class PolicyListPage extends TablePage<Policy> {
return html`
<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">${gettext("Create")}</span>
<span class="pf-c-dropdown__toggle-text">${t`Create`}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
@ -131,10 +131,10 @@ export class PolicyListPage extends TablePage<Policy> {
return html`<li>
<ak-forms-modal>
<span slot="submit">
${gettext("Create")}
${t`Create`}
</span>
<span slot="header">
${gettext(`Create ${type.name}`)}
${t`Create ${type.name}`}
</span>
<ak-proxy-form
slot="form"

View File

@ -1,5 +1,5 @@
import { CoreApi, PoliciesApi, Policy, PolicyTestResult } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
@ -20,7 +20,7 @@ export class PolicyTestForm extends Form<PolicyTest> {
result?: PolicyTestResult;
getSuccessMessage(): string {
return gettext("Successfully sent test-request.");
return t`Successfully sent test-request.`;
}
send = (data: PolicyTest): Promise<PolicyTestResult> => {
@ -33,15 +33,15 @@ export class PolicyTestForm extends Form<PolicyTest> {
renderResult(): TemplateResult {
return html`
<ak-form-element-horizontal
label=${gettext("Passing")}>
label=${t`Passing`}>
<div class="pf-c-form__group-label">
<div class="c-form__horizontal-group">
<span class="pf-c-form__label-text">${this.result?.passing ? gettext("Yes") : gettext("No")}</span>
<span class="pf-c-form__label-text">${this.result?.passing ? t`Yes` : t`No`}</span>
</div>
</div>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Messages")}>
label=${t`Messages`}>
<div class="pf-c-form__group-label">
<div class="c-form__horizontal-group">
<ul>
@ -59,7 +59,7 @@ export class PolicyTestForm extends Form<PolicyTest> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("User")}
label=${t`User`}
?required=${true}
name="user">
<select class="pf-c-form-control">
@ -73,7 +73,7 @@ export class PolicyTestForm extends Form<PolicyTest> {
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Context")}
label=${t`Context`}
name="context">
<ak-codemirror mode="yaml">
</ak-codemirror>

View File

@ -1,5 +1,5 @@
import { DummyPolicy, PoliciesApi } from "authentik-api";
import { gettext } from "django";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
@ -25,9 +25,9 @@ export class DummyPolicyForm extends Form<DummyPolicy> {
getSuccessMessage(): string {
if (this.policy) {
return gettext("Successfully updated policy.");
return t`Successfully updated policy.`;
} else {
return gettext("Successfully created policy.");
return t`Successfully created policy.`;
}
}
@ -47,7 +47,7 @@ export class DummyPolicyForm extends Form<DummyPolicy> {
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${gettext("Name")}
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
@ -56,34 +56,34 @@ export class DummyPolicyForm extends Form<DummyPolicy> {
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.policy?.executionLogging || false}>
<label class="pf-c-check__label">
${gettext("Execution logging")}
${t`Execution logging`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.")}</p>
<p class="pf-c-form__helper-text">${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}</p>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
${gettext("Policy-specific settings")}
${t`Policy-specific settings`}
</span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="result">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${this.policy?.result || false}>
<label class="pf-c-check__label">
${gettext("Pass policy?")}
${t`Pass policy?`}
</label>
</div>
<p class="pf-c-form__helper-text">${gettext("When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.")}</p>
<p class="pf-c-form__helper-text">${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Wait (min)")}
label=${t`Wait (min)`}
?required=${true}
name="waitMin">
<input type="number" value="${first(this.policy?.waitMin, 1)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${gettext("The policy takes a random time to execute. This controls the minimum time it will take.")}</p>
<p class="pf-c-form__helper-text">${t`The policy takes a random time to execute. This controls the minimum time it will take.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${gettext("Wait (max)")}
label=${t`Wait (max)`}
?required=${true}
name="waitMax">
<input type="number" value="${first(this.policy?.waitMax, 5)}" class="pf-c-form-control" required>

Some files were not shown because too many files have changed in this diff Show More