-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add visibility option to heading entities #22064
Conversation
934148d
to
14a20a3
Compare
14a20a3
to
d4e7c6c
Compare
WalkthroughWalkthroughThe changes introduce enhancements to the Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Outside diff range and nitpick comments (2)
src/panels/lovelace/cards/hui-heading-card.ts (1)
99-103
: LGTM: Usage ofpreview
property in render methodThe
preview
property is correctly passed to thehui-heading-entity
component, allowing child components to react to the preview state. This implementation is consistent with the PR objectives.Consider passing only the necessary properties from
this.hass
to the child component for better performance and clearer dependencies. For example:<hui-heading-entity .config=${config} .hass=${{ localize: this.hass.localize, states: this.hass.states, // Add other necessary properties }} .preview=${this.preview} > </hui-heading-entity>This approach would make the component's dependencies more explicit and potentially improve performance by reducing the number of properties passed to child components.
src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts (1)
186-190
: Remove redundant margin stylingThe
margin: 0;
andmargin-bottom: 8px;
declarations in the.intro
class conflict with each other. Sincemargin-bottom: 8px;
overrides the bottom margin, themargin: 0;
can be simplified tomargin: 0 0 8px 0;
for clarity.Apply this diff to simplify the margin styling:
.intro { - margin: 0; color: var(--secondary-text-color); - margin-bottom: 8px; + margin: 0 0 8px 0; }
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (5)
- src/panels/lovelace/cards/heading/hui-heading-entity.ts (4 hunks)
- src/panels/lovelace/cards/hui-heading-card.ts (2 hunks)
- src/panels/lovelace/cards/types.ts (1 hunks)
- src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts (7 hunks)
- src/translations/en.json (1 hunks)
Additional context used
Biome
src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts
[error] 153-153: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
Additional comments not posted (7)
src/panels/lovelace/cards/hui-heading-card.ts (2)
39-40
: LGTM: Addition ofpreview
propertyThe new
preview
property is correctly implemented as a boolean with the@property
decorator. This addition aligns with the PR objectives and follows the coding conventions used in the rest of the class.
Line range hint
1-214
: Summary: Successful implementation of visibility config optionThe changes in this file successfully implement the visibility config option for the heading entity element as described in the PR objectives. The new
preview
property is correctly added and utilized in the render method, allowing child components to react to the preview state.The implementation is consistent with the existing code structure and follows established patterns. These changes enhance the functionality of the
HuiHeadingCard
component by providing more control over the visibility of heading elements.To ensure that these changes are properly integrated and don't introduce any regressions, please run the following verification script:
This script will help verify the correct implementation of the
preview
property and its usage in the render method, as well as check for any potential regressions in theHuiHeadingCard
class.src/panels/lovelace/cards/types.ts (1)
511-511
: LGTM! Consider updating documentation.The addition of the
visibility
property to theHeadingEntityConfig
interface is well-implemented and aligns with the PR objective. It provides users with the ability to conditionally render heading entities based on specified conditions, enhancing the flexibility of the Lovelace UI.To ensure comprehensive documentation of this new feature, please run the following script to check if the relevant documentation has been updated:
If the script doesn't return any results, consider updating the documentation to include information about the new
visibility
property forHeadingEntityConfig
.src/translations/en.json (1)
Line range hint
5998-6012
: New visibility properties added to entity_configTwo new properties have been added to the
entity_config
object:
"visibility"
: This property likely indicates the conditions under which an entity is displayed."visibility_explanation"
: This property provides a description of how the visibility of the entity is determined.These additions enhance the configurability of entities in the UI, allowing for more granular control over when and how entities are displayed.
src/panels/lovelace/cards/heading/hui-heading-entity.ts (2)
35-36
: Addition of 'preview' property enhances visibility controlThe introduction of the
preview
property provides better control over the component's visibility during preview states, which is a valuable enhancement.
83-91
: '_updateVisibility' method correctly manages component visibilityThe
_updateVisibility
method effectively determines the component's visibility based on theforceVisible
flag,preview
state, and defined visibility conditions. The logic is sound and should work as intended.src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts (1)
105-125
: Ensure localization keys exist for new stringsThe localization keys used for the visibility panel header and explanation (
"ui.panel.lovelace.editor.card.heading.entity_config.visibility"
and"ui.panel.lovelace.editor.card.heading.entity_config.visibility_explanation"
) should be added to the localization files to support internationalization.Run the following script to check if the localization keys exist:
protected update(changedProps: PropertyValues<typeof this>): void { | ||
super.update(changedProps); | ||
if (changedProps.has("hass") || changedProps.has("preview")) { | ||
this._updateVisibility(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include 'config' changes in the visibility update condition
Currently, _updateVisibility()
is called when hass
or preview
changes. If the config
property changes, the visibility may also need to be updated to reflect the new configuration. Consider adding changedProps.has("config")
to ensure visibility is updated when the configuration changes.
Apply this diff to implement the change:
protected update(changedProps: PropertyValues<typeof this>): void {
super.update(changedProps);
- if (changedProps.has("hass") || changedProps.has("preview")) {
+ if (
+ changedProps.has("hass") ||
+ changedProps.has("preview") ||
+ changedProps.has("config")
+ ) {
this._updateVisibility();
}
}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
protected update(changedProps: PropertyValues<typeof this>): void { | |
super.update(changedProps); | |
if (changedProps.has("hass") || changedProps.has("preview")) { | |
this._updateVisibility(); | |
} | |
} | |
protected update(changedProps: PropertyValues<typeof this>): void { | |
super.update(changedProps); | |
if ( | |
changedProps.has("hass") || | |
changedProps.has("preview") || | |
changedProps.has("config") | |
) { | |
this._updateVisibility(); | |
} | |
} |
private _listenMediaQueries() { | ||
const config = this._config(this.config); | ||
if (!config?.visibility) { | ||
return; | ||
} | ||
const conditions = config.visibility; | ||
const hasOnlyMediaQuery = | ||
conditions.length === 1 && | ||
conditions[0].condition === "screen" && | ||
!!conditions[0].media_query; | ||
|
||
this._listeners = attachConditionMediaQueriesListeners( | ||
config.visibility, | ||
(matches) => { | ||
this._updateVisibility(hasOnlyMediaQuery && matches); | ||
} | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent duplicate media query listeners by clearing existing listeners
If connectedCallback()
is called multiple times without a corresponding disconnectedCallback()
, multiple media query listeners could be attached, potentially leading to unexpected behavior or memory leaks. To avoid this, consider calling _clearMediaQueries()
at the beginning of the _listenMediaQueries()
method to ensure that existing listeners are removed before new ones are added.
Apply this diff to implement the change:
private _listenMediaQueries() {
+ this._clearMediaQueries();
const config = this._config(this.config);
if (!config?.visibility) {
return;
}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
private _listenMediaQueries() { | |
const config = this._config(this.config); | |
if (!config?.visibility) { | |
return; | |
} | |
const conditions = config.visibility; | |
const hasOnlyMediaQuery = | |
conditions.length === 1 && | |
conditions[0].condition === "screen" && | |
!!conditions[0].media_query; | |
this._listeners = attachConditionMediaQueriesListeners( | |
config.visibility, | |
(matches) => { | |
this._updateVisibility(hasOnlyMediaQuery && matches); | |
} | |
); | |
} | |
private _listenMediaQueries() { | |
this._clearMediaQueries(); | |
const config = this._config(this.config); | |
if (!config?.visibility) { | |
return; | |
} | |
const conditions = config.visibility; | |
const hasOnlyMediaQuery = | |
conditions.length === 1 && | |
conditions[0].condition === "screen" && | |
!!conditions[0].media_query; | |
this._listeners = attachConditionMediaQueriesListeners( | |
config.visibility, | |
(matches) => { | |
this._updateVisibility(hasOnlyMediaQuery && matches); | |
} | |
); | |
} |
@@ -20,6 +31,7 @@ const entityConfigStruct = object({ | |||
content: optional(union([string(), array(string())])), | |||
icon: optional(string()), | |||
tap_action: optional(actionConfigStruct), | |||
visibility: optional(array(any())), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve type safety for the visibility
property
Using any()
in visibility: optional(array(any()))
reduces type safety and can lead to runtime errors. To enhance maintainability and catch potential issues at compile time, consider defining a specific struct for the visibility conditions.
Define a struct for the conditions, for example:
const conditionStruct = object({
entity: string(),
state: optional(string()),
// Add other required properties
});
const entityConfigStruct = object({
// existing properties
visibility: optional(array(conditionStruct)),
});
private _conditionChanged(ev: CustomEvent): void { | ||
ev.stopPropagation(); | ||
if (!this._config || !this.hass) { | ||
return; | ||
} | ||
|
||
const conditions = ev.detail.value as Condition[]; | ||
|
||
const newConfig: HeadingEntityConfig = { | ||
...this._config, | ||
visibility: conditions, | ||
}; | ||
if (newConfig.visibility?.length === 0) { | ||
delete newConfig.visibility; | ||
} | ||
|
||
fireEvent(this, "config-changed", { config: newConfig }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using the delete
operator for better performance
The delete
operator can negatively impact performance because it changes the object's shape in V8 JavaScript engine. Instead of deleting the visibility
property, set it to undefined
or omit it when creating newConfig
.
Apply this diff to address the performance issue:
const newConfig: HeadingEntityConfig = {
...this._config,
- visibility: conditions,
+ visibility: conditions.length > 0 ? conditions : undefined,
};
- if (newConfig.visibility?.length === 0) {
- delete newConfig.visibility;
- }
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
private _conditionChanged(ev: CustomEvent): void { | |
ev.stopPropagation(); | |
if (!this._config || !this.hass) { | |
return; | |
} | |
const conditions = ev.detail.value as Condition[]; | |
const newConfig: HeadingEntityConfig = { | |
...this._config, | |
visibility: conditions, | |
}; | |
if (newConfig.visibility?.length === 0) { | |
delete newConfig.visibility; | |
} | |
fireEvent(this, "config-changed", { config: newConfig }); | |
} | |
private _conditionChanged(ev: CustomEvent): void { | |
ev.stopPropagation(); | |
if (!this._config || !this.hass) { | |
return; | |
} | |
const conditions = ev.detail.value as Condition[]; | |
const newConfig: HeadingEntityConfig = { | |
...this._config, | |
visibility: conditions.length > 0 ? conditions : undefined, | |
}; | |
fireEvent(this, "config-changed", { config: newConfig }); | |
} |
Tools
Biome
[error] 153-153: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
Proposed change
Adds visibility option to heading entity element.
Type of change
Example configuration
Additional information
Checklist
If user exposed functionality or configuration variables are added/changed:
Summary by CodeRabbit
New Features
preview
property for enhanced visibility management in heading components.visibility
property allows for conditional display of heading entities.Documentation
Bug Fixes