Skip to content

Commit

Permalink
Merge pull request #1397 from totaldebug/beta
Browse files Browse the repository at this point in the history
RELEASE
  • Loading branch information
marksie1988 authored Jan 28, 2024
2 parents 65a3cd3 + a86ff69 commit 67b3640
Show file tree
Hide file tree
Showing 10 changed files with 678 additions and 405 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: yarn install
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration/language.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The Configuration editor supports the following locales:
========= ===========
Locale Language
========= ===========
ca Catalan
cs Czech
da Danish
de German
Expand All @@ -52,6 +53,7 @@ The card date information supports the following locales:
========= ==============================
Locale Language
========= ==============================
ca Catalan
cs Czech
da Danish
de-at German (Austria)
Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "atomic-calendar-revive",
"version": "9.4.0",
"version": "9.5.0-beta.2",
"description": "Calendar Card for Home Assistant",
"main": "atomic-calendar-revive.js",
"scripts": {
Expand All @@ -23,12 +23,12 @@
"author": "Steven Marks",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.23.0",
"@babel/core": "^7.23.7",
"@babel/cli": "^7.23.9",
"@babel/core": "^7.23.9",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.23.7",
"@babel/plugin-proposal-decorators": "^7.23.9",
"@babel/plugin-transform-template-literals": "^7.23.3",
"@babel/preset-env": "^7.23.8",
"@babel/preset-env": "^7.23.9",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-eslint": "^9.0.5",
Expand All @@ -38,8 +38,8 @@
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@typescript-eslint/eslint-plugin": "^6.18.1",
"@typescript-eslint/parser": "^6.18.1",
"@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^6.19.1",
"babel-preset-minify": "^0.5.2",
"commitizen": "^4.3.0",
"conventional-changelog-conventionalcommits": "^7.0.2",
Expand All @@ -49,14 +49,14 @@
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"prettier": "^3.1.1",
"rollup": "^4.9.5",
"prettier": "^3.2.4",
"rollup": "^4.9.6",
"rollup-plugin-serve": "^3.0.0",
"rollup-plugin-typescript2": "^0.36.0",
"semantic-release": "^22.0.12"
"semantic-release": "^23.0.0"
},
"dependencies": {
"@formatjs/icu-messageformat-parser": "^2.7.2",
"@formatjs/icu-messageformat-parser": "^2.7.6",
"@lit-labs/scoped-registry-mixin": "^1.0.3",
"@lit/reactive-element": "2.0.3",
"@material/mwc-formfield": "^0.27.0",
Expand All @@ -69,12 +69,12 @@
"@material/mwc-select": "^0.27.0",
"@material/mwc-switch": "^0.27.0",
"@material/mwc-textfield": "^0.27.0",
"@mdi/js": "^7.3.67",
"@mdi/js": "^7.4.47",
"@webcomponents/webcomponentsjs": "^2.8.0",
"custom-card-helpers": "^1.9.0",
"dayjs": "^1.11.10",
"lit": "^3.1.1",
"npm": "^10.2.5",
"npm": "^10.4.0",
"typescript": "^5.3.3"
},
"resolutions": {
Expand Down
150 changes: 67 additions & 83 deletions src/functions/sort_events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,99 +5,83 @@ import EventClass from '../lib/event.class';
// Function to sort events
export default function sortEvents(events: EventClass[], config) {
const currentDateTime = dayjs(); // Current date and time
const sortedEvents: EventClass[] = [...events]; // Array to manipulate events.
const allDayEventsArray: EventClass[] = []; // Array to store the all-day events.
const sortedEvents: EventClass[] = [...events].sort((a, b) => a.startDateTime.diff(b.startDateTime)); // Array to manipulate events.

// Iterate over the events array and move all all-day events to the allDayEvents array.
for (let i = events.length - 1; i >= 0; i--) {
const event = events[i];
if (event.isAllDayEvent) {
allDayEventsArray.push(event);
sortedEvents.splice(i, 1);
}
}

// Sort the all-day events.
allDayEventsArray.sort((a, b) => {
// First, compare dates
const dateComparison = a.startDateTime.diff(b.startDateTime);

if (dateComparison !== 0) {
return dateComparison; // If dates are different, sort by date
} else {
// If dates are the same, sort by title
return a.title.localeCompare(b.title);
// Step 1: Split array by startDateTime per day
const eventsByDay: { [key: string]: EventClass[] } = {};
sortedEvents.forEach((event) => {
const dateKey = dayjs(event.startDateTime).format('YYYY-MM-DD');
if (!eventsByDay[dateKey]) {
eventsByDay[dateKey] = [];
}
eventsByDay[dateKey].push(event);
});

if (config.sortBy === 'start') {
sortedEvents.sort((a, b) => {
const aStartDiff = a.startDateTime.diff(currentDateTime);
const bStartDiff = b.startDateTime.diff(currentDateTime);

if (aStartDiff <= 0 && bStartDiff <= 0) {
// Both events have started, sort by their end times
const aEndDiff = a.endDateTime.diff(currentDateTime);
const bEndDiff = b.endDateTime.diff(currentDateTime);

if (aEndDiff <= 0 && bEndDiff <= 0) {
// Both events are ongoing, sort by their end times
return a.endDateTime.diff(b.endDateTime);
} else {
// One event has finished or is ongoing, prioritize the one finishing sooner
return aEndDiff - bEndDiff;
}
} else {
// Sort by the difference between the start time and the current time
return aStartDiff - bStartDiff;
// Step 2: Loop through each day and sort events
Object.values(eventsByDay).forEach((dayEvents) => {
// 2a. Sort all-day events
const allDayEvents = dayEvents.filter((event) => event.isAllDayEvent);
allDayEvents.sort((a, b) => {
if (config.allDayBottom) {
return a.title.localeCompare(b.title); // Sort by title if at the bottom
}
return -a.title.localeCompare(b.title); // Sort by title in reverse if at the top
});
}

if (config.sortBy === 'milestone') {
sortedEvents.sort((a, b) => {
const isRunningA = currentDateTime.isBetween(a.startDateTime, a.endDateTime);
const isRunningB = currentDateTime.isBetween(b.startDateTime, b.endDateTime);
// 2b. Sort regular events by start time if sortBy = start
if (config.sortBy === 'start') {
dayEvents.filter((event) => !event.isAllDayEvent).sort((a, b) => a.startDateTime.diff(b.startDateTime));
}

if (isRunningA && !isRunningB) {
return -1;
} else if (!isRunningA && isRunningB) {
return 1;
} else {
const timeDiffA = Math.min(
Math.abs(a.startDateTime.diff(currentDateTime)),
Math.abs(a.endDateTime.diff(currentDateTime)),
);
// 2c. Sort regular events by milestone logic if sortBy = milestone
if (config.sortBy === 'milestone') {
dayEvents
.filter((event) => !event.isAllDayEvent)
.sort((a, b) => {
const isRunningA = currentDateTime.isBetween(a.startDateTime, a.endDateTime);
const isRunningB = currentDateTime.isBetween(b.startDateTime, b.endDateTime);

const timeDiffB = Math.min(
Math.abs(b.startDateTime.diff(currentDateTime)),
Math.abs(b.endDateTime.diff(currentDateTime)),
);
if (isRunningA && !isRunningB) {
return -1;
} else if (!isRunningA && isRunningB) {
return 1;
} else {
const timeDiffA = Math.min(
Math.abs(a.startDateTime.diff(currentDateTime)),
Math.abs(a.endDateTime.diff(currentDateTime)),
);

return timeDiffA - timeDiffB;
}
});
// Move finished events to the bottom
sortedEvents.sort((a, b) => {
if (a.isFinished !== b.isFinished) {
return a.isFinished ? 1 : -1;
}
// If both events are finished, sort them by their endDateTime in ascending order.
if (a.isFinished) {
return dayjs(a.endDateTime).isBefore(b.endDateTime) ? -1 : 1;
}
return 0;
});
}
const timeDiffB = Math.min(
Math.abs(b.startDateTime.diff(currentDateTime)),
Math.abs(b.endDateTime.diff(currentDateTime)),
);

// If config.allDayBottom is true, add the all-day events to the end of the sorted events array.
if (config.allDayBottom) {
sortedEvents.push(...allDayEventsArray);
}
// Otherwise, add the all-day events to the beginning of the sorted events array.
else {
sortedEvents.unshift(...allDayEventsArray);
}
return timeDiffA - timeDiffB;
}
});
dayEvents
.filter((event) => !event.isAllDayEvent)
.sort((a, b) => {
if (a.isFinished !== b.isFinished) {
return a.isFinished ? 1 : -1;
}
// If both events are finished, sort them by their endDateTime in ascending order.
if (a.isFinished) {
return dayjs(a.endDateTime).isBefore(b.endDateTime) ? -1 : 1;
}
return 0;
});
}

// Step 3: Merge each day, in order, without changing the order of the events
const sortedDay = config.allDayBottom
? [...dayEvents.filter((event) => !event.isAllDayEvent), ...allDayEvents]
: [...allDayEvents, ...dayEvents.filter((event) => !event.isAllDayEvent)];

// Update eventsByDay with the sorted day
eventsByDay[dayjs(dayEvents[0].startDateTime).format('YYYY-MM-DD')] = sortedDay;
});

return sortedEvents;
// Step 4: Merge all days and return the whole array sorted
return Object.values(eventsByDay).reduce((acc, dayEvents) => [...acc, ...dayEvents], []);
}
2 changes: 1 addition & 1 deletion src/lib/common.html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export function getTitleHTML(config: atomicCardConfig, event: EventClass, hass:
let { title } = event;

if (!isHtml(event.title) && config.titleLength && event.title.length > config.titleLength) {
title = event.title.slice(0, config.titleLength);
title = event.title.slice(0, config.titleLength) + '...';
}
if (config.disableEventLink || event.htmlLink === undefined || event.htmlLink === null) {
return html`
Expand Down
1 change: 1 addition & 0 deletions src/locale.dayjs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dayjs/locale/ca';
import 'dayjs/locale/cs';
import 'dayjs/locale/da';
import 'dayjs/locale/de-at';
Expand Down
114 changes: 114 additions & 0 deletions src/localize/languages/ca.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"common": {
"version": "Versió",
"show_warning": "Mostrar alerta",
"error": "Error",
"description": "Una targeta de calendari avançada per a Home Assistant amb Lovelace.",
"fullDayEventText": "Tot el dia",
"untilText": "Fins",
"noEventText": "Sense esdeveniments",
"noEventsForNextDaysText": "Sense esdeveniments en els propers dies",
"hiddenEventText": "esdeveniments ocults"
},
"ui": {
"common": {
"previous": "Anterior",
"next": "Següent",
"week": "Setmana"
}
},
"errors": {
"invalid_configuration": "Configuració incorrecte",
"update_card": "No es pot carregar el calendari des del component de Home Assistant",
"no_entities": "No has especificat cap entitat"
},
"required": {
"name": "Requerit",
"secondary": "Opcions requerides per al funcionament d'aquesta targeta"
},
"main": {
"name": "Opcions Principals",
"secondary": "Opcions aplicades globalment",
"fields": {
"name": "Nom",
"showColors": "Mostrar Colors",
"maxDaysToShow": "Màxim de dies a mostrar",
"showLocation": "Mostrar icona de localització",
"showLoader": "Mostrar animació de càrrega",
"showDate": "Mostrar data a la targeta",
"showDeclined": "Mostrar esdeveniments declinats",
"sortBy": "Ordena per",
"allDayBottom": "Mostrar esdeveniments de tot el dia al final",
"hideFinishedEvents": "Ocultar esdeveniments finalitzats",
"dateFormat": "Format de data",
"hoursFormat": "Format d'hora",
"defaultMode": "Modalitat per defecte",
"linkTarget": "Enllaçar destí",
"refreshInterval": "Interval de refresc",
"showRelativeTime": "Mostrar tems relatiu",
"firstDayOfWeek": "Primer dia de la setmana 0-6",
"cardHeight": "Alçada targeta",
"hideDuplicates": "Oculta duplicats",
"showMultiDay": "Divideix esdeveniments multi-dia",
"showMultiDayEventParts": "Mostrar parts d'esdeveniments multi-dia",
"eventTitle": "Estableix títol d'esdeveniment en blanc",
"compactMode": "Habilitar mode compacte",
"titleLength": "Màxima longitut del títol (0 per il·limitat)",
"descLength": "Màxima longitut de la descripció (0 per il·limitat)",
"showAllDayEvents": "Mostrat esdeveniments de tot el dia",
"offsetHeaderDate": "Compensació de la data de la capçalera",
"startDaysAhead": "Esdeveniments que comencen `x` dies a partir d'ara"
}
},
"event": {
"name": "Mode Esdeveniment",
"secondary": "Opcions específiques del Mode Esdeveniment",
"fields": {
"showCurrentEventLine": "Mostrar línia abans de l'esdeveniment?",
"showProgressBar": "Mostrar barra de progrés?",
"showMonth": "Mostrar mes?",
"showWeekDay": "Mostrar dia de la setmana",
"showDescription": "Mostrar descripció?",
"disableEventLink": "Desactivar enllaços al títol de l'esdeveniment?",
"disableLocationLink": "Desactivar enllaços a la localització?",
"showNoEventsForToday": "Mostrar No hi ha esdeveniments avui?",
"showFullDayProgress": "Mostrar progres dels esdeveniments de tot el dia?",
"untilText": "Text fins:",
"noEventText": "Text No hi ha esdeveniments avui:",
"noEventsForNextDaysText": "Text No hi ha esdeveniments els propers dies:",
"fullDayEventText": "Text Esdeveniment de tot el dia:",
"showEventIcon": "Mostrar icona d'esdeveniment",
"showHiddenText": "Mostrar text dels esdeveniments ocults?",
"hiddenEventText": "Text per als esdeveniments ocults:",
"showCalendarName": "Mostrar nom del calendari",
"showWeekNumber": "Mostrar número de la setmana",
"showEventDate": "Mostrar data als dels esdeveniments",
"showDatePerEvent": "Mostrar data al costat de cada esdeveniment",
"showTimeRemaining": "Mostrar temps restant",
"showAllDayHours": "Mostrar text d'esdeveniment de tot el dia",
"hoursOnSameLine": "Mostrar hores a la línia de l'esdeveniment"
}
},
"calendar": {
"name": "Mode Calendari",
"secondary": "Opcions específiques del Mode Calendari",
"fields": {
"showLastCalendarWeek": "Mostrar última setmana del calendari",
"disableCalEventLink": "Desactivar enllaços als esdeveniments del calendari",
"disableCalLocationLink": "Desactivar enllaços a la localització en el calendari",
"calShowDescription": "Mostrar descripció",
"disableCalLink": "Desactivar enllaç al calendari"
}
},
"appearance": {
"name": "Aparença",
"secondary": "Pesonalitzar els colors etc.",
"main": {
"name": "Principal",
"secondary": "Ajust del color global"
},
"fields": {
"dimFinishedEvents": "Atenuar esdeveniments finalitzats?"
}
}
}
Loading

0 comments on commit 67b3640

Please sign in to comment.