mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-02 00:27:49 +01:00
Update apps filtering and styles to show stage and remove advanced mode filters (#30165)
* Remove filter for unstable app stages * Show stage in app store repository view * Increase size of cards to accomadate badges * Add stage to installed apps, update style * Make "Search" consistent, "Search apps" not needed in this context * Remove show advanced mode logic for app visibility * Add margin to .addition * Remove [deprecated] from app page title also * Use common helper
This commit is contained in:
@@ -76,6 +76,7 @@ import { mdiHomeAssistant } from "../../../../../resources/home-assistant-logo-s
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import { bytesToString } from "../../../../../util/bytes-to-string";
|
||||
import { getAppDisplayName } from "../../common/app";
|
||||
import "../../components/supervisor-apps-card-content";
|
||||
import "../components/supervisor-app-metric";
|
||||
import { extractChangelog } from "../util/supervisor-app";
|
||||
@@ -197,7 +198,9 @@ class SupervisorAppInfo extends LitElement {
|
||||
<ha-card outlined>
|
||||
<div class="card-content">
|
||||
<div class="addon-header">
|
||||
${!this.narrow ? this.addon.name : nothing}
|
||||
${!this.narrow
|
||||
? getAppDisplayName(this.addon.name, this.addon.stage)
|
||||
: nothing}
|
||||
<div class="addon-version light-color">
|
||||
${this.addon.version
|
||||
? html`
|
||||
@@ -490,7 +493,7 @@ class SupervisorAppInfo extends LitElement {
|
||||
href=${this.addon.url!}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${this.addon.name}</a
|
||||
>${getAppDisplayName(this.addon.name, this.addon.stage)}</a
|
||||
>`,
|
||||
}
|
||||
)}
|
||||
@@ -1223,7 +1226,7 @@ class SupervisorAppInfo extends LitElement {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.apps.dashboard.uninstall_dialog.title",
|
||||
{
|
||||
name: this.addon.name,
|
||||
name: getAppDisplayName(this.addon.name, this.addon.stage),
|
||||
}
|
||||
),
|
||||
text: html`
|
||||
|
||||
4
src/panels/config/apps/common/app.ts
Normal file
4
src/panels/config/apps/common/app.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { AddonStage } from "../../../../data/hassio/addon";
|
||||
|
||||
export const getAppDisplayName = (name: string, stage: AddonStage): string =>
|
||||
stage === "deprecated" ? name.replace(/\s*\[deprecated\]\s*$/i, "") : name;
|
||||
@@ -1,9 +1,11 @@
|
||||
import { mdiHelpCircleOutline } from "@mdi/js";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import type { AddonStage } from "../../../../data/hassio/addon";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { getAppDisplayName } from "../common/app";
|
||||
|
||||
@customElement("supervisor-apps-card-content")
|
||||
class SupervisorAppsCardContent extends LitElement {
|
||||
@@ -12,6 +14,8 @@ class SupervisorAppsCardContent extends LitElement {
|
||||
// eslint-disable-next-line lit/no-native-attributes
|
||||
@property() public title!: string;
|
||||
|
||||
@property() public stage: AddonStage = "stable";
|
||||
|
||||
@property() public description?: string;
|
||||
|
||||
@property({ type: Boolean }) public available = true;
|
||||
@@ -29,6 +33,13 @@ class SupervisorAppsCardContent extends LitElement {
|
||||
@property({ attribute: false }) public iconImage?: string;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const stageLabel =
|
||||
this.stage !== "stable"
|
||||
? this.hass.localize(
|
||||
`ui.panel.config.apps.dashboard.capability.stages.${this.stage}`
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return html`
|
||||
${this.showTopbar
|
||||
? html` <div class="topbar ${this.topbarClass}"></div> `
|
||||
@@ -52,7 +63,12 @@ class SupervisorAppsCardContent extends LitElement {
|
||||
></ha-svg-icon>
|
||||
`}
|
||||
<div>
|
||||
<div class="title">${this.title}</div>
|
||||
<div class="title-row">
|
||||
<div class="title">${getAppDisplayName(this.title, this.stage)}</div>
|
||||
${stageLabel
|
||||
? html` <span class="stage ${this.stage}"> ${stageLabel} </span> `
|
||||
: nothing}
|
||||
</div>
|
||||
<div class="addition">
|
||||
${this.description}
|
||||
${
|
||||
@@ -91,13 +107,38 @@ class SupervisorAppsCardContent extends LitElement {
|
||||
color: var(--error-color);
|
||||
}
|
||||
.title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: var(--primary-text-color);
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--ha-space-2);
|
||||
min-width: 0;
|
||||
}
|
||||
.stage {
|
||||
flex: none;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.stage.experimental {
|
||||
color: var(--warning-color);
|
||||
background-color: rgba(var(--rgb-warning-color), 0.12);
|
||||
}
|
||||
.stage.deprecated {
|
||||
color: var(--error-color);
|
||||
background-color: rgba(var(--rgb-error-color), 0.12);
|
||||
}
|
||||
.addition {
|
||||
color: var(--secondary-text-color);
|
||||
margin-top: var(--ha-space-1);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
height: 2.4em;
|
||||
|
||||
@@ -154,17 +154,6 @@ export class HaConfigAppsAvailable extends LitElement {
|
||||
|
||||
${repos}
|
||||
`}
|
||||
${!this.hass.userData?.showAdvanced
|
||||
? html`
|
||||
<div class="advanced">
|
||||
<a href="/profile" target="_top">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.apps.store.missing_apps"
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
</hass-subpage>
|
||||
`;
|
||||
}
|
||||
@@ -296,18 +285,6 @@ export class HaConfigAppsAvailable extends LitElement {
|
||||
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||
}
|
||||
.advanced {
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.advanced a {
|
||||
margin-left: 0.5em;
|
||||
margin-inline-start: 0.5em;
|
||||
margin-inline-end: initial;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import "../../../layouts/hass-loading-screen";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import "./components/supervisor-apps-card-content";
|
||||
import { supervisorAppsStyle } from "./resources/supervisor-apps-style";
|
||||
|
||||
@customElement("ha-config-apps-installed")
|
||||
export class HaConfigAppsInstalled extends LitElement {
|
||||
@@ -92,9 +93,6 @@ export class HaConfigAppsInstalled extends LitElement {
|
||||
suffix
|
||||
.filter=${this._filter}
|
||||
@value-changed=${this._handleSearchChange}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.apps.installed.search"
|
||||
)}
|
||||
>
|
||||
</search-input>
|
||||
</div>
|
||||
@@ -123,6 +121,7 @@ export class HaConfigAppsInstalled extends LitElement {
|
||||
<supervisor-apps-card-content
|
||||
.hass=${this.hass}
|
||||
.title=${addon.name}
|
||||
.stage=${addon.stage}
|
||||
.description=${addon.description}
|
||||
available
|
||||
.showTopbar=${addon.update_available}
|
||||
@@ -225,66 +224,65 @@ export class HaConfigAppsInstalled extends LitElement {
|
||||
navigate("/config/apps/available");
|
||||
}
|
||||
|
||||
static styles: CSSResultGroup = css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background-color: var(--primary-background-color);
|
||||
}
|
||||
static styles: CSSResultGroup = [
|
||||
supervisorAppsStyle,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background-color: var(--primary-background-color);
|
||||
}
|
||||
|
||||
ha-card {
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
direction: ltr;
|
||||
}
|
||||
ha-card {
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.search {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
.search {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
search-input {
|
||||
display: block;
|
||||
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||
}
|
||||
search-input {
|
||||
display: block;
|
||||
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: var(--ha-space-4);
|
||||
margin-bottom: var(--ha-space-18);
|
||||
}
|
||||
.content {
|
||||
padding: var(--ha-space-4);
|
||||
margin-bottom: var(--ha-space-18);
|
||||
}
|
||||
|
||||
.card-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
grid-gap: var(--ha-space-2);
|
||||
}
|
||||
.card-content {
|
||||
padding: var(--ha-space-4);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: var(--ha-space-4);
|
||||
}
|
||||
button.link {
|
||||
color: var(--primary-color);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button.link {
|
||||
color: var(--primary-color);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ha-fab {
|
||||
position: fixed;
|
||||
right: calc(var(--ha-space-4) + var(--safe-area-inset-right));
|
||||
bottom: calc(var(--ha-space-4) + var(--safe-area-inset-bottom));
|
||||
inset-inline-end: calc(var(--ha-space-4) + var(--safe-area-inset-right));
|
||||
inset-inline-start: initial;
|
||||
z-index: 1;
|
||||
}
|
||||
`;
|
||||
ha-fab {
|
||||
position: fixed;
|
||||
right: calc(var(--ha-space-4) + var(--safe-area-inset-right));
|
||||
bottom: calc(var(--ha-space-4) + var(--safe-area-inset-bottom));
|
||||
inset-inline-end: calc(
|
||||
var(--ha-space-4) + var(--safe-area-inset-right)
|
||||
);
|
||||
inset-inline-start: initial;
|
||||
z-index: 1;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -11,8 +11,6 @@ class HaConfigApps extends HassRouterPage {
|
||||
|
||||
@property({ attribute: "is-wide", type: Boolean }) public isWide = false;
|
||||
|
||||
@property({ attribute: false }) public showAdvanced = false;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
@@ -41,7 +39,6 @@ class HaConfigApps extends HassRouterPage {
|
||||
pageEl.hass = this.hass;
|
||||
pageEl.narrow = this.narrow;
|
||||
pageEl.isWide = this.isWide;
|
||||
pageEl.showAdvanced = this.showAdvanced;
|
||||
pageEl.route = this.routeTail;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,22 +30,22 @@ export const supervisorAppsStyle = css`
|
||||
}
|
||||
.card-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
|
||||
grid-gap: var(--ha-space-2);
|
||||
}
|
||||
@media screen and (min-width: 640px) {
|
||||
.card-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 0.5fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(340px, 0.5fr));
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1020px) {
|
||||
.card-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 0.333fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(340px, 0.333fr));
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1300px) {
|
||||
.card-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 0.25fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(340px, 0.25fr));
|
||||
}
|
||||
}
|
||||
.error {
|
||||
|
||||
@@ -34,13 +34,7 @@ export class SupervisorAppsRepositoryEl extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const repo = this.repo;
|
||||
let _addons = this.addons;
|
||||
if (!this.hass.userData?.showAdvanced) {
|
||||
_addons = _addons.filter(
|
||||
(addon) => !addon.advanced && addon.stage === "stable"
|
||||
);
|
||||
}
|
||||
const addons = this._getAddons(_addons, this.filter);
|
||||
const addons = this._getAddons(this.addons, this.filter);
|
||||
|
||||
if (this.filter && addons.length < 1) {
|
||||
return html`
|
||||
@@ -72,6 +66,7 @@ export class SupervisorAppsRepositoryEl extends LitElement {
|
||||
<supervisor-apps-card-content
|
||||
.hass=${this.hass}
|
||||
.title=${addon.name}
|
||||
.stage=${addon.stage}
|
||||
.description=${addon.description}
|
||||
.available=${addon.available}
|
||||
.icon=${addon.installed && addon.update_available
|
||||
|
||||
@@ -2598,7 +2598,6 @@
|
||||
"check_updates": "Check for updates",
|
||||
"repositories": "Repositories",
|
||||
"registries": "Registries",
|
||||
"missing_apps": "Looking for apps? Enable advanced mode.",
|
||||
"no_results_found": "No results found in {repository}"
|
||||
},
|
||||
"repositories": {
|
||||
|
||||
Reference in New Issue
Block a user