Compare commits

...

4 Commits

Author SHA1 Message Date
Lukáš Kucharczyk 729e1d939b Version 1.5.1
continuous-integration/drone/push Build encountered an error Details
2023-11-14 21:10:42 +01:00
Lukáš Kucharczyk 2b4683e489 Improve and cleanup ConditionalElementHandler 2023-11-14 21:09:43 +01:00
Lukáš Kucharczyk cce810e8cf Improve purchase __str__ 2023-11-14 19:55:56 +01:00
Lukáš Kucharczyk 62cd17f702 Disallow choosing non-game purchase as related purchase 2023-11-14 19:55:19 +01:00
7 changed files with 99 additions and 52 deletions

View File

@ -1,3 +1,9 @@
## 1.5.1 / 2023-11-14 21:10+01:00
## Improved
* Disallow choosing non-game purchase as related purchase
* Improve display of purchases
## 1.5.0 / 2023-11-14 19:27+01:00
## New

View File

@ -6,7 +6,7 @@ RUN npm install && \
FROM python:3.10.9-slim-bullseye
ENV VERSION_NUMBER 1.5.0
ENV VERSION_NUMBER 1.5.1
ENV PROD 1
ENV PYTHONUNBUFFERED=1

View File

@ -56,7 +56,9 @@ class PurchaseForm(forms.ModelForm):
)
platform = forms.ModelChoiceField(queryset=Platform.objects.order_by("name"))
related_purchase = forms.ModelChoiceField(
queryset=Purchase.objects.order_by("edition__sort_name")
queryset=Purchase.objects.filter(type=Purchase.GAME).order_by(
"edition__sort_name"
)
)
class Meta:

View File

@ -128,10 +128,15 @@ class Purchase(models.Model):
)
def __str__(self):
platform_info = self.platform
if self.platform != self.edition.platform:
platform_info = f"{self.edition.platform} version on {self.platform}"
return f"{self.edition} ({platform_info}, {self.edition.year_released}, {self.get_ownership_type_display()})"
additional_info = [
self.get_type_display() if self.type != Purchase.GAME else "",
f"{self.edition.platform} version on {self.platform}"
if self.platform != self.edition.platform
else self.platform,
self.edition.year_released,
self.get_ownership_type_display(),
]
return f"{self.edition} ({', '.join(filter(None, map(str, additional_info)))})"
def is_game(self):
return self.type == self.GAME

View File

@ -1,4 +1,9 @@
import { syncSelectInputUntilChanged, getEl, conditionalElementHandler } from "./utils.js";
import {
syncSelectInputUntilChanged,
getEl,
disableElementsWhenTrue,
disableElementsWhenFalse,
} from "./utils.js";
let syncData = [
{
@ -11,21 +16,15 @@ let syncData = [
syncSelectInputUntilChanged(syncData, "form");
let myConfig = [
() => {
return getEl("#id_type").value == "game";
},
["#id_name", "#id_related_purchase"],
(el) => {
el.disabled = "disabled";
},
(el) => {
el.disabled = "";
function setupElementHandlers() {
disableElementsWhenTrue("#id_type", "game", [
"#id_name",
"#id_related_purchase",
]);
disableElementsWhenFalse("#id_type", "game", ["#id_date_finished"]);
}
]
document.DOMContentLoaded = conditionalElementHandler(...myConfig)
document.addEventListener("DOMContentLoaded", setupElementHandlers);
getEl("#id_type").onchange = () => {
conditionalElementHandler(...myConfig)
}
setupElementHandlers();
};

View File

@ -99,37 +99,72 @@ function getEl(selector) {
return document.getElementsByClassName(selector)
}
else {
return document.getElementsByName(selector)
return document.getElementsByTagName(selector)
}
}
/**
* @description Does something to elements when something happens.
* @param {() => boolean} condition The condition that is being tested.
* @param {string[]} targetElements
* @param {(elementName: HTMLElement) => void} callbackfn1 Called when the condition matches.
* @param {(elementName: HTMLElement) => void} callbackfn2 Called when the condition doesn't match.
* @description Applies different behaviors to elements based on multiple conditional configurations.
* Each configuration is an array containing a condition function, an array of target element selectors,
* and two callback functions for handling matched and unmatched conditions.
* @param {...Array} configs Each configuration is an array of the form:
* - 0: {function(): boolean} condition - Function that returns true or false based on a condition.
* - 1: {string[]} targetElements - Array of CSS selectors for target elements.
* - 2: {function(HTMLElement): void} callbackfn1 - Function to execute when condition is true.
* - 3: {function(HTMLElement): void} callbackfn2 - Function to execute when condition is false.
*/
function conditionalElementHandler(condition, targetElements, callbackfn1, callbackfn2) {
function conditionalElementHandler(...configs) {
configs.forEach(([condition, targetElements, callbackfn1, callbackfn2]) => {
if (condition()) {
targetElements.forEach((elementName) => {
targetElements.forEach(elementName => {
let el = getEl(elementName);
if (el === null) {
console.error("Element ${elementName} doesn't exist.");
console.error(`Element ${elementName} doesn't exist.`);
} else {
callbackfn1(el);
}
});
} else {
targetElements.forEach((elementName) => {
targetElements.forEach(elementName => {
let el = getEl(elementName);
if (el === null) {
console.error("Element ${elementName} doesn't exist.");
console.error(`Element ${elementName} doesn't exist.`);
} else {
callbackfn2(el);
}
});
}
});
}
export { toISOUTCString, syncSelectInputUntilChanged, getEl, conditionalElementHandler };
function disableElementsWhenFalse(targetSelect, targetValue, elementList) {
return conditionalElementHandler([
() => {
return getEl(targetSelect).value != targetValue;
},
elementList,
(el) => {
el.disabled = "disabled";
},
(el) => {
el.disabled = "";
},
]);
}
function disableElementsWhenTrue(targetSelect, targetValue, elementList) {
return conditionalElementHandler([
() => {
return getEl(targetSelect).value == targetValue;
},
elementList,
(el) => {
el.disabled = "disabled";
},
(el) => {
el.disabled = "";
},
]);
}
export { toISOUTCString, syncSelectInputUntilChanged, getEl, conditionalElementHandler, disableElementsWhenFalse, disableElementsWhenTrue, getValueFromProperty };

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "timetracker"
version = "1.5.0"
version = "1.5.1"
description = "A simple time tracker."
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
license = "GPL"