diff --git a/web/src/admin/applications/ApplicationCheckAccessForm.ts b/web/src/admin/applications/ApplicationCheckAccessForm.ts index 33c564ace3..df7c4a5aa5 100644 --- a/web/src/admin/applications/ApplicationCheckAccessForm.ts +++ b/web/src/admin/applications/ApplicationCheckAccessForm.ts @@ -4,8 +4,12 @@ import "#elements/forms/HorizontalFormElement"; import "#elements/forms/SearchSelect/index"; import { DEFAULT_CONFIG } from "#common/api/config"; +import { PFSize } from "#common/enums"; +import { APIMessage, MessageLevel } from "#common/messages"; import { Form } from "#elements/forms/Form"; +import { SlottedTemplateResult } from "#elements/types"; +import { ifPresent } from "#elements/utils/attributes"; import { Application, @@ -16,13 +20,24 @@ import { } from "@goauthentik/api"; import { msg } from "@lit/localize"; -import { CSSResult, html, nothing, TemplateResult } from "lit"; +import { CSSResult, html } from "lit"; import { customElement, property } from "lit/decorators.js"; import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; @customElement("ak-application-check-access-form") export class ApplicationCheckAccessForm extends Form<{ forUser: number }> { + public static override verboseName = msg("Access"); + public static override submitVerb = msg("Check"); + public static override createLabel = msg("Check"); + public static override submittingVerb = msg("Checking"); + + static styles: CSSResult[] = [...super.styles, PFDescriptionList]; + + #api = new CoreApi(DEFAULT_CONFIG); + + public override size = PFSize.XLarge; + @property({ attribute: false }) public application!: Application; @@ -30,19 +45,27 @@ export class ApplicationCheckAccessForm extends Form<{ forUser: number }> { public result: PolicyTestResult | null = null; @property({ attribute: false }) - public request?: number; + public request: number | null = null; - getSuccessMessage(): string { - return msg("Successfully sent test-request."); + public override formatAPISuccessMessage(): APIMessage { + return { + level: MessageLevel.success, + message: msg("Successfully sent test-request."), + }; } - async send(data: { forUser: number }): Promise { + protected override send(data: { forUser: number }): Promise { this.request = data.forUser; - const result = await new CoreApi(DEFAULT_CONFIG).coreApplicationsCheckAccessRetrieve({ - slug: this.application?.slug, - forUser: data.forUser, - }); - return (this.result = result); + + return this.#api + .coreApplicationsCheckAccessRetrieve({ + slug: this.application?.slug, + forUser: data.forUser, + }) + .then((result) => { + this.result = result; + return result; + }); } public override reset(): void { @@ -50,15 +73,14 @@ export class ApplicationCheckAccessForm extends Form<{ forUser: number }> { this.result = null; } - static styles: CSSResult[] = [...super.styles, PFDescriptionList]; + protected renderResult(): SlottedTemplateResult { + const { passing, messages = [], logMessages = [] } = this.result || {}; - renderResult(): TemplateResult { - return html` - + return html`
- +
@@ -67,54 +89,56 @@ export class ApplicationCheckAccessForm extends Form<{ forUser: number }> {
    - ${(this.result?.messages || []).length > 0 - ? this.result?.messages?.map((m) => { - return html`
  • - ${m} -
  • `; - }) - : html`
  • - - -
  • `} + ${messages.map((m) => { + return html`
  • + ${m} +
  • `; + })}
- - - `; + +
`; } - protected override renderForm(): TemplateResult { + protected override renderForm(): SlottedTemplateResult { return html` => { const args: CoreUsersListRequest = { ordering: "username", }; - if (query !== undefined) { + + if (query) { args.search = query; } - const users = await new CoreApi(DEFAULT_CONFIG).coreUsersList(args); + + const users = await this.#api.coreUsersList(args); + return users.results; }} .renderElement=${(user: User): string => { return user.username; }} - .renderDescription=${(user: User): TemplateResult => { + .renderDescription=${(user: User): SlottedTemplateResult => { return html`${user.name}`; }} .value=${(user: User | undefined): number | undefined => { return user?.pk; }} .selected=${(user: User): boolean => { - return user.pk.toString() === this.request?.toString(); + return ( + typeof this.request === "number" && + user.pk.toString() === this.request.toString() + ); }} > - ${this.result ? this.renderResult() : nothing}`; + ${this.renderResult()}`; } } diff --git a/web/src/admin/applications/ApplicationListPage.ts b/web/src/admin/applications/ApplicationListPage.ts index aebb4c6390..e1a8d9a771 100644 --- a/web/src/admin/applications/ApplicationListPage.ts +++ b/web/src/admin/applications/ApplicationListPage.ts @@ -201,7 +201,7 @@ export class ApplicationListPage extends WithBrandConfig(TablePage) "Opens the new application wizard, which will guide you through creating a new application with an existing provider.", )} > - ${msg("With New Provider...")} + ${msg("with New Provider...")}
  • @@ -214,7 +214,7 @@ export class ApplicationListPage extends WithBrandConfig(TablePage) "Opens the new application form, which will guide you through creating a new application with an existing provider.", )} > - ${msg("With Existing Provider...")} + ${msg("with Existing Provider...")}
  • diff --git a/web/src/admin/applications/ApplicationViewPage.ts b/web/src/admin/applications/ApplicationViewPage.ts index 3a3f50e389..014c956f49 100644 --- a/web/src/admin/applications/ApplicationViewPage.ts +++ b/web/src/admin/applications/ApplicationViewPage.ts @@ -16,11 +16,15 @@ import { DEFAULT_CONFIG } from "#common/api/config"; import { APIError, parseAPIResponseError, pluckErrorDetail } from "#common/errors/network"; import { AKElement } from "#elements/Base"; +import { modalInvoker } from "#elements/dialogs"; import { WithLicenseSummary } from "#elements/mixins/license"; import { setPageDetails } from "#components/ak-page-navbar"; import renderDescriptionList from "#components/DescriptionList"; +import { ApplicationCheckAccessForm } from "#admin/applications/ApplicationCheckAccessForm"; +import { ApplicationForm } from "#admin/applications/ApplicationForm"; + import { Application, ContentTypeEnum, @@ -181,36 +185,28 @@ export class ApplicationViewPage extends WithLicenseSummary(AKElement) { ], [ msg("Related actions"), - html` - ${msg("Save Changes")} - ${msg("Update Application")} - - - - - - ${msg("Check")} - ${msg("Check Application access")} - - - - + html` + ${this.application.launchUrl ? html` ${msg("Launch")} ` - : nothing}`, + : null}`, ], ])} diff --git a/web/src/admin/applications/ak-provider-table.ts b/web/src/admin/applications/ak-provider-table.ts index c9e3b8e4ad..1942bcccbb 100644 --- a/web/src/admin/applications/ak-provider-table.ts +++ b/web/src/admin/applications/ak-provider-table.ts @@ -8,7 +8,6 @@ import { SlottedTemplateResult } from "#elements/types"; import { Provider, ProvidersApi } from "@goauthentik/api"; import { msg } from "@lit/localize"; -import { html } from "lit"; import { customElement, property } from "lit/decorators.js"; @customElement("ak-provider-table") @@ -23,29 +22,24 @@ export class ProviderTable extends Table { public override order = "name"; - protected async apiEndpoint(): Promise> { + protected override async apiEndpoint(): Promise> { return new ProvidersApi(DEFAULT_CONFIG).providersAllList({ ...(await this.defaultEndpointConfig()), backchannel: this.backchannel, }); } - protected columns: TableColumn[] = [ + protected override columns: TableColumn[] = [ // --- [msg("Name"), "username"], [msg("Type")], ]; - protected row(item: Provider): SlottedTemplateResult[] { - return [ - html`
    -
    ${item.name}
    -
    `, - html`${item.verboseName}`, - ]; + protected override row(item: Provider): SlottedTemplateResult[] { + return [item.name, item.verboseName]; } - protected renderSelectedChip(item: Provider): SlottedTemplateResult { + protected override renderSelectedChip(item: Provider): SlottedTemplateResult { return item.name; } } diff --git a/web/src/admin/applications/components/ak-backchannel-input.ts b/web/src/admin/applications/components/ak-backchannel-input.ts index 132dfbe597..c0205993e8 100644 --- a/web/src/admin/applications/components/ak-backchannel-input.ts +++ b/web/src/admin/applications/components/ak-backchannel-input.ts @@ -73,7 +73,6 @@ export class AkBackchannelProvidersInput extends AKElement { }} > ${this.help ? html`

    ${this.help}

    ` : nothing} - `); @@ -100,7 +99,11 @@ export class AkBackchannelProvidersInput extends AKElement {
    - ${map(this.providers, renderOneChip)} + ${map(this.providers, renderOneChip)}
    ${this.help ? html`

    ${this.help}

    ` : nothing} diff --git a/web/src/admin/endpoints/devices/DeviceForm.ts b/web/src/admin/endpoints/devices/DeviceForm.ts index 0b34fea8d1..67b56ba4cc 100644 --- a/web/src/admin/endpoints/devices/DeviceForm.ts +++ b/web/src/admin/endpoints/devices/DeviceForm.ts @@ -20,6 +20,8 @@ import { ifDefined } from "lit/directives/if-defined.js"; @customElement("ak-endpoints-device-form") export class EndpointDeviceForm extends ModelForm { + public static override verboseName = msg("Device"); + public static override verboseNamePlural = msg("Devices"); loadInstance(pk: string): Promise { return new EndpointsApi(DEFAULT_CONFIG).endpointsDevicesRetrieve({ deviceUuid: pk, diff --git a/web/src/admin/endpoints/devices/DeviceListPage.ts b/web/src/admin/endpoints/devices/DeviceListPage.ts index 3131ab2da0..2f13cb2bca 100644 --- a/web/src/admin/endpoints/devices/DeviceListPage.ts +++ b/web/src/admin/endpoints/devices/DeviceListPage.ts @@ -1,15 +1,16 @@ import "#elements/cards/AggregateCard"; import "#elements/forms/DeleteBulkForm"; -import "#admin/endpoints/devices/DeviceForm"; import "#admin/endpoints/devices/DeviceAddHowTo"; -import "#elements/forms/ModalForm"; import { DEFAULT_CONFIG } from "#common/api/config"; +import { modalInvoker } from "#elements/dialogs"; import { PaginatedResponse, TableColumn, Timestamp } from "#elements/table/Table"; import { TablePage } from "#elements/table/TablePage"; import { SlottedTemplateResult } from "#elements/types"; +import { EndpointDeviceForm } from "#admin/endpoints/devices/DeviceForm"; + import { DeviceSummary, EndpointDevice, EndpointsApi } from "@goauthentik/api"; import { msg } from "@lit/localize"; @@ -132,17 +133,14 @@ export class DeviceListPage extends TablePage { html`${item.facts.data.os?.name} ${item.facts.data.os?.version}`, html`${item.accessGroupObj?.name || "-"}`, item.facts.created ? Timestamp(item.facts.created) : html`-`, - html` - ${msg("Save Changes")} - ${msg("Update Device")} - - - - `, + html``, ]; } diff --git a/web/src/admin/endpoints/devices/DeviceViewPage.ts b/web/src/admin/endpoints/devices/DeviceViewPage.ts index 6f08c2e0ae..dc29ed4e62 100644 --- a/web/src/admin/endpoints/devices/DeviceViewPage.ts +++ b/web/src/admin/endpoints/devices/DeviceViewPage.ts @@ -5,20 +5,20 @@ import "#admin/endpoints/devices/facts/DeviceProcessTable"; import "#admin/endpoints/devices/facts/DeviceUserTable"; import "#admin/endpoints/devices/facts/DeviceSoftwareTable"; import "#admin/endpoints/devices/facts/DeviceGroupTable"; -import "#admin/endpoints/devices/DeviceForm"; import "#admin/endpoints/devices/DeviceEvents"; -import "#elements/forms/ModalForm"; import "#elements/Tabs"; import { DEFAULT_CONFIG } from "#common/api/config"; import { APIError, parseAPIResponseError } from "#common/errors/network"; import { AKElement } from "#elements/Base"; +import { modalInvoker } from "#elements/dialogs"; import { Timestamp } from "#elements/table/shared"; import { setPageDetails } from "#components/ak-page-navbar"; import renderDescriptionList, { DescriptionPair } from "#components/DescriptionList"; +import { EndpointDeviceForm } from "#admin/endpoints/devices/DeviceForm"; import { getSize, osFamilyToLabel, trySortNumerical } from "#admin/endpoints/devices/utils"; import { DeviceConnection, Disk, EndpointDeviceDetails, EndpointsApi } from "@goauthentik/api"; @@ -124,18 +124,14 @@ export class DeviceViewPage extends AKElement { [msg("Device access group"), this.device?.accessGroupObj?.name ?? "-"], [ msg("Actions"), - html` - ${msg("Save Changes")} - ${msg("Update Device")} - - - - `, + html``, ], ], { horizontal: true }, diff --git a/web/src/admin/flows/FlowViewPage.ts b/web/src/admin/flows/FlowViewPage.ts index 7d68a70502..1d3bd92cab 100644 --- a/web/src/admin/flows/FlowViewPage.ts +++ b/web/src/admin/flows/FlowViewPage.ts @@ -1,6 +1,5 @@ import "#admin/flows/BoundStagesList"; import "#admin/flows/FlowDiagram"; -import "#admin/flows/FlowForm"; import "#admin/policies/BoundPoliciesList"; import "#admin/rbac/ak-rbac-object-permission-page"; import "#admin/events/ObjectChangelog"; @@ -11,11 +10,13 @@ import { AndNext, DEFAULT_CONFIG } from "#common/api/config"; import { isResponseErrorLike } from "#common/errors/network"; import { AKElement } from "#elements/Base"; +import { modalInvoker } from "#elements/dialogs"; import { SlottedTemplateResult } from "#elements/types"; import { setPageDetails } from "#components/ak-page-navbar"; import renderDescriptionList from "#components/DescriptionList"; +import { FlowForm } from "#admin/flows/FlowForm"; import { DesignationToLabel } from "#admin/flows/utils"; import { Flow, FlowsApi, ModelEnum } from "@goauthentik/api"; @@ -97,21 +98,14 @@ export class FlowViewPage extends AKElement { ], [ msg("Related actions"), - html` - ${msg("Save Changes")} - ${msg("Update Flow")} - - - - + html` - ${msg("Save Changes")} - ${msg("Update Group")} - - - - `, + html``, ], ])} diff --git a/web/src/admin/groups/RelatedGroupList.ts b/web/src/admin/groups/RelatedGroupList.ts index 37dd799c92..f773d78ded 100644 --- a/web/src/admin/groups/RelatedGroupList.ts +++ b/web/src/admin/groups/RelatedGroupList.ts @@ -1,19 +1,19 @@ -import "#admin/groups/ak-group-form"; import "#admin/users/ak-user-group-table"; import "#components/ak-status-label"; import "#elements/buttons/SpinnerButton/index"; import "#elements/forms/DeleteBulkForm"; import "#elements/forms/HorizontalFormElement"; -import "#elements/forms/ModalForm"; import "@patternfly/elements/pf-tooltip/pf-tooltip.js"; import { DEFAULT_CONFIG } from "#common/api/config"; -import { renderModal } from "#elements/dialogs"; +import { modalInvoker, renderModal } from "#elements/dialogs"; import { AKFormSubmitEvent, Form } from "#elements/forms/Form"; import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table"; import { SlottedTemplateResult } from "#elements/types"; +import { GroupForm } from "#admin/groups/ak-group-form"; + import { CoreApi, Group, User } from "@goauthentik/api"; import { msg, str } from "@lit/localize"; @@ -23,6 +23,10 @@ import { ifDefined } from "lit/directives/if-defined.js"; @customElement("ak-group-related-add") export class RelatedGroupAdd extends Form<{ groups: string[] }> { + public static override verboseName = msg("Group"); + public static override submitVerb = msg("Add"); + public static override createLabel = msg("Add"); + @property({ attribute: false }) public user?: User; @@ -74,7 +78,10 @@ export class RelatedGroupAdd extends Form<{ groups: string[] }> {
    - + ${this.groupsToAdd.map((group) => { return html` { return [ html`${item.name}`, html``, - html` - ${msg("Save Changes")} - ${msg("Update Group")} - - - `, + html``, ]; } renderToolbar(): TemplateResult { return html` ${this.targetUser - ? html` - ${msg("Add")} - ${msg("Add Group")} - - - - ` + ? html`` : nothing} - - ${msg("Create")} - ${msg("Create Group")} - - - + ${super.renderToolbar()} `; } diff --git a/web/src/admin/providers/oauth2/OAuth2ProviderViewPage.ts b/web/src/admin/providers/oauth2/OAuth2ProviderViewPage.ts index 2899768402..a32019ecdf 100644 --- a/web/src/admin/providers/oauth2/OAuth2ProviderViewPage.ts +++ b/web/src/admin/providers/oauth2/OAuth2ProviderViewPage.ts @@ -1,5 +1,4 @@ import "#admin/providers/RelatedApplicationButton"; -import "#admin/providers/oauth2/OAuth2ProviderForm"; import "#admin/events/ObjectChangelog"; import "#admin/rbac/ak-rbac-object-permission-page"; import "#admin/rbac/ObjectPermissionModal"; @@ -15,10 +14,13 @@ import { DEFAULT_CONFIG } from "#common/api/config"; import { EVENT_REFRESH } from "#common/constants"; import { AKElement } from "#elements/Base"; +import { modalInvoker } from "#elements/dialogs"; import { SlottedTemplateResult } from "#elements/types"; import renderDescriptionList from "#components/DescriptionList"; +import { OAuth2ProviderFormPage } from "#admin/providers/oauth2/OAuth2ProviderForm"; + import { ClientTypeEnum, CoreApi, @@ -238,21 +240,14 @@ export class OAuth2ProviderViewPage extends AKElement { ], [ msg("Related actions"), - html` - ${msg("Save Changes")} - ${msg("Update OAuth2 Provider")} - - - - `, + html``, ], ])}
    diff --git a/web/src/admin/providers/ssf/SSFProviderViewPage.ts b/web/src/admin/providers/ssf/SSFProviderViewPage.ts index feb1add29d..b7578da5c8 100644 --- a/web/src/admin/providers/ssf/SSFProviderViewPage.ts +++ b/web/src/admin/providers/ssf/SSFProviderViewPage.ts @@ -1,5 +1,4 @@ import "#admin/providers/RelatedApplicationButton"; -import "#admin/providers/ssf/SSFProviderFormPage"; import "#admin/providers/ssf/StreamTable"; import "#admin/events/ObjectChangelog"; import "#admin/rbac/ObjectPermissionModal"; @@ -14,10 +13,13 @@ import { DEFAULT_CONFIG } from "#common/api/config"; import { EVENT_REFRESH } from "#common/constants"; import { AKElement } from "#elements/Base"; +import { modalInvoker } from "#elements/dialogs"; import { SlottedTemplateResult } from "#elements/types"; import renderDescriptionList from "#components/DescriptionList"; +import { SSFProviderFormPage } from "#admin/providers/ssf/SSFProviderFormPage"; + import { ModelEnum, ProvidersApi, SSFProvider } from "@goauthentik/api"; import { msg } from "@lit/localize"; @@ -155,15 +157,14 @@ export class SSFProviderViewPage extends AKElement { ], [ msg("Related actions"), - html` - ${msg("Save Changes")} - ${msg("Update SSF Provider")} - - - - `, + html``, ], ])} diff --git a/web/src/admin/roles/ak-related-role-table.ts b/web/src/admin/roles/ak-related-role-table.ts index f3a1f63dc5..b0b630f00f 100644 --- a/web/src/admin/roles/ak-related-role-table.ts +++ b/web/src/admin/roles/ak-related-role-table.ts @@ -83,7 +83,10 @@ export class AddRelatedRoleForm extends Form<{ roles: string[] }> {
    - + ${this.rolesToAdd.map((role) => { return html`
    - + ${this.permissionsToAdd.map((permission) => { return html` - ${msg("Save Changes")} - ${msg("Update Role")} - - - - `, + html``, ], ])}
    diff --git a/web/src/admin/sources/BaseSourceForm.ts b/web/src/admin/sources/BaseSourceForm.ts index c05b5e492c..638a0b9ce3 100644 --- a/web/src/admin/sources/BaseSourceForm.ts +++ b/web/src/admin/sources/BaseSourceForm.ts @@ -3,6 +3,8 @@ import { ModelForm } from "#elements/forms/ModelForm"; import { msg } from "@lit/localize"; export abstract class BaseSourceForm extends ModelForm { + public static override verboseName = msg("Source"); + public static override verboseNamePlural = msg("Sources"); getSuccessMessage(): string { return this.instance ? msg("Successfully updated source.") diff --git a/web/src/admin/sources/ldap/LDAPSourceViewPage.ts b/web/src/admin/sources/ldap/LDAPSourceViewPage.ts index 3d4f41e68b..c10a3eebf7 100644 --- a/web/src/admin/sources/ldap/LDAPSourceViewPage.ts +++ b/web/src/admin/sources/ldap/LDAPSourceViewPage.ts @@ -1,6 +1,5 @@ import "#admin/rbac/ak-rbac-object-permission-page"; import "#admin/sources/ldap/LDAPSourceConnectivity"; -import "#admin/sources/ldap/LDAPSourceForm"; import "#admin/sources/ldap/LDAPSourceUserList"; import "#admin/sources/ldap/LDAPSourceGroupList"; import "#admin/events/ObjectChangelog"; @@ -8,7 +7,6 @@ import "#elements/CodeMirror"; import "#elements/Tabs"; import "#elements/buttons/ActionButton/index"; import "#elements/buttons/SpinnerButton/index"; -import "#elements/forms/ModalForm"; import "#elements/sync/SyncStatusCard"; import "#elements/tasks/ScheduleList"; @@ -16,10 +14,13 @@ import { DEFAULT_CONFIG } from "#common/api/config"; import { EVENT_REFRESH } from "#common/constants"; import { AKElement } from "#elements/Base"; +import { modalInvoker } from "#elements/dialogs"; import { SlottedTemplateResult } from "#elements/types"; import renderDescriptionList from "#components/DescriptionList"; +import { LDAPSourceForm } from "#admin/sources/ldap/LDAPSourceForm"; + import { LDAPSource, ModelEnum, SourcesApi } from "@goauthentik/api"; import { msg } from "@lit/localize"; @@ -105,23 +106,14 @@ export class LDAPSourceViewPage extends AKElement { ], [ msg("Related actions"), - html` - ${msg("Save Changes")} - ${msg("Update LDAP Source")} - - - - `, + html``, ], ], { twocolumn: true }, diff --git a/web/src/admin/sources/oauth/OAuthSourceViewPage.ts b/web/src/admin/sources/oauth/OAuthSourceViewPage.ts index 78593a14bf..d71eb23450 100644 --- a/web/src/admin/sources/oauth/OAuthSourceViewPage.ts +++ b/web/src/admin/sources/oauth/OAuthSourceViewPage.ts @@ -1,22 +1,23 @@ import "#admin/policies/BoundPoliciesList"; import "#admin/rbac/ak-rbac-object-permission-page"; import "#admin/sources/oauth/OAuthSourceDiagram"; -import "#admin/sources/oauth/OAuthSourceForm"; import "#admin/events/ObjectChangelog"; import "#elements/CodeMirror"; import "#elements/Tabs"; import "#elements/buttons/SpinnerButton/index"; -import "#elements/forms/ModalForm"; import { DEFAULT_CONFIG } from "#common/api/config"; import { EVENT_REFRESH } from "#common/constants"; import { AKElement } from "#elements/Base"; +import { modalInvoker } from "#elements/dialogs"; import { sourceBindingTypeNotices } from "#elements/sources/utils"; import { SlottedTemplateResult } from "#elements/types"; import renderDescriptionList from "#components/DescriptionList"; +import { OAuthSourceForm } from "#admin/sources/oauth/OAuthSourceForm"; + import { ModelEnum, OAuthSource, ProviderTypeEnum, SourcesApi } from "@goauthentik/api"; import { msg } from "@lit/localize"; @@ -137,21 +138,14 @@ export class OAuthSourceViewPage extends AKElement { ], [ msg("Related actions"), - html` - ${msg("Save Changes")} - ${msg("Update OAuth Source")} - - - - `, + html``, ], ])}
    diff --git a/web/src/admin/users/UserListPage.ts b/web/src/admin/users/UserListPage.ts index 213a783c3a..0f6a3abe64 100644 --- a/web/src/admin/users/UserListPage.ts +++ b/web/src/admin/users/UserListPage.ts @@ -251,10 +251,19 @@ export class UserListPage extends WithBrandConfig( const displayName = formatUserDisplayName(item); return [ - html``, - html` -
    ${item.username}
    - ${item.name ? item.name : html`<${msg("No name set")}>`} + html`${msg(str`Avatar`, + html`
    +
    ${item.username}
    + ${displayName ? item.name : html`<${msg("No name set")}>`}
    `, html``, Timestamp(item.lastLogin), diff --git a/web/src/admin/users/ak-user-group-table.ts b/web/src/admin/users/ak-user-group-table.ts index 87e0aed981..e33857dd58 100644 --- a/web/src/admin/users/ak-user-group-table.ts +++ b/web/src/admin/users/ak-user-group-table.ts @@ -9,7 +9,7 @@ import { SlottedTemplateResult } from "#elements/types"; import { CoreApi, Group } from "@goauthentik/api"; import { msg } from "@lit/localize"; -import { CSSResult, html, nothing } from "lit"; +import { CSSResult, html } from "lit"; import { customElement } from "lit/decorators.js"; import PFBanner from "@patternfly/patternfly/components/Banner/banner.css"; @@ -26,44 +26,44 @@ export class UserGroupTable extends Table { public override order = "name"; - protected async apiEndpoint(): Promise> { + protected override async apiEndpoint(): Promise> { return new CoreApi(DEFAULT_CONFIG).coreGroupsList({ ...(await this.defaultEndpointConfig()), includeUsers: false, }); } - protected columns: TableColumn[] = [ + protected override columns: TableColumn[] = [ [msg("Name"), "username"], [msg("Superuser"), "is_superuser"], [msg("Members"), ""], ]; - protected row(item: Group): SlottedTemplateResult[] { + protected override row(item: Group): SlottedTemplateResult[] { return [ - html`
    ${item.name}
    `, + item.name, html``, - html`${(item.users || []).length}`, + item.users?.length || 0, ]; } - protected renderSelectedChip(item: Group): SlottedTemplateResult { + protected override renderSelectedChip(item: Group): SlottedTemplateResult { return item.name; } protected override render(): SlottedTemplateResult { - const willSuperuser = this.selectedElements.filter((g) => g.isSuperuser).length; + const willSuperuser = this.selectedElements.some((g) => g.isSuperuser); - return html`${willSuperuser - ? html` -
    - ${msg( - "Warning: Adding the user to the selected group(s) will give them superuser permissions.", - )} -
    - ` - : nothing} - ${super.render()}`; + if (!willSuperuser) { + return super.render(); + } + + return html`
    + ${msg( + "Warning: Adding the user to the selected group(s) will give them superuser permissions.", + )} +
    + ${super.render()}`; } } diff --git a/web/src/common/api/responses.ts b/web/src/common/api/responses.ts index 4e63ac0700..0241b3a9dc 100644 --- a/web/src/common/api/responses.ts +++ b/web/src/common/api/responses.ts @@ -50,9 +50,9 @@ export interface PaginatedResponse { * @param input An iterable of items to include in the results array. */ export function createPaginatedResponse( - input: Iterable = [], + input?: Iterable | null, ): PaginatedResponse { - const results = Array.from(input); + const results = Array.from(input ?? []); return { pagination: { diff --git a/web/src/components/ak-radio-input.ts b/web/src/components/ak-radio-input.ts index d6e9f2332e..4adf736e87 100644 --- a/web/src/components/ak-radio-input.ts +++ b/web/src/components/ak-radio-input.ts @@ -34,12 +34,7 @@ export class AkRadioInput extends HorizontalLightComponen const helpText = this.help?.trim(); return html`${helpText - ? html`

    + ? html`

    ${helpText}

    ` : null} [this.neutralLabel, "pf-m-gray", "fa-question"] as const) + .with(true, () => [this.goodLabel, "pf-m-green", "fa-check"] as const) + .with(false, () => [this.badLabel, ...details] as const) + .exhaustive(); const classes = { "pf-c-label": true, diff --git a/web/src/components/ak-switch-input.ts b/web/src/components/ak-switch-input.ts index 073da96f29..cd39146089 100644 --- a/web/src/components/ak-switch-input.ts +++ b/web/src/components/ak-switch-input.ts @@ -60,8 +60,6 @@ export class AkSwitchInput extends AKElement { } render() { - const doCheck = this.checked ? this.checked : undefined; - return html`