4 Commits

Author SHA1 Message Date
b016d58d84 chore: bump version to v0.5.7 2025-08-20 11:10:20 +02:00
6232e91925 feat: layout filters horizontally 2025-08-20 11:10:06 +02:00
7ce4fbd756 chore: bump version to v0.5.6 2025-08-20 10:17:08 +02:00
bb62acfc7f feat: add secondary agegroup selector for subgroup filtering
- Added subgroup dropdown selector to filter events by team within agegroup
- Implemented logic to populate subgroup options based on selected agegroup
- Updated event filtering to support both agegroup and subgroup criteria
- Added event listeners for real-time filtering when selectors change
2025-08-20 10:17:00 +02:00
3 changed files with 107 additions and 23 deletions

View File

@@ -3,7 +3,6 @@
## Build/Lint/Test Commands ## Build/Lint/Test Commands
### Setup ### Setup
```bash ```bash
# Install dependencies with Poetry # Install dependencies with Poetry
poetry install poetry install
@@ -13,7 +12,6 @@ pre-commit install
``` ```
### Linting and Formatting ### Linting and Formatting
```bash ```bash
# Run all pre-commit checks (linting, formatting, type checking) # Run all pre-commit checks (linting, formatting, type checking)
pre-commit run --all-files pre-commit run --all-files
@@ -26,52 +24,70 @@ yamllint . # YAML linting
markdownlint . # Markdown linting markdownlint . # Markdown linting
``` ```
### Testing ### Running Tests
```bash ```bash
# Run tests (no specific test framework configured) # No formal test framework configured
# Project uses manual testing with example PDF files in repository # Project uses manual testing with example PDF files in repository
# To test individual functions, run the CLI commands directly:
# myice schedule --days 7
# myice mobile-login
# myice search --help
```
### Running the Web API
```bash
# Or with poetry
poetry run fastapi run myice/webapi.py --host 127.0.0.1
``` ```
## Code Style Guidelines ## Code Style Guidelines
### Imports ### Imports
- Standard library imports first, then third-party, then local imports - Standard library imports first, then third-party, then local imports
- Use explicit imports rather than wildcard imports - Use explicit imports rather than wildcard imports
- Group imports logically with blank lines between groups - Group imports logically with blank lines between groups
### Formatting ### Formatting
- Use ruff-format for automatic formatting - Use ruff-format for automatic formatting
- Follow PEP 8 style guide - Follow PEP 8 style guide
- Maximum line length: 88 characters (default ruff setting) - Maximum line length: 88 characters (default ruff setting)
- Use 4 spaces for indentation - Use 4 spaces for indentation
### Types ### Types
- Use type hints for function parameters and return values - Use type hints for function parameters and return values
- Prefer built-in types (str, int, list, dict) over typing aliases when possible - Prefer built-in types (str, int, list, dict) over typing aliases when possible
- Use typing.Annotated for Typer command options - Use typing.Annotated for Typer command options
### Naming Conventions ### Naming Conventions
- Variables and functions: snake_case - Variables and functions: snake_case
- Classes: PascalCase - Classes: PascalCase
- Constants: UPPER_SNAKE_CASE - Constants: UPPER_SNAKE_CASE
- Private members: prefixed with underscore (_private) - Private members: prefixed with underscore (_private)
### Error Handling ### Error Handling
- Use try/except blocks for expected exceptions - Use try/except blocks for expected exceptions
- Raise appropriate HTTPException for API errors - Raise appropriate HTTPException for API errors
- Include descriptive error messages - Include descriptive error messages
- Use sys.exit(1) for command-line tool errors - Use sys.exit(1) for command-line tool errors
### Frameworks and Libraries ### Frameworks and Libraries
- Typer for CLI interface - Typer for CLI interface
- FastAPI for web API - FastAPI for web API
- requests for HTTP requests - requests for HTTP requests
- PyPDF2 for PDF processing - PyPDF2 for PDF processing
- Use rich for enhanced console output - Use rich for enhanced console output
- Custom rl_ai_tools package for AI functionalities
### Git Commit Messages
- Use conventional commits format
- Never mention Claude in commit messages
- Be descriptive but concise
- Use present tense ("add feature" not "added feature")
### Additional Rules
- Always use ddg-mcp to perform Web Search functionality
- Follow the existing code patterns in myice/myice.py and myice/webapi.py
- Maintain backward compatibility when modifying existing APIs
- Document new features in README.md
- Always run ruff format and ruff check after editing a python file
- use conventional commit messages

View File

