web/admin: more and more polish (#21303)

* fix user edit button

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix impersonate button not aligned

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* cleanup oauth2 provider page

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* better desc for outpost health

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix static table not updating when items change

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix lint

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* include oidc providers in ssf provider retrieve

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* consistent oauth provider label

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* rework ssf view page

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make client-rust makefile on macos

specifically when gnu sed is installed in the path

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L.
2026-04-04 21:35:11 +01:00
committed by GitHub
parent 418fa620fe
commit 827a77dd52
17 changed files with 199 additions and 177 deletions
@@ -18,6 +18,10 @@ class SSFProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
ssf_url = SerializerMethodField()
token_obj = TokenSerializer(source="token", required=False, read_only=True)
oidc_auth_providers_obj = ProviderSerializer(
read_only=True, source="oidc_auth_providers", many=True
)
def get_ssf_url(self, instance: SSFProvider) -> str | None:
request: Request = self._context.get("request")
if not request:
@@ -45,6 +49,7 @@ class SSFProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
"signing_key",
"token_obj",
"oidc_auth_providers",
"oidc_auth_providers_obj",
"ssf_url",
"event_retention",
]
@@ -54,7 +59,7 @@ class SSFProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
class SSFProviderViewSet(UsedByMixin, ModelViewSet):
"""SSFProvider Viewset"""
queryset = SSFProvider.objects.all()
queryset = SSFProvider.objects.all().prefetch_related("oidc_auth_providers")
serializer_class = SSFProviderSerializer
filterset_fields = {
"application": ["isnull"],
+30 -1
View File
@@ -35,6 +35,7 @@ type SSFProvider struct {
SigningKey string `json:"signing_key"`
TokenObj Token `json:"token_obj"`
OidcAuthProviders []int32 `json:"oidc_auth_providers,omitempty"`
OidcAuthProvidersObj []Provider `json:"oidc_auth_providers_obj"`
SsfUrl NullableString `json:"ssf_url"`
EventRetention *string `json:"event_retention,omitempty"`
AdditionalProperties map[string]interface{}
@@ -46,7 +47,7 @@ type _SSFProvider SSFProvider
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewSSFProvider(pk int32, name string, component string, verboseName string, verboseNamePlural string, metaModelName string, signingKey string, tokenObj Token, ssfUrl NullableString) *SSFProvider {
func NewSSFProvider(pk int32, name string, component string, verboseName string, verboseNamePlural string, metaModelName string, signingKey string, tokenObj Token, oidcAuthProvidersObj []Provider, ssfUrl NullableString) *SSFProvider {
this := SSFProvider{}
this.Pk = pk
this.Name = name
@@ -56,6 +57,7 @@ func NewSSFProvider(pk int32, name string, component string, verboseName string,
this.MetaModelName = metaModelName
this.SigningKey = signingKey
this.TokenObj = tokenObj
this.OidcAuthProvidersObj = oidcAuthProvidersObj
this.SsfUrl = ssfUrl
return &this
}
@@ -292,6 +294,30 @@ func (o *SSFProvider) SetOidcAuthProviders(v []int32) {
o.OidcAuthProviders = v
}
// GetOidcAuthProvidersObj returns the OidcAuthProvidersObj field value
func (o *SSFProvider) GetOidcAuthProvidersObj() []Provider {
if o == nil {
var ret []Provider
return ret
}
return o.OidcAuthProvidersObj
}
// GetOidcAuthProvidersObjOk returns a tuple with the OidcAuthProvidersObj field value
// and a boolean to check if the value has been set.
func (o *SSFProvider) GetOidcAuthProvidersObjOk() ([]Provider, bool) {
if o == nil {
return nil, false
}
return o.OidcAuthProvidersObj, true
}
// SetOidcAuthProvidersObj sets field value
func (o *SSFProvider) SetOidcAuthProvidersObj(v []Provider) {
o.OidcAuthProvidersObj = v
}
// GetSsfUrl returns the SsfUrl field value
// If the value is explicit nil, the zero value for string will be returned
func (o *SSFProvider) GetSsfUrl() string {
@@ -371,6 +397,7 @@ func (o SSFProvider) ToMap() (map[string]interface{}, error) {
if !IsNil(o.OidcAuthProviders) {
toSerialize["oidc_auth_providers"] = o.OidcAuthProviders
}
toSerialize["oidc_auth_providers_obj"] = o.OidcAuthProvidersObj
toSerialize["ssf_url"] = o.SsfUrl.Get()
if !IsNil(o.EventRetention) {
toSerialize["event_retention"] = o.EventRetention
@@ -396,6 +423,7 @@ func (o *SSFProvider) UnmarshalJSON(data []byte) (err error) {
"meta_model_name",
"signing_key",
"token_obj",
"oidc_auth_providers_obj",
"ssf_url",
}
@@ -435,6 +463,7 @@ func (o *SSFProvider) UnmarshalJSON(data []byte) (err error) {
delete(additionalProperties, "signing_key")
delete(additionalProperties, "token_obj")
delete(additionalProperties, "oidc_auth_providers")
delete(additionalProperties, "oidc_auth_providers_obj")
delete(additionalProperties, "ssf_url")
delete(additionalProperties, "event_retention")
o.AdditionalProperties = additionalProperties
+1 -1
View File
@@ -5,7 +5,7 @@ GID = $(shell id -g)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
SED_INPLACE = sed -i ''
SED_INPLACE = /usr/bin/sed -i ''
else
SED_INPLACE = sed -i
endif
+4
View File
@@ -39,6 +39,8 @@ pub struct SsfProvider {
skip_serializing_if = "Option::is_none"
)]
pub oidc_auth_providers: Option<Vec<i32>>,
#[serde(rename = "oidc_auth_providers_obj")]
pub oidc_auth_providers_obj: Vec<models::Provider>,
#[serde(rename = "ssf_url", deserialize_with = "Option::deserialize")]
pub ssf_url: Option<String>,
#[serde(rename = "event_retention", skip_serializing_if = "Option::is_none")]
@@ -56,6 +58,7 @@ impl SsfProvider {
meta_model_name: String,
signing_key: uuid::Uuid,
token_obj: models::Token,
oidc_auth_providers_obj: Vec<models::Provider>,
ssf_url: Option<String>,
) -> SsfProvider {
SsfProvider {
@@ -68,6 +71,7 @@ impl SsfProvider {
signing_key,
token_obj,
oidc_auth_providers: None,
oidc_auth_providers_obj,
ssf_url,
event_retention: None,
}
+16 -1
View File
@@ -20,6 +20,13 @@ import {
TokenToJSON,
TokenToJSONTyped,
} from './Token';
import type { Provider } from './Provider';
import {
ProviderFromJSON,
ProviderFromJSONTyped,
ProviderToJSON,
ProviderToJSONTyped,
} from './Provider';
/**
* SSFProvider Serializer
@@ -81,6 +88,12 @@ export interface SSFProvider {
* @memberof SSFProvider
*/
oidcAuthProviders?: Array<number>;
/**
*
* @type {Array<Provider>}
* @memberof SSFProvider
*/
readonly oidcAuthProvidersObj: Array<Provider>;
/**
*
* @type {string}
@@ -107,6 +120,7 @@ export function instanceOfSSFProvider(value: object): value is SSFProvider {
if (!('metaModelName' in value) || value['metaModelName'] === undefined) return false;
if (!('signingKey' in value) || value['signingKey'] === undefined) return false;
if (!('tokenObj' in value) || value['tokenObj'] === undefined) return false;
if (!('oidcAuthProvidersObj' in value) || value['oidcAuthProvidersObj'] === undefined) return false;
if (!('ssfUrl' in value) || value['ssfUrl'] === undefined) return false;
return true;
}
@@ -130,6 +144,7 @@ export function SSFProviderFromJSONTyped(json: any, ignoreDiscriminator: boolean
'signingKey': json['signing_key'],
'tokenObj': TokenFromJSON(json['token_obj']),
'oidcAuthProviders': json['oidc_auth_providers'] == null ? undefined : json['oidc_auth_providers'],
'oidcAuthProvidersObj': ((json['oidc_auth_providers_obj'] as Array<any>).map(ProviderFromJSON)),
'ssfUrl': json['ssf_url'],
'eventRetention': json['event_retention'] == null ? undefined : json['event_retention'],
};
@@ -139,7 +154,7 @@ export function SSFProviderToJSON(json: any): SSFProvider {
return SSFProviderToJSONTyped(json, false);
}
export function SSFProviderToJSONTyped(value?: Omit<SSFProvider, 'pk'|'component'|'verbose_name'|'verbose_name_plural'|'meta_model_name'|'token_obj'|'ssf_url'> | null, ignoreDiscriminator: boolean = false): any {
export function SSFProviderToJSONTyped(value?: Omit<SSFProvider, 'pk'|'component'|'verbose_name'|'verbose_name_plural'|'meta_model_name'|'token_obj'|'oidc_auth_providers_obj'|'ssf_url'> | null, ignoreDiscriminator: boolean = false): any {
if (value == null) {
return value;
}
+6
View File
@@ -54685,6 +54685,11 @@ components:
type: array
items:
type: integer
oidc_auth_providers_obj:
type: array
items:
$ref: '#/components/schemas/Provider'
readOnly: true
ssf_url:
type: string
nullable: true
@@ -54695,6 +54700,7 @@ components:
- component
- meta_model_name
- name
- oidc_auth_providers_obj
- pk
- signing_key
- ssf_url
@@ -120,7 +120,7 @@ export class AgentConnectorForm extends WithBrandConfig(ModelForm<AgentConnector
>
</ak-switch-input>
<ak-form-element-horizontal
label=${msg("Federated OIDC Providers")}
label=${msg("Federated OAuth2/OpenID Providers")}
name="jwtFederationProviders"
>
<ak-dual-select-dynamic-selected
@@ -122,6 +122,9 @@ export class OutpostViewPage extends AKElement {
const unhealthyPct = (100 / totalCount) * unhealthyCount;
return html`<div class="pf-c-progress pf-m-inside">
<div class="pf-c-progress__description">
${msg(str`${healthyCount}/${totalCount} instances are healthy.`)}
</div>
<div
class="pf-c-progress__bar"
role="progressbar"
@@ -135,7 +135,6 @@ export class BoundPoliciesList<T extends PolicyBinding = PolicyBinding> extends
</ak-forms-modal>`;
} else if (item.user) {
return html`<button
slot="trigger"
class="pf-c-button pf-m-secondary"
${UserForm.asEditModalInvoker(item.userObj?.pk)}
>
@@ -452,7 +452,7 @@ export function renderForm({
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Federated OIDC Providers")}
label=${msg("Federated OAuth2/OpenID Providers")}
name="jwtFederationProviders"
>
<ak-dual-select-dynamic-selected
@@ -62,6 +62,18 @@ export function TypeToLabel(type?: ClientTypeEnum): string {
}
}
export function LogoutMethodToLabel(method?: OAuth2ProviderLogoutMethodEnum): string {
if (!method) return "";
switch (method) {
case OAuth2ProviderLogoutMethodEnum.Backchannel:
return msg("Back-channel");
case OAuth2ProviderLogoutMethodEnum.Frontchannel:
return msg("Front-channel");
case OAuth2ProviderLogoutMethodEnum.UnknownDefaultOpenApi:
return msg("Unknown");
}
}
@customElement("ak-provider-oauth2-view")
export class OAuth2ProviderViewPage extends AKElement {
@property({ type: Number })
@@ -183,11 +195,8 @@ export class OAuth2ProviderViewPage extends AKElement {
}
renderTabOverview(): SlottedTemplateResult {
if (!this.provider) {
return nothing;
}
const [appLabel, modelName] = ModelEnum.AuthentikProvidersOauth2Oauth2provider.split(".");
return html` ${this.provider?.assignedApplicationName
return html`${this.provider?.assignedApplicationName
? nothing
: html`<div slot="header" class="pf-c-banner pf-m-warning">
${msg("Warning: Provider is not used by an Application.")}
@@ -196,116 +205,56 @@ export class OAuth2ProviderViewPage extends AKElement {
<div
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-4-col-on-xl pf-m-4-col-on-2xl"
>
<div class="pf-c-card__title">${msg("Info")}</div>
<div class="pf-c-card__body">
<dl class="pf-c-description-list">
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${msg("Name")}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
${this.provider.name}
</div>
</dd>
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text"
>${msg("Assigned to application")}</span
${renderDescriptionList([
[msg("Name"), html`${this.provider?.name}`],
[
msg("Assigned to application"),
html`<ak-provider-related-application .provider=${this.provider}>
</ak-provider-related-application>`,
],
[msg("Client type"), html`${TypeToLabel(this.provider?.clientType)}`],
[msg("Client ID"), html`${this.provider?.clientId}`],
[
msg("Redirect URIs"),
(this.provider?.redirectUris || []).length > 0
? html`<ul>
${this.provider?.redirectUris.map((ru) => {
return html`<li class="pf-m-monospace">
${ru.matchingMode}: ${ru.url}
</li>`;
})}
</ul>`
: "-",
],
[
msg("Logout URI"),
this.provider?.logoutUri !== "" ? this.provider?.logoutUri : "-",
],
[
msg("Logout Method"),
html`${LogoutMethodToLabel(this.provider?.logoutMethod)}`,
],
[
msg("Related actions"),
html`<ak-forms-modal>
<span slot="submit">${msg("Save Changes")}</span>
<span slot="header">${msg("Update OAuth2 Provider")}</span>
<ak-provider-oauth2-form
slot="form"
.instancePk=${this.provider?.pk || 0}
>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
<ak-provider-related-application .provider=${this.provider}>
</ak-provider-related-application>
</div>
</dd>
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text"
>${msg("Client type")}</span
</ak-provider-oauth2-form>
<button
slot="trigger"
class="pf-c-button pf-m-primary pf-m-block"
>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
${TypeToLabel(this.provider.clientType)}
</div>
</dd>
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text"
>${msg("Client ID")}</span
>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text pf-m-monospace">
${this.provider.clientId}
</div>
</dd>
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text"
>${msg("Redirect URIs")}</span
>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
<ul>
${this.provider.redirectUris.map((ru) => {
return html`<li class="pf-m-monospace">
${ru.matchingMode}: ${ru.url}
</li>`;
})}
</ul>
</div>
</dd>
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text"
>${msg("Logout URI")}</span
>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text pf-m-monospace">
${this.provider.logoutUri}
</div>
</dd>
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text"
>${msg("Logout Method")}</span
>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
${this.provider.logoutMethod ===
OAuth2ProviderLogoutMethodEnum.Backchannel
? msg("Back-channel")
: this.provider.logoutMethod ===
OAuth2ProviderLogoutMethodEnum.Frontchannel
? msg("Front-channel")
: msg("")}
</div>
</dd>
</div>
</dl>
</div>
<div class="pf-c-card__footer">
<ak-forms-modal>
<span slot="submit">${msg("Save Changes")}</span>
<span slot="header">${msg("Update OAuth2 Provider")}</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")}
</button>
</ak-forms-modal>
${msg("Edit")}
</button>
</ak-forms-modal>`,
],
])}
</div>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-8-col">
@@ -345,7 +294,11 @@ export class OAuth2ProviderViewPage extends AKElement {
value="${this.providerUrls?.issuer || msg("-")}"
/>
</div>
<hr class="pf-c-divider" />
</form>
</div>
<hr class="pf-c-divider" />
<div class="pf-c-card__body">
<form class="pf-c-form">
<div class="pf-c-form__group">
<label
class="pf-c-form__label"
@@ -436,7 +389,7 @@ export class OAuth2ProviderViewPage extends AKElement {
<ak-task-list
.relObjAppLabel=${appLabel}
.relObjModel=${modelName}
.relObjId="${this.provider.pk}"
.relObjId="${this.provider?.pk}"
></ak-task-list>
</div>
</div>
@@ -334,7 +334,7 @@ ${provider.skipPathRegex}</textarea
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Federated OIDC Providers")}
label=${msg("Federated OAuth2/OpenID Providers")}
name="jwtFederationProviders"
>
<ak-dual-select-dynamic-selected
@@ -100,7 +100,7 @@ export class SSFProviderFormPage extends BaseProviderForm<SSFProvider> {
<ak-form-group label="${msg("Authentication settings")}">
<div class="pf-c-form">
<ak-form-element-horizontal
label=${msg("OIDC Providers")}
label=${msg("Federated OAuth2/OpenID Providers")}
name="oidcAuthProviders"
>
<ak-dual-select-dynamic-selected
@@ -16,6 +16,8 @@ import { EVENT_REFRESH } from "#common/constants";
import { AKElement } from "#elements/Base";
import { SlottedTemplateResult } from "#elements/types";
import renderDescriptionList from "#components/DescriptionList";
import { ModelEnum, ProvidersApi, SSFProvider } from "@goauthentik/api";
import { msg } from "@lit/localize";
@@ -25,11 +27,10 @@ import { customElement, property } from "lit/decorators.js";
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFList from "@patternfly/patternfly/components/List/list.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
@@ -53,13 +54,13 @@ export class SSFProviderViewPage extends AKElement {
PFButton,
PFPage,
PFGrid,
PFContent,
PFCard,
PFDescriptionList,
PFForm,
PFFormControl,
PFBanner,
PFDivider,
PFList,
PFList,
];
constructor() {
@@ -128,47 +129,55 @@ export class SSFProviderViewPage extends AKElement {
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-4-col-on-xl pf-m-4-col-on-2xl"
>
<div class="pf-c-card__body">
<dl class="pf-c-description-list">
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${msg("Name")}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
${this.provider.name}
</div>
</dd>
</div>
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${msg("URL")}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
<input
class="pf-c-form-control pf-m-monospace"
readonly
type="text"
value=${this.provider.ssfUrl || ""}
placeholder=${this.provider.ssfUrl
? msg("SSF URL")
: msg("No assigned application")}
/>
</div>
</dd>
</div>
</dl>
</div>
<div class="pf-c-card__footer">
<ak-forms-modal>
<span slot="submit">${msg("Save Changes")}</span>
<span slot="header">${msg("Update SSF Provider")}</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")}
</button>
</ak-forms-modal>
${renderDescriptionList([
[msg("Name"), html`${this.provider.name}`],
[
msg("URL"),
html`<input
class="pf-c-form-control pf-m-monospace"
readonly
type="text"
value=${this.provider.ssfUrl || ""}
placeholder=${this.provider.ssfUrl
? msg("SSF URL")
: msg("No assigned application")}
/>`,
],
[
msg("Federated OAuth2/OpenID Providers"),
(this.provider.oidcAuthProvidersObj || []).length > 0
? html`<ul class="pf-c-list">
${this.provider.oidcAuthProvidersObj.map((provider) => {
return html`
<li>
<a href="#/core/providers/${provider.pk}">
${provider.name}
</a>
</li>
`;
})}
</ul>`
: html`-`,
],
[
msg("Related actions"),
html`<ak-forms-modal>
<span slot="submit">${msg("Save Changes")}</span>
<span slot="header">${msg("Update SSF Provider")}</span>
<ak-provider-ssf-form
slot="form"
.instancePk=${this.provider.pk}
>
</ak-provider-ssf-form>
<button
slot="trigger"
class="pf-c-button pf-m-primary pf-m-block"
>
${msg("Edit")}
</button>
</ak-forms-modal>`,
],
])}
</div>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-8-col-on-2xl">
+1 -1
View File
@@ -176,7 +176,7 @@ export class UserViewPage extends WithBrandConfig(WithCapabilitiesConfig(WithSes
</ak-user-active-form>
${showImpersonate
? html`<button
class="pf-c-button pf-m-tertiary"
class="pf-c-button pf-m-tertiary pf-m-block"
${UserImpersonateForm.asEditModalInvoker(user.pk)}
aria-label=${msg(str`Impersonate ${displayName}`)}
>
+8
View File
@@ -3,6 +3,7 @@ import { createPaginatedResponse } from "#common/api/responses";
import { PaginatedResponse, Table } from "#elements/table/Table";
import { SlottedTemplateResult } from "#elements/types";
import { PropertyValues } from "lit";
import { html, nothing } from "lit-html";
import { property } from "lit/decorators.js";
@@ -23,4 +24,11 @@ export abstract class StaticTable<T extends object> extends Table<T> {
protected override renderTablePagination(): SlottedTemplateResult {
return nothing;
}
protected override willUpdate(changedProperties: PropertyValues<this>): void {
if (changedProperties.has("items")) {
this.fetch();
}
super.willUpdate(changedProperties);
}
}
-9
View File
@@ -25,15 +25,6 @@ td ak-mdx::part(content) {
td:has(ak-action-button),
td:has(ak-forms-modal),
td:has(ak-rbac-object-permission-modal) {
& > .pf-c-button,
& > button[slot="trigger"]:has(i),
& > *::part(spinner-button),
& > *::part(button) {
--pf-global--spacer--form-element: 0;
padding-inline: 0.5em !important;
}
button[slot="trigger"]:has(i) {
padding-inline: 0.5em !important;
}