Skip to content

Commit

Permalink
fix: keg donors uses wrong foreign key
Browse files Browse the repository at this point in the history
  • Loading branch information
czabaj committed Jul 22, 2023
1 parent d837f05 commit f87ac18
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 59 deletions.
4 changes: 3 additions & 1 deletion src/components/InputDonors/InputDonors.gen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import type {element as Jsx_element} from './Jsx.gen';

import type {t as Dict_t} from './Dict.gen';

import type {t as Map_t} from './Map.gen';

// tslint:disable-next-line:interface-over-type-literal
export type props<errorMessage,legendSlot,persons,value,onChange> = {
readonly errorMessage?: errorMessage;
Expand All @@ -19,4 +21,4 @@ export type props<errorMessage,legendSlot,persons,value,onChange> = {
readonly onChange: onChange
};

export const make: (_1:props<string,JSX.Element,string[],Dict_t<number>,((_1:Dict_t<number>) => void)>) => Jsx_element = InputDonorsBS.make;
export const make: (_1:props<string,JSX.Element,Map_t<string,string>,Dict_t<number>,((_1:Dict_t<number>) => void)>) => Jsx_element = InputDonorsBS.make;
12 changes: 10 additions & 2 deletions src/components/InputDonors/InputDonors.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@
.root table :where(td, th) {
text-align: left;
}
.root table :where(td, th):last-child {
inline-size: 4ch;
}
.root table input[type="number"] {
inline-size: 8ch;
inline-size: 10ch;
}
.root tbody th {
font-weight: var(--font-weight-regular);
}

.root tbody select {
width: 100%;
}

.root legend {
font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-regular);
font-size: var(--font-size-18);
margin-block-end: 0.5rem;
}
36 changes: 20 additions & 16 deletions src/components/InputDonors/InputDonors.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ type classesType = {root: string}
@module("./InputDonors.module.css") external classes: classesType = "default"

