diff --git a/frontend/main.ts b/frontend/main.ts index 88bbd54..1cb7271 100644 --- a/frontend/main.ts +++ b/frontend/main.ts @@ -158,9 +158,9 @@ function selectBoatChange() { } if (event.detail.customProperties.convert_handoperated_possible) { - only_steering.removeAttribute('disabled'); + only_steering.removeAttribute('readonly'); }else { - only_steering.setAttribute('disabled', 'disabled'); + only_steering.setAttribute('readonly', 'readonly'); } const destination = ( diff --git a/frontend/tests/log.spec.ts b/frontend/tests/log.spec.ts index bc74ec4..942d196 100644 --- a/frontend/tests/log.spec.ts +++ b/frontend/tests/log.spec.ts @@ -190,3 +190,57 @@ test("Kiosk can start and finish trip", async ({ page }, testInfo) => { await expect(page.locator('body')).toContainText('Ottensheim (25 km)'); await expect(page.locator('body')).toContainText('Ruderer: cox2, rower2'); }); + +test("Cox can start and finish trip with cox steering only", async ({ page }, testInfo) => { + await page.goto("/auth"); + await page.getByPlaceholder("Name").click(); + await page.getByPlaceholder("Name").fill("cox2"); + await page.getByPlaceholder("Name").press("Tab"); + await page.getByPlaceholder("Passwort").fill("cox"); + await page.getByPlaceholder("Passwort").press("Enter"); + + await page.goto("/"); + await page.getByRole("link", { name: "Ausfahrt eintragen" }).click(); + if (testInfo.project.name.includes("Mobile")) { + // No left boat selector on mobile views + await page.getByText('-- Wähle ein Boot aus ---').nth(1).click(); + await page.getByRole("option", { name: "cox_only_steering_boat" }).click(); + } else { + await page.getByText('2+', { exact: true }).click(); + await page.getByText("cox_only_steering_boat", { exact: true }).click(); + } + + // Trip starts 2 hours ago + const datetimeSelector = '#departure'; + const currentValue = await page.$eval(datetimeSelector, el => el.value); + const currentDate = new Date(currentValue); + currentDate.setMinutes(currentDate.getMinutes()); + currentDate.setHours(currentDate.getHours() - new Date().getTimezoneOffset()/60 - 2); + const newDatetime = currentDate.toISOString().slice(0, 16); + await page.$eval(datetimeSelector, (el, value) => el.value = value, newDatetime); + + await expect(page.locator("#shipmaster-newrowerjs")).toContainText("cox"); + await expect(page.locator("#steering_person-newrowerjs")).toContainText( + "cox", + ); + await page.getByRole("button", { name: "Ausfahrt eintragen" }).click(); + await expect(page.locator("body")).toContainText( + "Ausfahrt erfolgreich hinzugefügt", + ); + await expect(page.locator("body")).toContainText("cox_only_steering_boat"); + + await page.goto("/log"); + await page.locator("div:nth-child(2) > .border-0").click(); + + await page.getByRole("combobox", { name: "Destination" }).click(); + await page.getByRole("combobox", { name: "Destination" }).fill("Ottensheim"); + await page.getByRole("button", { name: "Ausfahrt beenden" }).click(); + await expect(page.locator("body")).toContainText( + "Ausfahrt korrekt eingetragen", + ); + + await page.goto('/log/show'); + await expect(page.locator('body')).toContainText('cox_only_steering_boat'); + await expect(page.locator('body')).toContainText('(cox2)'); + await expect(page.locator('body')).toContainText('Ottensheim (25 km)'); +}); diff --git a/seeds.sql b/seeds.sql index ceb2296..d832416 100644 --- a/seeds.sql +++ b/seeds.sql @@ -55,6 +55,7 @@ INSERT INTO "boat" (name, amount_seats, location_id) VALUES ('Kaputtes Boot :-(' INSERT INTO "boat" (name, amount_seats, location_id) VALUES ('Sehr kaputtes Boot :-((', 7, 1); INSERT INTO "boat" (name, amount_seats, location_id) VALUES ('Ottensheim Boot', 7, 2); INSERT INTO "boat" (name, amount_seats, location_id, owner) VALUES ('second_private_boat_from_rower', 1, 1, 2); +INSERT INTO "boat" (name, amount_seats, location_id, default_shipmaster_only_steering) VALUES ('cox_only_steering_boat', 3, 1, true); INSERT INTO "logbook_type" (name) VALUES ('Wanderfahrt'); INSERT INTO "logbook_type" (name) VALUES ('Regatta'); INSERT INTO "logbook" (boat_id, shipmaster,steering_person, shipmaster_only_steering, departure) VALUES (2, 2, 2, false, strftime('%Y', 'now') || '-12-24 10:00'); diff --git a/templates/admin/user/index.html.tera b/templates/admin/user/index.html.tera index 409de92..b2a8f9b 100644 --- a/templates/admin/user/index.html.tera +++ b/templates/admin/user/index.html.tera @@ -36,37 +36,52 @@ placeholder="Suchen nach (Name, [yes|no]-role:, has-[no-]membership-pdf)" /> -
-
- {% for user in users %} -
+
+ {% for user in users %} +
+
+ + + + {{ user.name }} + {% if not user.last_access and "admin" in loggedin_user.roles and user.mail %} +
+ • Willkommensmail verschicken +
+ {% endif %} + {% if user.last_access %}• ⏳ {{ user.last_access | date }}{% endif %} +
+ + {% for role in user.roles %} + {{ role }} + {% if not loop.last %},{% endif %} + {% endfor %} + +
+
-
+ class="w-full mt-2"> + {% if user.pw %} + Passwort zurücksetzen + {% endif %} +
-
- {{ user.name }} - {% if user.last_access %} - (last access: - {{ user.last_access | date }}) - {% endif %} - {% if user.pw %} - Passwort zurücksetzen - {% endif %} - {% if not user.last_access and "admin" in loggedin_user.roles %} - Willkommensmail verschicken - {% endif %} -
{% for role in roles %} {{ macros::checkbox(label=role.name, name="roles[" ~ role.id ~ "]", id=loop.index , checked=role.name in user.roles, disabled=allowed_to_edit == false) }} {% endfor %} +
{% if user.membership_pdf %} Beitrittserklärung herunterladen @@ -100,8 +115,8 @@
{% endif %} -
- {% endfor %} -
+
+
+ {% endfor %}
{% endblock content %} diff --git a/templates/includes/forms/log.html.tera b/templates/includes/forms/log.html.tera index 7395747..6a5fb50 100644 --- a/templates/includes/forms/log.html.tera +++ b/templates/includes/forms/log.html.tera @@ -36,7 +36,7 @@
Bootssteuerung
- {{ macros::checkbox(label='handgesteuert', name='shipmaster_only_steering', disabled=true) }} + {{ macros::checkbox(label='handgesteuert', name='shipmaster_only_steering', readonly=true) }}
{{ log::rower_select(id="newrower", selected=[], class="col-span-4", init=true) }} diff --git a/templates/includes/macros.html.tera b/templates/includes/macros.html.tera index d8c2b8e..0549f5b 100644 --- a/templates/includes/macros.html.tera +++ b/templates/includes/macros.html.tera @@ -137,14 +137,15 @@ {% if readonly %}readonly{% endif %}>
{% endmacro input %} -{% macro checkbox(label, name, id='', checked=false, class='', disabled=false) %} +{% macro checkbox(label, name, id='', checked=false, class='', disabled=false, readonly=false) %} diff --git a/templates/planned.html.tera b/templates/planned.html.tera index 84ae217..0dfab7c 100644 --- a/templates/planned.html.tera +++ b/templates/planned.html.tera @@ -50,7 +50,7 @@ target="_blank" rel="noopener noreferrer">hier) melde dich bitte bei it@rudernlinz.at. @Studenten: Bitte die aktuelle Studienbestätigung an it@rudernlinz.at schicken.
- Wir aktualisieren den Ruderassistent unregelmäßig mit unserem Bankkonto. Falls du schon bezahlt hast, kannst du diese Nachricht getrost ignorieren :^) + Unsere Kassiere aktualisieren den Ruderassistent unregelmäßig mit unserem Bankkonto. Falls du schon bezahlt hast, kannst du diese Nachricht getrost ignorieren. Wenn du schon vor "einigen Wochen" bezahlt hast bitte bei kassier@rudernlinz.at nachfragen :^) @@ -391,15 +391,15 @@ {# --- START Add Buttons --- #} {% if "manage_events" in loggedin_user.roles or "cox" in loggedin_user.roles %} -
+
{% if "manage_events" in loggedin_user.roles %} - + {% include "includes/plus-icon" %} Event