web/user: rework user source connection UI

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-12-30 21:59:41 +01:00
parent fc19372709
commit 9154b9b85d
14 changed files with 155 additions and 105 deletions

View File

@ -29,3 +29,4 @@ class UserSettingSerializer(PassiveSerializer):
component = CharField()
title = CharField()
configure_url = CharField(required=False)
icon_url = CharField()

View File

@ -75,14 +75,17 @@ class OAuthSource(Source):
)
def ui_user_settings(self) -> Optional[UserSettingSerializer]:
provider_type = self.type
provider = provider_type()
return UserSettingSerializer(
data={
"title": f"OAuth {self.name}",
"title": self.name,
"component": "ak-user-settings-source-oauth",
"configure_url": reverse(
"authentik_sources_oauth:oauth-client-login",
kwargs={"source_slug": self.slug},
),
"icon_url": provider.icon_url(),
}
)

View File

@ -80,9 +80,10 @@ class PlexSource(Source):
def ui_user_settings(self) -> Optional[UserSettingSerializer]:
return UserSettingSerializer(
data={
"title": f"Plex {self.name}",
"title": self.name,
"component": "ak-user-settings-source-plex",
"configure_url": self.client_id,
"icon_url": static("authentik/sources/plex.svg"),
}
)

View File

@ -31275,8 +31275,11 @@ components:
type: string
configure_url:
type: string
icon_url:
type: string
required:
- component
- icon_url
- object_uid
- title
UserSourceConnection:

View File

@ -339,9 +339,16 @@ html > form > input {
) !important;
}
/* data list */
.pf-c-data-list {
border-top-color: var(--ak-dark-background-lighter);
}
.pf-c-data-list__item {
--pf-c-data-list__item--BackgroundColor: var(--ak-dark-background-light);
--pf-c-data-list__item--BackgroundColor: transparent;
--pf-c-data-list__item--BorderBottomColor: var(--ak-dark-background-lighter);
color: var(--ak-dark-foreground);
}
}
.pf-c-data-list__item {
background-color: transparent;
}

View File

