Skip to content

Commit

Permalink
Added option to translate texts
Browse files Browse the repository at this point in the history
  • Loading branch information
marcokreeft87 committed Dec 27, 2022
1 parent 6ae95c4 commit e58ca42
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 54 deletions.
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ or added by clicking the "Add to lovelace" button on the HACS dashboard after in
| location_clickable| boolean | `false` | Click on the location leads to wikipedia |
| previous_race | enum | | Hide/strikethrough or make the past races italic options are (hide, strikethrough or italic) |
| standings | object | | Configuration for the driver standings card |
| translations | dictionary | _[translations](#Translations)_ | Dictionary to override the default translation |

```
type: custom:formulaone-card
Expand Down Expand Up @@ -110,3 +111,54 @@ title: Last Result
```
![image](https://user-images.githubusercontent.com/10223677/194120925-5fc6c1a7-8b2a-4c58-b89c-d0316d70efe9.png)
## Translations
The following texts can be translated or altered.
| Card type(s) | Key | Default value |
| next_race, schedule | date' | 'Date' |
| next_race | practice1' | 'Practice 1' |
| next_race | practice2' | 'Practice 2' |
| next_race | practice3' | 'Practice 3' |
| next_race, schedule | race' | 'Race' |
| next_race | racename' | 'Race name' |
| next_race | circuitname' | 'Circuit name' |
| next_race, schedule | location' | 'Location' |
| next_race | racetime' | 'Race' |
| next_race | sprint' | 'Sprint' |
| next_race | qualifying' | 'Qualifying' |
| next_race, schedule | endofseason' | 'Season is over. See you next year!' |
| constructor_standings | 'constructor' | 'Constructor' |
| constructor_standings, driver_standings, last_result | 'points' | 'Pts' |
| constructor_standings, driver_standings | 'wins' | 'Wins' |
| driver_standings | 'team' | 'Team' |
| driver_standings, last_result | 'driver' | 'Driver' |
| last_result | 'grid' | 'Grid' |
| last_result | 'status' | 'Status' |
| schedule | 'time' | 'Time' |
Example:
```
type: custom:formulaone-card
card_type: next_race
sensor: sensor.formula_one_sensor_races
title: Next Race
date_locale: nl
image_clickable: true
translations:
'date' : 'Date'
'practice1' : 'Practice 1'
'practice2' : 'Practice 2'
'practice3' : 'Practice 3'
'race' : 'Race'
'racename' : 'Race name'
'circuitname' : 'Circuit name'
'location' : 'Location'
'racetime' : 'Race'
'sprint' : 'Sprint'
'qualifying' : 'Qualifying'
'endofseason' : 'Season is over. See you next year!!'

```
54 changes: 27 additions & 27 deletions formulaone-card.js

Large diffs are not rendered by default.

Binary file modified formulaone-card.js.gz
Binary file not shown.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "formulaone-card",
"version": "0.1.9",
"version": "0.2.0",
"description": "Frontend card for hass-formulaoneapi",
"main": "index.js",
"scripts": {
Expand Down
13 changes: 12 additions & 1 deletion src/cards/base-card.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HomeAssistant } from "custom-card-helpers";
import { HTMLTemplateResult } from "lit-html";
import { FormulaOneCardConfig, FormulaOneSensor } from "../types/formulaone-card-types";
import { FormulaOneCardConfig, FormulaOneSensor, Translation } from "../types/formulaone-card-types";

export abstract class BaseCard {

Expand All @@ -22,7 +22,18 @@ export abstract class BaseCard {
return { last_update: new Date(sensorEntity.attributes['last_update']), data: sensorEntity.attributes['data'] }
}

translation(key: string) : string {

if(!this.config.translations || Object.keys(this.config.translations).indexOf(key) < 0) {
return this.defaultTranslations[key];
}

return this.config.translations[key];
}

abstract render() : HTMLTemplateResult;

abstract cardSize() : number;

abstract defaultTranslations: Translation;
}
11 changes: 8 additions & 3 deletions src/cards/constructor-standings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { ConstructorStanding, FormulaOneCardConfig } from "../types/formulaone-c
import { BaseCard } from "./base-card";

export default class ConstructorStandings extends BaseCard {
defaultTranslations = {
'constructor' : 'Constructor',
'points' : 'Pts',
'wins' : 'Wins'
};

constructor(sensor: string, hass: HomeAssistant, config: FormulaOneCardConfig) {
super(sensor, hass, config);
Expand Down Expand Up @@ -40,9 +45,9 @@ export default class ConstructorStandings extends BaseCard {
<thead>
<tr>
<th class="width-50">&nbsp;</th>
<th>Constructor</th>
<th class="width-60 text-center">Pts</th>
<th class="text-center">Wins</th>
<th>${this.translation('constructor')}</th>
<th class="width-60 text-center">${this.translation('points')}</th>
<th class="text-center">${this.translation('wins')}</th>
</tr>
</thead>
<tbody>
Expand Down
14 changes: 10 additions & 4 deletions src/cards/driver-standings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import { BaseCard } from "./base-card";
import * as countries from '../data/countries.json';

export default class DriverStandings extends BaseCard {
defaultTranslations = {
'driver' : 'Driver',
'team' : 'Team',
'points' : 'Pts',
'wins' : 'Wins'
};

constructor(sensor: string, hass: HomeAssistant, config: FormulaOneCardConfig) {
super(sensor, hass, config);
Expand Down Expand Up @@ -50,10 +56,10 @@ export default class DriverStandings extends BaseCard {
<thead>
<tr>
<th class="width-50" colspan="2">&nbsp;</th>
<th>Driver</th>
${(this.config.standings?.show_team ? html`<th>Team</th>` : '')}
<th class="width-60 text-center">Pts</th>
<th class="text-center">Wins</th>
<th>${this.translation('driver')}</th>
${(this.config.standings?.show_team ? html`<th>${this.translation('team')}</th>` : '')}
<th class="width-60 text-center">${this.translation('points')}</th>
<th class="text-center">${this.translation('wins')}</th>
</tr>
</thead>
<tbody>
Expand Down
15 changes: 11 additions & 4 deletions src/cards/last-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import { getCircuitName, getCountryFlagUrl, getDriverName } from "../utils";
import { BaseCard } from "./base-card";

export default class LastResult extends BaseCard {

defaultTranslations = {
'driver' : 'Driver',
'grid' : 'Grid',
'points' : 'Points',
'status' : 'Status'
};

constructor(sensor: string, hass: HomeAssistant, config: FormulaOneCardConfig) {
super(sensor, hass, config);
Expand Down Expand Up @@ -60,10 +67,10 @@ export default class LastResult extends BaseCard {
<thead>
<tr>
<th>&nbsp;</th>
<th>Driver</th>
<th class="text-center">Grid</th>
<th class="text-ccenter">Points</th>
<th>Status</th>
<th>${this.translation('driver')}</th>
<th class="text-center">${this.translation('grid')}</th>
<th class="text-ccenter">${this.translation('points')}</th>
<th>${this.translation('status')}</th>
</tr>
</thead>
<tbody>
Expand Down
29 changes: 22 additions & 7 deletions src/cards/next-race.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ import { getCircuitName, getCountryFlagUrl } from "../utils";
import { BaseCard } from "./base-card";

export default class NextRace extends BaseCard {

defaultTranslations = {
'date' : 'Date',
'practice1' : 'Practice 1',
'practice2' : 'Practice 2',
'practice3' : 'Practice 3',
'race' : 'Race',
'racename' : 'Race name',
'circuitname' : 'Circuit name',
'location' : 'Location',
'racetime' : 'Race',
'sprint' : 'Sprint',
'qualifying' : 'Qualifying',
'endofseason' : 'Season is over. See you next year!'
};

next_race: Race;

Expand Down Expand Up @@ -39,7 +54,7 @@ export default class NextRace extends BaseCard {
}

renderSeasonEnded(): HTMLTemplateResult {
return html`<table><tr><td class="text-center"><strong>Season is over. See you next year!</strong></td></tr></table>`;
return html`<table><tr><td class="text-center"><strong>${this.translation('endofseason')}</strong></td></tr></table>`;
}

render() : HTMLTemplateResult {
Expand Down Expand Up @@ -67,12 +82,12 @@ export default class NextRace extends BaseCard {
<tr>
<td colspan="5">${this.renderHeader()}</td>
</tr>
<tr><td>Date</td><td>${formatDateNumeric(raceDate, this.hass.locale, this.config.date_locale)}</td><td>&nbsp;</td><td>Practice 1</td><td align="right">${freePractice1}</td></tr>
<tr><td>Race</td><td>${this.next_race.round}</td><td>&nbsp;</td><td>Practice 2</td><td align="right">${freePractice2}</td></tr>
<tr><td>Race name</td><td>${this.next_race.raceName}</td><td>&nbsp;</td><td>Practice 3</td><td align="right">${freePractice3}</td></tr>
<tr><td>Circuit name</td><td>${this.next_race.Circuit.circuitName}</td><td>&nbsp;</td><td>Qualifying</td><td align="right">${qualifyingDate}</td></tr>
<tr><td>Location</td><td>${this.next_race.Circuit.Location.country}</td><td>&nbsp;</td><td>Sprint</td><td align="right">${sprintDate}</td></tr>
<tr><td>City</td><td>${this.next_race.Circuit.Location.locality}</td><td>&nbsp;</td><td>Race</td><td align="right">${raceDateFormatted}</td></tr>
<tr><td>${this.translation('date')}</td><td>${formatDateNumeric(raceDate, this.hass.locale, this.config.date_locale)}</td><td>&nbsp;</td><td>${this.translation('practice1')}</td><td align="right">${freePractice1}</td></tr>
<tr><td>${this.translation('race')}</td><td>${this.next_race.round}</td><td>&nbsp;</td><td>${this.translation('practice2')}</td><td align="right">${freePractice2}</td></tr>
<tr><td>${this.translation('racename')}</td><td>${this.next_race.raceName}</td><td>&nbsp;</td><td>${this.translation('practice3')}</td><td align="right">${freePractice3}</td></tr>
<tr><td>${this.translation('circuitname')}</td><td>${this.next_race.Circuit.circuitName}</td><td>&nbsp;</td><td>${this.translation('qualifying')}</td><td align="right">${qualifyingDate}</td></tr>
<tr><td>${this.translation('location')}</td><td>${this.next_race.Circuit.Location.country}</td><td>&nbsp;</td><td>${this.translation('sprint')}</td><td align="right">${sprintDate}</td></tr>
<tr><td>City</td><td>${this.next_race.Circuit.Location.locality}</td><td>&nbsp;</td><td>${this.translation('racetime')}</td><td align="right">${raceDateFormatted}</td></tr>
</tbody>
</table>
`;
Expand Down
18 changes: 13 additions & 5 deletions src/cards/schedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import { BaseCard } from "./base-card";

export default class Schedule extends BaseCard {

defaultTranslations = {
'date' : 'Date',
'race' : 'Race',
'time' : 'Time',
'location' : 'Location',
'endofseason' : 'Season is over. See you next year!'
};

next_race: Race;

constructor(sensor: string, hass: HomeAssistant, config: FormulaOneCardConfig) {
Expand All @@ -26,7 +34,7 @@ export default class Schedule extends BaseCard {
}

renderSeasonEnded(): HTMLTemplateResult {
return html`<table><tr><td class="text-center"><strong>Season is over. See you next year!</strong></td></tr></table>`;
return html`<table><tr><td class="text-center"><strong>${this.translation('endofseason')}</strong></td></tr></table>`;
}

renderLocation(circuit: Circuit) {
Expand Down Expand Up @@ -64,10 +72,10 @@ export default class Schedule extends BaseCard {
<thead>
<tr>
<th>&nbsp;</th>
<th>Race</th>
<th>Location</th>
<th class="text-center">Date</th>
<th class="text-center">Time</th>
<th>${this.translation('race')}</th>
<th>${this.translation('location')}</th>
<th class="text-center">${this.translation('date')}</th>
<th class="text-center">${this.translation('time')}</th>
</tr>
</thead>
<tbody>
Expand Down
5 changes: 5 additions & 0 deletions src/types/formulaone-card-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export interface FormulaOneCardConfig extends LovelaceCardConfig {
location_clickable?: boolean;
previous_race?: PreviousRaceDisplay;
standings?: StandingDisplayOptions;
translations?: Translation;
}

export interface Translation {
[key: string]: string;
}

export interface StandingDisplayOptions {
Expand Down
31 changes: 31 additions & 0 deletions tests/cards/base-card.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { HomeAssistant } from "custom-card-helpers";
import { HassEntity } from "home-assistant-js-websocket";
import { createMock } from "ts-auto-mock";
import ConstructorStandings from "../../src/cards/constructor-standings";
import { FormulaOneCardConfig } from "../../src/types/formulaone-card-types";

describe('Testing base-card file', () => {
const hass = createMock<HomeAssistant>();
const hassEntity = createMock<HassEntity>();
const config = createMock<FormulaOneCardConfig>();

test.each`
key | expected
${'constructor'}, ${'Constructor'}
${'points'}, ${'Punten'}
`('Calling translation should return correct translation', ({ key, expected }) => {

config.translations = {
"points" : "Punten"
};

hassEntity.attributes['data'] = undefined;
hass.states = {
'sensor.test_sensor_constructors': hassEntity
};

const card = new ConstructorStandings('sensor.test_sensor_constructors', hass, config);

expect(card.translation(key)).toBe(expected);
})
});

0 comments on commit e58ca42

Please sign in to comment.