Skip to content
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

refactor item validation check #191

Merged
merged 2 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ All the options are available in the lovelace editor but you can use `yaml` if y
| `full_size` | boolean | `false` | Show the card without the default card margins |
| `drop_todayevents_from` | time | `10:00:00` | From what time to hide all-day event (Format `hh:mm:ss`) |
| `use_summary` | boolean | `false` | Shows the event summary instead of matched label |
| `hide_time_range` | boolean | `false` | Option to hide the time on events which aren't fill day events |
| `next_days` | number | 2 | How many times the card will look into the future to find the next event |
| `day_style` | `default` or `counter` | `default` | Option of how the date of an event should be displayed. `default` shows the date in date format and `counter` shows the number of days remaining until the event. |
| `settings` | [Settings](#settings) | Required | Settings to detect the kind of trash and how to display it.|
Expand Down
1 change: 1 addition & 0 deletions src/cards/trash-card/formSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const getSchema = (customLocalize: ReturnType<typeof setupCustomlocalize>) => {
{ name: 'use_summary', selector: { boolean: {}}},
// eslint-disable-next-line @typescript-eslint/naming-convention
{ name: 'day_style', selector: { trashcard_datestyle: {}}},
{ name: 'hide_time_range', selector: { boolean: { }}},
{ name: 'items_per_row',
selector: { number: {
min: 1,
Expand Down
5 changes: 4 additions & 1 deletion src/cards/trash-card/trash-card-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ EntityWithOutIcon & {
drop_todayevents_from?: string;
// eslint-disable-next-line @typescript-eslint/naming-convention
use_summary?: boolean;

// eslint-disable-next-line @typescript-eslint/naming-convention
hide_time_range?: boolean;
// eslint-disable-next-line @typescript-eslint/naming-convention
day_style?: typeof DAYSTYLES[number];
};
Expand All @@ -55,6 +56,8 @@ const entityCardConfigStruct = assign(
// eslint-disable-next-line @typescript-eslint/naming-convention
use_summary: optional(boolean()),
// eslint-disable-next-line @typescript-eslint/naming-convention
hide_time_range: optional(boolean()),
// eslint-disable-next-line @typescript-eslint/naming-convention
next_days: optional(integer()),
// eslint-disable-next-line @typescript-eslint/naming-convention
items_per_row: optional(integer()),
Expand Down
3 changes: 2 additions & 1 deletion src/cards/trash-card/trash-card-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ const OTHER_LABELS = new Set([
'full_size',
'drop_todayevents_from',
'use_summary',
'day_style'
'day_style',
'hide_time_range'
]);

export const computeDarkMode = (hass?: HomeAssistant): boolean => {
Expand Down
57 changes: 23 additions & 34 deletions src/cards/trash-card/trash-card.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { animations } from 'lovelace-mushroom/src/utils/entity-styles';
import type { Appearance } from 'lovelace-mushroom/src/shared/config/appearance-config';
import type { CalendarItem } from '../../utils/calendarItem';
import { cardStyle } from 'lovelace-mushroom/src/utils/card-styles';
import { classMap } from 'lit/directives/class-map.js';
import { computeAppearance } from 'lovelace-mushroom/src/utils/appearance';
Expand All @@ -19,7 +20,6 @@ import { styleMap } from 'lit/directives/style-map.js';
import type { TrashCardConfig } from './trash-card-config';
import { actionHandler, computeRTL, computeStateDisplay, hasAction, type LovelaceCard, type LovelaceCardEditor } from 'lovelace-mushroom/src/ha';
import type { CalendarEvent, RawCalendarEvent } from '../../utils/calendarEvents';
import type { CalendarItem, ValidCalendarItem } from '../../utils/calendarItem';
import { computeRgbColor, defaultColorCss, defaultDarkColorCss } from 'lovelace-mushroom/src/utils/colors';
import { css, type CSSResultGroup, html, LitElement, nothing, type PropertyValues, type TemplateResult } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
Expand Down Expand Up @@ -152,13 +152,8 @@ export class TrashCard extends LitElement implements LovelaceCard {
return false;
}

// eslint-disable-next-line class-methods-use-this
protected isValidItem (item?: CalendarItem): item is ValidCalendarItem {
return Boolean(item && item.type !== 'none');
}

protected getDateString (item: CalendarItem): string {
if (!this.isValidItem(item) || !this.hass) {
protected getDateString (item: CalendarItem, excludeTime?: boolean): string {
if (!this.hass) {
return '';
}

Expand Down Expand Up @@ -189,7 +184,7 @@ export class TrashCard extends LitElement implements LovelaceCard {
undefined;

if (stateDay === todayDay || stateDay === tomorrowDay) {
const key = `card.trash.${stateDay === todayDay ? 'today' : 'tomorrow'}${startTime ? '_from_till' : ''}`;
const key = `card.trash.${stateDay === todayDay ? 'today' : 'tomorrow'}${startTime && !excludeTime ? '_from_till' : ''}`;

return `${customLocalize(`${key}`).replace('<START>', startTime ?? '').replace('<END>', endTime ?? '')}`;
}
Expand All @@ -205,7 +200,7 @@ export class TrashCard extends LitElement implements LovelaceCard {

const daysLeft = Math.round(Math.abs((todayMorning.getTime() - item.date.start.getTime()) / oneDay));

return `${customLocalize(`card.trash.daysleft${daysLeft > 1 ? '_more' : ''}${startTime ? '_from_till' : ''}`).replace('<DAYS>', `${daysLeft}`).replace('<START>', startTime ?? '').replace('<END>', endTime ?? '')}`;
return `${customLocalize(`card.trash.daysleft${daysLeft > 1 ? '_more' : ''}${startTime && !excludeTime ? '_from_till' : ''}`).replace('<DAYS>', `${daysLeft}`).replace('<START>', startTime ?? '').replace('<END>', endTime ?? '')}`;
}

const day = item.date.start.toLocaleDateString(this.hass.language, {
Expand All @@ -215,7 +210,7 @@ export class TrashCard extends LitElement implements LovelaceCard {
day: 'numeric'
});

const key = `card.trash.day${startTime ? '_from_till' : ''}`;
const key = `card.trash.day${startTime && !excludeTime ? '_from_till' : ''}`;

return customLocalize(`${key}`).replace('<DAY>', day).replace('<START>', startTime ?? '').replace('<END>', endTime ?? '');
}
Expand All @@ -227,16 +222,12 @@ export class TrashCard extends LitElement implements LovelaceCard {

const entityId = this.config.entity;
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
const items = this.currentItems;

if (!stateObj) {
if (!stateObj || !items || items.length === 0) {
return nothing;
}

const items = this.currentItems;

if (!items || items.length === 0) {
return html``;
}
const itemsPerRow = this.config.items_per_row ?? 1;

const cssStyleMap = styleMap({
Expand All @@ -246,7 +237,7 @@ export class TrashCard extends LitElement implements LovelaceCard {

return html`
<div style=${cssStyleMap}>
${items.map(item => this.renderItem(item))}
${items.map(item => this.renderItem(item))}
</div>
`;
}
Expand All @@ -259,7 +250,7 @@ export class TrashCard extends LitElement implements LovelaceCard {
const entityId = this.config.entity;
const stateObj = this.hass.states[entityId] as HassEntity | undefined;

if (!stateObj || !this.isValidItem(item)) {
if (!stateObj) {
return nothing;
}

Expand All @@ -278,7 +269,7 @@ export class TrashCard extends LitElement implements LovelaceCard {
backgroundStyle['background-color'] = `rgba(${rgbColor}, 0.5)`;
}

const secondary = this.getDateString(item);
const secondary = this.getDateString(item, this.config.hide_time_range ?? false);

const cssClassMap = classMap({
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand All @@ -287,30 +278,28 @@ export class TrashCard extends LitElement implements LovelaceCard {
});

return html`
<ha-card class=${cssClassMap} style=${styleMap(backgroundStyle)}>
<ha-card class=${cssClassMap} style=${styleMap(backgroundStyle)}>
<mushroom-card .appearance=${appearance} ?rtl=${rtl}>
<mushroom-state-item
?rtl=${rtl}
.appearance=${appearance}
.actionHandler=${actionHandler({ hasHold: hasAction(this.config.hold_action), hasDoubleClick: hasAction(this.config.double_tap_action) })}
>
${this.renderIcon(stateObj, item)}
<mushroom-state-info
slot="info"
.primary=${label}
.secondary=${secondary}
.multiline_secondary=${true}
></mushroom-state-info>
</mushroom-state-item>
<mushroom-state-info
slot="info"
.primary=${label}
.secondary=${secondary}
.multiline_secondary=${true}
></mushroom-state-info>
</mushroom-state-item>
</mushroom-card>
</ha-card>
`;
}

protected renderIcon (stateObj: HassEntity, item?: CalendarItem): TemplateResult {
if (!this.isValidItem(item)) {
return html``;
}
// eslint-disable-next-line class-methods-use-this
protected renderIcon (stateObj: HassEntity, item: CalendarItem): TemplateResult {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const icon = item.icon ?? 'mdi:delete-outline';
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
Expand Down Expand Up @@ -405,10 +394,10 @@ export class TrashCard extends LitElement implements LovelaceCard {
cursor: pointer;
}
mushroom-shape-icon {
--icon-color: rgb(var(--rgb-state-entity));
--icon-color: rgb(var(--rgb-state-entity));
--shape-color: rgba(var(--rgb-state-entity), 0.2);
}
`
`
];
}
}
3 changes: 2 additions & 1 deletion src/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"drop_todayevents_from": "Ab wieviel Uhr Ganztages Ereignis ausblenden",
"full_size": "Karte ohne Seitenrand",
"use_summary": "Ereignisse Bezeichnung anstelle des Lables verwenden",
"day_style": "Ereigniss Zeitpunkt anzeigen als"
"day_style": "Ereigniss Zeitpunkt anzeigen als",
"hide_time_range": "Uhrzeit ausblenden"
},
"trash": {
"pattern": {
Expand Down
3 changes: 2 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"drop_todayevents_from": "From what time to hide all-day event",
"full_size": "Card without margin",
"use_summary": "Event summary instead of label",
"day_style": "Show event time as"
"day_style": "Show event time as",
"hide_time_range": "Hide time"
},
"trash": {
"pattern": {
Expand Down
3 changes: 2 additions & 1 deletion src/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"drop_todayevents_from": "A partir de quelle heure masquer l'événement de toute la journée ?",
"full_size": "Carte sans marge",
"use_summary": "Résumé de l'événement au lieu de l'étiquette",
"day_style": "Afficher l'heure de l'événement en tant que"
"day_style": "Afficher l'heure de l'événement en tant que",
"hide_time_range": "cacher le temps"
},
"trash": {
"pattern": {
Expand Down
3 changes: 2 additions & 1 deletion src/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"drop_todayevents_from": "Da quale orario nascondere gli eventi di Tutto il giorno",
"full_size": "Card senza margini",
"use_summary": "Usa l'oggetto dell'evento al posto dell'etichetta",
"day_style": "Mostra la data degli eventi come"
"day_style": "Mostra la data degli eventi come",
"hide_time_range": "nascondere il tempo"
},
"trash": {
"pattern": {
Expand Down
3 changes: 2 additions & 1 deletion src/translations/sk.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"drop_todayevents_from": "d akého času sa má skryť celodenná udalosť",
"full_size": "Karta bez marže",
"use_summary": "Zhrnutie udalosti namiesto označenia",
"day_style": "Zobraziť čas udalosti ako"
"day_style": "Zobraziť čas udalosti ako",
"hide_time_range": "čas skrývania"
},
"trash": {
"pattern": {
Expand Down
9 changes: 2 additions & 7 deletions src/utils/calendarItem.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import type { CalendarEvent } from './calendarEvents';

interface ValidCalendarItem extends CalendarEvent {
interface CalendarItem extends CalendarEvent {
label: string;
color?: string;
icon?: string;
type: string;
}

type CalendarItem = {
type: 'none';
} | ValidCalendarItem;

export type {
CalendarItem,
ValidCalendarItem
CalendarItem
};
6 changes: 4 additions & 2 deletions src/utils/eventsToItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const getData = <T extends TrashTypes> (event: CalendarEvent, key: T, settings:
const typeInSettings = <T extends TrashTypes> (key: T, settings: Options['settings']): settings is Required<Options['settings']> =>
key in settings;

const eventToItem = (event: CalendarEvent | undefined, { settings, useSummary }: Options): CalendarItem => {
const eventToItem = (event: CalendarEvent | undefined, { settings, useSummary }: Options): CalendarItem | { type: 'none' } => {
if (!event || !('summary' in event.content)) {
return {
...event,
Expand All @@ -55,7 +55,9 @@ const eventToItem = (event: CalendarEvent | undefined, { settings, useSummary }:
};

const eventsToItems = (events: CalendarEvent[], options: Options): CalendarItem[] =>
events.map(event => eventToItem(event, options));
events.
map(event => eventToItem(event, options)).
filter((item): boolean => Boolean(item.type !== 'none')) as CalendarItem[];

export {
eventsToItems
Expand Down