291 files
This commit is contained in:
+89
-56
@@ -11,6 +11,12 @@
|
||||
* under another name starts unticked with that task's name; a summary says
|
||||
* per object how many tasks it has before and after. Typing another object
|
||||
* asks the server again (problem_sensors/preview).
|
||||
*
|
||||
* #211 (54 problem sensors of 18 devices, on a phone): the summary grew a
|
||||
* line per object and squeezed the list, the only part that could shrink,
|
||||
* to nothing. The dialog now sits in the shared modal frame: the title and
|
||||
* the buttons stay, everything between them scrolls as one, and the summary
|
||||
* folds to its totals once it names more than three objects.
|
||||
*/
|
||||
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
@@ -18,6 +24,7 @@ import { property, state } from "lit/decorators.js";
|
||||
|
||||
import { t, ensureLocale, langOf } from "../styles";
|
||||
import { runWs } from "../helpers/ws-run";
|
||||
import { focusModalShell, modalShellStyles, renderModalShell } from "../helpers/modal-shell";
|
||||
import { TRIGGER_FOR_MINUTES_RANGE } from "../helpers/setting-ranges";
|
||||
import { UserService } from "../user-service";
|
||||
import type { HAUser, HomeAssistant } from "../types";
|
||||
@@ -52,6 +59,16 @@ interface AdoptResponse {
|
||||
errors?: string[];
|
||||
}
|
||||
|
||||
/** One object of the summary: the tasks it gains (entry null = a new object). */
|
||||
interface SummaryGroup {
|
||||
name: string;
|
||||
entry: string | null;
|
||||
adding: number;
|
||||
}
|
||||
|
||||
/** Up to this many objects the summary opens with its lines shown. */
|
||||
const SUMMARY_LINES_OPEN = 3;
|
||||
|
||||
export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -74,6 +91,9 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
// #136: minutes the problem must persist before the created task triggers
|
||||
// (one field applied to every selection). "0" = react to the first flicker.
|
||||
@state() private _forMinutes = "0";
|
||||
/** #211: the summary's lines shown; decided when the list arrives (folded
|
||||
* beyond three objects), then the user's. */
|
||||
@state() private _summaryOpen = true;
|
||||
|
||||
private _localeReady = false;
|
||||
private _userService: UserService | null = null;
|
||||
@@ -87,6 +107,7 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
this._localeReady = true;
|
||||
ensureLocale(this._lang).then(() => this.requestUpdate());
|
||||
}
|
||||
if (changed.has("_open") && this._open) focusModalShell(this.shadowRoot);
|
||||
}
|
||||
|
||||
public async open(): Promise<void> {
|
||||
@@ -125,6 +146,7 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
// What the target probably already watches starts unticked.
|
||||
this._selected = new Set(this._sensors.filter((s) => !s.covered_by).map((s) => s.entity_id));
|
||||
this._users = users;
|
||||
this._summaryOpen = this._summaryGroups().length <= SUMMARY_LINES_OPEN;
|
||||
}
|
||||
|
||||
/** The default object: the one linked to the device, else the one the
|
||||
@@ -169,9 +191,9 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
if (resp?.covered) this._covered = { ...this._covered, ...resp.covered };
|
||||
}
|
||||
|
||||
/** Per target object: tasks before → after (only ticked rows count). */
|
||||
private _summary(L: string) {
|
||||
const groups = new Map<string, { name: string; entry: string | null; adding: number }>();
|
||||
/** The objects the ticked rows go to, each with the tasks it gains. */
|
||||
private _summaryGroups(): SummaryGroup[] {
|
||||
const groups = new Map<string, SummaryGroup>();
|
||||
for (const s of this._sensors) {
|
||||
if (!this._selected.has(s.entity_id)) continue;
|
||||
const entry = this._existingEntryFor(s);
|
||||
@@ -181,11 +203,30 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
g.adding += 1;
|
||||
groups.set(key, g);
|
||||
}
|
||||
if (groups.size === 0) return nothing;
|
||||
return [...groups.values()];
|
||||
}
|
||||
|
||||
/** Per target object: tasks before → after (only ticked rows count), under
|
||||
* a line with the totals that stays when the lines are folded (#211). */
|
||||
private _summary(L: string) {
|
||||
const groups = this._summaryGroups();
|
||||
if (groups.length === 0) return nothing;
|
||||
const created = groups.filter((g) => !g.entry).length;
|
||||
const totals = t(created ? "adopt_summary_totals_new" : "adopt_summary_totals", L)
|
||||
.replace("{tasks}", String(groups.reduce((n, g) => n + g.adding, 0)))
|
||||
.replace("{objects}", String(groups.length))
|
||||
.replace("{new}", String(created));
|
||||
return html`
|
||||
<div class="summary">
|
||||
<div class="summary-title">${t("adopt_summary_title", L)}</div>
|
||||
${[...groups.values()].map((g) => {
|
||||
<details
|
||||
class="summary"
|
||||
.open=${this._summaryOpen}
|
||||
@toggle=${(e: Event) => { this._summaryOpen = (e.target as HTMLDetailsElement).open; }}
|
||||
>
|
||||
<summary>
|
||||
<span class="summary-title">${t("adopt_summary_title", L)}</span>
|
||||
<span class="summary-totals">${totals}</span>
|
||||
</summary>
|
||||
${groups.map((g) => {
|
||||
if (!g.entry) {
|
||||
return html`<div class="summary-line new">
|
||||
${t("setups_new_object_count", L).replace("{name}", g.name).replace("{count}", String(g.adding))}
|
||||
@@ -199,7 +240,7 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
.replace("{after}", String(before + g.adding))}
|
||||
</div>`;
|
||||
})}
|
||||
</div>
|
||||
</details>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -269,13 +310,12 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
const allSelected =
|
||||
this._sensors.length > 0 && this._selected.size === this._sensors.length;
|
||||
|
||||
return html`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${(e: Event) => e.stopPropagation()}>
|
||||
<div class="title">${t("adopt_problem_title", L)}</div>
|
||||
<div class="hint">${t("adopt_problem_hint", L)}</div>
|
||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||
return renderModalShell(() => this._close(), html`
|
||||
<div class="title">${t("adopt_problem_title", L)}</div>
|
||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||
|
||||
<div class="dialog-scroll">
|
||||
<div class="hint">${t("adopt_problem_hint", L)}</div>
|
||||
${this._loading
|
||||
? html`<div class="loading">…</div>`
|
||||
: this._sensors.length === 0
|
||||
@@ -392,47 +432,28 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
</label>
|
||||
`
|
||||
: nothing}
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${t("cancel", L)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._adopt}
|
||||
.disabled=${this._selected.size === 0 || this._adopting}
|
||||
>
|
||||
${t("adopt_problem_adopt", L)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${t("cancel", L)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@click=${this._adopt}
|
||||
.disabled=${this._selected.size === 0 || this._adopting}
|
||||
>
|
||||
${t("adopt_problem_adopt", L)}
|
||||
</ha-button>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 560px;
|
||||
width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
static styles = [modalShellStyles, css`
|
||||
:host {
|
||||
--ms-modal-max-width: 560px;
|
||||
--ms-modal-max-height: 90dvh;
|
||||
--ms-modal-gap: 12px;
|
||||
--ms-modal-z: 1000;
|
||||
}
|
||||
.title {
|
||||
font-size: 18px;
|
||||
@@ -452,6 +473,9 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
font-size: 14px;
|
||||
padding: 12px 0;
|
||||
}
|
||||
/* Stays at the top of the scrolling middle: the count while ticking.
|
||||
top: -1px + 1px more padding: on a 3x screen a fractional offset let a
|
||||
line of the text scrolled under it show above it. */
|
||||
.select-all {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -459,6 +483,11 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
cursor: pointer;
|
||||
position: sticky;
|
||||
top: -1px;
|
||||
z-index: 1;
|
||||
padding: 5px 0 4px;
|
||||
background: var(--card-background-color, var(--ha-card-background, #1c1c1c));
|
||||
}
|
||||
.select-all input {
|
||||
cursor: pointer;
|
||||
@@ -467,8 +496,6 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
overflow-y: auto;
|
||||
max-height: 50vh;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
@@ -536,9 +563,15 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
border-top: 1px dashed var(--divider-color);
|
||||
padding-top: 6px;
|
||||
}
|
||||
.summary > summary {
|
||||
cursor: pointer;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.summary-title {
|
||||
font-weight: 500;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.summary-totals {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.summary-line {
|
||||
color: var(--primary-color);
|
||||
@@ -594,7 +627,7 @@ export class MaintenanceAdoptProblemSensorsDialog extends LitElement {
|
||||
gap: 8px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
`;
|
||||
`];
|
||||
}
|
||||
|
||||
if (!customElements.get("maintenance-adopt-problem-sensors-dialog")) {
|
||||
|
||||
+54
-76
@@ -7,6 +7,9 @@
|
||||
*
|
||||
* Uses a native <input> for the name — <ha-textfield> is not registered in the
|
||||
* custom-panel context, so it renders without its field (the documented trap).
|
||||
*
|
||||
* In the shared modal frame (#211): the list of views scrolls, the name
|
||||
* field and the Close button stay.
|
||||
*/
|
||||
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
@@ -14,6 +17,7 @@ import { property, state } from "lit/decorators.js";
|
||||
|
||||
import { t, ensureLocale, langOf } from "../styles";
|
||||
import { runWs } from "../helpers/ws-run";
|
||||
import { focusModalShell, modalShellStyles, renderModalShell } from "../helpers/modal-shell";
|
||||
import type { HomeAssistant, SavedView, SavedViewFilters } from "../types";
|
||||
|
||||
interface ViewsResponse {
|
||||
@@ -41,6 +45,7 @@ export class MaintenanceSavedViewsDialog extends LitElement {
|
||||
this._localeReady = true;
|
||||
ensureLocale(this._lang).then(() => this.requestUpdate());
|
||||
}
|
||||
if (changed.has("_open") && this._open) focusModalShell(this.shadowRoot);
|
||||
}
|
||||
|
||||
public async open(currentFilters: SavedViewFilters, views: SavedView[]): Promise<void> {
|
||||
@@ -90,81 +95,58 @@ export class MaintenanceSavedViewsDialog extends LitElement {
|
||||
render() {
|
||||
if (!this._open) return html``;
|
||||
const L = this._lang;
|
||||
return html`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${(e: Event) => e.stopPropagation()}>
|
||||
<div class="title">${t("views_dialog_title", L)}</div>
|
||||
<div class="hint">${t("views_dialog_hint", L)}</div>
|
||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||
return renderModalShell(() => this._close(), html`
|
||||
<div class="title">${t("views_dialog_title", L)}</div>
|
||||
<div class="hint">${t("views_dialog_hint", L)}</div>
|
||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||
|
||||
<div class="save-row">
|
||||
<input
|
||||
class="name-input"
|
||||
type="text"
|
||||
.value=${this._name}
|
||||
placeholder=${t("views_name_placeholder", L)}
|
||||
maxlength="60"
|
||||
@input=${(e: Event) => (this._name = (e.target as HTMLInputElement).value)}
|
||||
@keydown=${(e: KeyboardEvent) => {
|
||||
if (e.key === "Enter") this._save();
|
||||
}}
|
||||
/>
|
||||
<ha-button @click=${this._save} .disabled=${!this._name.trim() || this._busy}>
|
||||
${t("views_save_current", L)}
|
||||
</ha-button>
|
||||
</div>
|
||||
|
||||
${this._views.length === 0
|
||||
? html`<div class="empty">${t("views_none_yet", L)}</div>`
|
||||
: html`
|
||||
<div class="list">
|
||||
${this._views.map(
|
||||
(v) => html`
|
||||
<div class="row">
|
||||
<span class="row-name">${v.name}</span>
|
||||
<ha-icon-button
|
||||
.path=${"M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"}
|
||||
.label=${t("delete", L)}
|
||||
@click=${() => this._delete(v.id)}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
`,
|
||||
)}
|
||||
</div>
|
||||
`}
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>${t("close", L)}</ha-button>
|
||||
</div>
|
||||
<div class="save-row">
|
||||
<input
|
||||
class="name-input"
|
||||
type="text"
|
||||
.value=${this._name}
|
||||
placeholder=${t("views_name_placeholder", L)}
|
||||
maxlength="60"
|
||||
@input=${(e: Event) => (this._name = (e.target as HTMLInputElement).value)}
|
||||
@keydown=${(e: KeyboardEvent) => {
|
||||
if (e.key === "Enter") this._save();
|
||||
}}
|
||||
/>
|
||||
<ha-button @click=${this._save} .disabled=${!this._name.trim() || this._busy}>
|
||||
${t("views_save_current", L)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
${this._views.length === 0
|
||||
? html`<div class="empty">${t("views_none_yet", L)}</div>`
|
||||
: html`
|
||||
<div class="list dialog-scroll">
|
||||
${this._views.map(
|
||||
(v) => html`
|
||||
<div class="row">
|
||||
<span class="row-name">${v.name}</span>
|
||||
<ha-icon-button
|
||||
.path=${"M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"}
|
||||
.label=${t("delete", L)}
|
||||
@click=${() => this._delete(v.id)}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
`,
|
||||
)}
|
||||
</div>
|
||||
`}
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>${t("close", L)}</ha-button>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 480px;
|
||||
width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
static styles = [modalShellStyles, css`
|
||||
:host {
|
||||
--ms-modal-max-height: 90dvh;
|
||||
--ms-modal-gap: 12px;
|
||||
--ms-modal-z: 1000;
|
||||
}
|
||||
.title {
|
||||
font-size: 18px;
|
||||
@@ -198,11 +180,7 @@ export class MaintenanceSavedViewsDialog extends LitElement {
|
||||
padding: 8px 0;
|
||||
}
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
overflow-y: auto;
|
||||
max-height: 50vh;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
@@ -227,7 +205,7 @@ export class MaintenanceSavedViewsDialog extends LitElement {
|
||||
gap: 8px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
`;
|
||||
`];
|
||||
}
|
||||
|
||||
if (!customElements.get("maintenance-saved-views-dialog")) {
|
||||
|
||||
+28
-44
@@ -19,6 +19,9 @@
|
||||
* reset button completing it will press; tasks adopted before (or wired by
|
||||
* hand) are offered the same in their own section, with a before/after line
|
||||
* (integration_setups/reset_offers + wire_resets).
|
||||
*
|
||||
* #211: in the shared modal frame like the adopt dialog: the title and the
|
||||
* buttons stay, the offers and the devices scroll as one.
|
||||
*/
|
||||
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
@@ -26,6 +29,7 @@ import { property, state } from "lit/decorators.js";
|
||||
|
||||
import { t, ensureLocale, langOf } from "../styles";
|
||||
import { runWs } from "../helpers/ws-run";
|
||||
import { focusModalShell, modalShellStyles, renderModalShell } from "../helpers/modal-shell";
|
||||
import type { HomeAssistant } from "../types";
|
||||
|
||||
interface SetupTask {
|
||||
@@ -112,6 +116,7 @@ export class MaintenanceSuggestedSetupsDialog extends LitElement {
|
||||
this._localeReady = true;
|
||||
ensureLocale(this._lang).then(() => this.requestUpdate());
|
||||
}
|
||||
if (changed.has("_open") && this._open) focusModalShell(this.shadowRoot);
|
||||
}
|
||||
|
||||
/** Ticked by default: everything the target does not probably have yet. */
|
||||
@@ -336,13 +341,12 @@ export class MaintenanceSuggestedSetupsDialog extends LitElement {
|
||||
if (!this._open) return html``;
|
||||
const L = this._lang;
|
||||
|
||||
return html`
|
||||
<div class="overlay" @click=${this._close}>
|
||||
<div class="card" @click=${(e: Event) => e.stopPropagation()}>
|
||||
<div class="title">${t("setups_title", L)}</div>
|
||||
<div class="hint">${t("setups_hint", L)}</div>
|
||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||
return renderModalShell(() => this._close(), html`
|
||||
<div class="title">${t("setups_title", L)}</div>
|
||||
${this._error ? html`<div class="error">${this._error}</div>` : nothing}
|
||||
|
||||
<div class="dialog-scroll">
|
||||
<div class="hint">${t("setups_hint", L)}</div>
|
||||
${this._renderOffers(L)}
|
||||
${this._loading
|
||||
? html`<div class="loading">…</div>`
|
||||
@@ -428,50 +432,31 @@ export class MaintenanceSuggestedSetupsDialog extends LitElement {
|
||||
})}
|
||||
</div>
|
||||
`}
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${t("cancel", L)}
|
||||
</ha-button>
|
||||
<ha-button @click=${this._adopt} .disabled=${!this._anythingTicked || this._adopting}>
|
||||
${t("setups_adopt", L)}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
<div class="actions">
|
||||
<ha-button appearance="plain" @click=${this._close}>
|
||||
${t("cancel", L)}
|
||||
</ha-button>
|
||||
<ha-button @click=${this._adopt} .disabled=${!this._anythingTicked || this._adopting}>
|
||||
${t("setups_adopt", L)}
|
||||
</ha-button>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-background-color, #fff);
|
||||
color: var(--primary-text-color);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
min-width: min(360px, calc(100vw - 24px));
|
||||
max-width: 560px;
|
||||
width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
static styles = [modalShellStyles, css`
|
||||
:host {
|
||||
--ms-modal-max-width: 560px;
|
||||
--ms-modal-max-height: 90dvh;
|
||||
--ms-modal-gap: 12px;
|
||||
--ms-modal-z: 1000;
|
||||
}
|
||||
.title { font-size: 18px; font-weight: 500; }
|
||||
.hint { color: var(--secondary-text-color); font-size: 13px; }
|
||||
.error { color: var(--error-color, #f44336); font-size: 13px; }
|
||||
.loading, .empty { color: var(--secondary-text-color); font-size: 14px; padding: 12px 0; }
|
||||
.list { display: flex; flex-direction: column; gap: 6px; overflow-y: auto; max-height: 55vh; }
|
||||
.list { display: flex; flex-direction: column; gap: 6px; }
|
||||
.row {
|
||||
display: flex; align-items: flex-start; gap: 10px; padding: 8px;
|
||||
border: 1px solid var(--divider-color); border-radius: 6px;
|
||||
@@ -497,7 +482,6 @@ export class MaintenanceSuggestedSetupsDialog extends LitElement {
|
||||
.offers {
|
||||
display: flex; flex-direction: column; gap: 6px; padding: 8px;
|
||||
border: 1px solid var(--primary-color); border-radius: 6px;
|
||||
overflow-y: auto; max-height: 40vh; flex-shrink: 0;
|
||||
}
|
||||
.offers-title { font-weight: 500; font-size: 14px; }
|
||||
.offer { display: flex; align-items: flex-start; gap: 6px; font-size: 13px; cursor: pointer; }
|
||||
@@ -520,7 +504,7 @@ export class MaintenanceSuggestedSetupsDialog extends LitElement {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 8px; }
|
||||
`;
|
||||
`];
|
||||
}
|
||||
|
||||
if (!customElements.get("maintenance-suggested-setups-dialog")) {
|
||||
|
||||
@@ -3072,6 +3072,7 @@ export class MaintenanceTaskDialog extends LitElement {
|
||||
<option value="completion" ?selected=${this._intervalAnchor === "completion"}>${t("anchor_completion", L)}</option>
|
||||
<option value="planned" ?selected=${this._intervalAnchor === "planned"}>${t("anchor_planned", L)}</option>
|
||||
</select>
|
||||
<div class="field-help anchor-help">${t("interval_anchor_hint", L)}</div>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
|
||||
Reference in New Issue
Block a user