Skip to main content

Override a Page

Overview

This task will show you how to override the page used for the SignOn prompt.

Overriding a page

  • Open your \<CustomerName>-React POS project in vscode editor.

  • Navigate to /src-js/packages/<CustomerName>-ReactPOS/Components folder

  • Create a new folder called SignOn

  • Inside that folder create a new file called index.js

  • Add the following content in the index.js and save the file.

import React, { useEffect } from "react";
import { connect } from "react-redux";
import { getPageState } from "@enactor/redux-javascript-bridge";
import {
ResolvableMessage,
selectMessageHook,
} from "@enactor/react-javascript-bridge";
import {
POINTER,
ConnectedPosKeyboard,
defaultMapStateToProps,
defaultMapDispatchToProps,
SIGN_ON_BACKGROUND,
ConnectedTextInput,
pointAction,
inputStateCleanup,
getInputsForPromptUrl,
sendEventWithMultipleInputs,
hideKeyboard,
getCurrentDeviceResolution,
resolveClassName,
MOBILE_DEVICE,
} from "@enactor/react-base-components";
import { SignOnHeader, SignOnNumericKeypad } from "@enactor/react-pos";

const USERNAME = "username";
const PASSWORD = "password";

const SignOn = (props) => {
const handleOKPressed = () => {
let { promptUrl, onEvent } = props;
onEvent("OKPressed", promptUrl, {
userId: USERNAME,
pIN: PASSWORD,
});
};
const onEnterPressed = () => {
let {
inputState: { focussedElement },
promptUrl,
} = props;
if (focussedElement === USERNAME) {
props.onPoint({
promptUrl,
sourceDevice: POINTER,
inputName: PASSWORD,
cursorStartPosition: 0,
cursorEndPosition: 0,
});
} else {
handleOKPressed();
}
};
const handleKeyUp = (event) => {
let { key, target } = event;
if (key === "Enter") {
if (target.name === "username") {
props.onPoint({
promptUrl: props.promptUrl,
sourceDevice: POINTER,
inputName: PASSWORD,
cursorStartPosition: 0,
cursorEndPosition: 0,
});
} else {
handleOKPressed();
}
}
};
useEffect(() => {
window.document.body.classList.add("signon");
const {
eventHandlers: { changeBackground },
inputState: { focussedElement },
promptUrl,
} = props;
if (focussedElement !== USERNAME) {
props.onPoint({
promptUrl,
sourceDevice: POINTER,
inputName: USERNAME,
cursorStartPosition: 0,
cursorEndPosition: 0,
});
}
changeBackground(SIGN_ON_BACKGROUND);
return () => {
window.document.body.classList.remove("signon");
props.onUnmount(props.promptUrl);
};
}, []);
const {
eventHandlers,
promptInstanceId,
promptUrl,
context,
promptData,
deviceType,
} = props;
return (
<div className="signon">
<SignOnHeader eventHandlers={eventHandlers} />
<div
className={resolveClassName({
"body-area": true,
mobile: deviceType === MOBILE_DEVICE,
})}
>
<div className="signon-box" onKeyUp={handleKeyUp}>
<div className="signon-box-left">
<div className="signon-form-row">
<div className="signon-form-txt">
<ResolvableMessage
messageBase="Pos/SignOn/SignOnMessages"
messageId="USER_ID"
/>
</div>
<ConnectedTextInput
context={context}
promptUrl={promptUrl}
promptInstanceId={promptInstanceId}
className="signon-input"
name={USERNAME}
placeholder={selectMessageHook({
messageId: "ENTER_USER_NAME",
messageBase: "Pos/SignOn/SignOnMessages",
})}
test-component-id={"INPUT_TEXT_1"}
/>
<div className="signon-error" />
</div>
<div className="signon-form-row">
<div className="signon-form-txt">
<ResolvableMessage
messageBase="Pos/SignOn/SignOnMessages"
messageId="PASSWORD"
/>
</div>
<ConnectedTextInput
textType="password"
context={context}
promptUrl={promptUrl}
promptInstanceId={promptInstanceId}
className="signon-input"
name={PASSWORD}
placeholder={selectMessageHook({
messageId: "ENTER_PIN",
messageBase: "Pos/SignOn/SignOnMessages",
})}
test-component-id={"INPUT_TEXT_2"}
/>
<div className="signon-error" />
</div>
</div>
<div className="signon-box-numpad" keyboard-control-wrapper="true">
<SignOnNumericKeypad
context={context}
promptInstanceId={promptInstanceId}
promptUrl={promptUrl}
enterClickedHandler={onEnterPressed}
/>
</div>
</div>
<ConnectedPosKeyboard
promptInstanceId={promptInstanceId}
context={context}
onEnter={onEnterPressed}
/>
</div>
</div>
);
};

const mapStateToProps = (state, ownProps) => {
const { promptUrl } = getPageState(state, ownProps);
let inputState = getInputsForPromptUrl(state, promptUrl);
const deviceType = getCurrentDeviceResolution(state, ownProps);

return {
...defaultMapStateToProps(state, ownProps),
promptUrl,
inputState,
deviceType,
...ownProps,
};
};

const mapDispatchToProps = (dispatch, ownProps) => {
return {
...defaultMapDispatchToProps(dispatch, ownProps),
onEvent: (eventName, promptUrl, cacheValueAttributePayloadAttributeMap) =>
dispatch(
sendEventWithMultipleInputs(
eventName,
promptUrl,
cacheValueAttributePayloadAttributeMap
)
),
onPoint: ({
promptUrl,
sourceDevice,
inputName,
cursorStartPosition,
cursorEndPosition,
}) =>
dispatch(
pointAction({
promptUrls: [promptUrl],
sourceDevice,
focussedElement: inputName,
cursorStartPosition,
cursorEndPosition,
})
),
onUnmount: (promptUrl) => {
dispatch(
inputStateCleanup({
promptUrls: [promptUrl],
})
);
dispatch(hideKeyboard());
},
};
};

export default connect(mapStateToProps, mapDispatchToProps)(SignOn);

This is almost a copy of our existing implementation.

To let the application find this prompt, we need to add a route mapping for it:

  • Navigate to /src-js/packages/<CustomerName>-ReactPOS/src/Configuration folder.

  • Open the \<CustomerName>Routes.js file and add a route for the new component we created in index.js file as shown.

  • Add the following item to the routes array

      "Pos/SignOn/EnterUser": {
    promptUrl: "Pos/SignOn/EnterUser",
    component: SignOn
    }

Make sure to add an import for the SignOn component

The key here is the URL of the prompt state in the process

Now if you restart the ReactPos application it will show our overridden component for the SignOn page, by default no change will be visible however.

Therefore experiment by changing the text and adding or removing the components.

For example try replacing

<div className="signon-form-txt">
<ResolvableMessage
messageBase="Pos/SignOn/SignOnMessages"
messageId="USER_ID"
/>
</div>

with

<div className="signon-form-txt">Enter your user id here</div>