web/user: fix user source settings not updating correctly after deletion

also optimise the amount of API requests sent

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#3411
This commit is contained in:
Jens Langhammer 2022-08-16 11:43:13 +02:00
parent d7e8ca1c8f
commit 54eeb7add6
3 changed files with 112 additions and 80 deletions

View File

@ -15,13 +15,16 @@ import AKGlobal from "@goauthentik/web/authentik.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css"; import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css"; import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css";
import { SourcesApi, UserSetting } from "@goauthentik/api"; import { PaginatedUserSourceConnectionList, SourcesApi, UserSetting } from "@goauthentik/api";
@customElement("ak-user-settings-source") @customElement("ak-user-settings-source")
export class UserSourceSettingsPage extends LitElement { export class UserSourceSettingsPage extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
sourceSettings?: Promise<UserSetting[]>; sourceSettings?: Promise<UserSetting[]>;
@property({ attribute: false })
connections?: PaginatedUserSourceConnectionList;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [ return [
PFDataList, PFDataList,
@ -55,15 +58,30 @@ export class UserSourceSettingsPage extends LitElement {
firstUpdated(): void { firstUpdated(): void {
this.sourceSettings = new SourcesApi(DEFAULT_CONFIG).sourcesAllUserSettingsList(); this.sourceSettings = new SourcesApi(DEFAULT_CONFIG).sourcesAllUserSettingsList();
new SourcesApi(DEFAULT_CONFIG).sourcesUserConnectionsAllList().then((connections) => {
this.connections = connections;
});
} }
renderSourceSettings(source: UserSetting): TemplateResult { renderSourceSettings(source: UserSetting): TemplateResult {
let connectionPk = -1;
if (this.connections) {
const connections = this.connections.results.filter(
(con) => con.source.slug === source.objectUid,
);
if (connections.length > 0) {
connectionPk = connections[0].pk;
} else {
connectionPk = 0;
}
}
switch (source.component) { switch (source.component) {
case "ak-user-settings-source-oauth": case "ak-user-settings-source-oauth":
return html`<ak-user-settings-source-oauth return html`<ak-user-settings-source-oauth
class="pf-c-data-list__item-row" class="pf-c-data-list__item-row"
objectId=${source.objectUid} objectId=${source.objectUid}
title=${source.title} title=${source.title}
connectionPk=${connectionPk}
.configureUrl=${source.configureUrl} .configureUrl=${source.configureUrl}
> >
</ak-user-settings-source-oauth>`; </ak-user-settings-source-oauth>`;
@ -72,6 +90,7 @@ export class UserSourceSettingsPage extends LitElement {
class="pf-c-data-list__item-row" class="pf-c-data-list__item-row"
objectId=${source.objectUid} objectId=${source.objectUid}
title=${source.title} title=${source.title}
connectionPk=${connectionPk}
.configureUrl=${source.configureUrl} .configureUrl=${source.configureUrl}
> >
</ak-user-settings-source-plex>`; </ak-user-settings-source-plex>`;

View File

@ -1,4 +1,6 @@
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/web/api/Config"; import { AndNext, DEFAULT_CONFIG } from "@goauthentik/web/api/Config";
import { EVENT_REFRESH } from "@goauthentik/web/constants";
import "@goauthentik/web/elements/Spinner";
import { MessageLevel } from "@goauthentik/web/elements/messages/Message"; import { MessageLevel } from "@goauthentik/web/elements/messages/Message";
import { showMessage } from "@goauthentik/web/elements/messages/MessageContainer"; import { showMessage } from "@goauthentik/web/elements/messages/MessageContainer";
import { BaseUserSettings } from "@goauthentik/web/user/user-settings/BaseUserSettings"; import { BaseUserSettings } from "@goauthentik/web/user/user-settings/BaseUserSettings";
@ -8,7 +10,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js";
import { SourcesApi } from "@goauthentik/api"; import { SourcesApi } from "@goauthentik/api";
@ -17,20 +18,20 @@ export class SourceSettingsOAuth extends BaseUserSettings {
@property() @property()
title!: string; title!: string;
@property({ type: Number })
connectionPk = 0;
render(): TemplateResult { render(): TemplateResult {
return html`${until( if (this.connectionPk === -1) {
new SourcesApi(DEFAULT_CONFIG) return html`<ak-spinner></ak-spinner>`;
.sourcesUserConnectionsOauthList({ }
sourceSlug: this.objectId, if (this.connectionPk > 0) {
})
.then((connection) => {
if (connection.results.length > 0) {
return html`<button return html`<button
class="pf-c-button pf-m-danger" class="pf-c-button pf-m-danger"
@click=${() => { @click=${() => {
return new SourcesApi(DEFAULT_CONFIG) return new SourcesApi(DEFAULT_CONFIG)
.sourcesUserConnectionsOauthDestroy({ .sourcesUserConnectionsOauthDestroy({
id: connection.results[0].pk || 0, id: this.connectionPk,
}) })
.then(() => { .then(() => {
showMessage({ showMessage({
@ -43,6 +44,14 @@ export class SourceSettingsOAuth extends BaseUserSettings {
level: MessageLevel.error, level: MessageLevel.error,
message: t`Failed to disconnected source: ${exc}`, message: t`Failed to disconnected source: ${exc}`,
}); });
})
.finally(() => {
this.parentElement?.dispatchEvent(
new CustomEvent(EVENT_REFRESH, {
bubbles: true,
composed: true,
}),
);
}); });
}} }}
> >
@ -57,7 +66,5 @@ export class SourceSettingsOAuth extends BaseUserSettings {
> >
${t`Connect`} ${t`Connect`}
</a>`; </a>`;
}),
)}`;
} }
} }

View File

@ -1,6 +1,7 @@
import { DEFAULT_CONFIG } from "@goauthentik/web/api/Config"; import { DEFAULT_CONFIG } from "@goauthentik/web/api/Config";
import { PlexAPIClient, popupCenterScreen } from "@goauthentik/web/api/Plex"; import { PlexAPIClient, popupCenterScreen } from "@goauthentik/web/api/Plex";
import { EVENT_REFRESH } from "@goauthentik/web/constants"; import { EVENT_REFRESH } from "@goauthentik/web/constants";
import "@goauthentik/web/elements/Spinner";
import { MessageLevel } from "@goauthentik/web/elements/messages/Message"; import { MessageLevel } from "@goauthentik/web/elements/messages/Message";
import { showMessage } from "@goauthentik/web/elements/messages/MessageContainer"; import { showMessage } from "@goauthentik/web/elements/messages/MessageContainer";
import { BaseUserSettings } from "@goauthentik/web/user/user-settings/BaseUserSettings"; import { BaseUserSettings } from "@goauthentik/web/user/user-settings/BaseUserSettings";
@ -9,7 +10,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import { SourcesApi } from "@goauthentik/api"; import { SourcesApi } from "@goauthentik/api";
@ -18,6 +18,9 @@ export class SourceSettingsPlex extends BaseUserSettings {
@property() @property()
title!: string; title!: string;
@property({ type: Number })
connectionPk = 0;
async doPlex(): Promise<void> { async doPlex(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.configureUrl || ""); const authInfo = await PlexAPIClient.getPin(this.configureUrl || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700); const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
@ -39,19 +42,16 @@ export class SourceSettingsPlex extends BaseUserSettings {
} }
render(): TemplateResult { render(): TemplateResult {
return html`${until( if (this.connectionPk === -1) {
new SourcesApi(DEFAULT_CONFIG) return html`<ak-spinner></ak-spinner>`;
.sourcesUserConnectionsPlexList({ }
sourceSlug: this.objectId, if (this.connectionPk > 0) {
})
.then((connection) => {
if (connection.results.length > 0) {
return html`<button return html`<button
class="pf-c-button pf-m-danger" class="pf-c-button pf-m-danger"
@click=${() => { @click=${() => {
return new SourcesApi(DEFAULT_CONFIG) return new SourcesApi(DEFAULT_CONFIG)
.sourcesUserConnectionsPlexDestroy({ .sourcesUserConnectionsPlexDestroy({
id: connection.results[0].pk || 0, id: this.connectionPk,
}) })
.then(() => { .then(() => {
showMessage({ showMessage({
@ -64,6 +64,14 @@ export class SourceSettingsPlex extends BaseUserSettings {
level: MessageLevel.error, level: MessageLevel.error,
message: t`Failed to disconnected source: ${exc}`, message: t`Failed to disconnected source: ${exc}`,
}); });
})
.finally(() => {
this.parentElement?.dispatchEvent(
new CustomEvent(EVENT_REFRESH, {
bubbles: true,
composed: true,
}),
);
}); });
}} }}
> >
@ -73,7 +81,5 @@ export class SourceSettingsPlex extends BaseUserSettings {
return html`<button @click=${this.doPlex} class="pf-c-button pf-m-primary"> return html`<button @click=${this.doPlex} class="pf-c-button pf-m-primary">
${t`Connect`} ${t`Connect`}
</button>`; </button>`;
}),
)}`;
} }
} }