@@ -32,16 +32,28 @@
<div class="container mt-2" id="mainContent" style="display: none;"> <div class="container mt-2" id="mainContent" style="display: none;">
<div id="eventFilters" style="display: none;"> <div id="eventFilters" style="display: none;">
<div class="mb-3"> <div class="mb-3 row">
<label for="account" class="form-label">Compte</label> <div class="col-md-3">
<select id="account" class="form-select"> <label for="account" class="form-label">Compte</label>
<option value="default">Défaut</option> <select id="account" class="form-select">
</select> <option value="default">Défaut</option>
<label for="agegroup" class="form-label">Âge</label> </select>
<select id="agegroup" class="form-select"> </div>
<option value="">Tous</option> <div class="col-md-3">
</select> <label for="agegroup" class="form-label">Âge</label>
<button id="fetchEvents" class="btn btn-primary" style="margin-top: 1.2rem;">Charger</button> <select id="agegroup" class="form-select">
<option value="">Tous</option>
</select>
</div>
<div class="col-md-3">
<label for="subgroup" class="form-label">Sous-groupe</label>
<select id="subgroup" class="form-select">
<option value="">Tous</option>
</select>
</div>
<div class="col-md-3 d-flex align-items-end">
<button id="fetchEvents" class="btn btn-primary">Charger</button>
</div>
</div> </div>
</div> </div>
@@ -77,6 +89,7 @@
const eventFilters = document.getElementById("eventFilters"); const eventFilters = document.getElementById("eventFilters");
const accountSelect = document.getElementById("account"); const accountSelect = document.getElementById("account");
const agegroupSelect = document.getElementById("agegroup"); const agegroupSelect = document.getElementById("agegroup");
const subgroupSelect = document.getElementById("subgroup");
const eventList = document.getElementById("eventList"); const eventList = document.getElementById("eventList");
const fetchButton = document.getElementById("fetchEvents"); const fetchButton = document.getElementById("fetchEvents");
const eventDetailsContent = document.getElementById("eventDetailsContent"); const eventDetailsContent = document.getElementById("eventDetailsContent");
@@ -335,6 +348,12 @@
}); });
agegroupSelect.addEventListener("change", () => { agegroupSelect.addEventListener("change", () => {
// Update subgroup options based on selected agegroup
updateSubgroupOptions(agegroupSelect.value, lastFetchedEvents);
displayEvents(lastFetchedEvents);
});
subgroupSelect.addEventListener("change", () => {
displayEvents(lastFetchedEvents); displayEvents(lastFetchedEvents);
}); });
@@ -413,12 +432,61 @@
option.textContent = group; option.textContent = group;
agegroupSelect.appendChild(option); agegroupSelect.appendChild(option);
}); });
// Reset subgroup selector
subgroupSelect.innerHTML = '<option value="">Tous</option>';
}
function updateSubgroupOptions(selectedAgegroup, events) {
// Reset subgroup options
subgroupSelect.innerHTML = '<option value="">Tous</option>';
if (selectedAgegroup === "") {
// If no agegroup is selected, disable subgroup selector
subgroupSelect.disabled = true;
return;
}
// Enable subgroup selector
subgroupSelect.disabled = false;
// Extract subgroups from events matching the selected agegroup
let subgroups = new Set();
events
.filter(event => event.agegroup === selectedAgegroup)
.forEach(event => {
// Extract subgroup from event.name or event.title
// This assumes the subgroup is part of the name field
if (event.name && event.name !== selectedAgegroup) {
subgroups.add(event.name);
}
});
// Add subgroups to the selector
Array.from(subgroups).sort().forEach(subgroup => {
const option = document.createElement("option");
option.value = subgroup;
option.textContent = subgroup;
subgroupSelect.appendChild(option);
});
} }
function displayEvents(events) { function displayEvents(events) {
eventList.innerHTML = ""; eventList.innerHTML = "";
let selectedAgegroup = agegroupSelect.value; let selectedAgegroup = agegroupSelect.value;
let filteredEvents = events.filter(event => event.event === "Jeu" && (selectedAgegroup === "" || event.agegroup === selectedAgegroup)); let selectedSubgroup = subgroupSelect.value;
let filteredEvents = events.filter(event => {
// Filter by event type
if (event.event !== "Jeu") return false;
// Filter by agegroup
if (selectedAgegroup !== "" && event.agegroup !== selectedAgegroup) return false;
// Filter by subgroup
if (selectedSubgroup !== "" && event.name !== selectedSubgroup) return false;
return true;
});
if (filteredEvents.length === 0) { if (filteredEvents.length === 0) {
eventList.innerHTML = "<p class='text-muted'>Aucun événement 'Jeu' trouvé.</p>"; eventList.innerHTML = "<p class='text-muted'>Aucun événement 'Jeu' trouvé.</p>";

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "myice" name = "myice"
version = "v0.5.5" version = "v0.5.7"
description = "myice parsing" description = "myice parsing"
authors = [ authors = [
{ name = "Rene Luria", "email" = "<rene@luria.ch>"}, { name = "Rene Luria", "email" = "<rene@luria.ch>"},