diff --git a/src/actions/form-template-item-actions.js b/src/actions/form-template-item-actions.js
index 705e81930..6d6fb664e 100644
--- a/src/actions/form-template-item-actions.js
+++ b/src/actions/form-template-item-actions.js
@@ -22,7 +22,6 @@ import {
startLoading,
escapeFilterValue
} from "openstack-uicore-foundation/lib/utils/actions";
-import { rateToCents } from "../utils/rate-helpers";
import { snackbarErrorHandler, snackbarSuccessHandler } from "./base-actions";
import { getAccessTokenSafely } from "../utils/methods";
import {
@@ -178,11 +177,6 @@ const normalizeEntity = (entity) => {
normalizedEntity.images = normalizedEntity.images?.filter(
(img) => img.file_path
);
- normalizedEntity.early_bird_rate = rateToCents(
- normalizedEntity.early_bird_rate
- );
- normalizedEntity.standard_rate = rateToCents(normalizedEntity.standard_rate);
- normalizedEntity.onsite_rate = rateToCents(normalizedEntity.onsite_rate);
return normalizedEntity;
};
diff --git a/src/actions/inventory-item-actions.js b/src/actions/inventory-item-actions.js
index ced14ab19..86ab71f39 100644
--- a/src/actions/inventory-item-actions.js
+++ b/src/actions/inventory-item-actions.js
@@ -25,7 +25,6 @@ import {
authErrorHandler,
escapeFilterValue
} from "openstack-uicore-foundation/lib/utils/actions";
-import { rateToCents } from "../utils/rate-helpers";
import history from "../history";
import { getAccessTokenSafely } from "../utils/methods";
import {
@@ -200,12 +199,6 @@ const normalizeEntity = (entity) => {
(img) => img.file_path
);
- normalizedEntity.early_bird_rate = rateToCents(
- normalizedEntity.early_bird_rate
- );
- normalizedEntity.standard_rate = rateToCents(normalizedEntity.standard_rate);
- normalizedEntity.onsite_rate = rateToCents(normalizedEntity.onsite_rate);
-
return normalizedEntity;
};
diff --git a/src/actions/sponsor-forms-actions.js b/src/actions/sponsor-forms-actions.js
index 9bb70cf6e..3883ed1dd 100644
--- a/src/actions/sponsor-forms-actions.js
+++ b/src/actions/sponsor-forms-actions.js
@@ -29,7 +29,6 @@ import {
getAccessTokenSafely,
normalizeSelectAllField
} from "../utils/methods";
-import { rateToCents, RATE_FIELDS } from "../utils/rate-helpers";
import {
DEFAULT_CURRENT_PAGE,
DEFAULT_ORDER_DIR,
@@ -1238,8 +1237,6 @@ const normalizeItem = (entity) => {
normalizedEntity.images = images?.filter((img) => img.file_path);
}
- normalizeRates(entity, normalizedEntity);
-
if (quantity_limit_per_show === "")
delete normalizedEntity.quantity_limit_per_show;
if (quantity_limit_per_sponsor === "")
@@ -1363,26 +1360,9 @@ const normalizeManagedItem = (entity) => {
(img) => img.file_path
);
- normalizeRates(entity, normalizedEntity);
-
return normalizedEntity;
};
-const normalizeRates = (entity, normalizedEntity) => {
- if (RATE_FIELDS.EARLY_BIRD in entity)
- normalizedEntity[RATE_FIELDS.EARLY_BIRD] = rateToCents(
- entity[RATE_FIELDS.EARLY_BIRD]
- );
- if (RATE_FIELDS.STANDARD in entity)
- normalizedEntity[RATE_FIELDS.STANDARD] = rateToCents(
- entity[RATE_FIELDS.STANDARD]
- );
- if (RATE_FIELDS.ONSITE in entity)
- normalizedEntity[RATE_FIELDS.ONSITE] = rateToCents(
- entity[RATE_FIELDS.ONSITE]
- );
-};
-
export const deleteSponsorFormManagedItem =
(formId, itemId) => async (dispatch, getState) => {
const { currentSummitState, currentSponsorState } = getState();
diff --git a/src/components/mui/formik-inputs/item-price-tiers.js b/src/components/mui/formik-inputs/item-price-tiers.js
index 6bdd2a235..43b6f5825 100644
--- a/src/components/mui/formik-inputs/item-price-tiers.js
+++ b/src/components/mui/formik-inputs/item-price-tiers.js
@@ -67,6 +67,7 @@ const ItemPriceTiers = ({ readOnly = false }) => {
) : (
diff --git a/src/components/mui/formik-inputs/mui-formik-pricefield.js b/src/components/mui/formik-inputs/mui-formik-pricefield.js
index 193b08637..5c2bc08c2 100644
--- a/src/components/mui/formik-inputs/mui-formik-pricefield.js
+++ b/src/components/mui/formik-inputs/mui-formik-pricefield.js
@@ -17,23 +17,45 @@ const MuiFormikPriceField = ({
// eslint-disable-next-line no-unused-vars
const [field, meta, helpers] = useField(name);
const [cleared, setCleared] = useState(false);
+ const [isFocused, setIsFocused] = useState(false);
+ const [focusedValue, setFocusedValue] = useState("");
- const emptyValue = meta.initialValue === null ? null : 0;
+ // emptyValue is always 0 when editing this field, null is handled by N/A checkbox
+ const emptyValue = 0;
+
+ const getRawString = () => {
+ if (cleared || field.value == null) return "";
+ if (field.value === 0) return "0";
+ const raw = inCents ? field.value / ONE_HUNDRED : field.value;
+ return String(Number(raw.toFixed(DECIMAL_DIGITS)));
+ };
const getDisplayValue = () => {
+ if (isFocused) return focusedValue;
if (cleared) return "";
if (field.value == null || field.value === 0) {
return field.value === 0 ? 0 : "";
}
- const raw = inCents ? field.value / ONE_HUNDRED : field.value;
- const str = String(Number(raw.toFixed(DECIMAL_DIGITS)));
+ const str = getRawString();
const dotIdx = str.indexOf(".");
if (dotIdx !== -1 && str.length - dotIdx - 1 === 1) return `${str}0`;
return str;
};
+ const handleFocus = () => {
+ setIsFocused(true);
+ setFocusedValue(getRawString());
+ };
+
+ const handleBlur = (e) => {
+ setIsFocused(false);
+ field.onBlur(e);
+ if (props.onBlur) props.onBlur(e);
+ };
+
const handleChange = (e) => {
const newVal = e.target.value;
+ setFocusedValue(newVal);
if (newVal === "") {
setCleared(true);
@@ -64,6 +86,8 @@ const MuiFormikPriceField = ({
type="number"
value={getDisplayValue()}
onChange={handleChange}
+ onFocus={handleFocus}
+ onBlur={handleBlur}
slotProps={{
input: {
startAdornment: $
diff --git a/src/pages/sponsors/sponsor-form-item-list-page/index.js b/src/pages/sponsors/sponsor-form-item-list-page/index.js
index 532af58c3..321f88c5f 100644
--- a/src/pages/sponsors/sponsor-form-item-list-page/index.js
+++ b/src/pages/sponsors/sponsor-form-item-list-page/index.js
@@ -41,6 +41,7 @@ import SponsorFormAddItemFromInventoryPopup from "./components/sponsor-form-add-
import MuiTableEditable from "../../../components/mui/editable-table/mui-table-editable";
import { DEFAULT_CURRENT_PAGE } from "../../../utils/constants";
import { rateCellValidation } from "../../../utils/yup";
+import { rateToCents } from "../../../utils/rate-helpers";
const SponsorFormItemListPage = ({
match,
@@ -91,8 +92,9 @@ const SponsorFormItemListPage = ({
};
const handleCellEdit = (rowId, column, value) => {
- const valueWithNoSign = String(value).replace(/^[^\d.-]+/, "");
- const tmpEntity = { id: rowId, [column]: valueWithNoSign };
+ // since editable cell is TextField and not PriceField, we need to convert to cents
+ const valueInCents = rateToCents(value);
+ const tmpEntity = { id: rowId, [column]: valueInCents };
updateSponsorFormItem(formId, tmpEntity);
};
diff --git a/src/pages/sponsors/sponsor-forms-tab/components/manage-items/sponsor-forms-manage-items.js b/src/pages/sponsors/sponsor-forms-tab/components/manage-items/sponsor-forms-manage-items.js
index 54ceb0de0..783112d06 100644
--- a/src/pages/sponsors/sponsor-forms-tab/components/manage-items/sponsor-forms-manage-items.js
+++ b/src/pages/sponsors/sponsor-forms-tab/components/manage-items/sponsor-forms-manage-items.js
@@ -43,6 +43,7 @@ import SponsorInventoryDialog from "../../../../sponsors-global/form-templates/s
import SponsorFormItemFromInventoryPopup from "./sponsor-form-item-from-inventory";
import { DEFAULT_CURRENT_PAGE } from "../../../../../utils/constants";
import { rateCellValidation } from "../../../../../utils/yup";
+import { rateToCents } from "../../../../../utils/rate-helpers";
const SponsorFormsManageItems = ({
term,
@@ -167,11 +168,13 @@ const SponsorFormsManageItems = ({
};
const handleCellEdit = (rowId, column, value) => {
- const valueWithNoSign = String(value).replace(/^[^\d.-]+/, "");
+ // since editable cell is TextField and not PriceField, we need to convert to cents
+ const valueInCents = rateToCents(value);
const tmpEntity = {
id: rowId,
- [column]: valueWithNoSign
+ [column]: valueInCents
};
+
saveSponsorFormManagedItem(formId, tmpEntity);
};
diff --git a/src/reducers/sponsors/__tests__/sponsor-form-items-list-reducer.test.js b/src/reducers/sponsors/__tests__/sponsor-form-items-list-reducer.test.js
index a33b5d430..ed56c4be1 100644
--- a/src/reducers/sponsors/__tests__/sponsor-form-items-list-reducer.test.js
+++ b/src/reducers/sponsors/__tests__/sponsor-form-items-list-reducer.test.js
@@ -183,9 +183,6 @@ describe("SponsorFormItemsListReducer", () => {
...initialState,
currentItem: {
...item,
- early_bird_rate: "1.00",
- standard_rate: "1.00",
- onsite_rate: "1.00",
meta_fields: []
}
});
diff --git a/src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js b/src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js
index 3d47f6452..fafbfbfa9 100644
--- a/src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js
+++ b/src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js
@@ -12,7 +12,7 @@
* */
import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions";
-import { formatRateFromCents, rateFromCents } from "../../utils/rate-helpers";
+import { formatRateFromCents } from "../../utils/rate-helpers";
import {
RECEIVE_SPONSOR_CUSTOMIZED_FORM_ITEMS,
REQUEST_SPONSOR_CUSTOMIZED_FORM_ITEMS,
@@ -110,9 +110,6 @@ const sponsorCustomizedFormItemsListReducer = (
const currentItem = {
...item,
- early_bird_rate: rateFromCents(item.early_bird_rate),
- standard_rate: rateFromCents(item.standard_rate),
- onsite_rate: rateFromCents(item.onsite_rate),
meta_fields: item.meta_fields.length > 0 ? item.meta_fields : []
};
return { ...state, currentItem };
diff --git a/src/reducers/sponsors/sponsor-form-items-list-reducer.js b/src/reducers/sponsors/sponsor-form-items-list-reducer.js
index a9779cdfe..817e2c773 100644
--- a/src/reducers/sponsors/sponsor-form-items-list-reducer.js
+++ b/src/reducers/sponsors/sponsor-form-items-list-reducer.js
@@ -12,7 +12,7 @@
* */
import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions";
-import { formatRateFromCents, rateFromCents } from "../../utils/rate-helpers";
+import { formatRateFromCents } from "../../utils/rate-helpers";
import {
RECEIVE_SPONSOR_FORM_ITEM,
RECEIVE_SPONSOR_FORM_ITEMS,
@@ -100,9 +100,6 @@ const sponsorFormItemsListReducer = (state = DEFAULT_STATE, action) => {
const currentItem = {
...item,
- early_bird_rate: rateFromCents(item.early_bird_rate),
- standard_rate: rateFromCents(item.standard_rate),
- onsite_rate: rateFromCents(item.onsite_rate),
meta_fields: item.meta_fields.length > 0 ? item.meta_fields : []
};
diff --git a/src/reducers/sponsors_inventory/form-template-item-reducer.js b/src/reducers/sponsors_inventory/form-template-item-reducer.js
index 8b900dc94..2e616a7a0 100644
--- a/src/reducers/sponsors_inventory/form-template-item-reducer.js
+++ b/src/reducers/sponsors_inventory/form-template-item-reducer.js
@@ -12,7 +12,7 @@
* */
import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions";
-import { RATE_FIELDS, rateFromCents } from "../../utils/rate-helpers";
+import { RATE_FIELDS } from "../../utils/rate-helpers";
import {
RECEIVE_FORM_TEMPLATE_ITEM,
RESET_FORM_TEMPLATE_ITEM_FORM,
@@ -70,10 +70,6 @@ const formTemplateItemReducer = (state = DEFAULT_STATE, action) => {
}
}
- entity.early_bird_rate = rateFromCents(entity.early_bird_rate);
- entity.standard_rate = rateFromCents(entity.standard_rate);
- entity.onsite_rate = rateFromCents(entity.onsite_rate);
-
return {
...state,
entity: {
@@ -93,10 +89,6 @@ const formTemplateItemReducer = (state = DEFAULT_STATE, action) => {
}
}
- entity.early_bird_rate = rateFromCents(entity.early_bird_rate);
- entity.standard_rate = rateFromCents(entity.standard_rate);
- entity.onsite_rate = rateFromCents(entity.onsite_rate);
-
return {
...state,
entity: {
diff --git a/src/reducers/sponsors_inventory/inventory-item-reducer.js b/src/reducers/sponsors_inventory/inventory-item-reducer.js
index b70bf43b7..7ecf1753a 100644
--- a/src/reducers/sponsors_inventory/inventory-item-reducer.js
+++ b/src/reducers/sponsors_inventory/inventory-item-reducer.js
@@ -12,7 +12,7 @@
* */
import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions";
-import { RATE_FIELDS, rateFromCents } from "../../utils/rate-helpers";
+import { RATE_FIELDS } from "../../utils/rate-helpers";
import {
RECEIVE_INVENTORY_ITEM,
RESET_INVENTORY_ITEM_FORM,
@@ -69,10 +69,6 @@ const inventoryItemReducer = (state = DEFAULT_STATE, action) => {
}
}
- entity.early_bird_rate = rateFromCents(entity.early_bird_rate);
- entity.standard_rate = rateFromCents(entity.standard_rate);
- entity.onsite_rate = rateFromCents(entity.onsite_rate);
-
return {
...state,
entity: {
@@ -92,10 +88,6 @@ const inventoryItemReducer = (state = DEFAULT_STATE, action) => {
}
}
- entity.early_bird_rate = rateFromCents(entity.early_bird_rate);
- entity.standard_rate = rateFromCents(entity.standard_rate);
- entity.onsite_rate = rateFromCents(entity.onsite_rate);
-
return {
...state,
entity: {
diff --git a/src/utils/rate-helpers.js b/src/utils/rate-helpers.js
index c841e817f..3be7b9465 100644
--- a/src/utils/rate-helpers.js
+++ b/src/utils/rate-helpers.js
@@ -1,7 +1,7 @@
import T from "i18n-react";
import {
amountFromCents,
- amountToCents,
+ parsePrice,
currencyAmountFromCents
} from "openstack-uicore-foundation/lib/utils/money";
@@ -22,7 +22,7 @@ export const rateFromCents = (cents) => {
export const rateToCents = (value) => {
if (value === null || value === undefined) return null;
if (value === "") return 0;
- return amountToCents(value);
+ return parsePrice(value);
};
export const formatRateFromCents = (cents) => {