Added the cost editor
This commit is contained in:
parent
083d79caaa
commit
066709eddb
5
public/locales/bg/budgetOption.json
Normal file
5
public/locales/bg/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Не прикажи",
|
||||||
|
"ShowAndEdit": "Прикажи и уреди",
|
||||||
|
"ShowOnly": "Прикажи само"
|
||||||
|
}
|
||||||
5
public/locales/bg/priority.json
Normal file
5
public/locales/bg/priority.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"High": "Висок",
|
||||||
|
"Low": "Нисак",
|
||||||
|
"Normal": "Нормално"
|
||||||
|
}
|
||||||
5
public/locales/cs/budgetOption.json
Normal file
5
public/locales/cs/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Nepokážte.",
|
||||||
|
"ShowAndEdit": "Zobrazit a upravit",
|
||||||
|
"ShowOnly": "Zobrazit pouze"
|
||||||
|
}
|
||||||
5
public/locales/cs/priority.json
Normal file
5
public/locales/cs/priority.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"High": "Vysoký",
|
||||||
|
"Low": "Nízký",
|
||||||
|
"Normal": "Normální"
|
||||||
|
}
|
||||||
5
public/locales/de/budgetOption.json
Normal file
5
public/locales/de/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Nicht anzeigen",
|
||||||
|
"ShowAndEdit": "Anzeigen und Bearbeiten",
|
||||||
|
"ShowOnly": "Nur anzeigen"
|
||||||
|
}
|
||||||
4
public/locales/de/priority.json
Normal file
4
public/locales/de/priority.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"High": "Hoch",
|
||||||
|
"Low": "Niedrig"
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"DoNotShow": "Do Not Show",
|
"DoNotShow": "Do Not Show",
|
||||||
"ShowOnly": "Show Only",
|
"ShowAndEdit": "Show And Edit",
|
||||||
"ShowAndEdit": "Show And Edit"
|
"ShowOnly": "Show Only"
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"High": "High",
|
||||||
"Low": "Low",
|
"Low": "Low",
|
||||||
"Normal": "Normal",
|
"Normal": "Normal"
|
||||||
"High": "High"
|
|
||||||
}
|
}
|
||||||
5
public/locales/es/budgetOption.json
Normal file
5
public/locales/es/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "No mostrar",
|
||||||
|
"ShowAndEdit": "Mostrar y editar",
|
||||||
|
"ShowOnly": "Mostrar solo"
|
||||||
|
}
|
||||||
4
public/locales/es/priority.json
Normal file
4
public/locales/es/priority.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"High": "Alto",
|
||||||
|
"Low": "Bajo"
|
||||||
|
}
|
||||||
5
public/locales/fr/budgetOption.json
Normal file
5
public/locales/fr/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Ne pas afficher",
|
||||||
|
"ShowAndEdit": "Afficher et modifier",
|
||||||
|
"ShowOnly": "Afficher uniquement"
|
||||||
|
}
|
||||||
4
public/locales/fr/priority.json
Normal file
4
public/locales/fr/priority.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"High": "Élevé",
|
||||||
|
"Low": "Faible"
|
||||||
|
}
|
||||||
5
public/locales/ko/budgetOption.json
Normal file
5
public/locales/ko/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "표시하지 마세요",
|
||||||
|
"ShowAndEdit": "보기 및 편집",
|
||||||
|
"ShowOnly": "쇼 온리"
|
||||||
|
}
|
||||||
4
public/locales/ko/priority.json
Normal file
4
public/locales/ko/priority.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"Low": "로우",
|
||||||
|
"Normal": "정상"
|
||||||
|
}
|
||||||
5
public/locales/nl/budgetOption.json
Normal file
5
public/locales/nl/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Niet weergeven",
|
||||||
|
"ShowAndEdit": "Weergeven en bewerken",
|
||||||
|
"ShowOnly": "Alleen weergeven"
|
||||||
|
}
|
||||||
5
public/locales/nl/priority.json
Normal file
5
public/locales/nl/priority.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"High": "Hoog",
|
||||||
|
"Low": "Laag",
|
||||||
|
"Normal": "Normaal"
|
||||||
|
}
|
||||||
5
public/locales/pl/budgetOption.json
Normal file
5
public/locales/pl/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Nie wyświetlać",
|
||||||
|
"ShowAndEdit": "Pokaż i edytuj",
|
||||||
|
"ShowOnly": "Pokaż tylko"
|
||||||
|
}
|
||||||
4
public/locales/pl/priority.json
Normal file
4
public/locales/pl/priority.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"High": "Wysoki",
|
||||||
|
"Low": "Niski"
|
||||||
|
}
|
||||||
5
public/locales/pt/budgetOption.json
Normal file
5
public/locales/pt/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Não exibir",
|
||||||
|
"ShowAndEdit": "Mostrar e Editar",
|
||||||
|
"ShowOnly": "Mostrar apenas"
|
||||||
|
}
|
||||||
5
public/locales/pt/priority.json
Normal file
5
public/locales/pt/priority.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"High": "Alto",
|
||||||
|
"Low": "Baixo",
|
||||||
|
"Normal": "Normal."
|
||||||
|
}
|
||||||
5
public/locales/uk/budgetOption.json
Normal file
5
public/locales/uk/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "Не відображати",
|
||||||
|
"ShowAndEdit": "Показати та редагувати",
|
||||||
|
"ShowOnly": "Показати тільки"
|
||||||
|
}
|
||||||
5
public/locales/uk/priority.json
Normal file
5
public/locales/uk/priority.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"High": "Високий",
|
||||||
|
"Low": "Низький",
|
||||||
|
"Normal": "Звичайний"
|
||||||
|
}
|
||||||
5
public/locales/ur/budgetOption.json
Normal file
5
public/locales/ur/budgetOption.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"DoNotShow": "न दिखाएं।",
|
||||||
|
"ShowAndEdit": "دکھائیں اور ترمیم کریں",
|
||||||
|
"ShowOnly": "صرف ذلك هو المطلوب."
|
||||||
|
}
|
||||||
5
public/locales/ur/priority.json
Normal file
5
public/locales/ur/priority.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"High": "بहुत ऊँचा",
|
||||||
|
"Low": "کम",
|
||||||
|
"Normal": "سामान्य"
|
||||||
|
}
|
||||||
80
src/components/common/CostEditor.tsx
Normal file
80
src/components/common/CostEditor.tsx
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import Input, { InputType } from "./Input";
|
||||||
|
|
||||||
|
export type CostValue = {
|
||||||
|
amount: number;
|
||||||
|
isoCurrencySymbol: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface CostEditorProps {
|
||||||
|
name: string;
|
||||||
|
value: CostValue;
|
||||||
|
amountLabel?: string;
|
||||||
|
currencyLabel?: string;
|
||||||
|
amountError?: string;
|
||||||
|
currencyError?: string;
|
||||||
|
onChange: (value: CostValue) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeAmount(rawValue: string) {
|
||||||
|
if (rawValue.trim() === "") {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsed = Number(rawValue);
|
||||||
|
return Number.isFinite(parsed) ? parsed : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CostEditor(props: CostEditorProps) {
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
amountLabel,
|
||||||
|
currencyLabel,
|
||||||
|
amountError,
|
||||||
|
currencyError,
|
||||||
|
onChange,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const currentValue: CostValue = {
|
||||||
|
amount: value?.amount ?? 0,
|
||||||
|
isoCurrencySymbol: value?.isoCurrencySymbol ?? "",
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<Input
|
||||||
|
includeLabel={false}
|
||||||
|
name={`${name}-amount`}
|
||||||
|
label={amountLabel ?? "Amount"}
|
||||||
|
title={amountLabel ?? "Amount"}
|
||||||
|
type={InputType.number}
|
||||||
|
value={currentValue.amount}
|
||||||
|
step={0.01}
|
||||||
|
error={amountError ?? ""}
|
||||||
|
onChange={(event) => {
|
||||||
|
const nextAmount = normalizeAmount(String(event.target.value));
|
||||||
|
onChange({
|
||||||
|
...currentValue,
|
||||||
|
amount: nextAmount,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
includeLabel={false}
|
||||||
|
name={`${name}-currency`}
|
||||||
|
label={currencyLabel ?? "Currency"}
|
||||||
|
title={currencyLabel ?? "Currency"}
|
||||||
|
type={InputType.text}
|
||||||
|
value={currentValue.isoCurrencySymbol}
|
||||||
|
maxLength={3}
|
||||||
|
error={currencyError ?? ""}
|
||||||
|
onChange={(event) => {
|
||||||
|
onChange({
|
||||||
|
...currentValue,
|
||||||
|
isoCurrencySymbol: String(event.target.value).toUpperCase(),
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import ErrorBlock from "./ErrorBlock";
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
|
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { Checklist } from "./Checklist";
|
import { Checklist } from "./Checklist";
|
||||||
|
import CostEditor, { CostValue } from "./CostEditor";
|
||||||
import { TagsInput } from "./inputTags";
|
import { TagsInput } from "./inputTags";
|
||||||
|
|
||||||
export enum InputType {
|
export enum InputType {
|
||||||
@ -11,6 +12,7 @@ export enum InputType {
|
|||||||
checkbox = "checkbox",
|
checkbox = "checkbox",
|
||||||
checklist = "checklist",
|
checklist = "checklist",
|
||||||
color = "color",
|
color = "color",
|
||||||
|
cost = "cost",
|
||||||
date = "date",
|
date = "date",
|
||||||
datetimelocal = "datetime-local",
|
datetimelocal = "datetime-local",
|
||||||
email = "email",
|
email = "email",
|
||||||
@ -42,7 +44,7 @@ export interface InputProps {
|
|||||||
placeHolder?: string;
|
placeHolder?: string;
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
type: InputType;
|
type: InputType;
|
||||||
value?: string | number | readonly string[] | boolean | undefined;
|
value?: string | number | readonly string[] | boolean | CostValue | undefined;
|
||||||
defaultValue?: string | number | readonly string[] | undefined;
|
defaultValue?: string | number | readonly string[] | undefined;
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
@ -147,6 +149,18 @@ function Input(props: InputProps) {
|
|||||||
error={props.error}
|
error={props.error}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
[InputType.cost]: (props) => (
|
||||||
|
<CostEditor
|
||||||
|
name={name}
|
||||||
|
value={(value ?? { amount: 0, isoCurrencySymbol: "" }) as CostValue}
|
||||||
|
amountError={error}
|
||||||
|
onChange={(nextValue) => {
|
||||||
|
onChange?.({
|
||||||
|
target: { value: nextValue },
|
||||||
|
} as any);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
|
||||||
// future controls go here
|
// future controls go here
|
||||||
};
|
};
|
||||||
|
|||||||
@ -28,7 +28,14 @@ export const BudgetEditor: React.FC<CapabilityEditorProps> = (props) => {
|
|||||||
InputType.number,
|
InputType.number,
|
||||||
fieldErrors,
|
fieldErrors,
|
||||||
)}
|
)}
|
||||||
<div>Cost goes here</div>
|
{renderTaskField(
|
||||||
|
task,
|
||||||
|
onChange,
|
||||||
|
"cost",
|
||||||
|
"Cost",
|
||||||
|
InputType.cost,
|
||||||
|
fieldErrors,
|
||||||
|
)}
|
||||||
<BudgetOptionPicker
|
<BudgetOptionPicker
|
||||||
includeLabel={true}
|
includeLabel={true}
|
||||||
name="budgetOption"
|
name="budgetOption"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user