Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions application/backend/lib/konzerte/konzertestore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import User from "jc-shared/user/user.js";
const persistence = pers("veranstaltungenstore", ["startDate", "endDate", "url"]);
const logger = winston.loggers.get("transactions");
import conf from "../../simpleConfigure.js";
import optionenstore from "../optionen/optionenstore.js";
import groupBy from "lodash/groupBy.js";

function byDateRange(rangeFrom: DatumUhrzeit, rangeTo: DatumUhrzeit, sortOrder: "ASC" | "DESC") {
const result = persistence.listByField(
Expand Down Expand Up @@ -57,6 +59,11 @@ export default {
},

saveKonzert(konzert: Konzert, user: User) {
// update eventTypRich on save
const optionen = optionenstore.get();
const typByName = groupBy(optionen?.typenPlus || [], "name");
konzert.kopf.eventTypRich = typByName[konzert.kopf.eventTyp]?.[0];

persistence.save(konzert as { id: string }, user);
return konzert;
},
Expand Down
1 change: 0 additions & 1 deletion application/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export default tseslint.config(
"react/forbid-component-props": "off",
"react/no-danger": "off",
"no-sync": "off",
"react/jsx-no-bind": "off",
"react/jsx-filename-extension": ["error", { extensions: [".tsx"] }],
"react/jsx-no-literals": "off",
"react/require-default-props": "off",
Expand Down
6 changes: 3 additions & 3 deletions application/rider/src/RiderStandalone.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { BoxParams } from "jc-shared/rider/rider.ts";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { riderFor, saveRider } from "@/loader.ts";
Expand Down Expand Up @@ -32,12 +32,12 @@ export function RiderStandalone() {
}
}, [rider, isSuccess]);

function save() {
const save = useCallback(() => {
if (rider) {
rider.boxes = targetBoxes;
mutateRider.mutate(rider);
}
}
}, [mutateRider, rider, targetBoxes]);

const token = theme.useToken().token;

Expand Down
5 changes: 4 additions & 1 deletion application/shared/konzert/unterkunft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import DatumUhrzeit from "../commons/DatumUhrzeit.js";
import Misc from "../commons/misc.js";
import { RecursivePartial } from "../commons/advancedTypes.js";
import keys from "lodash/keys.js";
import { Hotelpreise } from "../optionen/optionValues.js";

export type Zimmerpreise = Omit<Hotelpreise, "name">;

export default class Unterkunft {
einzelNum = 0;
Expand Down Expand Up @@ -98,7 +101,7 @@ export default class Unterkunft {
return this.einzelNum * this.einzelEUR * naechte + this.doppelNum * this.doppelEUR * naechte + this.suiteNum * this.suiteEUR * naechte;
}

get zimmerPreise(): { einzelEUR: number; doppelEUR: number; suiteEUR: number } {
get zimmerPreise(): Zimmerpreise {
return { einzelEUR: this.einzelEUR, doppelEUR: this.doppelEUR, suiteEUR: this.suiteEUR };
}
}
3 changes: 2 additions & 1 deletion application/shared/optionen/optionValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import find from "lodash/find.js";
import Kontakt from "../veranstaltung/kontakt.js";
import map from "lodash/map.js";
import forEach from "lodash/forEach.js";
import { Zimmerpreise } from "../konzert/unterkunft.js";

const sortByNameCaseInsensitive = sortBy(toLower);

Expand Down Expand Up @@ -137,7 +138,7 @@ export default class OptionValues {
}
}

updateHotelpreise(hotel: Kontakt, zimmerPreise: { einzelEUR: number; doppelEUR: number; suiteEUR: number }): void {
updateHotelpreise(hotel: Kontakt, zimmerPreise: Zimmerpreise): void {
if (find(this.hotels, { name: hotel.name })) {
remove(this.hotelpreise, (p: Hotelpreise) => p.name === hotel.name);
this.hotelpreise.push({ name: hotel.name, ...zimmerPreise });
Expand Down
2 changes: 1 addition & 1 deletion application/vue/src/app/JC-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pre {
padding: 0 !important;
}
.team-block .ant-collapse-header {
padding: 2px 2px 0 !important;
padding: 0 1px 0 !important;
}
.ant-collapse-header {
padding: 4px 8px !important;
Expand Down
7 changes: 2 additions & 5 deletions application/vue/src/app/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { Button, Col, Form, Row, Input } from "antd";
import { LoginState, useAuth } from "@/commons/authConsts.ts";
import { Navigate, useLocation } from "react-router";
import React from "react";
import React, { useCallback } from "react";
import { RowWrapper } from "@/widgets/RowWrapper.tsx";

function Login() {
const { login, loginState } = useAuth();
const { search } = useLocation();
const from = search.substring(1);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const onFinish = (values: any) => {
login(values.username, values.password);
};
const onFinish = useCallback(({ username, password }: { username: string; password: string }) => login(username, password), [login]);

if (loginState === LoginState.LOGGED_IN) {
return <Navigate to={decodeURIComponent(from)} />;
Expand Down
1 change: 1 addition & 0 deletions application/vue/src/app/useUpdateApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import noop from "lodash/noop";

export default function useUpdateApp() {
useRegisterSW({
onNeedRefresh: window.location.reload,
onRegisteredSW(_, r) {
r &&
setInterval(
Expand Down
27 changes: 10 additions & 17 deletions application/vue/src/components/content/HelpContent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { useMemo, useState } from "react";
import { useCallback, useMemo, useState } from "react";
import HelpVeranstaltungen from "@/components/content/help/HelpVeranstaltungen.tsx";
import HelpNeues from "@/components/content/help/HelpNeues.tsx";
import { FloatButton, Typography } from "antd";
Expand All @@ -21,9 +21,14 @@ export default function HelpContent() {
return pathname === "/veranstaltungen" || pathname === "/team" || pathname.startsWith("/konzert") || pathname.startsWith("/wiki");
}, [pathname]);

const closeHelp = useCallback(() => setHelpOpen(false), []);
const openHelp = useCallback(() => setHelpOpen(true), []);
const closeInfo = useCallback(() => setInfoOpen(false), []);
const openInfo = useCallback(() => setInfoOpen(true), []);

return (
<>
<JazzModal footer={null} onCancel={() => setHelpOpen(false)} open={helpOpen} title="Hilfe" width={600}>
<JazzModal footer={null} onCancel={closeHelp} open={helpOpen} title="Hilfe" width={600}>
<Typography.Title level={4}>Hilfe für aktuelle Seite</Typography.Title>
<p>Abhängig von Deinen Benutzerrechten sind einige Dinge für Dich nicht sichtbar oder aktiv.</p>
<HelpPrefs />
Expand All @@ -32,25 +37,13 @@ export default function HelpContent() {
<HelpKonzert />
<HelpWiki />
</JazzModal>
<JazzModal footer={null} onCancel={() => setInfoOpen(false)} open={infoOpen} title="Neuigkeiten" width={600}>
<JazzModal footer={null} onCancel={closeInfo} open={infoOpen} title="Neuigkeiten" width={600}>
<p>Dieser Dialog wird nach und nach mit Inhalten gefüllt...</p>
<HelpNeues />
</JazzModal>
<FloatButton.Group icon={<IconForSmallBlock iconName="QuestionLg" />} trigger="click">
{hasHelp ? (
<FloatButton
icon={<IconForSmallBlock iconName="QuestionLg" />}
onClick={() => {
setHelpOpen(true);
}}
/>
) : null}
<FloatButton
icon={<IconForSmallBlock iconName="InfoLg" />}
onClick={() => {
setInfoOpen(true);
}}
/>
{hasHelp ? <FloatButton icon={<IconForSmallBlock iconName="QuestionLg" />} onClick={openHelp} /> : null}
<FloatButton icon={<IconForSmallBlock iconName="InfoLg" />} onClick={openInfo} />
</FloatButton.Group>
</>
);
Expand Down
38 changes: 20 additions & 18 deletions application/vue/src/components/content/JazzDrawerWithForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,38 +93,40 @@ export default function JazzDrawerWithForm<T>({
return { checkDirty: updateDirtyIfChanged };
}, [updateDirtyIfChanged]);

const onClose = useCallback(() => setOpen(false), []);

const onKeyDown = useCallback((event: React.KeyboardEvent<HTMLFormElement>) => {
const target = event.target as HTMLInputElement;
if (event.key === "Enter" && target?.role !== "textbox" && event?.type === "textarea") {
event.preventDefault();
return false;
}
}, []);

const onValuesChange = useCallback(() => {
updateDirtyIfChanged();
checkErrors();
}, [checkErrors, updateDirtyIfChanged]);

const openDrawer = useCallback(() => setOpen(true), []);

return (
<JazzFormContext.Provider value={jazzFormContext}>
<Drawer
closable={!isDirty}
extra={buttons}
maskClosable={!isDirty}
onClose={() => setOpen(false)}
onClose={onClose}
open={open}
placement="top"
size="large"
title={title}
>
<Form
colon={false}
form={form}
layout="vertical"
onKeyDown={(event) => {
const target = event.target as HTMLInputElement;
if (event.key === "Enter" && target?.role !== "textbox" && event?.type === "textarea") {
event.preventDefault();
return false;
}
}}
onValuesChange={() => {
updateDirtyIfChanged();
checkErrors();
}}
>
<Form colon={false} form={form} layout="vertical" onKeyDown={onKeyDown} onValuesChange={onValuesChange}>
<RowWrapper>{children}</RowWrapper>
</Form>
</Drawer>
<ButtonWithIcon alwaysText block color={color(buttonType)} icon={icon(buttonType)} onClick={() => setOpen(true)} text={buttonText} />
<ButtonWithIcon alwaysText block color={color(buttonType)} icon={icon(buttonType)} onClick={openDrawer} text={buttonText} />
</JazzFormContext.Provider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export default function JazzFormAndHeaderExtended<T>({
const [loaded, setLoaded] = useState(false);
useDirtyBlocker(isDirty);
const { hasErrors, checkErrors } = useCheckErrors(form, loaded);

const updateDirtyIfChanged = useCallback(() => {
const curr = form.getFieldsValue(true);
logDiffForDirty(initialValue, curr, false);
Expand Down Expand Up @@ -89,33 +88,34 @@ export default function JazzFormAndHeaderExtended<T>({
return { checkDirty: updateDirtyIfChanged };
}, [updateDirtyIfChanged]);

const onFinish = useCallback(
() =>
form
.validateFields()
.then(async () => {
setIsDirty(false);
saveForm(form.getFieldsValue(true));
})
.catch(checkErrors),
[checkErrors, form, saveForm, setIsDirty],
);

const onKeyDown = useCallback((event: React.KeyboardEvent<HTMLFormElement>) => {
const target = event.target as HTMLInputElement;
if (event.key === "Enter" && target?.role !== "textbox" && event?.type === "textarea") {
event.preventDefault();
return false;
}
}, []);

const onValuesChange = useCallback(() => {
updateDirtyIfChanged();
checkErrors();
}, [checkErrors, updateDirtyIfChanged]);

return (
<JazzFormContext.Provider value={jazzFormContext}>
<Form
colon={false}
form={form}
layout="vertical"
onFinish={() =>
form
.validateFields()
.then(async () => {
setIsDirty(false);
saveForm(form.getFieldsValue(true));
})
.catch(checkErrors)
}
onKeyDown={(event) => {
const target = event.target as HTMLInputElement;
if (event.key === "Enter" && target?.role !== "textbox" && event?.type === "textarea") {
event.preventDefault();
return false;
}
}}
onValuesChange={() => {
updateDirtyIfChanged();
checkErrors();
}}
>
<Form colon={false} form={form} layout="vertical" onFinish={onFinish} onKeyDown={onKeyDown} onValuesChange={onValuesChange}>
<JazzPageHeader
breadcrumb={breadcrumb}
buttons={buttons}
Expand Down
25 changes: 12 additions & 13 deletions application/vue/src/components/content/help/HelpSection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Collapse, ConfigProvider, List } from "antd";
import { ReactNode } from "react";
import { ReactNode, useCallback } from "react";

export default function HelpSection({
initiallyOpen,
Expand All @@ -10,6 +10,16 @@ export default function HelpSection({
readonly label: ReactNode;
readonly items: { title: ReactNode; content: ReactNode; description?: string }[];
}) {
const renderItem = useCallback(
(item: { title: ReactNode; content: ReactNode; description?: string }) => (
<List.Item>
<List.Item.Meta description={item.description} title={item.title} />
{item.content}
</List.Item>
),
[],
);

return (
<ConfigProvider theme={{ components: { Collapse: { contentPadding: 0, headerPadding: 0 } } }}>
<Collapse
Expand All @@ -19,18 +29,7 @@ export default function HelpSection({
{
key: initiallyOpen ? "stuff" : "",
label: label,
children: (
<List
bordered
dataSource={items}
renderItem={(item) => (
<List.Item>
<List.Item.Meta description={item.description} title={item.title} />
{item.content}
</List.Item>
)}
/>
),
children: <List bordered dataSource={items} renderItem={renderItem} />,
},
]}
/>
Expand Down
Loading