mirror of
https://github.com/goauthentik/authentik
synced 2026-05-07 07:32:23 +02:00
Compare commits
17 Commits
blueprint_
...
a11y-label
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65f279827a | ||
|
|
b782770199 | ||
|
|
14eacd459d | ||
|
|
7a744d2530 | ||
|
|
e32baca745 | ||
|
|
2216463391 | ||
|
|
3efecd276e | ||
|
|
7d8be1e68d | ||
|
|
520466e37d | ||
|
|
4e9fbdf5c2 | ||
|
|
1a43829eed | ||
|
|
0fb6d1ee9f | ||
|
|
c1aca5920a | ||
|
|
d86d180ed2 | ||
|
|
449a7193fd | ||
|
|
b33f9517a0 | ||
|
|
ac9b1aa5f5 |
@@ -28,7 +28,8 @@ import { RuntimeLitLocalizer } from "@lit/localize-tools/lib/modes/runtime.js";
|
||||
|
||||
//#region Setup
|
||||
|
||||
const missingMessagePattern = /([\w_-]+)\smessage\s(?:[\w_-]+)\sis\smissing/;
|
||||
const missingMessagePattern = /([\w_-]+)\smessage\s(?:[\w_.-]+)\sis\smissing/;
|
||||
const outdatedMessagePattern = /([\w_-]+)\smessage\s(?:[\w_.-]+)\sdoes\snot\sexist/;
|
||||
const logger = ConsoleLogger.child({ name: "Locales" });
|
||||
|
||||
const localizeRules = readConfigFileAndWriteSchema(path.join(PackageRoot, "lit-localize.json"));
|
||||
@@ -153,7 +154,12 @@ export async function generateLocaleModules() {
|
||||
/**
|
||||
* @type {Map<string, number>}
|
||||
*/
|
||||
const localeWarnings = new Map();
|
||||
const missingTranslationWarnings = new Map();
|
||||
|
||||
/**
|
||||
* @type {Map<string, number>}
|
||||
*/
|
||||
const outdatedTranslationWarnings = new Map();
|
||||
|
||||
const initialConsoleWarn = console.warn;
|
||||
|
||||
@@ -163,12 +169,26 @@ export async function generateLocaleModules() {
|
||||
return;
|
||||
}
|
||||
|
||||
const [, matchedLocale] = arg0.match(missingMessagePattern) || [];
|
||||
const [, matchedMissingTranslation] = arg0.match(missingMessagePattern) || [];
|
||||
|
||||
if (matchedLocale) {
|
||||
const count = localeWarnings.get(matchedLocale) || 0;
|
||||
if (matchedMissingTranslation) {
|
||||
const count = missingTranslationWarnings.get(matchedMissingTranslation) || 0;
|
||||
|
||||
localeWarnings.set(matchedLocale, count + 1);
|
||||
missingTranslationWarnings.set(matchedMissingTranslation, count + 1);
|
||||
|
||||
logger.debug(arg0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const [, matchedOutdatedTranslation] = arg0.match(outdatedMessagePattern) || [];
|
||||
|
||||
if (matchedOutdatedTranslation) {
|
||||
const count = outdatedTranslationWarnings.get(matchedOutdatedTranslation) || 0;
|
||||
|
||||
outdatedTranslationWarnings.set(matchedOutdatedTranslation, count + 1);
|
||||
|
||||
logger.debug(arg0);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -181,7 +201,7 @@ export async function generateLocaleModules() {
|
||||
|
||||
await localizer.build();
|
||||
|
||||
const report = Array.from(localeWarnings)
|
||||
const missingTranslationsReport = Array.from(missingTranslationWarnings)
|
||||
.filter(([, count]) => count)
|
||||
.sort(([, totalsA], [, totalsB]) => {
|
||||
return totalsB - totalsA;
|
||||
@@ -189,7 +209,17 @@ export async function generateLocaleModules() {
|
||||
.map(([locale, count]) => `${locale}: ${count.toLocaleString()}`)
|
||||
.join("\n");
|
||||
|
||||
logger.info(`Missing translations:\n${report}`);
|
||||
logger.info(`Missing translations:\n${missingTranslationsReport}`);
|
||||
|
||||
const outdatedTranslationsReport = Array.from(outdatedTranslationWarnings)
|
||||
.filter(([, count]) => count)
|
||||
.sort(([, totalsA], [, totalsB]) => {
|
||||
return totalsB - totalsA;
|
||||
})
|
||||
.map(([locale, count]) => `${locale}: ${count.toLocaleString()}`)
|
||||
.join("\n");
|
||||
|
||||
logger.info(`Outdated translations:\n${outdatedTranslationsReport}`);
|
||||
|
||||
localizer.assertTranslationsAreValid();
|
||||
|
||||
|
||||
@@ -48,12 +48,12 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
|
||||
>`;
|
||||
}
|
||||
return [
|
||||
[msg("Version"), version.versionCurrent],
|
||||
[msg("UI Version"), import.meta.env.AK_VERSION],
|
||||
[msg("Build"), build],
|
||||
[msg("Python version"), status.runtime.pythonVersion],
|
||||
[msg("Platform"), status.runtime.platform],
|
||||
[msg("Kernel"), status.runtime.uname],
|
||||
[msg("Version", { id: "label.version" }), version.versionCurrent],
|
||||
[msg("UI Version", { id: "label.ui-version" }), import.meta.env.AK_VERSION],
|
||||
[msg("Build", { id: "label.build" }), build],
|
||||
[msg("Python version", { id: "label.python-version" }), status.runtime.pythonVersion],
|
||||
[msg("Platform", { id: "label.platform" }), status.runtime.platform],
|
||||
[msg("Kernel", { id: "label.kernel" }), status.runtime.uname],
|
||||
[
|
||||
msg("OpenSSL"),
|
||||
`${status.runtime.opensslVersion} ${status.runtime.opensslFipsEnabled ? "FIPS" : ""}`,
|
||||
|
||||
@@ -51,54 +51,149 @@ export function renderSidebarItems(entries: readonly SidebarEntry[]) {
|
||||
return repeat(entries, ([path, label]) => path || label, renderSidebarItem);
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
export const createAdminSidebarEntries = (): readonly SidebarEntry[] => [
|
||||
[null, msg("Dashboards"), { "?expanded": true }, [
|
||||
["/administration/overview", msg("Overview")],
|
||||
["/administration/dashboard/users", msg("User Statistics")],
|
||||
["/administration/system-tasks", msg("System Tasks")]]
|
||||
[
|
||||
null,
|
||||
msg("Dashboards", { id: "sidebar.category.dashboards" }),
|
||||
{ "?expanded": true },
|
||||
[
|
||||
["/administration/overview", msg("Overview", { id: "sidebar.item.overview" })],
|
||||
[
|
||||
"/administration/dashboard/users",
|
||||
msg("User Statistics", { id: "sidebar.item.user-statistics" }),
|
||||
],
|
||||
[
|
||||
"/administration/system-tasks",
|
||||
msg("System Tasks", { id: "sidebar.item.system-tasks" }),
|
||||
],
|
||||
],
|
||||
],
|
||||
[null, msg("Applications"), null, [
|
||||
["/core/applications", msg("Applications"), [`^/core/applications/(?<slug>${SLUG_REGEX})$`]],
|
||||
["/core/providers", msg("Providers"), [`^/core/providers/(?<id>${ID_REGEX})$`]],
|
||||
["/outpost/outposts", msg("Outposts")]]
|
||||
[
|
||||
null,
|
||||
msg("Applications", { id: "sidebar.category.applications" }),
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/core/applications",
|
||||
msg("Applications", { id: "sidebar.item.applications" }),
|
||||
[`^/core/applications/(?<slug>${SLUG_REGEX})$`],
|
||||
],
|
||||
[
|
||||
"/core/providers",
|
||||
msg("Providers", { id: "sidebar.item.providers" }),
|
||||
[`^/core/providers/(?<id>${ID_REGEX})$`],
|
||||
],
|
||||
["/outpost/outposts", msg("Outposts", { id: "sidebar.item.outposts" })],
|
||||
],
|
||||
],
|
||||
[null, msg("Events"), null, [
|
||||
["/events/log", msg("Logs"), [`^/events/log/(?<id>${UUID_REGEX})$`]],
|
||||
["/events/rules", msg("Notification Rules")],
|
||||
["/events/transports", msg("Notification Transports")]]
|
||||
[
|
||||
null,
|
||||
msg("Events", { id: "sidebar.category.events" }),
|
||||
null,
|
||||
[
|
||||
["/events/log", msg("Logs"), [`^/events/log/(?<id>${UUID_REGEX})$`]],
|
||||
["/events/rules", msg("Notification Rules", { id: "sidebar.item.system-tasks" })],
|
||||
[
|
||||
"/events/transports",
|
||||
msg("Notification Transports", { id: "sidebar.item.notification-transports" }),
|
||||
],
|
||||
],
|
||||
],
|
||||
[null, msg("Customization"), null, [
|
||||
["/policy/policies", msg("Policies")],
|
||||
["/core/property-mappings", msg("Property Mappings")],
|
||||
["/blueprints/instances", msg("Blueprints")],
|
||||
["/policy/reputation", msg("Reputation scores")]]
|
||||
[
|
||||
null,
|
||||
msg("Customization", { id: "sidebar.category.customization" }),
|
||||
null,
|
||||
[
|
||||
["/policy/policies", msg("Policies", { id: "sidebar.item.policies" })],
|
||||
[
|
||||
"/core/property-mappings",
|
||||
msg("Property Mappings", { id: "sidebar.item.property-mappings" }),
|
||||
],
|
||||
["/blueprints/instances", msg("Blueprints", { id: "sidebar.item.blueprints" })],
|
||||
[
|
||||
"/policy/reputation",
|
||||
msg("Reputation scores", { id: "sidebar.item.reputation-scores" }),
|
||||
],
|
||||
],
|
||||
],
|
||||
[null, msg("Flows and Stages"), null, [
|
||||
["/flow/flows", msg("Flows"), [`^/flow/flows/(?<slug>${SLUG_REGEX})$`]],
|
||||
["/flow/stages", msg("Stages")],
|
||||
["/flow/stages/prompts", msg("Prompts")]]
|
||||
[
|
||||
null,
|
||||
msg("Flows and Stages", { id: "sidebar.category.flows-and-stages" }),
|
||||
null,
|
||||
[
|
||||
["/flow/flows", msg("Flows"), [`^/flow/flows/(?<slug>${SLUG_REGEX})$`]],
|
||||
["/flow/stages", msg("Stages", { id: "sidebar.item.stages" })],
|
||||
["/flow/stages/prompts", msg("Prompts", { id: "sidebar.item.prompts" })],
|
||||
],
|
||||
],
|
||||
[null, msg("Directory"), null, [
|
||||
["/identity/users", msg("Users"), [`^/identity/users/(?<id>${ID_REGEX})$`]],
|
||||
["/identity/groups", msg("Groups"), [`^/identity/groups/(?<id>${UUID_REGEX})$`]],
|
||||
["/identity/roles", msg("Roles"), [`^/identity/roles/(?<id>${UUID_REGEX})$`]],
|
||||
["/identity/initial-permissions", msg("Initial Permissions"), [`^/identity/initial-permissions/(?<id>${ID_REGEX})$`]],
|
||||
["/core/sources", msg("Federation and Social login"), [`^/core/sources/(?<slug>${SLUG_REGEX})$`]],
|
||||
["/core/tokens", msg("Tokens and App passwords")],
|
||||
["/flow/stages/invitations", msg("Invitations")]]
|
||||
[
|
||||
null,
|
||||
msg("Directory", { id: "sidebar.category.directory" }),
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/identity/users",
|
||||
msg("Users", { id: "sidebar.item.users" }),
|
||||
[`^/identity/users/(?<id>${ID_REGEX})$`],
|
||||
],
|
||||
[
|
||||
"/identity/groups",
|
||||
msg("Groups", { id: "sidebar.item.groups" }),
|
||||
[`^/identity/groups/(?<id>${UUID_REGEX})$`],
|
||||
],
|
||||
[
|
||||
"/identity/roles",
|
||||
msg("Roles", { id: "sidebar.item.roles" }),
|
||||
[`^/identity/roles/(?<id>${UUID_REGEX})$`],
|
||||
],
|
||||
[
|
||||
"/identity/initial-permissions",
|
||||
msg("Initial Permissions", { id: "sidebar.item.initial-permissions" }),
|
||||
[`^/identity/initial-permissions/(?<id>${ID_REGEX})$`],
|
||||
],
|
||||
[
|
||||
"/core/sources",
|
||||
msg("Federation and Social login", {
|
||||
id: "sidebar.item.federation-and-social-login",
|
||||
}),
|
||||
[`^/core/sources/(?<slug>${SLUG_REGEX})$`],
|
||||
],
|
||||
[
|
||||
"/core/tokens",
|
||||
msg("Tokens and App passwords", { id: "sidebar.item.tokens-and-app-passwords" }),
|
||||
],
|
||||
["/flow/stages/invitations", msg("Invitations", { id: "sidebar.item.invitations" })],
|
||||
],
|
||||
],
|
||||
[null, msg("System"), null, [
|
||||
["/core/brands", msg("Brands")],
|
||||
["/crypto/certificates", msg("Certificates")],
|
||||
["/outpost/integrations", msg("Outpost Integrations")],
|
||||
["/admin/settings", msg("Settings")]]
|
||||
[
|
||||
null,
|
||||
msg("System", { id: "sidebar.category.system" }),
|
||||
null,
|
||||
[
|
||||
["/core/brands", msg("Brands", { id: "sidebar.item.brands" })],
|
||||
["/crypto/certificates", msg("Certificates", { id: "sidebar.item.certificates" })],
|
||||
[
|
||||
"/outpost/integrations",
|
||||
msg("Outpost Integrations", { id: "sidebar.item.outpost-integrations" }),
|
||||
],
|
||||
["/admin/settings", msg("Settings", { id: "sidebar.item.settings" })],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// prettier-ignore
|
||||
export const createAdminSidebarEnterpriseEntries = (): readonly SidebarEntry[] => [
|
||||
[null, msg("Enterprise"), null, [
|
||||
["/enterprise/licenses", msg("Licenses"), null]
|
||||
[
|
||||
null,
|
||||
msg("Enterprise", { id: "sidebar.category.enterprise" }),
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/enterprise/licenses",
|
||||
msg("Licenses", {
|
||||
id: "sidebar.item.licenses",
|
||||
}),
|
||||
null,
|
||||
],
|
||||
],
|
||||
],
|
||||
]]
|
||||
];
|
||||
|
||||
@@ -7,6 +7,7 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EventWithContext } from "#common/events";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { actionToLabel } from "#common/labels";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
@@ -17,7 +18,7 @@ import { EventGeo, renderEventUser } from "#admin/events/utils";
|
||||
|
||||
import { Event, EventsApi } from "@goauthentik/api";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, html, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
@@ -26,8 +27,13 @@ import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
@customElement("ak-recent-events")
|
||||
export class RecentEventsCard extends Table<Event> {
|
||||
public override role = "region";
|
||||
public override ariaLabel = msg("Recent events");
|
||||
public override label = msg("Events");
|
||||
public override ariaLabel = msg("Recent events", { id: "aria.label.recent-events" });
|
||||
public override label = msg("Events", { id: "card.label.recent-events" });
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Event", { id: "entity.event.singular" }),
|
||||
plural: msg("Events", { id: "entity.event.plural" }),
|
||||
};
|
||||
|
||||
@property()
|
||||
order = "-created";
|
||||
@@ -54,10 +60,10 @@ export class RecentEventsCard extends Table<Event> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Action"), "action"],
|
||||
[msg("User"), "user"],
|
||||
[msg("Creation Date"), "created"],
|
||||
[msg("Client IP"), "client_ip"],
|
||||
[msg("Action", { id: "column.action" }), "action"],
|
||||
[msg("User", { id: "column.user" }), "user"],
|
||||
[msg("Creation Date", { id: "column.creation-date" }), "created"],
|
||||
[msg("Client IP", { id: "column.client-ip" }), "client_ip"],
|
||||
];
|
||||
|
||||
renderToolbar(): TemplateResult {
|
||||
@@ -83,10 +89,20 @@ export class RecentEventsCard extends Table<Event> {
|
||||
return super.renderEmpty(inner);
|
||||
}
|
||||
|
||||
const entityLabel = this.entityLabel.plural.toLowerCase();
|
||||
|
||||
return super.renderEmpty(
|
||||
html`<ak-empty-state
|
||||
><span>${msg("No Events found.")}</span>
|
||||
<div slot="body">${msg("No matching events could be found.")}</div>
|
||||
><span
|
||||
>${msg(str`No ${entityLabel} found.`, {
|
||||
id: "empty-state.heading",
|
||||
})}</span
|
||||
>
|
||||
<div slot="body">
|
||||
${msg(str`No matching ${entityLabel} could be found.`, {
|
||||
id: "empty-state.body",
|
||||
})}
|
||||
</div>
|
||||
</ak-empty-state>`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ import { customElement } from "lit/decorators.js";
|
||||
|
||||
@customElement("ak-admin-status-chart-outpost")
|
||||
export class OutpostStatusChart extends AKChart<SummarizedSyncStatus[]> {
|
||||
public override ariaLabel = msg("Outpost status chart");
|
||||
public override ariaLabel = msg("Outpost status chart", {
|
||||
id: "aria.label.outpost-status-chart",
|
||||
});
|
||||
|
||||
getChartType(): string {
|
||||
return "doughnut";
|
||||
|
||||
@@ -29,7 +29,9 @@ export interface SummarizedSyncStatus {
|
||||
|
||||
@customElement("ak-admin-status-chart-sync")
|
||||
export class SyncStatusChart extends AKChart<SummarizedSyncStatus[]> {
|
||||
public override ariaLabel = msg("Synchronization status chart");
|
||||
public override ariaLabel = msg("Synchronization status chart", {
|
||||
id: "aria.label.sync-status-chart",
|
||||
});
|
||||
|
||||
getChartType(): string {
|
||||
return "doughnut";
|
||||
|
||||
@@ -46,9 +46,8 @@ export class AdminSettingsForm extends Form<SettingsRequest> {
|
||||
@property({ attribute: false })
|
||||
public settings!: Settings;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully updated settings.");
|
||||
}
|
||||
protected override readonly actionName = "save";
|
||||
protected override entityLabel = msg("Settings");
|
||||
|
||||
async send(settingsRequest: SettingsRequest): Promise<Settings> {
|
||||
const result = await new AdminApi(DEFAULT_CONFIG).adminSettingsUpdate({
|
||||
|
||||
@@ -32,9 +32,9 @@ export class ApplicationCheckAccessForm extends Form<{ forUser: number }> {
|
||||
@property({ attribute: false })
|
||||
request?: number;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully sent test-request.");
|
||||
}
|
||||
protected override readonly actionName = "send";
|
||||
|
||||
protected override entityLabel = msg("Test Request");
|
||||
|
||||
async send(data: { forUser: number }): Promise<PolicyTestResult> {
|
||||
this.request = data.forUser;
|
||||
|
||||
@@ -57,11 +57,7 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
@property({ type: Boolean })
|
||||
public clearIcon = false;
|
||||
|
||||
protected override getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated application.")
|
||||
: msg("Successfully created application.");
|
||||
}
|
||||
protected override entityLabel = msg("Application");
|
||||
|
||||
public override async send(applicationRequest: Application): Promise<Application | void> {
|
||||
applicationRequest.backchannelProviders = this.backchannelProviders.map((p) => p.pk);
|
||||
@@ -138,12 +134,18 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
<ak-text-input
|
||||
name="name"
|
||||
autocomplete="off"
|
||||
placeholder=${msg("Type an application name...")}
|
||||
placeholder=${msg("Type an application name...", {
|
||||
id: "application.form.name.placeholder",
|
||||
})}
|
||||
value=${ifDefined(this.instance?.name)}
|
||||
label=${msg("Application Name")}
|
||||
label=${msg("Application Name", {
|
||||
id: "application.form.name.label",
|
||||
})}
|
||||
spellcheck="false"
|
||||
required
|
||||
help=${msg("The name displayed in the application library.")}
|
||||
help=${msg("The name displayed in the application library.", {
|
||||
id: "application.form.name.help",
|
||||
})}
|
||||
></ak-text-input>
|
||||
<ak-slug-input
|
||||
name="slug"
|
||||
@@ -151,16 +153,26 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
value=${ifDefined(this.instance?.slug)}
|
||||
label=${msg("Slug")}
|
||||
required
|
||||
help=${msg("Internal application name used in URLs.")}
|
||||
help=${msg("Internal application name used in URLs.", {
|
||||
id: "application.form.slug.help",
|
||||
desc: "Help text for the slug field in the application form",
|
||||
})}
|
||||
input-hint="code"
|
||||
></ak-slug-input>
|
||||
<ak-text-input
|
||||
name="group"
|
||||
value=${ifDefined(this.instance?.group)}
|
||||
label=${msg("Group")}
|
||||
placeholder=${msg("e.g. Collaboration, Communication, Internal, etc.")}
|
||||
placeholder=${msg("e.g. Collaboration, Communication, Internal, etc.", {
|
||||
id: "application.form.group.placeholder",
|
||||
desc: "Placeholder text for the group field in the application form",
|
||||
})}
|
||||
help=${msg(
|
||||
"Optionally enter a group name. Applications with identical groups are shown grouped together.",
|
||||
{
|
||||
id: "application.form.group.help",
|
||||
desc: "Help text for the group field in the application form",
|
||||
},
|
||||
)}
|
||||
input-hint="code"
|
||||
></ak-text-input>
|
||||
@@ -168,7 +180,10 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
name="provider"
|
||||
label=${msg("Provider")}
|
||||
value=${ifPresent(this.instance?.provider)}
|
||||
help=${msg("Select a provider that this application should use.")}
|
||||
help=${msg("Select a provider that this application should use.", {
|
||||
id: "application.form.provider.help",
|
||||
desc: "Help text for the provider field in the application form",
|
||||
})}
|
||||
blankable
|
||||
></ak-provider-search-input>
|
||||
<ak-backchannel-providers-input
|
||||
@@ -176,18 +191,26 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
label=${msg("Backchannel Providers")}
|
||||
help=${msg(
|
||||
"Select backchannel providers which augment the functionality of the main provider.",
|
||||
{
|
||||
id: "application.form.backchannel-providers.help",
|
||||
desc: "Help text for the backchannel providers field in the application form",
|
||||
},
|
||||
)}
|
||||
.providers=${this.backchannelProviders}
|
||||
.confirm=${this.#handleConfirmBackchannelProviders}
|
||||
.remover=${this.#makeRemoveBackchannelProviderHandler}
|
||||
.tooltip=${html`<pf-tooltip
|
||||
position="top"
|
||||
content=${msg("Add provider")}
|
||||
content=${msg("Add provider", {
|
||||
id: "application.form.backchannel-providers.add-provider.tooltip",
|
||||
})}
|
||||
></pf-tooltip>`}
|
||||
>
|
||||
</ak-backchannel-providers-input>
|
||||
<ak-radio-input
|
||||
label=${msg("Policy engine mode")}
|
||||
label=${msg("Policy engine mode", {
|
||||
id: "application.form.policy-engine-mode.label",
|
||||
})}
|
||||
required
|
||||
name="policyEngineMode"
|
||||
.options=${policyEngineModes}
|
||||
@@ -208,9 +231,14 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
<ak-switch-input
|
||||
name="openInNewTab"
|
||||
?checked=${this.instance?.openInNewTab ?? false}
|
||||
label=${msg("Open in new tab")}
|
||||
label=${msg("Open in new tab", {
|
||||
id: "application.form.open-in-new-tab.label",
|
||||
})}
|
||||
help=${msg(
|
||||
"If checked, the launch URL will open in a new browser tab or window from the user's application library.",
|
||||
{
|
||||
id: "application.form.open-in-new-tab.help",
|
||||
},
|
||||
)}
|
||||
>
|
||||
</ak-switch-input>
|
||||
@@ -219,32 +247,44 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
label="${msg("Icon")}"
|
||||
name="metaIcon"
|
||||
value=${ifPresent(this.instance?.metaIcon)}
|
||||
current=${msg("Currently set to:")}
|
||||
current=${msg("Currently set to:", {
|
||||
id: "application.form.icon.current",
|
||||
})}
|
||||
></ak-file-input>
|
||||
${this.instance?.metaIcon
|
||||
? html`
|
||||
<ak-switch-input
|
||||
name=""
|
||||
label=${msg("Clear icon")}
|
||||
help=${msg("Delete currently set icon.")}
|
||||
label=${msg("Clear icon", {
|
||||
id: "application.form.clear-icon.label",
|
||||
})}
|
||||
help=${msg("Delete currently set icon.", {
|
||||
id: "application.form.clear-icon.help",
|
||||
})}
|
||||
@change=${this.handleClearIcon}
|
||||
></ak-switch-input>
|
||||
`
|
||||
: nothing}`
|
||||
: html` <ak-text-input
|
||||
label=${msg("Icon")}
|
||||
label=${msg("Icon", {
|
||||
id: "application.form.icon.label",
|
||||
})}
|
||||
name="metaIcon"
|
||||
value=${this.instance?.metaIcon ?? ""}
|
||||
help=${iconHelperText}
|
||||
>
|
||||
</ak-text-input>`}
|
||||
<ak-text-input
|
||||
label=${msg("Publisher")}
|
||||
label=${msg("Publisher", {
|
||||
id: "application.form.publisher.label",
|
||||
})}
|
||||
name="metaPublisher"
|
||||
value="${ifDefined(this.instance?.metaPublisher)}"
|
||||
></ak-text-input>
|
||||
<ak-textarea-input
|
||||
label=${msg("Description")}
|
||||
label=${msg("Description", {
|
||||
id: "application.form.description.label",
|
||||
})}
|
||||
name="metaDescription"
|
||||
value=${ifDefined(this.instance?.metaDescription)}
|
||||
></ak-textarea-input>
|
||||
|
||||
@@ -45,7 +45,17 @@ export const applicationListStyle = css`
|
||||
@customElement("ak-application-list")
|
||||
export class ApplicationListPage extends WithBrandConfig(TablePage<Application>) {
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Applications");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Application", { id: "entity.application.singular" }),
|
||||
plural: msg("Applications", { id: "entity.application.plural" }),
|
||||
};
|
||||
|
||||
protected override get searchPlaceholder() {
|
||||
return msg("Search for an application by name or group...", {
|
||||
id: "search.placeholder.application-list",
|
||||
});
|
||||
}
|
||||
|
||||
public get pageDescription() {
|
||||
return msg(
|
||||
str`External applications that use ${this.brandingTitle} as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.`,
|
||||
@@ -69,12 +79,16 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
||||
static styles: CSSResult[] = [...TablePage.styles, PFCard, applicationListStyle];
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
["", undefined, msg("Application Icon")],
|
||||
[msg("Name"), "name"],
|
||||
[msg("Group"), "group"],
|
||||
[msg("Provider")],
|
||||
[msg("Provider Type")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
["", undefined, msg("Application Icon", { id: "column.application-icon" })],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Group", { id: "column.group" }), "group"],
|
||||
[msg("Provider", { id: "column.provider" })],
|
||||
[msg("Provider Type", { id: "column.provider-type" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
protected renderSidebarAfter(): TemplateResult {
|
||||
@@ -132,7 +146,7 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
||||
html`${item.providerObj?.verboseName || msg("-")}`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Application")}</span>
|
||||
<ak-application-form slot="form" .instancePk=${item.slug}>
|
||||
</ak-application-form>
|
||||
@@ -173,18 +187,20 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
||||
</button>
|
||||
</ak-application-wizard>
|
||||
<ak-forms-modal .open=${getURLParam("createForm", false)}>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Application")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-application-form slot="form"> </ak-application-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>`;
|
||||
}
|
||||
|
||||
renderToolbar(): TemplateResult {
|
||||
return html` ${super.renderToolbar()}
|
||||
<ak-forms-confirm
|
||||
successMessage=${msg("Successfully cleared application cache")}
|
||||
errorMessage=${msg("Failed to delete application cache")}
|
||||
success-message=${msg("Successfully cleared application cache")}
|
||||
error-message=${msg("Failed to delete application cache")}
|
||||
action=${msg("Clear cache")}
|
||||
.onConfirm=${() => {
|
||||
return new PoliciesApi(DEFAULT_CONFIG).policiesAllCacheClearCreate();
|
||||
|
||||
@@ -12,6 +12,9 @@ import "#elements/buttons/SpinnerButton/ak-spinner-button";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { APIError, parseAPIResponseError, pluckErrorDetail } from "#common/errors/network";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
|
||||
@@ -60,6 +63,11 @@ export class ApplicationViewPage extends AKElement {
|
||||
|
||||
//#region State
|
||||
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Application", { id: "entity.application.singular" }),
|
||||
plural: msg("Applications", { id: "entity.application.plural" }),
|
||||
};
|
||||
|
||||
@state()
|
||||
protected application?: Application;
|
||||
|
||||
@@ -219,9 +227,11 @@ export class ApplicationViewPage extends AKElement {
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit"
|
||||
>${ActionTenseRecord.apply.present()}</span
|
||||
>
|
||||
<span slot="header">
|
||||
${msg("Update Application")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</span>
|
||||
<ak-application-form
|
||||
slot="form"
|
||||
@@ -232,7 +242,7 @@ export class ApplicationViewPage extends AKElement {
|
||||
slot="trigger"
|
||||
class="pf-c-button pf-m-secondary"
|
||||
>
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, TableColumn } from "#elements/table/Table";
|
||||
import { TableModal } from "#elements/table/TableModal";
|
||||
@@ -17,6 +18,11 @@ export class ProviderSelectModal extends TableModal<Provider> {
|
||||
checkbox = true;
|
||||
checkboxChip = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Provider", { id: "entity.provider.singular" }),
|
||||
plural: msg("Providers", { id: "entity.provider.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
@property({ type: Boolean })
|
||||
@@ -36,8 +42,8 @@ export class ProviderSelectModal extends TableModal<Provider> {
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Name"), "username"],
|
||||
[msg("Type")],
|
||||
[msg("Name", { id: "column.name" }), "username"],
|
||||
[msg("Type", { id: "column.type" })],
|
||||
];
|
||||
|
||||
row(item: Provider): SlottedTemplateResult[] {
|
||||
|
||||
@@ -5,7 +5,7 @@ import "#elements/forms/SearchSelect/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
|
||||
import { CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { CodeMirrorHelperText, CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { ModelForm } from "#elements/forms/ModelForm";
|
||||
|
||||
import { ApplicationEntitlement, CoreApi } from "@goauthentik/api";
|
||||
@@ -29,12 +29,7 @@ export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement
|
||||
@property()
|
||||
targetPk?: string;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance?.pbmUuid) {
|
||||
return msg("Successfully updated entitlement.");
|
||||
}
|
||||
return msg("Successfully created entitlement.");
|
||||
}
|
||||
protected override entityLabel = msg("Entitlement");
|
||||
|
||||
static styles: CSSResult[] = [...super.styles, PFContent];
|
||||
|
||||
@@ -54,7 +49,13 @@ export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Entitlement Name", {
|
||||
id: "label.entitlement-name",
|
||||
})}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${this.instance?.name ?? ""}"
|
||||
@@ -62,15 +63,18 @@ export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement
|
||||
required
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${msg("Attributes")} name="attributes">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Attributes", {
|
||||
id: "label.attributes",
|
||||
})}
|
||||
name="attributes"
|
||||
>
|
||||
<ak-codemirror
|
||||
mode=${CodeMirrorMode.YAML}
|
||||
value="${YAML.stringify(this.instance?.attributes ?? {})}"
|
||||
>
|
||||
</ak-codemirror>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Set custom attributes using YAML or JSON.")}
|
||||
</p>
|
||||
${CodeMirrorHelperText()}
|
||||
</ak-form-element-horizontal>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import "#elements/forms/ProxyForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { PFSize } from "#common/enums";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -37,6 +38,11 @@ export class ApplicationEntitlementsPage extends Table<ApplicationEntitlement> {
|
||||
|
||||
order = "order";
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Entitlement", { id: "entity.entitlement.singular" }),
|
||||
plural: msg("Entitlements", { id: "entity.entitlement.plural" }),
|
||||
};
|
||||
|
||||
async apiEndpoint(): Promise<PaginatedResponse<ApplicationEntitlement>> {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsList({
|
||||
...(await this.defaultEndpointConfig()),
|
||||
@@ -46,8 +52,12 @@ export class ApplicationEntitlementsPage extends Table<ApplicationEntitlement> {
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Name"), "name"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -76,8 +86,8 @@ export class ApplicationEntitlementsPage extends Table<ApplicationEntitlement> {
|
||||
return [
|
||||
html`${item.name}`,
|
||||
html`<ak-forms-modal size=${PFSize.Medium}>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Entitlement")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${this.editEntityLabel}</span>
|
||||
<ak-application-entitlement-form
|
||||
slot="form"
|
||||
.instancePk=${item.pbmUuid}
|
||||
@@ -85,7 +95,7 @@ export class ApplicationEntitlementsPage extends Table<ApplicationEntitlement> {
|
||||
>
|
||||
</ak-application-entitlement-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<pf-tooltip position="top" content=${this.editEntityLabel}>
|
||||
<i class="fas fa-edit" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
@@ -126,12 +136,12 @@ export class ApplicationEntitlementsPage extends Table<ApplicationEntitlement> {
|
||||
|
||||
renderToolbar(): TemplateResult {
|
||||
return html`<ak-forms-modal size=${PFSize.Medium}>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Entitlement")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-application-entitlement-form slot="form" targetPk=${ifDefined(this.app)}>
|
||||
</ak-application-entitlement-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Create entitlement")}
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal> `;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,26 @@ import { msg } from "@lit/localize";
|
||||
import { html } from "lit";
|
||||
|
||||
const renderSummary = (type: string, name: string, fields: DescriptionPair[]) =>
|
||||
renderDescriptionList([[msg("Type"), type], [msg("Name"), name], ...fields], {
|
||||
threecolumn: true,
|
||||
});
|
||||
renderDescriptionList(
|
||||
[
|
||||
[
|
||||
msg("Type", {
|
||||
id: "label.type",
|
||||
}),
|
||||
type,
|
||||
],
|
||||
[
|
||||
msg("Name", {
|
||||
id: "label.name",
|
||||
}),
|
||||
name,
|
||||
],
|
||||
...fields,
|
||||
],
|
||||
{
|
||||
threecolumn: true,
|
||||
},
|
||||
);
|
||||
|
||||
function renderSAMLOverview(rawProvider: OneOfProvider) {
|
||||
const provider = rawProvider as SAMLProvider;
|
||||
@@ -39,22 +56,36 @@ function renderSAMLOverview(rawProvider: OneOfProvider) {
|
||||
|
||||
function renderSCIMOverview(rawProvider: OneOfProvider) {
|
||||
const provider = rawProvider as SCIMProvider;
|
||||
return renderSummary("SCIM", provider.name, [[msg("URL"), provider.url]]);
|
||||
return renderSummary("SCIM", provider.name, [
|
||||
[
|
||||
msg("URL", {
|
||||
id: "label.url",
|
||||
}),
|
||||
provider.url,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
function renderRadiusOverview(rawProvider: OneOfProvider) {
|
||||
const provider = rawProvider as RadiusProvider;
|
||||
return renderSummary("Radius", provider.name, [
|
||||
[msg("Client Networks"), provider.clientNetworks],
|
||||
[msg("Client Networks", { id: "label.client-networks" }), provider.clientNetworks],
|
||||
]);
|
||||
}
|
||||
|
||||
function renderRACOverview(rawProvider: OneOfProvider) {
|
||||
const provider = rawProvider as RACProvider;
|
||||
return renderSummary("RAC", provider.name, [
|
||||
[msg("Connection expiry"), provider.connectionExpiry ?? "-"],
|
||||
[
|
||||
msg("Property mappings"),
|
||||
msg("Connection expiry", {
|
||||
id: "label.connection-expiry",
|
||||
}),
|
||||
provider.connectionExpiry ?? msg("-"),
|
||||
],
|
||||
[
|
||||
msg("Property mappings", {
|
||||
id: "label.property-mappings",
|
||||
}),
|
||||
Array.isArray(provider.propertyMappings) && provider.propertyMappings.length
|
||||
? provider.propertyMappings.join(", ")
|
||||
: msg("None"),
|
||||
@@ -70,45 +101,88 @@ function formatRedirectUris(uris: RedirectURI[] = []) {
|
||||
html`<li>
|
||||
${uri.url}
|
||||
(${uri.matchingMode === MatchingModeEnum.Strict
|
||||
? msg("strict")
|
||||
: msg("regexp")})
|
||||
? msg("strict", { id: "matching-mode.strict" })
|
||||
: msg("regexp", { id: "matching-mode.regexp" })})
|
||||
</li>`,
|
||||
)}
|
||||
</ul>`
|
||||
: "-";
|
||||
}
|
||||
|
||||
const proxyModeToLabel = new Map([
|
||||
[ProxyMode.Proxy, msg("Proxy")],
|
||||
[ProxyMode.ForwardSingle, msg("Forward auth (single application)")],
|
||||
[ProxyMode.ForwardDomain, msg("Forward auth (domain-level)")],
|
||||
[ProxyMode.UnknownDefaultOpenApi, msg("Unknown proxy mode")],
|
||||
]);
|
||||
function createProxyModeLabelRecord(): Record<ProxyMode, string> {
|
||||
return {
|
||||
[ProxyMode.Proxy]: msg("Proxy", {
|
||||
id: "label.proxy-mode.proxy",
|
||||
}),
|
||||
[ProxyMode.ForwardSingle]: msg("Forward auth (single application)", {
|
||||
id: "label.proxy-mode.forward-single",
|
||||
}),
|
||||
[ProxyMode.ForwardDomain]: msg("Forward auth (domain-level)", {
|
||||
id: "label.proxy-mode.forward-domain",
|
||||
}),
|
||||
[ProxyMode.UnknownDefaultOpenApi]: msg("Unknown proxy mode", {
|
||||
id: "label.proxy-mode.unknown",
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function renderProxyOverview(rawProvider: OneOfProvider) {
|
||||
const provider = rawProvider as ProxyProvider;
|
||||
|
||||
const proxyModeToLabel = createProxyModeLabelRecord();
|
||||
const mode = provider.mode ?? ProxyMode.Proxy;
|
||||
const modeLabel = proxyModeToLabel[mode];
|
||||
|
||||
return renderSummary("Proxy", provider.name, [
|
||||
[msg("Mode"), proxyModeToLabel.get(provider.mode ?? ProxyMode.Proxy)],
|
||||
[msg("Mode", { id: "label.proxy-mode" }), modeLabel],
|
||||
...match(provider.mode)
|
||||
.with(
|
||||
ProxyMode.Proxy,
|
||||
() =>
|
||||
[
|
||||
[msg("Internal Host"), provider.internalHost],
|
||||
[msg("External Host"), provider.externalHost],
|
||||
] as DescriptionPair[],
|
||||
[
|
||||
msg("Internal Host", {
|
||||
id: "label.internal-host",
|
||||
}),
|
||||
provider.internalHost,
|
||||
],
|
||||
[
|
||||
msg("External Host", {
|
||||
id: "label.external-host",
|
||||
}),
|
||||
provider.externalHost,
|
||||
],
|
||||
] satisfies DescriptionPair[],
|
||||
)
|
||||
.with(
|
||||
ProxyMode.ForwardSingle,
|
||||
() => [[msg("External Host"), provider.externalHost]] as DescriptionPair[],
|
||||
() =>
|
||||
[
|
||||
[
|
||||
msg("External Host", {
|
||||
id: "label.external-host",
|
||||
}),
|
||||
provider.externalHost,
|
||||
],
|
||||
] satisfies DescriptionPair[],
|
||||
)
|
||||
.with(
|
||||
ProxyMode.ForwardDomain,
|
||||
() =>
|
||||
[
|
||||
[msg("Authentication URL"), provider.externalHost],
|
||||
[msg("Cookie domain"), provider.cookieDomain],
|
||||
] as DescriptionPair[],
|
||||
[
|
||||
msg("Authentication URL", {
|
||||
id: "label.authentication-url",
|
||||
}),
|
||||
provider.externalHost,
|
||||
],
|
||||
[
|
||||
msg("Cookie domain", {
|
||||
id: "label.cookie-domain",
|
||||
}),
|
||||
provider.cookieDomain,
|
||||
],
|
||||
] satisfies DescriptionPair[],
|
||||
)
|
||||
.otherwise(() => {
|
||||
throw new Error(
|
||||
@@ -125,24 +199,57 @@ function renderProxyOverview(rawProvider: OneOfProvider) {
|
||||
]);
|
||||
}
|
||||
|
||||
const clientTypeToLabel = new Map<ClientTypeEnum, string>([
|
||||
[ClientTypeEnum.Confidential, msg("Confidential")],
|
||||
[ClientTypeEnum.Public, msg("Public")],
|
||||
[ClientTypeEnum.UnknownDefaultOpenApi, msg("Unknown type")],
|
||||
]);
|
||||
function createClientTypeLabelRecord(): Record<ClientTypeEnum, string> {
|
||||
return {
|
||||
[ClientTypeEnum.Confidential]: msg("Confidential", {
|
||||
id: "label.oauth2.client.type.confidential",
|
||||
}),
|
||||
[ClientTypeEnum.Public]: msg("Public", {
|
||||
id: "label.oauth2.client.type.public",
|
||||
}),
|
||||
[ClientTypeEnum.UnknownDefaultOpenApi]: msg("Unknown type", {
|
||||
id: "label.oauth2.client.type.unknown",
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function renderOAuth2Overview(rawProvider: OneOfProvider) {
|
||||
const provider = rawProvider as OAuth2Provider;
|
||||
const clientTypeToLabel = createClientTypeLabelRecord();
|
||||
const clientTypeLabel = provider.clientType ? clientTypeToLabel[provider.clientType] : "";
|
||||
|
||||
return renderSummary("OAuth2", provider.name, [
|
||||
[msg("Client type"), provider.clientType ? clientTypeToLabel.get(provider.clientType) : ""],
|
||||
[msg("Client ID"), provider.clientId],
|
||||
[msg("Redirect URIs"), formatRedirectUris(provider.redirectUris)],
|
||||
[
|
||||
msg("Client type", {
|
||||
id: "label.oauth2.client.type",
|
||||
}),
|
||||
clientTypeLabel,
|
||||
],
|
||||
[
|
||||
msg("Client ID", {
|
||||
id: "label.oauth2.client.id",
|
||||
}),
|
||||
provider.clientId,
|
||||
],
|
||||
[
|
||||
msg("Redirect URIs", {
|
||||
id: "label.oauth2.redirect.uris",
|
||||
}),
|
||||
formatRedirectUris(provider.redirectUris),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
function renderLDAPOverview(rawProvider: OneOfProvider) {
|
||||
const provider = rawProvider as LDAPProvider;
|
||||
return renderSummary("Proxy", provider.name, [[msg("Base DN"), provider.baseDn]]);
|
||||
return renderSummary("Proxy", provider.name, [
|
||||
[
|
||||
msg("Base DN", {
|
||||
id: "label.ldap.base.dn",
|
||||
}),
|
||||
provider.baseDn,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
const providerName = (p: ProviderModelEnum): string => p.toString().split(".")[1];
|
||||
|
||||
@@ -30,7 +30,11 @@ const COLUMNS = [
|
||||
[msg("Binding")],
|
||||
[msg("Enabled"), "enabled"],
|
||||
[msg("Timeout"), "timeout"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
@customElement("ak-application-wizard-bindings-step")
|
||||
|
||||
@@ -29,7 +29,7 @@ export class ApplicationWizardRACProviderForm extends ApplicationWizardProviderF
|
||||
<form id="providerform" class="pf-c-form pf-m-horizontal" slot="form">
|
||||
<ak-text-input
|
||||
name="name"
|
||||
label=${msg("Name")}
|
||||
label=${msg("Provider Name", { id: "label.provider-name" })}
|
||||
value=${ifDefined(provider.name)}
|
||||
.errorMessages=${this.errorMessages("name")}
|
||||
required
|
||||
@@ -61,17 +61,24 @@ export class ApplicationWizardRACProviderForm extends ApplicationWizardProviderF
|
||||
input-hint="code"
|
||||
></ak-text-input>
|
||||
|
||||
<ak-form-group open label="${msg("Protocol settings")}">
|
||||
<ak-form-group
|
||||
open
|
||||
label="${msg("Protocol settings", { id: "label.protocol-settings" })}"
|
||||
>
|
||||
<div class="pf-c-form">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Property mappings")}
|
||||
label=${msg("Property mappings", { id: "label.property-mappings" })}
|
||||
name="propertyMappings"
|
||||
>
|
||||
<ak-dual-select-dynamic-selected
|
||||
.provider=${propertyMappingsProvider}
|
||||
.selector=${propertyMappingsSelector(provider?.propertyMappings)}
|
||||
available-label="${msg("Available Property Mappings")}"
|
||||
selected-label="${msg("Selected Property Mappings")}"
|
||||
available-label=${msg("Available Property Mappings", {
|
||||
id: "label.available-property-mappings",
|
||||
})}
|
||||
selected-label=${msg("Selected Property Mappings", {
|
||||
id: "label.selected-property-mappings",
|
||||
})}
|
||||
></ak-dual-select-dynamic-selected>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
|
||||
@@ -46,11 +46,7 @@ export class BlueprintForm extends ModelForm<BlueprintInstance, string> {
|
||||
return inst;
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated instance.")
|
||||
: msg("Successfully created instance.");
|
||||
}
|
||||
protected override entityLabel = msg("Instance");
|
||||
|
||||
static styles: CSSResult[] = [...super.styles, PFContent];
|
||||
|
||||
@@ -67,7 +63,13 @@ export class BlueprintForm extends ModelForm<BlueprintInstance, string> {
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Blueprint Name", {
|
||||
id: "label.blueprint-name",
|
||||
})}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -58,7 +58,10 @@ export function formatBlueprintDescription(item: BlueprintInstance): string | nu
|
||||
@customElement("ak-blueprint-list")
|
||||
export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Blueprints");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Blueprint Instance", { id: "entity.blueprint-instance.singular" }),
|
||||
plural: msg("Blueprint Instances", { id: "entity.blueprint-instance.plural" }),
|
||||
};
|
||||
public pageDescription = msg("Automate and template configuration within authentik.");
|
||||
public pageIcon = "pf-icon pf-icon-blueprint";
|
||||
|
||||
@@ -78,11 +81,15 @@ export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Status"), "status"],
|
||||
[msg("Last applied"), "last_applied"],
|
||||
[msg("Enabled"), "enabled"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Status", { id: "column.status" }), "status"],
|
||||
[msg("Last applied", { id: "column.last-applied" }), "last_applied"],
|
||||
[msg("Enabled", { id: "column.enabled" }), "enabled"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -156,7 +163,7 @@ export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
||||
html`<ak-status-label ?good=${item.enabled}></ak-status-label>`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Blueprint")}</span>
|
||||
<ak-blueprint-form slot="form" .instancePk=${item.pk}> </ak-blueprint-form>
|
||||
<button
|
||||
@@ -204,10 +211,12 @@ export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Blueprint Instance")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-blueprint-form slot="form"> </ak-blueprint-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -41,11 +41,7 @@ export class BrandForm extends ModelForm<Brand, string> {
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated brand.")
|
||||
: msg("Successfully created brand.");
|
||||
}
|
||||
protected override entityLabel = msg("Brand");
|
||||
|
||||
async send(data: Brand): Promise<Brand> {
|
||||
data.attributes ??= {};
|
||||
|
||||
@@ -21,8 +21,16 @@ import { customElement, property } from "lit/decorators.js";
|
||||
@customElement("ak-brand-list")
|
||||
export class BrandListPage extends TablePage<Brand> {
|
||||
protected override searchEnabled = true;
|
||||
public override searchPlaceholder = msg("Search by domain or brand name...");
|
||||
public pageTitle = msg("Brands");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Brand", { id: "entity.brand.singular" }),
|
||||
plural: msg("Brands", { id: "entity.brand.plural" }),
|
||||
};
|
||||
protected get searchPlaceholder() {
|
||||
return msg("Search by domain or brand name...", {
|
||||
id: "search.placeholder.brand-list",
|
||||
});
|
||||
}
|
||||
|
||||
public pageDescription = msg("Configure visual settings and defaults for different domains.");
|
||||
public pageIcon = "pf-icon pf-icon-tenant";
|
||||
|
||||
@@ -41,10 +49,14 @@ export class BrandListPage extends TablePage<Brand> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Domain"), "domain"],
|
||||
[msg("Brand name"), "branding_title"],
|
||||
[msg("Default?"), "default"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Domain", { id: "column.domain" }), "domain"],
|
||||
[msg("Brand name", { id: "column.brand-name" }), "branding_title"],
|
||||
[msg("Default?", { id: "column.default-question-mark" }), "default"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -79,7 +91,7 @@ export class BrandListPage extends TablePage<Brand> {
|
||||
html`<ak-status-label ?good=${item._default}></ak-status-label>`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Brand")}</span>
|
||||
<ak-brand-form slot="form" .instancePk=${item.brandUuid}> </ak-brand-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
@@ -101,10 +113,12 @@ export class BrandListPage extends TablePage<Brand> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create Brand")}</span>
|
||||
<span slot="header">${msg("New Brand")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-brand-form slot="form"> </ak-brand-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("New Brand")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -17,9 +17,10 @@ import { customElement } from "lit/decorators.js";
|
||||
|
||||
@customElement("ak-crypto-certificate-generate-form")
|
||||
export class CertificateKeyPairForm extends Form<CertificateGenerationRequest> {
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully generated certificate-key pair.");
|
||||
}
|
||||
protected override readonly actionName = "generate";
|
||||
protected override entityLabel = msg("Certificate Key Pair", {
|
||||
id: "entity.certificate-key-pair.singular",
|
||||
});
|
||||
|
||||
async send(data: CertificateGenerationRequest): Promise<CertificateKeyPair> {
|
||||
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsGenerateCreate({
|
||||
|
||||
@@ -21,11 +21,9 @@ export class CertificateKeyPairForm extends ModelForm<CertificateKeyPair, string
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated certificate-key pair.")
|
||||
: msg("Successfully created certificate-key pair.");
|
||||
}
|
||||
protected override entityLabel = msg("Certificate Key Pair", {
|
||||
id: "entity.certificate-key-pair.singular",
|
||||
});
|
||||
|
||||
async send(data: CertificateKeyPair): Promise<CertificateKeyPair> {
|
||||
if (this.instance) {
|
||||
@@ -40,7 +38,11 @@ export class CertificateKeyPairForm extends ModelForm<CertificateKeyPair, string
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} name="name" required>
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Certificate Key Pair Name", { id: "label.certificate-key-pair-name" })}
|
||||
name="name"
|
||||
required
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -33,9 +33,15 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
|
||||
clearOnRefresh = true;
|
||||
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Certificate-Key Pairs");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Certificate Key Pair", { id: "entity.certificate-key-pair.singular" }),
|
||||
plural: msg("Certificate Key Pairs", { id: "entity.certificate-key-pair.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Import certificates of external providers or create certificates to sign requests with.",
|
||||
{
|
||||
id: "page.description.certificate-key-pair-list",
|
||||
},
|
||||
);
|
||||
public pageIcon = "pf-icon pf-icon-key";
|
||||
|
||||
@@ -51,10 +57,14 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Private key available?")],
|
||||
[msg("Expiry date")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Private key available?", { id: "column.private-key-available-question-mark" })],
|
||||
[msg("Expiry date", { id: "column.expiry-date" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -114,7 +124,7 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
|
||||
html`<ak-label color=${color}> ${item.certExpiry?.toLocaleString()} </ak-label>`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Certificate-Key Pair")}</span>
|
||||
<ak-crypto-certificate-form slot="form" .instancePk=${item.pk}>
|
||||
</ak-crypto-certificate-form>
|
||||
|
||||
@@ -25,11 +25,7 @@ export class EnterpriseLicenseForm extends ModelForm<License, string> {
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated license.")
|
||||
: msg("Successfully created license.");
|
||||
}
|
||||
protected override entityLabel = msg("License");
|
||||
|
||||
async load(): Promise<void> {
|
||||
this.installID = (
|
||||
|
||||
@@ -41,7 +41,10 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
||||
clearOnRefresh = true;
|
||||
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Licenses");
|
||||
protected override entityLabel = {
|
||||
singular: msg("License", { id: "entity.license.singular" }),
|
||||
plural: msg("Licenses", { id: "entity.license.plural" }),
|
||||
};
|
||||
public pageDescription = msg("Manage enterprise licenses");
|
||||
public pageIcon = "pf-icon pf-icon-key";
|
||||
|
||||
@@ -88,10 +91,14 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Users")],
|
||||
[msg("Expiry date")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Users", { id: "column.users" })],
|
||||
[msg("Expiry date", { id: "column.expiry-date" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
// TODO: Make this more generic, maybe automatically get the plural name
|
||||
@@ -221,7 +228,7 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
||||
html`<ak-label color=${color}> ${item.expiry?.toLocaleString()} </ak-label>`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update License")}</span>
|
||||
<ak-enterprise-license-form slot="form" .instancePk=${item.licenseUuid}>
|
||||
</ak-enterprise-license-form>
|
||||
|
||||
@@ -28,7 +28,17 @@ export class EventListPage extends WithLicenseSummary(TablePage<Event>) {
|
||||
expandable = true;
|
||||
supportsQL = true;
|
||||
|
||||
public pageTitle = msg("Event Log");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Event Log", { id: "entity.event-log.singular" }),
|
||||
plural: msg("Event Log", { id: "entity.plural.event-log" }),
|
||||
};
|
||||
|
||||
protected override get searchPlaceholder() {
|
||||
return msg("Search for an event by action or user...", {
|
||||
id: "search.placeholder.event-list",
|
||||
});
|
||||
}
|
||||
|
||||
public pageDescription = "";
|
||||
|
||||
public pageIcon = "pf-icon pf-icon-catalog";
|
||||
@@ -52,12 +62,16 @@ export class EventListPage extends WithLicenseSummary(TablePage<Event>) {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Action"), "action"],
|
||||
[msg("User"), "user"],
|
||||
[msg("Creation Date"), "created"],
|
||||
[msg("Client IP"), "client_ip"],
|
||||
[msg("Brand"), "brand_name"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Action", { id: "column.action" }), "action"],
|
||||
[msg("User", { id: "column.user" }), "user"],
|
||||
[msg("Creation Date", { id: "column.creation-date" }), "created"],
|
||||
[msg("Client IP", { id: "column.client-ip" }), "client_ip"],
|
||||
[msg("Brand", { id: "column.brand" }), "brand_name"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
protected override rowLabel(item: Event): string | null {
|
||||
|
||||
@@ -41,11 +41,7 @@ export class RuleForm extends ModelForm<NotificationRule, string> {
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated rule.")
|
||||
: msg("Successfully created rule.");
|
||||
}
|
||||
protected override entityLabel = msg("Rule");
|
||||
|
||||
async send(data: NotificationRule): Promise<NotificationRule> {
|
||||
if (this.instance) {
|
||||
@@ -60,7 +56,11 @@ export class RuleForm extends ModelForm<NotificationRule, string> {
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Rule Name", { id: "label.rule-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -33,9 +33,15 @@ export class RuleListPage extends TablePage<NotificationRule> {
|
||||
clearOnRefresh = true;
|
||||
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Notification Rules");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Notification Rule", { id: "entity.notification-rule.singular" }),
|
||||
plural: msg("Notification Rules", { id: "entity.notification-rule.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Send notifications whenever a specific Event is created and matched by policies.",
|
||||
{
|
||||
id: "page.description.event-rule-list",
|
||||
},
|
||||
);
|
||||
public pageIcon = "pf-icon pf-icon-attention-bell";
|
||||
|
||||
@@ -47,11 +53,15 @@ export class RuleListPage extends TablePage<NotificationRule> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Enabled")],
|
||||
[msg("Name"), "name"],
|
||||
[msg("Severity"), "severity"],
|
||||
[msg("Sent to group"), "group"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Enabled", { id: "column.enabled" })],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Severity", { id: "column.severity" }), "severity"],
|
||||
[msg("Sent to group", { id: "column.send-to-group" }), "group"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -89,7 +99,7 @@ export class RuleListPage extends TablePage<NotificationRule> {
|
||||
: msg("-")}`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Notification Rule")}</span>
|
||||
<ak-event-rule-form slot="form" .instancePk=${item.pk}> </ak-event-rule-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
@@ -111,10 +121,12 @@ export class RuleListPage extends TablePage<NotificationRule> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Notification Rule")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-event-rule-form slot="form"> </ak-event-rule-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -47,11 +47,7 @@ export class TransportForm extends ModelForm<NotificationTransport, string> {
|
||||
@property({ type: Boolean })
|
||||
showEmail = false;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated transport.")
|
||||
: msg("Successfully created transport.");
|
||||
}
|
||||
protected override entityLabel = msg("Transport");
|
||||
|
||||
async send(data: NotificationTransport): Promise<NotificationTransport> {
|
||||
if (this.instance) {
|
||||
@@ -87,7 +83,11 @@ export class TransportForm extends ModelForm<NotificationTransport, string> {
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html`
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Transport Name", { id: "label.transport-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -27,9 +27,15 @@ import { customElement, property } from "lit/decorators.js";
|
||||
@customElement("ak-event-transport-list")
|
||||
export class TransportListPage extends TablePage<NotificationTransport> {
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Notification Transports");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Notification Transport", { id: "entity.notification-transport.singular" }),
|
||||
plural: msg("Notification Transports", { id: "entity.notification-transport.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Define how notifications are sent to users, like Email or Webhook.",
|
||||
{
|
||||
id: "page.description.event-transport-list",
|
||||
},
|
||||
);
|
||||
public pageIcon = "pf-icon pf-icon-export";
|
||||
|
||||
@@ -47,9 +53,13 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Mode"), "mode"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Mode", { id: "column.mode" }), "mode"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -80,7 +90,7 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
||||
html`${item.modeVerbose}`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Notification Transport")}</span>
|
||||
<ak-event-transport-form slot="form" .instancePk=${item.pk}>
|
||||
</ak-event-transport-form>
|
||||
@@ -135,10 +145,12 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Notification Transport")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-event-transport-form slot="form"> </ak-event-transport-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import "#elements/forms/ModalForm";
|
||||
import "#elements/forms/ProxyForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -31,6 +32,11 @@ export class BoundStagesList extends Table<FlowStageBinding> {
|
||||
|
||||
order = "order";
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Stage Binding", { id: "entity.stage-binding.singular" }),
|
||||
plural: msg("Stage Bindings", { id: "entity.stage-binding.plural" }),
|
||||
};
|
||||
|
||||
@property()
|
||||
target?: string;
|
||||
|
||||
@@ -46,10 +52,14 @@ export class BoundStagesList extends Table<FlowStageBinding> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Order"), "order"],
|
||||
[msg("Name"), "stage__name"],
|
||||
[msg("Type")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Order", { id: "column.order" }), "order"],
|
||||
[msg("Name", { id: "column.name" }), "stage__name"],
|
||||
[msg("Type", { id: "column.type" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -86,7 +96,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
|
||||
html`${item.stageObj?.name}`,
|
||||
html`${item.stageObj?.verboseName}`,
|
||||
html` <ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg(str`Update ${item.stageObj?.verboseName}`)}</span>
|
||||
<ak-proxy-form
|
||||
slot="form"
|
||||
@@ -97,11 +107,11 @@ export class BoundStagesList extends Table<FlowStageBinding> {
|
||||
>
|
||||
</ak-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
${msg("Edit Stage")}
|
||||
${this.editEntityLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Stage binding")}</span>
|
||||
<ak-stage-binding-form slot="form" .instancePk=${item.pk}>
|
||||
</ak-stage-binding-form>
|
||||
@@ -140,8 +150,8 @@ export class BoundStagesList extends Table<FlowStageBinding> {
|
||||
bindingTarget=${ifDefined(this.target)}
|
||||
></ak-stage-wizard>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Stage binding")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</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">
|
||||
@@ -161,8 +171,8 @@ export class BoundStagesList extends Table<FlowStageBinding> {
|
||||
bindingTarget=${ifDefined(this.target)}
|
||||
></ak-stage-wizard>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Stage binding")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</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">
|
||||
|
||||
@@ -35,11 +35,7 @@ export class FlowForm extends WithCapabilitiesConfig(ModelForm<Flow, string>) {
|
||||
return flow;
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated flow.")
|
||||
: msg("Successfully created flow.");
|
||||
}
|
||||
protected override entityLabel = msg("Flow");
|
||||
|
||||
@property({ type: Boolean })
|
||||
clearBackground = false;
|
||||
@@ -78,7 +74,11 @@ export class FlowForm extends WithCapabilitiesConfig(ModelForm<Flow, string>) {
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Flow Name", { id: "label.flow-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -21,9 +21,9 @@ export class FlowImportForm extends Form<Flow> {
|
||||
@state()
|
||||
result?: FlowImportResult;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully imported flow.");
|
||||
}
|
||||
protected override readonly actionName = "import";
|
||||
|
||||
protected override entityLabel = msg("Flow");
|
||||
|
||||
static styles: CSSResult[] = [...super.styles, PFDescriptionList];
|
||||
|
||||
|
||||
@@ -24,12 +24,22 @@ import { customElement, property } from "lit/decorators.js";
|
||||
@customElement("ak-flow-list")
|
||||
export class FlowListPage extends TablePage<Flow> {
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Flows");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Flow", { id: "entity.flow.singular" }),
|
||||
plural: msg("Flows", { id: "entity.flow.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them.",
|
||||
{
|
||||
id: "page.description.flow-list",
|
||||
},
|
||||
);
|
||||
public pageIcon = "pf-icon pf-icon-process-automation";
|
||||
|
||||
protected override get searchPlaceholder(): string {
|
||||
return msg("Search by flow name or identifier...");
|
||||
}
|
||||
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
|
||||
@@ -48,10 +58,14 @@ export class FlowListPage extends TablePage<Flow> {
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Identifier"), "slug"],
|
||||
[msg("Name"), "name"],
|
||||
[msg("Stages")],
|
||||
[msg("Policies")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Stages", { id: "column.stages" })],
|
||||
[msg("Policies", { id: "column.policies" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -86,7 +100,7 @@ export class FlowListPage extends TablePage<Flow> {
|
||||
html`${Array.from(item.stages || []).length}`,
|
||||
html`${Array.from(item.policies || []).length}`,
|
||||
html` <ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Flow")}</span>
|
||||
<ak-flow-form slot="form" .instancePk=${item.slug}> </ak-flow-form>
|
||||
<button
|
||||
@@ -128,16 +142,24 @@ export class FlowListPage extends TablePage<Flow> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Flow")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-flow-form slot="form"> </ak-flow-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Import")}</span>
|
||||
<span slot="header">${msg("Import Flow")}</span>
|
||||
<ak-flow-import-form slot="form"> </ak-flow-import-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Import")}</button>
|
||||
<button
|
||||
slot="trigger"
|
||||
class="pf-c-button pf-m-primary"
|
||||
aria-label=${msg("Import Flow")}
|
||||
>
|
||||
${msg("Import")}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
@@ -146,8 +168,8 @@ export class FlowListPage extends TablePage<Flow> {
|
||||
return html`
|
||||
${super.renderToolbar()}
|
||||
<ak-forms-confirm
|
||||
successMessage=${msg("Successfully cleared flow cache")}
|
||||
errorMessage=${msg("Failed to delete flow cache")}
|
||||
success-message=${msg("Successfully cleared flow cache")}
|
||||
error-message=${msg("Failed to delete flow cache")}
|
||||
action=${msg("Clear cache")}
|
||||
.onConfirm=${() => {
|
||||
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesCacheClearCreate();
|
||||
|
||||
@@ -123,13 +123,13 @@ export class FlowViewPage extends AKElement {
|
||||
</dd>
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Related actions")}</span
|
||||
>${msg("Actions")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit"> ${msg("Update")} </span>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">
|
||||
${msg("Update Flow")}
|
||||
</span>
|
||||
@@ -147,6 +147,16 @@ export class FlowViewPage extends AKElement {
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
</dd>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<a
|
||||
class="pf-c-button pf-m-block pf-m-secondary"
|
||||
href=${this.flow.exportUrl}
|
||||
>
|
||||
${msg("Export")}
|
||||
</a>
|
||||
</div>
|
||||
</dd>
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Execute flow")}</span
|
||||
@@ -222,21 +232,6 @@ export class FlowViewPage extends AKElement {
|
||||
</button>
|
||||
</div>
|
||||
</dd>
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Export flow")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<a
|
||||
class="pf-c-button pf-m-block pf-m-secondary"
|
||||
href=${this.flow.exportUrl}
|
||||
>
|
||||
${msg("Export")}
|
||||
</a>
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@@ -40,12 +40,7 @@ export class StageBindingForm extends ModelForm<FlowStageBinding, string> {
|
||||
@state()
|
||||
defaultOrder = 0;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance?.pk) {
|
||||
return msg("Successfully updated binding.");
|
||||
}
|
||||
return msg("Successfully created binding.");
|
||||
}
|
||||
protected override entityLabel = msg("Binding");
|
||||
|
||||
send(data: FlowStageBinding): Promise<unknown> {
|
||||
if (this.instance?.pk) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import "#components/ak-switch-input";
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
|
||||
import { DataProvision, DualSelectPair } from "#elements/ak-dual-select/types";
|
||||
import { CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { CodeMirrorHelperText, CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { ModelForm } from "#elements/forms/ModelForm";
|
||||
|
||||
import { CoreApi, CoreGroupsListRequest, Group, RbacApi, Role } from "@goauthentik/api";
|
||||
@@ -48,11 +48,7 @@ export class GroupForm extends ModelForm<Group, string> {
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated group.")
|
||||
: msg("Successfully created group.");
|
||||
}
|
||||
protected override entityLabel = msg("Group");
|
||||
|
||||
async send(data: Group): Promise<Group> {
|
||||
data.attributes ??= {};
|
||||
@@ -147,9 +143,7 @@ export class GroupForm extends ModelForm<Group, string> {
|
||||
value="${YAML.stringify(this.instance?.attributes ?? {})}"
|
||||
>
|
||||
</ak-codemirror>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Set custom attributes using YAML or JSON.")}
|
||||
</p>
|
||||
${CodeMirrorHelperText()}
|
||||
</ak-form-element-horizontal>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import "#elements/forms/ModalForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, TableColumn } from "#elements/table/Table";
|
||||
import { TablePage } from "#elements/table/TablePage";
|
||||
@@ -22,11 +23,22 @@ export class GroupListPage extends TablePage<Group> {
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
protected override searchEnabled = true;
|
||||
public searchPlaceholder = msg("Search for a group by name…");
|
||||
public searchLabel = msg("Group Search");
|
||||
public pageTitle = msg("Groups");
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Group", { id: "entity.group.singular" }),
|
||||
plural: msg("Groups", { id: "entity.group.plural" }),
|
||||
};
|
||||
|
||||
protected override get searchPlaceholder() {
|
||||
return msg("Search for a group by name...", {
|
||||
id: "search.placeholder.groups-list",
|
||||
});
|
||||
}
|
||||
|
||||
public pageDescription = msg(
|
||||
"Group users together and give them permissions based on the membership.",
|
||||
{
|
||||
id: "page.description.groups-list",
|
||||
},
|
||||
);
|
||||
public pageIcon = "pf-icon pf-icon-users";
|
||||
public supportsQL = true;
|
||||
@@ -42,11 +54,15 @@ export class GroupListPage extends TablePage<Group> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Parent"), "parent"],
|
||||
[msg("Members")],
|
||||
[msg("Superuser privileges?")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Parent", { id: "column.parent" }), "parent"],
|
||||
[msg("Members", { id: "column.members" })],
|
||||
[msg("Superuser privileges?", { id: "column.superuser-privileges-question-mark" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -83,11 +99,11 @@ export class GroupListPage extends TablePage<Group> {
|
||||
html`<ak-status-label type="neutral" ?good=${item.isSuperuser}></ak-status-label>`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Group")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${this.editEntityLabel}</span>
|
||||
<ak-group-form slot="form" .instancePk=${item.pk}> </ak-group-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<pf-tooltip position="top" content=${this.editEntityLabel}>
|
||||
<i class="fas fa-edit" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
@@ -99,10 +115,12 @@ export class GroupListPage extends TablePage<Group> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create Group")}</span>
|
||||
<span slot="header">${msg("New Group")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-group-form slot="form"> </ak-group-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("New Group")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ import "#elements/ak-mdx/ak-mdx";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -37,6 +40,11 @@ import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css";
|
||||
|
||||
@customElement("ak-group-view")
|
||||
export class GroupViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Group", { id: "entity.group.singular" }),
|
||||
plural: msg("Groups", { id: "entity.group.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: String })
|
||||
set groupId(id: string) {
|
||||
new CoreApi(DEFAULT_CONFIG)
|
||||
@@ -145,12 +153,16 @@ export class GroupViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Group")}</span>
|
||||
<span slot="submit">
|
||||
${ActionTenseRecord.apply.present()}
|
||||
</span>
|
||||
<span slot="header">
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</span>
|
||||
<ak-group-form slot="form" .instancePk=${this.group.pk}>
|
||||
</ak-group-form>
|
||||
<button slot="trigger" class="pf-m-primary pf-c-button">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import "#components/ak-status-label";
|
||||
import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, TableColumn, Timestamp } from "#elements/table/Table";
|
||||
import { TableModal } from "#elements/table/TableModal";
|
||||
@@ -22,8 +23,17 @@ type UserListRequestFilter = Partial<Pick<CoreUsersListRequest, "isActive">>;
|
||||
|
||||
@customElement("ak-group-member-select-table")
|
||||
export class MemberSelectTable extends TableModal<User> {
|
||||
public override searchPlaceholder = msg("Search for users by username or display name...");
|
||||
public override searchLabel = msg("Search Users");
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("User", { id: "entity.user.singular" }),
|
||||
plural: msg("Users", { id: "entity.user.plural" }),
|
||||
};
|
||||
|
||||
protected override get searchPlaceholder() {
|
||||
return msg("Search for users by username or display name...", {
|
||||
id: "search.placeholder.user-select-modal",
|
||||
});
|
||||
}
|
||||
|
||||
public override label = msg("Select Users");
|
||||
static styles = [
|
||||
...super.styles,
|
||||
@@ -72,9 +82,9 @@ export class MemberSelectTable extends TableModal<User> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "username"],
|
||||
[msg("Active"), "is_active"],
|
||||
[msg("Last login"), "last_login"],
|
||||
[msg("Name", { id: "column.name" }), "username"],
|
||||
[msg("Active", { id: "column.active" }), "is_active"],
|
||||
[msg("Last login", { id: "column.last-login" }), "last_login"],
|
||||
];
|
||||
|
||||
renderToolbarAfter() {
|
||||
|
||||
@@ -8,6 +8,7 @@ import "#elements/forms/ModalForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { Form } from "#elements/forms/Form";
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
@@ -28,9 +29,9 @@ export class RelatedGroupAdd extends Form<{ groups: string[] }> {
|
||||
@state()
|
||||
groupsToAdd: Group[] = [];
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully added user to group(s).");
|
||||
}
|
||||
protected override readonly actionName = "add";
|
||||
|
||||
protected override entityLabel = msg("User To Group", { id: "entity.user-to-group.singular" });
|
||||
|
||||
async send(data: { groups: string[] }): Promise<unknown> {
|
||||
await Promise.all(
|
||||
@@ -90,6 +91,11 @@ export class RelatedGroupList extends Table<Group> {
|
||||
clearOnRefresh = true;
|
||||
protected override searchEnabled = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Group", { id: "entity.group.singular" }),
|
||||
plural: msg("Groups", { id: "entity.group.plural" }),
|
||||
};
|
||||
|
||||
@property()
|
||||
order = "name";
|
||||
|
||||
@@ -105,10 +111,14 @@ export class RelatedGroupList extends Table<Group> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Parent"), "parent"],
|
||||
[msg("Superuser privileges?")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Parent", { id: "column.parent" }), "parent"],
|
||||
[msg("Superuser privileges?", { id: "column.superuser-privileges-question-mark" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -143,8 +153,8 @@ export class RelatedGroupList extends Table<Group> {
|
||||
html`${item.parentName || msg("-")}`,
|
||||
html`<ak-status-label type="neutral" ?good=${item.isSuperuser}></ak-status-label>`,
|
||||
html` <ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Group")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${this.editEntityLabel}</span>
|
||||
<ak-group-form slot="form" .instancePk=${item.pk}> </ak-group-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
@@ -169,8 +179,8 @@ export class RelatedGroupList extends Table<Group> {
|
||||
</ak-forms-modal>`
|
||||
: nothing}
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Group")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-group-form slot="form"> </ak-group-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
${msg("Add new group")}
|
||||
|
||||
@@ -15,6 +15,7 @@ import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { PFSize } from "#common/enums";
|
||||
import { parseAPIResponseError, pluckErrorDetail } from "#common/errors/network";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { MessageLevel } from "#common/messages";
|
||||
import { me } from "#common/users";
|
||||
|
||||
@@ -48,9 +49,9 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
|
||||
@state()
|
||||
usersToAdd: User[] = [];
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully added user(s).");
|
||||
}
|
||||
protected override readonly actionName = "add";
|
||||
|
||||
protected override entityLabel = msg("Users", { id: "entity.user.plural" });
|
||||
|
||||
async send(data: { users: number[] }): Promise<{ users: number[] }> {
|
||||
await Promise.all(
|
||||
@@ -123,10 +124,19 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
|
||||
|
||||
@customElement("ak-user-related-list")
|
||||
export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Table<User>)) {
|
||||
public override searchPlaceholder = msg("Search for users by username or display name...");
|
||||
public override searchLabel = msg("Group User Search");
|
||||
protected override get searchPlaceholder() {
|
||||
return msg("Search for users by username or display name...", {
|
||||
id: "search.placeholder.user-related-list",
|
||||
});
|
||||
}
|
||||
|
||||
public override label = msg("Group Users");
|
||||
|
||||
public override entityLabel: EntityLabel = {
|
||||
singular: msg("User", { id: "entity.user.singular" }),
|
||||
plural: msg("Users", { id: "entity.user.plural" }),
|
||||
};
|
||||
|
||||
expandable = true;
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
@@ -165,10 +175,14 @@ export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Tabl
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "username"],
|
||||
[msg("Active"), "is_active"],
|
||||
[msg("Last login"), "last_login"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "username"],
|
||||
[msg("Active", { id: "column.active" }), "is_active"],
|
||||
[msg("Last login", { id: "column.last-login" }), "last_login"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -216,8 +230,8 @@ export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Tabl
|
||||
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update User")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${this.editEntityLabel}</span>
|
||||
<ak-user-form slot="form" .instancePk=${item.pk}> </ak-user-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
@@ -343,7 +357,7 @@ export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Tabl
|
||||
</ak-action-button>
|
||||
${item.email
|
||||
? html`<ak-forms-modal .closeAfterSuccessfulSubmit=${false}>
|
||||
<span slot="submit"> ${msg("Send link")} </span>
|
||||
<span slot="submit">${msg("Send link")}</span>
|
||||
<span slot="header">
|
||||
${msg("Send recovery link to user")}
|
||||
</span>
|
||||
@@ -417,8 +431,8 @@ export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Tabl
|
||||
>
|
||||
<li role="presentation">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create User")}</span>
|
||||
<span slot="header">${msg("New User")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
${this.targetGroup
|
||||
? html`
|
||||
<div class="pf-c-banner pf-m-info" slot="above-form">
|
||||
@@ -430,7 +444,7 @@ export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Tabl
|
||||
: nothing}
|
||||
<ak-user-form .group=${this.targetGroup} slot="form"> </ak-user-form>
|
||||
<a role="menuitem" slot="trigger" class="pf-c-dropdown__menu-item">
|
||||
${msg("New user...")}
|
||||
${this.newEntityActionLabel}
|
||||
</a>
|
||||
</ak-forms-modal>
|
||||
</li>
|
||||
@@ -453,7 +467,7 @@ export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Tabl
|
||||
<ak-user-service-account-form .group=${this.targetGroup} slot="form">
|
||||
</ak-user-service-account-form>
|
||||
<a role="menuitem" slot="trigger" class="pf-c-dropdown__menu-item">
|
||||
${msg("New service account...")}
|
||||
${msg("New Service Account")}
|
||||
</a>
|
||||
</ak-forms-modal>
|
||||
</li>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { docLink } from "#common/global";
|
||||
import { groupBy } from "#common/utils";
|
||||
|
||||
import { DataProvider, DualSelectPair } from "#elements/ak-dual-select/types";
|
||||
import { CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { CodeMirrorHelperText, CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { ModelForm } from "#elements/forms/ModelForm";
|
||||
import { PaginatedResponse } from "#elements/table/Table";
|
||||
|
||||
@@ -120,11 +120,7 @@ export class OutpostForm extends ModelForm<Outpost, string> {
|
||||
this.providers = providerProvider(this.type);
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated outpost.")
|
||||
: msg("Successfully created outpost.");
|
||||
}
|
||||
protected override entityLabel = msg("Outpost", { id: "entity.outpost.singular" });
|
||||
|
||||
async send(data: Outpost): Promise<Outpost> {
|
||||
if (this.instance) {
|
||||
@@ -146,7 +142,11 @@ export class OutpostForm extends ModelForm<Outpost, string> {
|
||||
[OutpostTypeEnum.Rac, msg("RAC")],
|
||||
];
|
||||
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Outpost Name", { id: "label.outpost-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
@@ -243,9 +243,7 @@ export class OutpostForm extends ModelForm<Outpost, string> {
|
||||
this.instance ? this.instance.config : this.defaultConfig?.config,
|
||||
)}"
|
||||
></ak-codemirror>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Set custom attributes using YAML or JSON.")}
|
||||
</p>
|
||||
${CodeMirrorHelperText()}
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("See more here:")}
|
||||
<a
|
||||
|
||||
@@ -54,9 +54,15 @@ export function TypeToLabel(type?: OutpostTypeEnum): string {
|
||||
export class OutpostListPage extends TablePage<Outpost> {
|
||||
expandable = true;
|
||||
|
||||
public pageTitle = msg("Outposts");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Outpost", { id: "entity.outpost.singular" }),
|
||||
plural: msg("Outposts", { id: "entity.outpost.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Outposts are deployments of authentik components to support different environments and protocols, like reverse proxies.",
|
||||
{
|
||||
id: "page.description.outpost-list",
|
||||
},
|
||||
);
|
||||
|
||||
public pageIcon = "pf-icon pf-icon-zone";
|
||||
@@ -84,12 +90,16 @@ export class OutpostListPage extends TablePage<Outpost> {
|
||||
health: { [key: string]: OutpostHealth[] } = {};
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Type"), "type"],
|
||||
[msg("Providers")],
|
||||
[msg("Integration"), "service_connection__name"],
|
||||
[msg("Health and Version")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Type", { id: "column.type" }), "type"],
|
||||
[msg("Providers", { id: "column.providers" })],
|
||||
[msg("Integration", { id: "column.integration" }), "service_connection__name"],
|
||||
[msg("Health and Version", { id: "column.health-and-version" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
static styles: CSSResult[] = [...super.styles, PFDescriptionList];
|
||||
@@ -126,7 +136,7 @@ export class OutpostListPage extends TablePage<Outpost> {
|
||||
></ak-outpost-health-simple>`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg("Update Outpost")}</span>
|
||||
<ak-outpost-form
|
||||
slot="form"
|
||||
@@ -233,10 +243,12 @@ export class OutpostListPage extends TablePage<Outpost> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Outpost")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-outpost-form slot="form"> </ak-outpost-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -21,11 +21,7 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated integration.")
|
||||
: msg("Successfully created integration.");
|
||||
}
|
||||
protected override entityLabel = msg("Integration", { id: "entity.integration.singular" });
|
||||
|
||||
async send(data: DockerServiceConnection): Promise<DockerServiceConnection> {
|
||||
if (this.instance) {
|
||||
@@ -40,7 +36,13 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Service Connection Docker Name", {
|
||||
id: "label.service-connection-docker-name",
|
||||
})}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -3,7 +3,7 @@ import "#elements/forms/HorizontalFormElement";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
|
||||
import { CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { CodeMirrorHelperText, CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { ModelForm } from "#elements/forms/ModelForm";
|
||||
|
||||
import { KubernetesServiceConnection, OutpostsApi } from "@goauthentik/api";
|
||||
@@ -26,11 +26,7 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated integration.")
|
||||
: msg("Successfully created integration.");
|
||||
}
|
||||
protected override entityLabel = msg("Integration", { id: "entity.integration.singular" });
|
||||
|
||||
async send(data: KubernetesServiceConnection): Promise<KubernetesServiceConnection> {
|
||||
if (this.instance) {
|
||||
@@ -45,7 +41,13 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Service Connection Kubernetes Name", {
|
||||
id: "label.service-connection-kubernetes-name",
|
||||
})}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
@@ -79,9 +81,7 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
|
||||
value="${YAML.stringify(this.instance?.kubeconfig ?? {})}"
|
||||
>
|
||||
</ak-codemirror>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Set custom attributes using YAML or JSON.")}
|
||||
</p>
|
||||
${CodeMirrorHelperText()}
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="verifySsl">
|
||||
<label class="pf-c-switch">
|
||||
|
||||
@@ -28,9 +28,15 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
@customElement("ak-outpost-service-connection-list")
|
||||
export class OutpostServiceConnectionListPage extends TablePage<ServiceConnection> {
|
||||
public pageTitle = msg("Outpost integrations");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Outpost Integration", { id: "entity.outpost-integration.singular" }),
|
||||
plural: msg("Outpost Integrations", { id: "entity.outpost-integration.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Outpost integrations define how authentik connects to external platforms to manage and deploy Outposts.",
|
||||
{
|
||||
id: "page.description.outpost-service-connection-list",
|
||||
},
|
||||
);
|
||||
|
||||
public pageIcon = "pf-icon pf-icon-integration";
|
||||
@@ -62,11 +68,15 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
|
||||
state: { [key: string]: ServiceConnectionState } = {};
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Type")],
|
||||
[msg("Local"), "local"],
|
||||
[msg("State")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Type", { id: "column.type" })],
|
||||
[msg("Local", { id: "column.local" }), "local"],
|
||||
[msg("State", { id: "column.state" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
@property()
|
||||
@@ -83,7 +93,7 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
|
||||
: html`<ak-label color=${PFColor.Red}>${msg("Unhealthy")}</ak-label>`}`,
|
||||
html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg(str`Update ${item.verboseName}`)}</span>
|
||||
<ak-proxy-form
|
||||
slot="form"
|
||||
|
||||
@@ -6,6 +6,7 @@ import "#elements/wizard/TypeCreateWizardPage";
|
||||
import "#elements/wizard/Wizard";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { formatNewMessage } from "#common/i18n/actions";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import type { Wizard } from "#elements/wizard/Wizard";
|
||||
@@ -25,7 +26,7 @@ export class ServiceConnectionWizard extends AKElement {
|
||||
static styles: CSSResult[] = [PFBase, PFButton];
|
||||
|
||||
@property()
|
||||
createText = msg("Create");
|
||||
createText = formatNewMessage(msg("Service Connection"));
|
||||
|
||||
@property({ attribute: false })
|
||||
connectionTypes: TypeCreate[] = [];
|
||||
|
||||
@@ -3,9 +3,5 @@ import { ModelForm } from "#elements/forms/ModelForm";
|
||||
import { msg } from "@lit/localize";
|
||||
|
||||
export abstract class BasePolicyForm<T> extends ModelForm<T, string> {
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated policy.")
|
||||
: msg("Successfully created policy.");
|
||||
}
|
||||
protected override entityLabel = msg("Policy", { id: "entity.policy.singular" });
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ import "#elements/forms/ProxyForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { PFSize } from "#common/enums";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -55,6 +58,11 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
|
||||
order = "order";
|
||||
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Policy Binding", { id: "entity.policy-binding.singular" }),
|
||||
plural: msg("Policy Bindings", { id: "entity.policy-binding.plural" }),
|
||||
};
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(PFSpacing);
|
||||
}
|
||||
@@ -75,11 +83,15 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Order"), "order"],
|
||||
[msg("Order", { id: "column.order" }), "order"],
|
||||
[this.allowedTypesLabel],
|
||||
[msg("Enabled"), "enabled"],
|
||||
[msg("Timeout"), "timeout"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Enabled", { id: "column.enabled" }), "enabled"],
|
||||
[msg("Timeout", { id: "column.timeout" }), "timeout"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
getPolicyUserGroupRowLabel(item: PolicyBinding): string {
|
||||
@@ -107,7 +119,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
getObjectEditButton(item: PolicyBinding): SlottedTemplateResult {
|
||||
if (item.policy) {
|
||||
return html`<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg(str`Update ${item.policyObj?.name}`)}</span>
|
||||
<ak-proxy-form
|
||||
slot="form"
|
||||
@@ -123,20 +135,20 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
</ak-forms-modal>`;
|
||||
} else if (item.group) {
|
||||
return html`<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Group")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(msg("Group"))}</span>
|
||||
<ak-group-form slot="form" .instancePk=${item.groupObj?.pk}> </ak-group-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
${msg("Edit Group")}
|
||||
${formatEditMessage(msg("Group"))}
|
||||
</button>
|
||||
</ak-forms-modal>`;
|
||||
} else if (item.user) {
|
||||
return html`<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update User")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(msg("User"))}</span>
|
||||
<ak-user-form slot="form" .instancePk=${item.userObj?.pk}> </ak-user-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
${msg("Edit User")}
|
||||
${formatEditMessage(msg("User"))}
|
||||
</button>
|
||||
</ak-forms-modal>`;
|
||||
}
|
||||
@@ -182,8 +194,8 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
html`${item.timeout}`,
|
||||
html` ${this.getObjectEditButton(item)}
|
||||
<ak-forms-modal size=${PFSize.Medium}>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Binding")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${this.editEntityLabel}</span>
|
||||
<ak-policy-binding-form
|
||||
slot="form"
|
||||
.instancePk=${item.pk}
|
||||
@@ -193,7 +205,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
>
|
||||
</ak-policy-binding-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
${msg("Edit Binding")}
|
||||
${this.updateEntityLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-rbac-object-permission-modal
|
||||
@@ -217,8 +229,8 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
bindingTarget=${ifDefined(this.target)}
|
||||
></ak-policy-wizard>
|
||||
<ak-forms-modal size=${PFSize.Medium}>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Binding")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-policy-binding-form
|
||||
slot="form"
|
||||
targetPk=${ifDefined(this.target)}
|
||||
@@ -244,8 +256,8 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
></ak-policy-wizard>`
|
||||
: nothing}
|
||||
<ak-forms-modal size=${PFSize.Medium}>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Binding")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-policy-binding-form
|
||||
slot="form"
|
||||
targetPk=${ifDefined(this.target)}
|
||||
|
||||
@@ -68,12 +68,9 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
|
||||
@state()
|
||||
defaultOrder = 0;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance?.pk) {
|
||||
return msg("Successfully updated binding.");
|
||||
}
|
||||
return msg("Successfully created binding.");
|
||||
}
|
||||
protected override entityLabel = msg("Policy Binding", {
|
||||
id: "entity.policy.binding.singular",
|
||||
});
|
||||
|
||||
static styles: CSSResult[] = [...super.styles, PFContent];
|
||||
|
||||
|
||||
@@ -31,9 +31,15 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
||||
@customElement("ak-policy-list")
|
||||
export class PolicyListPage extends TablePage<Policy> {
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Policies");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Policy", { id: "entity.policy.singular" }),
|
||||
plural: msg("Policies", { id: "entity.policy.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages.",
|
||||
{
|
||||
id: "page.description.policy-list",
|
||||
},
|
||||
);
|
||||
public pageIcon = "pf-icon pf-icon-infrastructure";
|
||||
|
||||
@@ -49,9 +55,9 @@ export class PolicyListPage extends TablePage<Policy> {
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Name"), "name"],
|
||||
[msg("Type")],
|
||||
[msg("Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Type", { id: "column.type" })],
|
||||
[msg("Actions", { id: "column.actions" })],
|
||||
];
|
||||
|
||||
row(item: Policy): SlottedTemplateResult[] {
|
||||
@@ -66,7 +72,7 @@ export class PolicyListPage extends TablePage<Policy> {
|
||||
</ak-label>`}`,
|
||||
html`${item.verboseName}`,
|
||||
html` <ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg(str`Update ${item.verboseName}`)}</span>
|
||||
<ak-proxy-form
|
||||
slot="form"
|
||||
@@ -127,8 +133,8 @@ export class PolicyListPage extends TablePage<Policy> {
|
||||
renderToolbar(): TemplateResult {
|
||||
return html` ${super.renderToolbar()}
|
||||
<ak-forms-confirm
|
||||
successMessage=${msg("Successfully cleared policy cache")}
|
||||
errorMessage=${msg("Failed to delete policy cache")}
|
||||
success-message=${msg("Successfully cleared policy cache")}
|
||||
error-message=${msg("Failed to delete policy cache")}
|
||||
action=${msg("Clear cache")}
|
||||
.onConfirm=${() => {
|
||||
return new PoliciesApi(DEFAULT_CONFIG).policiesAllCacheClearCreate();
|
||||
|
||||
@@ -6,7 +6,7 @@ import "#elements/forms/SearchSelect/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
|
||||
import { CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { CodeMirrorHelperText, CodeMirrorMode } from "#elements/CodeMirror";
|
||||
import { Form } from "#elements/forms/Form";
|
||||
|
||||
import {
|
||||
@@ -38,9 +38,11 @@ export class PolicyTestForm extends Form<PolicyTestRequest> {
|
||||
@property({ attribute: false })
|
||||
request?: PolicyTestRequest;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully sent test-request.");
|
||||
}
|
||||
protected override readonly actionName = "send";
|
||||
|
||||
protected override entityLabel = msg("Test Request", {
|
||||
id: "entity.policy.test.request.singular",
|
||||
});
|
||||
|
||||
async send(data: PolicyTestRequest): Promise<PolicyTestResult> {
|
||||
this.request = data;
|
||||
@@ -128,9 +130,7 @@ export class PolicyTestForm extends Form<PolicyTestRequest> {
|
||||
value=${YAML.stringify(this.request?.context ?? {})}
|
||||
>
|
||||
</ak-codemirror>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Set custom attributes using YAML or JSON.")}
|
||||
</p>
|
||||
${CodeMirrorHelperText()}
|
||||
</ak-form-element-horizontal>
|
||||
${this.result ? this.renderResult() : nothing}`;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import "#elements/wizard/TypeCreateWizardPage";
|
||||
import "#elements/wizard/Wizard";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { formatNewMessage } from "#common/i18n/actions";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { FormWizardPage } from "#elements/wizard/FormWizardPage";
|
||||
@@ -34,7 +35,7 @@ export class PolicyWizard extends AKElement {
|
||||
static styles: CSSResult[] = [PFBase, PFButton];
|
||||
|
||||
@property()
|
||||
createText = msg("Create");
|
||||
createText = formatNewMessage(msg("Policy"));
|
||||
|
||||
@property({ type: Boolean })
|
||||
showBindingPage = false;
|
||||
|
||||
@@ -38,7 +38,11 @@ export class DummyPolicyForm extends BasePolicyForm<DummyPolicy> {
|
||||
"A policy used for testing. Always returns the same result as specified below after waiting a random duration.",
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Dummy Policy Name", { id: "label.dummy-policy-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
|
||||
@@ -50,7 +50,11 @@ export class EventMatcherPolicyForm extends BasePolicyForm<EventMatcherPolicy> {
|
||||
"Matches an event against a set of criteria. If any of the configured values match, the policy passes.",
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Event Matcher Policy Name", { id: "label.event-matcher-policy-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
|
||||
@@ -38,7 +38,11 @@ export class PasswordExpiryPolicyForm extends BasePolicyForm<PasswordExpiryPolic
|
||||
"Checks if the request's user's password has been changed in the last x days, and denys based on settings.",
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Expiry Policy Name", { id: "label.expiry-policy-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
|
||||
@@ -42,7 +42,11 @@ export class ExpressionPolicyForm extends BasePolicyForm<ExpressionPolicy> {
|
||||
"Executes the python snippet to determine whether to allow or deny a request.",
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Expression Policy Name", { id: "label.expression-policy-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
|
||||
@@ -53,7 +53,11 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
|
||||
"Ensure the user satisfies requirements of geography or network topology, based on IP address. If any of the configured values match, the policy passes.",
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("GeoIP Policy Name", { id: "label.geoip-policy-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${this.instance?.name ?? ""}"
|
||||
|
||||
@@ -220,7 +220,11 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
|
||||
"Checks the value from the policy request against several rules, mostly used to ensure password strength.",
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Password Policy Name", { id: "label.password-policy-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
|
||||
@@ -25,9 +25,15 @@ import { customElement, property } from "lit/decorators.js";
|
||||
@customElement("ak-policy-reputation-list")
|
||||
export class ReputationListPage extends TablePage<Reputation> {
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Reputation scores");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Reputation Score", { id: "entity.reputation-score.singular" }),
|
||||
plural: msg("Reputation Scores", { id: "entity.reputation-score.plural" }),
|
||||
};
|
||||
public pageDescription = msg(
|
||||
"Reputation for IP and user identifiers. Scores are decreased for each failed login and increased for each successful login.",
|
||||
{
|
||||
id: "page.description.policy-reputation-list",
|
||||
},
|
||||
);
|
||||
public pageIcon = "fa fa-ban";
|
||||
|
||||
@@ -48,11 +54,15 @@ export class ReputationListPage extends TablePage<Reputation> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Identifier"), "identifier"],
|
||||
[msg("IP"), "ip"],
|
||||
[msg("Score"), "score"],
|
||||
[msg("Updated"), "updated"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Identifier", { id: "column.identifier" }), "identifier"],
|
||||
[msg("IP", { id: "column.ip" }), "ip"],
|
||||
[msg("Score", { id: "column.score" }), "score"],
|
||||
[msg("Updated", { id: "column.updated" }), "updated"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
|
||||
@@ -48,7 +48,11 @@ username they are attempting to login as, by one.`,
|
||||
doesn't pass when either or both of the selected options are equal or above the threshold.`,
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Reputation Policy Name", { id: "label.reputation-policy-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
|
||||
@@ -38,7 +38,13 @@ export class UniquePasswordPolicyForm extends BasePolicyForm<UniquePasswordPolic
|
||||
"Ensure that the user's new password is different from their previous passwords. The number of past passwords to check is configurable.",
|
||||
)}
|
||||
</span>
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Unique Password Policy Name", {
|
||||
id: "label.unique-password-policy-name",
|
||||
})}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
|
||||
@@ -19,18 +19,18 @@ export abstract class BasePropertyMappingForm<T extends PropertyMapping> extends
|
||||
> {
|
||||
protected docLink: string | URL = "/add-secure-apps/providers/property-mappings/expression";
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated mapping.")
|
||||
: msg("Successfully created mapping.");
|
||||
}
|
||||
protected override entityLabel = msg("Mapping", { id: "entity.mapping.singular" });
|
||||
|
||||
renderExtraFields(): SlottedTemplateResult {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html` <ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html` <ak-form-element-horizontal
|
||||
label=${msg("Property Mapping Name", { id: "label.property-mapping-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -22,6 +22,7 @@ import "#elements/forms/ProxyForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { getURLParam, updateURLParams } from "#elements/router/RouteMatch";
|
||||
import { PaginatedResponse, TableColumn } from "#elements/table/Table";
|
||||
@@ -38,13 +39,17 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
||||
@customElement("ak-property-mapping-list")
|
||||
export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Property Mappings");
|
||||
public pageDescription = msg("Control how authentik exposes and interprets information.");
|
||||
public pageIcon = "pf-icon pf-icon-blueprint";
|
||||
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Property Mapping", { id: "entity.property-mapping.singular" }),
|
||||
plural: msg("Property Mappings", { id: "entity.property-mapping.plural" }),
|
||||
};
|
||||
|
||||
@property()
|
||||
order = "name";
|
||||
|
||||
@@ -59,9 +64,13 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Type"), "type"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Type", { id: "column.type" }), "type"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -91,7 +100,7 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
||||
html`${item.name}`,
|
||||
html`${item.verboseName}`,
|
||||
html` <ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${msg(str`Update ${item.verboseName}`)}</span>
|
||||
<ak-proxy-form
|
||||
slot="form"
|
||||
|
||||
@@ -57,7 +57,11 @@ export class PropertyMappingProviderRACForm extends BasePropertyMappingForm<RACP
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html`
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("RAC Property Mapping Name", { id: "label.rac-property-mapping-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
|
||||
@@ -38,9 +38,11 @@ export class PolicyTestForm extends Form<PropertyMappingTestRequest> {
|
||||
@property({ attribute: false })
|
||||
request?: PropertyMappingTestRequest;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully sent test-request.");
|
||||
}
|
||||
protected override readonly actionName = "send";
|
||||
|
||||
protected override entityLabel = msg("Test Request", {
|
||||
id: "entity.policy.test.request.singular",
|
||||
});
|
||||
|
||||
async send(data: PropertyMappingTestRequest): Promise<PropertyMappingTestResult> {
|
||||
this.request = data;
|
||||
|
||||
@@ -20,6 +20,7 @@ import "#elements/wizard/TypeCreateWizardPage";
|
||||
import "#elements/wizard/Wizard";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { formatNewMessage } from "#common/i18n/actions";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import type { Wizard } from "#elements/wizard/Wizard";
|
||||
@@ -80,7 +81,9 @@ export class PropertyMappingWizard extends AKElement {
|
||||
</ak-wizard-page-form>
|
||||
`;
|
||||
})}
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${formatNewMessage(msg("Property Mapping"))}
|
||||
</button>
|
||||
</ak-wizard>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -7,11 +7,7 @@ import { APIMessage } from "#elements/messages/Message";
|
||||
import { msg } from "@lit/localize";
|
||||
|
||||
export abstract class BaseProviderForm<T> extends ModelForm<T, number> {
|
||||
public override getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated provider.")
|
||||
: msg("Successfully created provider.");
|
||||
}
|
||||
protected override entityLabel = msg("Provider", { id: "entity.provider.singular" });
|
||||
|
||||
protected override formatAPIErrorMessage(error: APIError): APIMessage {
|
||||
return {
|
||||
|
||||
@@ -17,6 +17,7 @@ import "#elements/forms/ProxyForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { PaginatedResponse, TableColumn } from "#elements/table/Table";
|
||||
import { TablePage } from "#elements/table/TablePage";
|
||||
@@ -32,10 +33,22 @@ import { customElement, property } from "lit/decorators.js";
|
||||
export class ProviderListPage extends TablePage<Provider> {
|
||||
protected override searchEnabled = true;
|
||||
|
||||
override pageTitle = msg("Providers");
|
||||
protected override entityLabel = {
|
||||
singular: msg("Provider", { id: "entity.provider.singular" }),
|
||||
plural: msg("Providers", { id: "entity.provider.plural" }),
|
||||
};
|
||||
|
||||
protected override get searchPlaceholder() {
|
||||
return msg("Search for a provider by name or application...", {
|
||||
id: "search.placeholder.provider-list",
|
||||
});
|
||||
}
|
||||
|
||||
public pageDescription = msg(
|
||||
"Provide support for protocols like SAML and OAuth to assigned applications.",
|
||||
{
|
||||
id: "page.description.provider-list",
|
||||
},
|
||||
);
|
||||
|
||||
public pageIcon = "pf-icon pf-icon-integration";
|
||||
@@ -46,9 +59,6 @@ export class ProviderListPage extends TablePage<Provider> {
|
||||
@property()
|
||||
public order = "name";
|
||||
|
||||
public searchLabel = msg("Provider Search");
|
||||
public searchPlaceholder = msg("Search for providers…");
|
||||
|
||||
override async apiEndpoint(): Promise<PaginatedResponse<Provider>> {
|
||||
return new ProvidersApi(DEFAULT_CONFIG).providersAllList(
|
||||
await this.defaultEndpointConfig(),
|
||||
@@ -56,10 +66,14 @@ export class ProviderListPage extends TablePage<Provider> {
|
||||
}
|
||||
|
||||
protected override columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Application")],
|
||||
[msg("Type")],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Application", { id: "column.application" })],
|
||||
[msg("Type", { id: "column.type" })],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
override renderToolbarSelected(): TemplateResult {
|
||||
@@ -113,7 +127,7 @@ export class ProviderListPage extends TablePage<Provider> {
|
||||
html`${item.verboseName}`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${msg(str`Update ${item.verboseName}`)}</span>
|
||||
<ak-proxy-form
|
||||
slot="form"
|
||||
|
||||
@@ -12,6 +12,7 @@ import "#elements/EmptyState";
|
||||
import "#elements/buttons/SpinnerButton/ak-spinner-button";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
|
||||
@@ -21,6 +22,7 @@ import { Provider, ProvidersApi } from "@goauthentik/api";
|
||||
|
||||
import { spread } from "@open-wc/lit-helpers";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { css, CSSResult, html, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
@@ -28,6 +30,11 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
|
||||
@customElement("ak-provider-view")
|
||||
export class ProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Provider", { id: "entity.provider.singular" }),
|
||||
plural: msg("Providers", { id: "entity.provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
set providerID(value: number) {
|
||||
new ProvidersApi(DEFAULT_CONFIG)
|
||||
|
||||
@@ -10,6 +10,7 @@ import "#elements/wizard/TypeCreateWizardPage";
|
||||
import "#elements/wizard/Wizard";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { formatNewMessage } from "#common/i18n/actions";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { TypeCreateWizardPageLayouts } from "#elements/wizard/TypeCreateWizardPage";
|
||||
@@ -30,7 +31,7 @@ export class ProviderWizard extends AKElement {
|
||||
static styles: CSSResult[] = [PFBase, PFButton];
|
||||
|
||||
@property()
|
||||
createText = msg("Create");
|
||||
createText = formatNewMessage(msg("Provider"));
|
||||
|
||||
@property({ attribute: false })
|
||||
providerTypes: TypeCreate[] = [];
|
||||
@@ -79,14 +80,13 @@ export class ProviderWizard extends AKElement {
|
||||
`;
|
||||
})}
|
||||
<button
|
||||
aria-label=${msg("New Provider")}
|
||||
aria-description="${msg("Open the wizard to create a new provider.")}"
|
||||
type="button"
|
||||
part="button trigger"
|
||||
slot="trigger"
|
||||
class="pf-c-button pf-m-primary"
|
||||
>
|
||||
${msg("Create")}
|
||||
${formatNewMessage(msg("Provider"))}
|
||||
</button>
|
||||
</ak-wizard>
|
||||
`;
|
||||
|
||||
@@ -2,6 +2,9 @@ import "#admin/applications/ApplicationForm";
|
||||
import "#elements/Spinner";
|
||||
import "#elements/forms/ModalForm";
|
||||
|
||||
import { formatCreateMessage, formatNewMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
|
||||
import { Provider } from "@goauthentik/api";
|
||||
@@ -17,6 +20,11 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
export class RelatedApplicationButton extends AKElement {
|
||||
static styles: CSSResult[] = [PFBase, PFButton];
|
||||
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Application", { id: "entity.application.singular" }),
|
||||
plural: msg("Applications", { id: "entity.application.plural" }),
|
||||
};
|
||||
|
||||
@property({ attribute: false })
|
||||
provider?: Provider;
|
||||
|
||||
@@ -37,10 +45,13 @@ export class RelatedApplicationButton extends AKElement {
|
||||
</a>`;
|
||||
}
|
||||
return html`<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Application")}</span>
|
||||
<span slot="submit">${formatCreateMessage(this.entityLabel)}</span>
|
||||
<span slot="header">${formatNewMessage(this.entityLabel)}</span>
|
||||
|
||||
<ak-application-form slot="form" .provider=${this.provider?.pk}> </ak-application-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${formatNewMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import "#elements/forms/ModalForm";
|
||||
import "#elements/sync/SyncObjectForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -25,6 +26,11 @@ export class GoogleWorkspaceProviderGroupList extends Table<GoogleWorkspaceProvi
|
||||
|
||||
expandable = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Google Workspace Group", { id: "entity.google-workspace-group.singular" }),
|
||||
plural: msg("Google Workspace Groups", { id: "entity.google-workspace-group.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
checkbox = true;
|
||||
@@ -79,9 +85,8 @@ export class GoogleWorkspaceProviderGroupList extends Table<GoogleWorkspaceProvi
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Name")],
|
||||
[msg("ID")],
|
||||
[msg("Name", { id: "column.name" })],
|
||||
[msg("ID", { id: "column.id" })],
|
||||
];
|
||||
|
||||
row(item: GoogleWorkspaceProviderGroup): SlottedTemplateResult[] {
|
||||
|
||||
@@ -3,6 +3,7 @@ import "#elements/forms/ModalForm";
|
||||
import "#elements/sync/SyncObjectForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -23,6 +24,11 @@ export class GoogleWorkspaceProviderUserList extends Table<GoogleWorkspaceProvid
|
||||
@property({ type: Number })
|
||||
providerId?: number;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Google Workspace User", { id: "entity.google-workspace-user.singular" }),
|
||||
plural: msg("Google Workspace Users", { id: "entity.google-workspace-user.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
expandable = true;
|
||||
@@ -80,8 +86,8 @@ export class GoogleWorkspaceProviderUserList extends Table<GoogleWorkspaceProvid
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Username")],
|
||||
[msg("ID")],
|
||||
[msg("Username", { id: "column.username" })],
|
||||
[msg("ID", { id: "column.id" })],
|
||||
];
|
||||
|
||||
row(item: GoogleWorkspaceProviderUser): SlottedTemplateResult[] {
|
||||
|
||||
@@ -13,6 +13,9 @@ import "#elements/tasks/TaskList";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -42,6 +45,15 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
@customElement("ak-provider-google-workspace-view")
|
||||
export class GoogleWorkspaceProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Google Workspace Provider", {
|
||||
id: "entity.google-workspace-provider.singular",
|
||||
}),
|
||||
plural: msg("Google Workspace Providers", {
|
||||
id: "entity.google-workspace-provider.plural",
|
||||
}),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -206,15 +218,15 @@ export class GoogleWorkspaceProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Google Workspace Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-google-workspace-form
|
||||
slot="form"
|
||||
.instancePk=${this.provider.pk}
|
||||
>
|
||||
</ak-provider-google-workspace-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,9 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { WithSession } from "#elements/mixins/session";
|
||||
@@ -39,6 +42,11 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
@customElement("ak-provider-ldap-view")
|
||||
export class LDAPProviderViewPage extends WithSession(AKElement) {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Ldap Provider", { id: "entity.ldap-provider.singular" }),
|
||||
plural: msg("Ldap Providers", { id: "entity.ldap-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -130,14 +138,11 @@ export class LDAPProviderViewPage extends WithSession(AKElement) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
${
|
||||
this.provider?.outpostSet.length < 1
|
||||
? html`<div slot="header" class="pf-c-banner pf-m-warning">
|
||||
${msg("Warning: Provider is not used by any Outpost.")}
|
||||
</div>`
|
||||
: nothing
|
||||
}
|
||||
return html`${!this.provider.outpostSet.length
|
||||
? html`<div slot="header" class="pf-c-banner pf-m-warning">
|
||||
${msg("Warning: Provider is not used by any Outpost.")}
|
||||
</div>`
|
||||
: nothing}
|
||||
<div class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__body">
|
||||
@@ -182,24 +187,20 @@ export class LDAPProviderViewPage extends WithSession(AKElement) {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update LDAP Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-ldap-form slot="form" .instancePk=${this.provider.pk}>
|
||||
</ak-provider-ldap-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__title">
|
||||
${msg("How to connect")}
|
||||
</div>
|
||||
<div class="pf-c-card__title">${msg("How to connect")}</div>
|
||||
<div class="pf-c-card__body">
|
||||
<p>
|
||||
${msg("Connect to the LDAP Server on port 389:")}
|
||||
</p>
|
||||
<p>${msg("Connect to the LDAP Server on port 389:")}</p>
|
||||
<ul class="pf-c-list">
|
||||
<li>${msg("Check the IP of the Kubernetes service, or")}</li>
|
||||
<li>${msg("The Host IP of the docker host")}</li>
|
||||
@@ -210,7 +211,7 @@ export class LDAPProviderViewPage extends WithSession(AKElement) {
|
||||
<span class="pf-c-form__label-text">${msg("Bind DN")}</span>
|
||||
</label>
|
||||
<input
|
||||
class="pf-c-form-control"
|
||||
class="pf-c-form-control pf-m-monospace"
|
||||
readonly
|
||||
type="text"
|
||||
value=${`cn=${this.currentUser?.username},ou=users,${this.provider?.baseDn?.toLowerCase()}`}
|
||||
@@ -218,12 +219,12 @@ export class LDAPProviderViewPage extends WithSession(AKElement) {
|
||||
</div>
|
||||
<div class="pf-c-form__group">
|
||||
<label class="pf-c-form__label">
|
||||
<span class="pf-c-form__label-text">${msg(
|
||||
"Bind Password",
|
||||
)}</span>
|
||||
<span class="pf-c-form__label-text"
|
||||
>${msg("Bind Password")}</span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
class="pf-c-form-control"
|
||||
class="pf-c-form-control pf-m-monospace"
|
||||
readonly
|
||||
type="text"
|
||||
value=${msg("Your authentik password")}
|
||||
@@ -234,7 +235,7 @@ export class LDAPProviderViewPage extends WithSession(AKElement) {
|
||||
<span class="pf-c-form__label-text">${msg("Search base")}</span>
|
||||
</label>
|
||||
<input
|
||||
class="pf-c-form-control"
|
||||
class="pf-c-form-control pf-m-monospace"
|
||||
readonly
|
||||
type="text"
|
||||
value=${ifDefined(this.provider?.baseDn?.toLowerCase())}
|
||||
@@ -243,8 +244,7 @@ export class LDAPProviderViewPage extends WithSession(AKElement) {
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import "#elements/forms/ModalForm";
|
||||
import "#elements/sync/SyncObjectForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -27,6 +28,11 @@ export class MicrosoftEntraProviderGroupList extends Table<MicrosoftEntraProvide
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Microsoft Entra Group", { id: "entity.microsoft-entra-group.singular" }),
|
||||
plural: msg("Microsoft Entra Groups", { id: "entity.microsoft-entra-group.plural" }),
|
||||
};
|
||||
|
||||
renderToolbar(): TemplateResult {
|
||||
return html`<ak-forms-modal cancelText=${msg("Close")} ?closeAfterSuccessfulSubmit=${false}>
|
||||
<span slot="submit">${msg("Sync")}</span>
|
||||
@@ -76,9 +82,8 @@ export class MicrosoftEntraProviderGroupList extends Table<MicrosoftEntraProvide
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Name")],
|
||||
[msg("ID")],
|
||||
[msg("Name", { id: "column.name" })],
|
||||
[msg("ID", { id: "column.id" })],
|
||||
];
|
||||
|
||||
row(item: MicrosoftEntraProviderGroup): SlottedTemplateResult[] {
|
||||
|
||||
@@ -3,6 +3,7 @@ import "#elements/forms/ModalForm";
|
||||
import "#elements/sync/SyncObjectForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -25,6 +26,11 @@ export class MicrosoftEntraProviderUserList extends Table<MicrosoftEntraProvider
|
||||
|
||||
expandable = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Microsoft Entra User", { id: "entity.microsoft-entra-user.singular" }),
|
||||
plural: msg("Microsoft Entra Users", { id: "entity.microsoft-entra-user.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
checkbox = true;
|
||||
@@ -80,8 +86,8 @@ export class MicrosoftEntraProviderUserList extends Table<MicrosoftEntraProvider
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Username")],
|
||||
[msg("ID")],
|
||||
[msg("Username", { id: "column.username" })],
|
||||
[msg("ID", { id: "column.id" })],
|
||||
];
|
||||
|
||||
row(item: MicrosoftEntraProviderUser): SlottedTemplateResult[] {
|
||||
|
||||
@@ -13,6 +13,9 @@ import "#elements/tasks/TaskList";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -42,6 +45,13 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
@customElement("ak-provider-microsoft-entra-view")
|
||||
export class MicrosoftEntraProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Microsoft Entra Provider", {
|
||||
id: "entity.microsoft-entra-provider.singular",
|
||||
}),
|
||||
plural: msg("Microsoft Entra Providers", { id: "entity.microsoft-entra-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -206,15 +216,15 @@ export class MicrosoftEntraProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Microsoft Entra Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-microsoft-entra-form
|
||||
slot="form"
|
||||
.instancePk=${this.provider.pk}
|
||||
>
|
||||
</ak-provider-microsoft-entra-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,9 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -64,6 +67,11 @@ export function TypeToLabel(type?: ClientTypeEnum): string {
|
||||
|
||||
@customElement("ak-provider-oauth2-view")
|
||||
export class OAuth2ProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("O Auth2 Provider", { id: "entity.o-auth2-provider.singular" }),
|
||||
plural: msg("O Auth2 Providers", { id: "entity.o-auth2-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
set providerID(value: number) {
|
||||
new ProvidersApi(DEFAULT_CONFIG)
|
||||
@@ -298,15 +306,15 @@ export class OAuth2ProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update OAuth2 Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-oauth2-form
|
||||
slot="form"
|
||||
.instancePk=${this.provider.pk || 0}
|
||||
>
|
||||
</ak-provider-oauth2-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,9 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import type { Replacer } from "#elements/ak-mdx/index";
|
||||
import { AKElement } from "#elements/Base";
|
||||
@@ -78,6 +81,11 @@ export function isForward(mode: ProxyMode): boolean {
|
||||
|
||||
@customElement("ak-provider-proxy-view")
|
||||
export class ProxyProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Proxy Provider", { id: "entity.proxy-provider.singular" }),
|
||||
plural: msg("Proxy Providers", { id: "entity.proxy-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -381,15 +389,15 @@ export class ProxyProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Proxy Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-proxy-form
|
||||
slot="form"
|
||||
.instancePk=${this.provider.pk || 0}
|
||||
>
|
||||
</ak-provider-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import "#elements/forms/ModalForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -23,6 +24,11 @@ export class ConnectionTokenListPage extends Table<ConnectionToken> {
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Connection Token", { id: "entity.connection-token.singular" }),
|
||||
plural: msg("Connection Tokens", { id: "entity.connection-token.plural" }),
|
||||
};
|
||||
|
||||
@property()
|
||||
order = "name";
|
||||
|
||||
|
||||
@@ -30,11 +30,7 @@ export class EndpointForm extends ModelForm<Endpoint, string> {
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated endpoint.")
|
||||
: msg("Successfully created endpoint.");
|
||||
}
|
||||
protected override entityLabel = msg("Endpoint");
|
||||
|
||||
async send(data: Endpoint): Promise<Endpoint> {
|
||||
data.authMode = EndpointAuthModeEnum.Prompt;
|
||||
|
||||
@@ -7,6 +7,9 @@ import "#elements/forms/ModalForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { formatCreateMessage, formatEditMessage, formatNewMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -30,6 +33,11 @@ export class EndpointListPage extends Table<Endpoint> {
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Endpoint", { id: "entity.endpoint.singular" }),
|
||||
plural: msg("Endpoints", { id: "entity.endpoint.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
@property()
|
||||
@@ -49,9 +57,13 @@ export class EndpointListPage extends Table<Endpoint> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "name"],
|
||||
[msg("Host"), "host"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[msg("Host", { id: "column.host" }), "host"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -88,8 +100,8 @@ export class EndpointListPage extends Table<Endpoint> {
|
||||
html`${item.host}`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Endpoint")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-rac-endpoint-form slot="form" .instancePk=${item.pk}>
|
||||
</ak-rac-endpoint-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
@@ -121,11 +133,13 @@ export class EndpointListPage extends Table<Endpoint> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Endpoint")}</span>
|
||||
<span slot="submit">${formatCreateMessage(this.entityLabel)}</span>
|
||||
<span slot="header">${formatNewMessage(this.entityLabel)}</span>
|
||||
<ak-rac-endpoint-form slot="form" .providerID=${this.provider?.pk}>
|
||||
</ak-rac-endpoint-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${formatNewMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -31,12 +31,7 @@ export class RACProviderFormPage extends ModelForm<RACProvider, number> {
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance) {
|
||||
return msg("Successfully updated provider.");
|
||||
}
|
||||
return msg("Successfully created provider.");
|
||||
}
|
||||
protected override entityLabel = msg("RAC provider");
|
||||
|
||||
async send(data: RACProvider): Promise<RACProvider> {
|
||||
if (this.instance) {
|
||||
|
||||
@@ -13,6 +13,9 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -41,6 +44,11 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
@customElement("ak-provider-rac-view")
|
||||
export class RACProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Rac Provider", { id: "entity.rac-provider.singular" }),
|
||||
plural: msg("Rac Providers", { id: "entity.rac-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -189,12 +197,12 @@ export class RACProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update RAC Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-rac-form slot="form" .instancePk=${this.provider.pk || 0}>
|
||||
</ak-provider-rac-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,9 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -35,6 +38,11 @@ import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css";
|
||||
|
||||
@customElement("ak-provider-radius-view")
|
||||
export class RadiusProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Radius Provider", { id: "entity.radius-provider.singular" }),
|
||||
plural: msg("Radius Providers", { id: "entity.radius-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -139,7 +147,9 @@ export class RadiusProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="submit"
|
||||
>${ActionTenseRecord.apply.present()}</span
|
||||
>
|
||||
<span slot="header">
|
||||
${msg("Update Radius Provider")}
|
||||
</span>
|
||||
@@ -149,7 +159,7 @@ export class RadiusProviderViewPage extends AKElement {
|
||||
>
|
||||
</ak-provider-radius-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -139,7 +139,7 @@ export function renderForm({
|
||||
return html` <ak-text-input
|
||||
name="name"
|
||||
value=${ifDefined(provider.name)}
|
||||
label=${msg("Name")}
|
||||
label=${msg("SAML Provider Name", { id: "label.saml-provider-name" })}
|
||||
required
|
||||
.errorMessages=${errors.name}
|
||||
></ak-text-input>
|
||||
|
||||
@@ -15,9 +15,9 @@ import { customElement } from "lit/decorators.js";
|
||||
|
||||
@customElement("ak-provider-saml-import-form")
|
||||
export class SAMLProviderImportForm extends Form<SAMLProvider> {
|
||||
getSuccessMessage(): string {
|
||||
return msg("Successfully imported provider.");
|
||||
}
|
||||
protected override readonly actionName = "import";
|
||||
|
||||
protected override entityLabel = msg("Provider", { id: "entity.provider.singular" });
|
||||
|
||||
async send(data: SAMLProvider): Promise<void> {
|
||||
const file = this.files().get("metadata");
|
||||
@@ -33,7 +33,11 @@ export class SAMLProviderImportForm extends Form<SAMLProvider> {
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html`<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${msg("SAML Provider Name", { id: "label.saml-provider-name" })}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input type="text" class="pf-c-form-control" required />
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
|
||||
@@ -11,6 +11,9 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
import { MessageLevel } from "#common/messages";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
@@ -59,6 +62,11 @@ interface SAMLPreviewAttribute {
|
||||
|
||||
@customElement("ak-provider-saml-view")
|
||||
export class SAMLProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Saml Provider", { id: "entity.saml-provider.singular" }),
|
||||
plural: msg("Saml Providers", { id: "entity.saml-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -363,12 +371,12 @@ export class SAMLProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update SAML Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-saml-form slot="form" .instancePk=${this.provider.pk || 0}>
|
||||
</ak-provider-saml-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import "#elements/forms/ModalForm";
|
||||
import "#elements/sync/SyncObjectForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -23,6 +24,11 @@ export class SCIMProviderGroupList extends Table<SCIMProviderGroup> {
|
||||
@property({ type: Number })
|
||||
providerId?: number;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Scim Group", { id: "entity.scim-group.singular" }),
|
||||
plural: msg("Scim Groups", { id: "entity.scim-group.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
expandable = true;
|
||||
@@ -76,9 +82,8 @@ export class SCIMProviderGroupList extends Table<SCIMProviderGroup> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Name")],
|
||||
[msg("ID")],
|
||||
[msg("Name", { id: "column.name" })],
|
||||
[msg("ID", { id: "column.id" })],
|
||||
];
|
||||
|
||||
row(item: SCIMProviderGroup): SlottedTemplateResult[] {
|
||||
|
||||
@@ -3,6 +3,7 @@ import "#elements/forms/ModalForm";
|
||||
import "#elements/sync/SyncObjectForm";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -23,6 +24,11 @@ export class SCIMProviderUserList extends Table<SCIMProviderUser> {
|
||||
@property({ type: Number })
|
||||
providerId?: number;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Scim User", { id: "entity.scim-user.singular" }),
|
||||
plural: msg("Scim Users", { id: "entity.scim-user.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
expandable = true;
|
||||
@@ -77,8 +83,8 @@ export class SCIMProviderUserList extends Table<SCIMProviderUser> {
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Username")],
|
||||
[msg("ID")],
|
||||
[msg("Username", { id: "column.username" })],
|
||||
[msg("ID", { id: "column.id" })],
|
||||
];
|
||||
|
||||
row(item: SCIMProviderUser): SlottedTemplateResult[] {
|
||||
|
||||
@@ -15,6 +15,9 @@ import "#elements/tasks/TaskList";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -47,6 +50,11 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
@customElement("ak-provider-scim-view")
|
||||
export class SCIMProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Scim Provider", { id: "entity.scim-provider.singular" }),
|
||||
plural: msg("Scim Providers", { id: "entity.scim-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
providerID?: number;
|
||||
|
||||
@@ -236,12 +244,12 @@ export class SCIMProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update SCIM Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-scim-form slot="form" .instancePk=${this.provider.pk}>
|
||||
</ak-provider-scim-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,9 @@ import "#elements/tasks/TaskList";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { formatEditMessage } from "#common/i18n/actions";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { ActionTenseRecord } from "#common/i18n/verbs";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -40,6 +43,11 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
@customElement("ak-provider-ssf-view")
|
||||
export class SSFProviderViewPage extends AKElement {
|
||||
protected entityLabel: EntityLabel = {
|
||||
singular: msg("Ssf Provider", { id: "entity.ssf-provider.singular" }),
|
||||
plural: msg("Ssf Providers", { id: "entity.ssf-provider.plural" }),
|
||||
};
|
||||
|
||||
@property({ type: Number })
|
||||
set providerID(value: number) {
|
||||
new ProvidersApi(DEFAULT_CONFIG)
|
||||
@@ -169,12 +177,12 @@ export class SSFProviderViewPage extends AKElement {
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update SSF Provider")}</span>
|
||||
<span slot="submit">${ActionTenseRecord.apply.present()}</span>
|
||||
<span slot="header">${formatEditMessage(this.entityLabel)}</span>
|
||||
<ak-provider-ssf-form slot="form" .instancePk=${this.provider.pk || 0}>
|
||||
</ak-provider-ssf-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
${formatEditMessage(this.entityLabel)}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@ import "#elements/forms/ProxyForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
@@ -17,6 +18,11 @@ import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
@customElement("ak-provider-ssf-stream-list")
|
||||
export class SSFProviderStreamList extends Table<SSFStream> {
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Ssf Stream", { id: "entity.ssf-stream.singular" }),
|
||||
plural: msg("Ssf Streams", { id: "entity.ssf-stream.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
@@ -40,7 +46,7 @@ export class SSFProviderStreamList extends Table<SSFStream> {
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Audience"), "aud"],
|
||||
[msg("Audience", { id: "column.audience" }), "aud"],
|
||||
];
|
||||
|
||||
row(item: SSFStream): SlottedTemplateResult[] {
|
||||
|
||||
@@ -37,11 +37,9 @@ export class InitialPermissionsForm extends ModelForm<InitialPermissions, string
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return this.instance
|
||||
? msg("Successfully updated initial permissions.")
|
||||
: msg("Successfully created initial permissions.");
|
||||
}
|
||||
protected override entityLabel = msg("Initial Permissions", {
|
||||
id: "entity.initial.permissions.singular",
|
||||
});
|
||||
|
||||
async send(data: InitialPermissions): Promise<InitialPermissions> {
|
||||
if (this.instance?.pk) {
|
||||
@@ -57,15 +55,33 @@ export class InitialPermissionsForm extends ModelForm<InitialPermissions, string
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Permission Name", {
|
||||
id: "label.initial.permissions.name",
|
||||
desc: "Label for initial permissions name input",
|
||||
})}
|
||||
required
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
placeholder=${msg("Type a descriptive name...", {
|
||||
id: "placeholder.initial.permissions.name",
|
||||
desc: "Placeholder text for initial permissions name input",
|
||||
})}
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${msg("Role")} required name="role">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Role", {
|
||||
id: "label.initial.permissions.role",
|
||||
desc: "Label for initial permissions role mode",
|
||||
})}
|
||||
required
|
||||
name="role"
|
||||
>
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<Role[]> => {
|
||||
const args: RbacRolesListRequest = {
|
||||
|
||||
@@ -5,6 +5,7 @@ import "#elements/forms/ModalForm";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
|
||||
import { PaginatedResponse, TableColumn } from "#elements/table/Table";
|
||||
import { TablePage } from "#elements/table/TablePage";
|
||||
@@ -23,7 +24,12 @@ export class InitialPermissionsListPage extends TablePage<InitialPermissions> {
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
protected override searchEnabled = true;
|
||||
public pageTitle = msg("Initial Permissions");
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Initial Permission", { id: "entity.initial-permission.singular" }),
|
||||
plural: msg("Initial Permissions", { id: "entity.initial-permission.plural" }),
|
||||
};
|
||||
|
||||
public pageDescription = msg("Set initial permissions for newly created objects.");
|
||||
public pageIcon = "fa fa-lock";
|
||||
|
||||
@@ -38,8 +44,12 @@ export class InitialPermissionsListPage extends TablePage<InitialPermissions> {
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
// ---
|
||||
[msg("Name"), "name"],
|
||||
[msg("Actions"), null, msg("Row Actions")],
|
||||
[msg("Name", { id: "column.name" }), "name"],
|
||||
[
|
||||
msg("Actions", { id: "column.actions" }),
|
||||
null,
|
||||
msg("Row Actions", { id: "column.row-actions" }),
|
||||
],
|
||||
];
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
@@ -75,12 +85,12 @@ export class InitialPermissionsListPage extends TablePage<InitialPermissions> {
|
||||
html`${item.name}`,
|
||||
html`<div>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update Initial Permissions")}</span>
|
||||
<span slot="submit">${this.updateEntityLabel}</span>
|
||||
<span slot="header">${this.editEntityLabel}</span>
|
||||
<ak-initial-permissions-form slot="form" .instancePk=${item.pk}>
|
||||
</ak-initial-permissions-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<pf-tooltip position="top" content=${this.editEntityLabel}>
|
||||
<i class="fas fa-edit" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
@@ -92,10 +102,12 @@ export class InitialPermissionsListPage extends TablePage<InitialPermissions> {
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Create")}</span>
|
||||
<span slot="header">${msg("Create Initial Permissions")}</span>
|
||||
<span slot="submit">${this.createEntityLabel}</span>
|
||||
<span slot="header">${this.newEntityActionLabel}</span>
|
||||
<ak-initial-permissions-form slot="form"> </ak-initial-permissions-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${this.newEntityActionLabel}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EntityLabel } from "#common/i18n/nouns";
|
||||
import { groupBy } from "#common/utils";
|
||||
|
||||
import { PaginatedResponse, TableColumn } from "#elements/table/Table";
|
||||
@@ -20,6 +21,11 @@ export class PermissionSelectModal extends TableModal<Permission> {
|
||||
checkbox = true;
|
||||
checkboxChip = true;
|
||||
|
||||
protected override entityLabel: EntityLabel = {
|
||||
singular: msg("Permission", { id: "entity.permission.singular" }),
|
||||
plural: msg("Permissions", { id: "entity.permission.plural" }),
|
||||
};
|
||||
|
||||
protected override searchEnabled = true;
|
||||
|
||||
@property()
|
||||
@@ -40,8 +46,8 @@ export class PermissionSelectModal extends TableModal<Permission> {
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
[msg("Name"), "codename"],
|
||||
[msg("Model"), ""],
|
||||
[msg("Name", { id: "column.name" }), "codename"],
|
||||
[msg("Model", { id: "column.model" }), ""],
|
||||
];
|
||||
|
||||
row(item: Permission): SlottedTemplateResult[] {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user