web: app icons v2 (#6410)
* fix more icons stuff Signed-off-by: Jens Langhammer <jens@goauthentik.io> * refactor app icon into separate component Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update locale Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make app icon work correctly in admin list and app view page Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import "@goauthentik/admin/applications/ApplicationForm";
|
||||
import "@goauthentik/admin/applications/wizard/ApplicationWizard";
|
||||
import { PFSize } from "@goauthentik/app/elements/Spinner";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { uiConfig } from "@goauthentik/common/ui/config";
|
||||
import MDApplication from "@goauthentik/docs/core/applications.md";
|
||||
@ -11,13 +12,12 @@ import { getURLParam } from "@goauthentik/elements/router/RouteMatch";
|
||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@goauthentik/user/LibraryApplication/AppIcon";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
|
||||
import { Application, CoreApi } from "@goauthentik/api";
|
||||
@ -56,13 +56,8 @@ export class ApplicationListPage extends TablePage<Application> {
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(
|
||||
PFAvatar,
|
||||
PFCard,
|
||||
css`
|
||||
:host {
|
||||
--icon-height: 2rem;
|
||||
--icon-border: 0.25rem;
|
||||
}
|
||||
/* Fix alignment issues with images in tables */
|
||||
.pf-c-table tbody > tr > * {
|
||||
vertical-align: middle;
|
||||
@ -76,14 +71,6 @@ export class ApplicationListPage extends TablePage<Application> {
|
||||
.pf-c-sidebar.pf-m-gutter > .pf-c-sidebar__main > * + * {
|
||||
margin-left: calc(var(--pf-c-sidebar__main--child--MarginLeft) / 2);
|
||||
}
|
||||
.icon {
|
||||
font-size: var(--icon-height);
|
||||
color: var(--ak-global--Color--100);
|
||||
padding: var(--icon-border);
|
||||
max-height: calc(var(--icon-height) + var(--icon-border) + var(--icon-border));
|
||||
line-height: calc(var(--icon-height) + var(--icon-border) + var(--icon-border));
|
||||
filter: drop-shadow(5px 5px 5px rgba(128, 128, 128, 0.25));
|
||||
}
|
||||
`,
|
||||
);
|
||||
}
|
||||
@ -137,24 +124,9 @@ export class ApplicationListPage extends TablePage<Application> {
|
||||
</ak-forms-delete-bulk>`;
|
||||
}
|
||||
|
||||
renderIcon(item: Application): TemplateResult {
|
||||
if (item?.metaIcon) {
|
||||
if (item.metaIcon.startsWith("fa://")) {
|
||||
const icon = item.metaIcon.replaceAll("fa://", "");
|
||||
return html`<i class="icon fas ${icon}"></i>`;
|
||||
}
|
||||
return html`<img
|
||||
class="icon pf-c-avatar"
|
||||
src="${ifDefined(item.metaIcon)}"
|
||||
alt="${msg("Application Icon")}"
|
||||
/>`;
|
||||
}
|
||||
return html`<span class="icon">${item?.name.charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
row(item: Application): TemplateResult[] {
|
||||
return [
|
||||
this.renderIcon(item),
|
||||
html`<ak-app-icon size=${PFSize.Medium} .app=${item}></ak-app-icon>`,
|
||||
html`<a href="#/core/applications/${item.slug}">
|
||||
<div>${item.name}</div>
|
||||
${item.metaPublisher ? html`<small>${item.metaPublisher}</small>` : html``}
|
||||
|
@ -2,6 +2,7 @@ import "@goauthentik/admin/applications/ApplicationAuthorizeChart";
|
||||
import "@goauthentik/admin/applications/ApplicationCheckAccessForm";
|
||||
import "@goauthentik/admin/applications/ApplicationForm";
|
||||
import "@goauthentik/admin/policies/BoundPoliciesList";
|
||||
import { PFSize } from "@goauthentik/app/elements/Spinner";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
@ -9,6 +10,7 @@ import "@goauthentik/elements/PageHeader";
|
||||
import "@goauthentik/elements/Tabs";
|
||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||
import "@goauthentik/elements/events/ObjectChangelog";
|
||||
import "@goauthentik/user/LibraryApplication/AppIcon";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
@ -80,11 +82,15 @@ export class ApplicationViewPage extends AKElement {
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<ak-page-header
|
||||
icon=${this.application?.metaIcon || ""}
|
||||
header=${this.application?.name || msg("Loading")}
|
||||
description=${ifDefined(this.application?.metaPublisher)}
|
||||
.iconImage=${true}
|
||||
>
|
||||
<ak-app-icon
|
||||
size=${PFSize.Small}
|
||||
slot="icon"
|
||||
.app=${this.application}
|
||||
></ak-app-icon>
|
||||
</ak-page-header>
|
||||
${this.renderApp()}`;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import PFExpandableSection from "@patternfly/patternfly/components/ExpandableSection/expandable-section.css";
|
||||
@ -19,7 +19,15 @@ export class Expand extends AKElement {
|
||||
textClosed = msg("Show more");
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFBase, PFExpandableSection];
|
||||
return [
|
||||
PFBase,
|
||||
PFExpandableSection,
|
||||
css`
|
||||
.pf-c-expandable-section.pf-m-display-lg {
|
||||
background-color: var(--pf-global--BackgroundColor--100);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
|
@ -91,6 +91,11 @@ export class PageHeader extends AKElement {
|
||||
.notification-trigger.has-notifications {
|
||||
color: var(--pf-global--active-color--100);
|
||||
}
|
||||
h1 {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center !important;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
@ -120,10 +125,10 @@ export class PageHeader extends AKElement {
|
||||
renderIcon(): TemplateResult {
|
||||
if (this.icon) {
|
||||
if (this.iconImage && !this.icon.startsWith("fa://")) {
|
||||
return html`<img class="pf-icon" src="${this.icon}" alt="page icon" /> `;
|
||||
return html`<img class="pf-icon" src="${this.icon}" alt="page icon" />`;
|
||||
}
|
||||
const icon = this.icon.replaceAll("fa://", "fa ");
|
||||
return html`<i class=${icon}></i> `;
|
||||
return html`<i class=${icon}></i>`;
|
||||
}
|
||||
return html``;
|
||||
}
|
||||
@ -147,8 +152,8 @@ export class PageHeader extends AKElement {
|
||||
<section class="pf-c-page__main-section pf-m-light">
|
||||
<div class="pf-c-content">
|
||||
<h1>
|
||||
${this.renderIcon()}
|
||||
<slot name="header"> ${this.header} </slot>
|
||||
<slot name="icon">${this.renderIcon()}</slot>
|
||||
<slot name="header">${this.header}</slot>
|
||||
</h1>
|
||||
${this.description ? html`<p>${this.description}</p>` : html``}
|
||||
</div>
|
||||
|
80
web/src/user/LibraryApplication/AppIcon.ts
Normal file
80
web/src/user/LibraryApplication/AppIcon.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import { AKElement } from "@goauthentik/app/elements/Base";
|
||||
import { PFSize } from "@goauthentik/app/elements/Spinner";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import PFFAIcons from "@patternfly/patternfly/base/patternfly-fa-icons.css";
|
||||
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
|
||||
|
||||
import { Application } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-app-icon")
|
||||
export class AppIcon extends AKElement {
|
||||
@property({ attribute: false })
|
||||
app?: Application;
|
||||
|
||||
@property()
|
||||
size: PFSize = PFSize.Large;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
PFFAIcons,
|
||||
PFAvatar,
|
||||
css`
|
||||
:host([size="pf-m-lg"]) {
|
||||
--icon-height: 4rem;
|
||||
--icon-border: 0.25rem;
|
||||
}
|
||||
:host([size="pf-m-md"]) {
|
||||
--icon-height: 2rem;
|
||||
--icon-border: 0.125rem;
|
||||
}
|
||||
:host([size="pf-m-sm"]) {
|
||||
--icon-height: 1rem;
|
||||
--icon-border: 0.125rem;
|
||||
}
|
||||
.pf-c-avatar {
|
||||
--pf-c-avatar--BorderRadius: 0;
|
||||
--pf-c-avatar--Height: calc(
|
||||
var(--icon-height) + var(--icon-border) + var(--icon-border)
|
||||
);
|
||||
--pf-c-avatar--Width: calc(
|
||||
var(--icon-height) + var(--icon-border) + var(--icon-border)
|
||||
);
|
||||
}
|
||||
.icon {
|
||||
font-size: var(--icon-height);
|
||||
color: var(--ak-global--Color--100);
|
||||
padding: var(--icon-border);
|
||||
max-height: calc(var(--icon-height) + var(--icon-border) + var(--icon-border));
|
||||
line-height: calc(var(--icon-height) + var(--icon-border) + var(--icon-border));
|
||||
filter: drop-shadow(5px 5px 5px rgba(128, 128, 128, 0.25));
|
||||
}
|
||||
div {
|
||||
height: calc(var(--icon-height) + var(--icon-border) + var(--icon-border));
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.app) {
|
||||
return html`<div><i class="icon fas fa-question-circle"></i></div>`;
|
||||
}
|
||||
if (this.app?.metaIcon) {
|
||||
if (this.app.metaIcon.startsWith("fa://")) {
|
||||
const icon = this.app.metaIcon.replaceAll("fa://", "");
|
||||
return html`<div><i class="icon fas ${icon}"></i></div>`;
|
||||
}
|
||||
return html`<img
|
||||
class="icon pf-c-avatar"
|
||||
src="${ifDefined(this.app.metaIcon)}"
|
||||
alt="${msg("Application Icon")}"
|
||||
/>`;
|
||||
}
|
||||
return html`<span class="icon">${this.app?.name.charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { truncateWords } from "@goauthentik/common/utils";
|
||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||
import "@goauthentik/elements/Expand";
|
||||
import "@goauthentik/user/LibraryApplication/AppIcon";
|
||||
import { UserInterface } from "@goauthentik/user/UserInterface";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@ -8,7 +9,6 @@ import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
@ -31,24 +31,10 @@ export class LibraryApplication extends AKElement {
|
||||
PFBase,
|
||||
PFCard,
|
||||
PFButton,
|
||||
PFAvatar,
|
||||
css`
|
||||
:host {
|
||||
--icon-height: 4rem;
|
||||
--icon-border: 0.25rem;
|
||||
}
|
||||
.pf-c-card {
|
||||
--pf-c-card--BoxShadow: var(--pf-global--BoxShadow--md);
|
||||
}
|
||||
.pf-c-avatar {
|
||||
--pf-c-avatar--BorderRadius: 0;
|
||||
--pf-c-avatar--Height: calc(
|
||||
var(--icon-height) + var(--icon-border) + var(--icon-border)
|
||||
);
|
||||
--pf-c-avatar--Width: calc(
|
||||
var(--icon-height) + var(--icon-border) + var(--icon-border)
|
||||
);
|
||||
}
|
||||
.pf-c-card__header {
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
@ -58,13 +44,8 @@ export class LibraryApplication extends AKElement {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.icon {
|
||||
font-size: var(--icon-height);
|
||||
color: var(--ak-global--Color--100);
|
||||
padding: var(--icon-border);
|
||||
max-height: calc(var(--icon-height) + var(--icon-border) + var(--icon-border));
|
||||
line-height: calc(var(--icon-height) + var(--icon-border) + var(--icon-border));
|
||||
filter: drop-shadow(5px 5px 5px rgba(128, 128, 128, 0.25));
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
.expander {
|
||||
flex-grow: 1;
|
||||
@ -80,21 +61,6 @@ export class LibraryApplication extends AKElement {
|
||||
];
|
||||
}
|
||||
|
||||
renderIcon(): TemplateResult {
|
||||
if (this.application?.metaIcon) {
|
||||
if (this.application.metaIcon.startsWith("fa://")) {
|
||||
const icon = this.application.metaIcon.replaceAll("fa://", "");
|
||||
return html`<i class="icon fas ${icon}"></i>`;
|
||||
}
|
||||
return html`<img
|
||||
class="icon pf-c-avatar"
|
||||
src="${ifDefined(this.application.metaIcon)}"
|
||||
alt="${msg("Application Icon")}"
|
||||
/>`;
|
||||
}
|
||||
return html`<span class="icon">${this.application?.name.charAt(0).toUpperCase()}</span>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.application) {
|
||||
return html`<ak-spinner></ak-spinner>`;
|
||||
@ -111,7 +77,7 @@ export class LibraryApplication extends AKElement {
|
||||
href="${ifDefined(this.application.launchUrl ?? "")}"
|
||||
target="${ifDefined(this.application.openInNewTab ? "_blank" : undefined)}"
|
||||
>
|
||||
${this.renderIcon()}
|
||||
<ak-app-icon .app=${this.application}></ak-app-icon>
|
||||
</a>
|
||||
</div>
|
||||
<div class="pf-c-card__title">
|
Reference in New Issue
Block a user