@ -168,13 +168,13 @@ export class IdentificationStage extends BaseStage<
}
return html`<div class="pf-c-login__main-footer-band">
${this.challenge.enrollUrl
? html` <p class="pf-c-login__main-footer-band-item">
? html`<p class="pf-c-login__main-footer-band-item">
${t`Need an account?`}
<a id="enroll" href="${this.challenge.enrollUrl}">${t`Sign up.`}</a>
</p>`
: html``}
${this.challenge.recoveryUrl
? html` <p class="pf-c-login__main-footer-band-item">
? html`<p class="pf-c-login__main-footer-band-item">
<a id="recovery" href="${this.challenge.recoveryUrl}"
>${t`Forgot username or password?`}</a
>

View File

@ -988,14 +988,18 @@ msgstr "Connect"
msgid "Connect to the LDAP Server on port 389:"
msgstr "Connect to the LDAP Server on port 389:"
#: src/user/user-settings/sources/SourceSettings.ts
msgid "Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials."
msgstr "Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials."
#: src/user/user-settings/UserSettingsPage.ts
msgid "Connected services"
msgstr "Connected services"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connected."
msgstr "Connected."
#~ msgid "Connected."
#~ msgstr "Connected."
#: src/common/ws.ts
msgid "Connection error, reconnecting..."
@ -3138,8 +3142,8 @@ msgstr "Not configured action"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Not connected."
msgstr "Not connected."
#~ msgid "Not connected."
#~ msgstr "Not connected."
#: src/elements/router/Router404.ts
msgid "Not found"
@ -4329,8 +4333,8 @@ msgstr "Source linked"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Source {0}"
msgstr "Source {0}"
#~ msgid "Source {0}"
#~ msgstr "Source {0}"
#: src/pages/sources/SourcesListPage.ts
msgid "Source(s)"

View File

@ -987,14 +987,18 @@ msgstr "Connecter"
msgid "Connect to the LDAP Server on port 389:"
msgstr ""
#: src/user/user-settings/sources/SourceSettings.ts
msgid "Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials."
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "Connected services"
msgstr "Services connectés"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connected."
msgstr "Connecté."
#~ msgid "Connected."
#~ msgstr "Connecté."
#: src/common/ws.ts
msgid "Connection error, reconnecting..."
@ -3117,8 +3121,8 @@ msgstr "Action non configurée"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Not connected."
msgstr "Déconnecté."
#~ msgid "Not connected."
#~ msgstr "Déconnecté."
#: src/elements/router/Router404.ts
msgid "Not found"
@ -4292,8 +4296,8 @@ msgstr "Source liée"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Source {0}"
msgstr "Source {0}"
#~ msgid "Source {0}"
#~ msgstr "Source {0}"
#: src/pages/sources/SourcesListPage.ts
msgid "Source(s)"

View File

@ -982,14 +982,18 @@ msgstr ""
msgid "Connect to the LDAP Server on port 389:"
msgstr ""
#: src/user/user-settings/sources/SourceSettings.ts
msgid "Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials."
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "Connected services"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connected."
msgstr ""
#~ msgid "Connected."
#~ msgstr ""
#: src/common/ws.ts
msgid "Connection error, reconnecting..."
@ -3128,8 +3132,8 @@ msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Not connected."
msgstr ""
#~ msgid "Not connected."
#~ msgstr ""
#: src/elements/router/Router404.ts
msgid "Not found"
@ -4319,8 +4323,8 @@ msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Source {0}"
msgstr ""
#~ msgid "Source {0}"
#~ msgstr ""
#: src/pages/sources/SourcesListPage.ts
msgid "Source(s)"

View File

@ -978,14 +978,18 @@ msgstr "Bağlan"
msgid "Connect to the LDAP Server on port 389:"
msgstr "Bağlantı noktası 389 LDAP sunucusuna bağlanın:"
#: src/user/user-settings/sources/SourceSettings.ts
msgid "Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials."
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "Connected services"
msgstr "Bağlı hizmetler"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connected."
msgstr "Bağlantılı."
#~ msgid "Connected."
#~ msgstr "Bağlantılı."
#: src/common/ws.ts
msgid "Connection error, reconnecting..."
@ -3091,8 +3095,8 @@ msgstr "Yapılandırılmış eylem"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Not connected."
msgstr "Bağlantılı değil."
#~ msgid "Not connected."
#~ msgstr "Bağlantılı değil."
#: src/elements/router/Router404.ts
msgid "Not found"
@ -4253,8 +4257,8 @@ msgstr "Kaynak bağlantılı"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Source {0}"
msgstr "Kaynak {0}"
#~ msgid "Source {0}"
#~ msgstr "Kaynak {0}"
#: src/pages/sources/SourcesListPage.ts
msgid "Source(s)"

View File

@ -3,7 +3,6 @@ import { property } from "lit/decorators.js";
import AKGlobal from "../../authentik.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
@ -16,6 +15,6 @@ export abstract class BaseUserSettings extends LitElement {
configureUrl?: string;
static get styles(): CSSResult[] {
return [PFBase, PFCard, PFButton, PFForm, PFFormControl, AKGlobal];
return [PFBase, PFButton, PFForm, PFFormControl, AKGlobal];
}
}

View File

@ -1,10 +1,12 @@
import { t } from "@lingui/macro";
import { CSSResult, LitElement, TemplateResult, html } from "lit";
import { CSSResult, LitElement, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import AKGlobal from "../../../authentik.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css";
import { SourcesApi, UserSetting } from "@goauthentik/api";
@ -20,7 +22,27 @@ export class UserSourceSettingsPage extends LitElement {
sourceSettings?: Promise<UserSetting[]>;
static get styles(): CSSResult[] {
return [PFGrid];
return [
PFDataList,
PFContent,
AKGlobal,
css`
.pf-c-data-list__cell {
display: flex;
align-items: center;
}
.pf-c-data-list__cell img {
max-width: 48px;
width: 48px;
margin-right: 16px;
}
@media (prefers-color-scheme: dark) {
.pf-c-data-list__cell img {
filter: invert(1);
}
}
`,
];
}
constructor() {
@ -38,6 +60,7 @@ export class UserSourceSettingsPage extends LitElement {
switch (source.component) {
case "ak-user-settings-source-oauth":
return html`<ak-user-settings-source-oauth
class="pf-c-data-list__item-row"
objectId=${source.objectUid}
title=${source.title}
.configureUrl=${source.configureUrl}
@ -45,6 +68,7 @@ export class UserSourceSettingsPage extends LitElement {
</ak-user-settings-source-oauth>`;
case "ak-user-settings-source-plex":
return html`<ak-user-settings-source-plex
class="pf-c-data-list__item-row"
objectId=${source.objectUid}
title=${source.title}
.configureUrl=${source.configureUrl}
@ -56,22 +80,36 @@ export class UserSourceSettingsPage extends LitElement {
}
render(): TemplateResult {
return html`<div class="pf-l-grid pf-m-gutter">
${until(
this.sourceSettings?.then((source) => {
if (source.length < 1) {
return html`<ak-empty-state
header=${t`No services available.`}
></ak-empty-state>`;
}
return source.map((stage) => {
return html`<div class="pf-l-grid__item pf-m-6-col pf-m-4-col-on-xl">
${this.renderSourceSettings(stage)}
</div>`;
});
}),
html`<ak-empty-state ?loading="${true}" header=${t`Loading`}> </ak-empty-state>`,
)}
</div>`;
return html` <div class="pf-c-content">
<p>
${t`Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials.`}
</p>
</div>
<ul class="pf-c-data-list" role="list">
${until(
this.sourceSettings?.then((source) => {
if (source.length < 1) {
return html`<ak-empty-state
header=${t`No services available.`}
></ak-empty-state>`;
}
return source.map((stage) => {
return html`<li class="pf-c-data-list__item">
<div class="pf-c-data-list__item-content">
<div class="pf-c-data-list__cell">
<img src="${stage.iconUrl}" />
${stage.title}
</div>
<div class="pf-c-data-list__cell">
${this.renderSourceSettings(stage)}
</div>
</div>
</li>`;
});
}),
html`<ak-empty-state ?loading="${true}" header=${t`Loading`}>
</ak-empty-state>`,
)}
</ul>`;
}
}

View File

@ -16,13 +16,6 @@ export class SourceSettingsOAuth extends BaseUserSettings {
title!: string;
render(): TemplateResult {
return html`<div class="pf-c-card">
<div class="pf-c-card__title">${t`Source ${this.title}`}</div>
<div class="pf-c-card__body">${this.renderInner()}</div>
</div>`;
}
renderInner(): TemplateResult {
return html`${until(
new SourcesApi(DEFAULT_CONFIG)
.sourcesUserConnectionsOauthList({
@ -30,29 +23,27 @@ export class SourceSettingsOAuth extends BaseUserSettings {
})
.then((connection) => {
if (connection.results.length > 0) {
return html`<p>${t`Connected.`}</p>
<button
class="pf-c-button pf-m-danger"
@click=${() => {
return new SourcesApi(
DEFAULT_CONFIG,
).sourcesUserConnectionsOauthDestroy({
id: connection.results[0].pk || 0,
});
}}
>
${t`Disconnect`}
</button>`;
}
return html`<p>${t`Not connected.`}</p>
<a
class="pf-c-button pf-m-primary"
href="${ifDefined(this.configureUrl)}${AndNext(
"/if/user/#/settings;page-sources",
)}"
return html` <button
class="pf-c-button pf-m-danger"
@click=${() => {
return new SourcesApi(
DEFAULT_CONFIG,
).sourcesUserConnectionsOauthDestroy({
id: connection.results[0].pk || 0,
});
}}
>
${t`Connect`}
</a>`;
${t`Disconnect`}
</button>`;
}
return html` <a
class="pf-c-button pf-m-primary"
href="${ifDefined(this.configureUrl)}${AndNext(
"/if/user/#/settings;page-sources",
)}"
>
${t`Connect`}
</a>`;
}),
)}`;
}

View File

@ -16,13 +16,6 @@ export class SourceSettingsPlex extends BaseUserSettings {
@property()
title!: string;
render(): TemplateResult {
return html`<div class="pf-c-card">
<div class="pf-c-card__title">${t`Source ${this.title}`}</div>
<div class="pf-c-card__body">${this.renderInner()}</div>
</div>`;
}
async doPlex(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.configureUrl || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
@ -43,7 +36,7 @@ export class SourceSettingsPlex extends BaseUserSettings {
);
}
renderInner(): TemplateResult {
render(): TemplateResult {
return html`${until(
new SourcesApi(DEFAULT_CONFIG)
.sourcesUserConnectionsPlexList({
@ -51,24 +44,22 @@ export class SourceSettingsPlex extends BaseUserSettings {
})
.then((connection) => {
if (connection.results.length > 0) {
return html`<p>${t`Connected.`}</p>
<button
class="pf-c-button pf-m-danger"
@click=${() => {
return new SourcesApi(
DEFAULT_CONFIG,
).sourcesUserConnectionsPlexDestroy({
id: connection.results[0].pk || 0,
});
}}
>
${t`Disconnect`}
</button>`;
}
return html`<p>${t`Not connected.`}</p>
<button @click=${this.doPlex} class="pf-c-button pf-m-primary">
${t`Connect`}
return html` <button
class="pf-c-button pf-m-danger"
@click=${() => {
return new SourcesApi(
DEFAULT_CONFIG,
).sourcesUserConnectionsPlexDestroy({
id: connection.results[0].pk || 0,
});
}}
>
${t`Disconnect`}
</button>`;
}
return html` <button @click=${this.doPlex} class="pf-c-button pf-m-primary">
${t`Connect`}
</button>`;
}),
)}`;
}