@gentype @react.component
let make = (~errorMessage=?, ~legendSlot=?, ~persons, ~value, ~onChange) => {
let make = (~errorMessage=?, ~legendSlot=?, ~persons: Map.t<string, string>, ~value, ~onChange) => {
let {minorUnit} = FormattedCurrency.useCurrency()
let (valueEntries, availableNames, amountsSum) = React.useMemo1(() => {
let (valueEntries, unusedPersons, amountsSum) = React.useMemo1(() => {
let entries = value->Dict.toArray
let names = entries->Array.map(((name, _)) => name)
let usedNames = Set.fromArray(names)
let unusedNames = persons->Array.filter(name => !(usedNames->Set.has(name)))
let unused =
persons
->Map.entries
->Iterator.toArray
->Array.filter(((personId, _)) => value->Dict.get(personId) === None)
let sum = entries->Array.reduce(0, (acc, (_, amount)) => acc + amount)
(entries, unusedNames, sum)
(entries, unused, sum)
}, [value])
<fieldset className={`reset ${classes.root}`}>
{switch legendSlot {
Expand All @@ -29,9 +31,9 @@ let make = (~errorMessage=?, ~legendSlot=?, ~persons, ~value, ~onChange) => {
</thead>
<tbody>
{valueEntries
->Array.map(((name, amount)) => {
<tr key={name}>
<th scope="row"> {React.string(name)} </th>
->Array.map(((personId, amount)) => {
<tr key={personId}>
<th scope="row"> {React.string(persons->Map.get(personId)->Option.getExn)} </th>
<td>
<input
min="0"
Expand All @@ -40,7 +42,7 @@ let make = (~errorMessage=?, ~legendSlot=?, ~persons, ~value, ~onChange) => {
let newAmount = target["valueAsNumber"]
let newAmountInt = (newAmount *. minorUnit)->Int.fromFloat
let newValue = value->Dict.copy
newValue->Dict.set(name, newAmountInt)
newValue->Dict.set(personId, newAmountInt)
onChange(newValue)
}}
step=1.
Expand All @@ -53,10 +55,10 @@ let make = (~errorMessage=?, ~legendSlot=?, ~persons, ~value, ~onChange) => {
className={`${Styles.button.base} ${Styles.button.iconOnly} ${Styles.button.sizeExtraSmall}`}
onClick={_ => {
let newValue = value->Dict.copy
newValue->Dict.delete(name)
newValue->Dict.delete(personId)
onChange(newValue)
}}
title="Odebrat donátora"
title="Odebrat vkladatele"
type_="button">
{React.string("❌")}
</button>
Expand All @@ -67,9 +69,9 @@ let make = (~errorMessage=?, ~legendSlot=?, ~persons, ~value, ~onChange) => {
</tbody>
<tbody>
<tr>
<td>
<td colSpan=2>
<select
disabled={availableNames->Array.length === 0}
disabled={unusedPersons->Array.length === 0}
onChange={event => {
let person = ReactEvent.Form.target(event)["value"]
if person !== "" {
Expand All @@ -80,8 +82,10 @@ let make = (~errorMessage=?, ~legendSlot=?, ~persons, ~value, ~onChange) => {
}}
value="">
<option disabled={true} value=""> {React.string("Přidat vkladatele")} </option>
{availableNames
->Array.map(name => <option key={name} value={name}> {React.string(name)} </option>)
{unusedPersons
->Array.map(((personId, name)) =>
<option key={personId} value={personId}> {React.string(name)} </option>
)
->React.array}
</select>
</td>
Expand Down
14 changes: 11 additions & 3 deletions src/components/InputDonors/InputDonors.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ const Wrapper = (args: any) => {
export const Base: StoryObj = {
args: {
legendSlot: "Vkladatelé sudu",
value: { Petr: 10000 },
persons: ["Petr", "Jana", "Karel"],
value: { PetrId: 10000 },
persons: new Map([
["PetrId", "Petr"],
["JanaId", "Jana"],
["KarelId", "Karel"],
]),
},
render: Wrapper,
};
Expand All @@ -38,7 +42,11 @@ export const Error: StoryObj = {
args: {
errorMessage: "Error message",
value: {},
persons: ["Petr", "Jana", "Karel"],
persons: new Map([
["PetrId", "Petr"],
["JanaId", "Jana"],
["KarelId", "Karel"],
]),
},
render: Wrapper,
};
44 changes: 44 additions & 0 deletions src/components/InputToggle/InputToggle.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.root {
--toggle-width: 40px;
--toggle-height: calc(var(--toggle-width) / 2);

display: inline-block;
position: relative;
}

.root input {
cursor: pointer;
inset: 0;
opacity: 0;
position: absolute;
z-index: 1;
}

.root div {
position: relative;
width: var(--toggle-width);
height: var(--toggle-height);
border-radius: var(--radius-round);
background: var(--surface-3);
transition: background var(--transition-fast);
}

.root div::after {
content: "";
position: absolute;
top: 0;
left: 0;
height: var(--toggle-height);
width: var(--toggle-height);
background: var(--surface-2);
box-shadow: var(--shadow-4);
border-radius: var(--radius-round);
transition: transform var(--transition-fast);
}

.root input:checked + div {
background: #009578;
}
.root input:checked + div::after {
transform: translateX(var(--toggle-height));
}
16 changes: 16 additions & 0 deletions src/components/InputToggle/InputToggle.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
type classesType = {root: string}
@module("./InputToggle.module.css") external classes: classesType = "default"

@react.component
let make = (~\"aria-describedby"=?, ~\"aria-invalid"=?, ~checked, ~id=?, ~name=?, ~onChange) => {
<div className=classes.root>
{React.cloneElement(
<input checked ?id ?name type_="checkbox" onChange />,
{
"aria-describedby": \"aria-describedby",
"aria-invalid": \"aria-invalid",
},
)}
<div />
</div>
}
10 changes: 7 additions & 3 deletions src/components/InputWrapper/InputWrapper.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
gap: 1rem;
}

:global(.inputWrapper) :where(input, select) {
border: var(--border-size-1) solid var(--surface-1);
:global(.inputWrapper) :where(p) {
margin: 0;
}

:global(.inputWrapper) :where(input, select)[aria-invalid="true"] {
border-color: var(--surface-danger);
}

:global(.inputWrapper) > div > div:first-child {
display: flex;
gap: 0.5rem;
}

.errorMessage {
font-size: 75%;
margin: 0;
color: var(--text-danger);
}
31 changes: 19 additions & 12 deletions src/components/InputWrapper/InputWrapper.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type classesType = {errorMessage: string, hasError: string, root: string}
type classesType = {description: string, errorMessage: string, hasError: string, root: string}
@module("./InputWrapper.module.css") external classes: classesType = "default"

module ErrorMessage = {
Expand All @@ -9,21 +9,28 @@ module ErrorMessage = {
}

@react.component
let make = (~className=?, ~inputError=?, ~inputName, ~inputSlot, ~labelSlot) => {
let make = (~className=?, ~inputError=?, ~inputName, ~inputSlot, ~labelSlot, ~unitSlot=?) => {
let unitId = unitSlot !== None ? `${inputName}_unit` : ""
let hasError = inputError != None
let errorId = `${inputName}-error`
let errorId = hasError ? `${inputName}_error` : ""
<div className={`inputWrapper ${className->Option.getWithDefault("")}`}>
<label htmlFor=inputName> {labelSlot} </label>
<div>
{React.cloneElement(
inputSlot,
{
"aria-invalid": hasError ? "true" : "",
"aria-describedby": hasError ? errorId : "",
"id": inputName,
"name": className,
},
)}
<div>
{React.cloneElement(
inputSlot,
{
"aria-describedby": `${errorId} ${unitId}`,
"aria-invalid": hasError ? "true" : "false",
"id": inputName,
"name": className,
},
)}
{switch unitSlot {
| None => React.null
| Some(description) => <p className={classes.description} id={unitId}> {description} </p>
}}
</div>
{switch inputError {
| None => React.null
| Some(errorMessage) => <ErrorMessage id={errorId} message={errorMessage} />
Expand Down
9 changes: 9 additions & 0 deletions src/pages/PlaceSetting/KegAddNew.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.form {
display: flex;
flex-direction: column;
gap: 2rem;
}

.form > fieldset:first-child input[type="number"] {
width: 10ch;
}
Loading

0 comments on commit f87ac18

Please sign in to comment.