Skip to content

Commit

Permalink
Merge pull request #82 from bosonprotocol/widget-parameters
Browse files Browse the repository at this point in the history
feat: add redemption widget parameters to allow several usecases
  • Loading branch information
levalleux-ludo authored Oct 12, 2023
2 parents 416f7d8 + ef611c0 commit 8d6d392
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 65 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@bosonprotocol/react-kit": "^0.22.0-alpha.1",
"@bosonprotocol/react-kit": "^0.22.0-alpha.2",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand Down
61 changes: 44 additions & 17 deletions public/example.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,35 +72,60 @@ <h2>Redemption Widget</h2>
</td>
</tr>
<tr>
<td>Bypass Mode</td>
<td>Show Overview</td>
<td>
<select id="select-redeem-bypass-mode" onchange="updateRedeemButton('data-bypass-mode', this.value)">
<option value="NORMAL">NORMAL</option>
<option value="REDEEM">REDEEM</option>
<option value="CANCEL">CANCEL</option>
<input type="checkbox" id="input-redeem-show-overview" checked onchange="updateRedeemButton('data-show-redemption-overview', this.checked)">
</td>
<td>
<button onclick="clearRedeemInputs(); setValue('input-redeem-show-overview', false, 'checked')" >Example</button>
</td>
</tr>
<tr>
<td>Exchange State</td>
<td>
<select id="select-redeem-exchange-state" onchange="updateRedeemButton('data-exchange-state', this.value)">
<option value="Committed">Committed</option>
<option value="Redeemed">Redeemed</option>
<option value="Disputed">Disputed</option>
<option value="Completed">Completed</option>
</select>
</td>
<td>
<button onclick="clearRedeemInputs(); setValue('select-redeem-exchange-state', 'Redeemed')" >Example</button>
</td>
</tr>
<tr>
<td>Widget Action</td>
<td>
<select id="select-redeem-widget-action" onchange="updateRedeemButton('data-widget-action', this.value)">
<option value="SELECT_EXCHANGE">SELECT_EXCHANGE</option>
<option value="EXCHANGE_DETAILS">EXCHANGE_DETAILS</option>
<option value="REDEEM_FORM">REDEEM_FORM</option>
<option value="CANCEL_FORM">CANCEL_FORM</option>
<option value="CONFIRM_REDEEM">CONFIRM_REDEEM</option>
</select>
</td>
<td>
<button onclick="clearRedeemInputs(); setValue('input-redeem-exchange-id', '80'); setValue('select-redeem-bypass-mode', 'CANCEL')" >Example</button>
<button onclick="clearRedeemInputs(); setValue('input-redeem-exchange-id', '80'); setValue('select-redeem-widget-action', 'CANCEL_FORM')" >Example</button>
</td>
</tr>
<tr>
<td>CallbackURL</td>
<td>PostDeliveryInfoURL</td>
<td>
<input type="url" id="input-redeem-callback-url" onchange="updateRedeemButton('data-redeem-callback-url', encodeURI(this.value))" size="30">
<input type="url" id="input-post-delivery-info-url" onchange="updateRedeemButton('data-post-delivery-info-url', encodeURI(this.value))" size="30">
</td>
<td>
<button onclick="clearRedeemInputs(); setValue('input-redeem-callback-url', 'http://localhost:3666')" >Example</button>
<button onclick="clearRedeemInputs(); setValue('input-post-delivery-info-url', 'http://localhost:3666')" >Example</button>
</td>
</tr>
<tr>
<td>CallbackHeader</td>
<td>PostDeliveryInfoHeader</td>
<td>
<textarea id="input-redeem-callback-header" onchange="updateRedeemButton('data-redeem-callback-headers', encodeURI(this.value))" rows="10" cols="30">
<textarea id="input-post-delivery-info-header" onchange="updateRedeemButton('data-post-delivery-info-headers', encodeURI(this.value))" rows="10" cols="30">
</textarea>
</td>
<td>
<button onclick="clearRedeemInputs(); setValue('input-redeem-callback-url', 'http://localhost:3666'); setValue('input-redeem-callback-header', decodeURI('%7B%0A%20%20%22authorization%22:%20%22Bearer%20eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9%22,%0A%20%20%22another-header%22:%20%22*****%22%0A%7D'))" >Example</button>
<button onclick="clearRedeemInputs(); setValue('input-post-delivery-info-url', 'http://localhost:3666'); setValue('input-post-delivery-info-header', decodeURI('%7B%0A%20%20%22authorization%22:%20%22Bearer%20eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9%22,%0A%20%20%22another-header%22:%20%22*****%22%0A%7D'))" >Example</button>
</td>
</tr>
</tbody>
Expand All @@ -124,17 +149,19 @@ <h2>Redemption Widget</h2>
document.getElementById('boson-finance-button').setAttribute('disabled', true)
}
}
function setValue(elementId, value) {
function setValue(elementId, value, attribute = "value") {
let element = document.getElementById(elementId)
element.value = value
element[attribute] = value
element.onchange()
}
function clearRedeemInputs() {
setValue('input-redeem-exchange-id', '')
setValue('input-redeem-seller-id', '')
setValue('select-redeem-bypass-mode', 'NORMAL')
setValue('input-redeem-callback-url', '')
setValue('input-redeem-callback-header', '')
setValue('select-redeem-widget-action', 'SELECT_EXCHANGE')
setValue('input-redeem-show-overview', true, 'checked')
setValue('select-redeem-exchange-state', 'Committed')
setValue('input-post-delivery-info-url', '')
setValue('input-post-delivery-info-header', '')
}
function clearFinanceInputs() {
setValue('input-finance-seller-id', '')
Expand Down
43 changes: 28 additions & 15 deletions public/scripts/boson-widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ const constants = {
showRedeemId: "boson-redeem",
showFinanceId: "boson-finance",
exchangeIdTag: "data-exchange-id",
bypassModeTag: "data-bypass-mode",
redeemCallbackUrl: "data-redeem-callback-url",
redeemCallbackHeaders: "data-redeem-callback-headers",
exchangeStateTag: "data-exchange-state",
showRedemptionOverviewTag: "data-show-redemption-overview",
widgetActionTag: "data-widget-action",
postDeliveryInfoUrlTag: "data-post-delivery-info-url",
postDeliveryInfoHeadersTag: "data-post-delivery-info-headers",
sellerIdTag: "data-seller-id",
configIdTag: "data-config-id",
accountTag: "data-account",
Expand Down Expand Up @@ -119,20 +121,26 @@ function bosonWidgetReload() {
const exchangeId =
showRedeemId.attributes[constants.exchangeIdTag]?.value;
const sellerId = showRedeemId.attributes[constants.sellerIdTag]?.value;
const bypassMode =
showRedeemId.attributes[constants.bypassModeTag]?.value;
const redeemCallbackUrl =
showRedeemId.attributes[constants.redeemCallbackUrl]?.value;
const redeemCallbackHeaders =
showRedeemId.attributes[constants.redeemCallbackHeaders]?.value;
const exchangeState =
showRedeemId.attributes[constants.exchangeStateTag]?.value;
const showRedemptionOverview =
showRedeemId.attributes[constants.showRedemptionOverviewTag]?.value;
const widgetAction =
showRedeemId.attributes[constants.widgetActionTag]?.value;
const postDeliveryInfoUrl =
showRedeemId.attributes[constants.postDeliveryInfoUrlTag]?.value;
const postDeliveryInfoHeaders =
showRedeemId.attributes[constants.postDeliveryInfoHeadersTag]?.value;
const configId = showRedeemId.attributes[constants.configIdTag]?.value;
const account = showRedeemId.attributes[constants.accountTag]?.value;
bosonWidgetShowRedeem({
exchangeId,
sellerId,
bypassMode,
redeemCallbackUrl,
redeemCallbackHeaders,
exchangeState,
showRedemptionOverview,
widgetAction,
postDeliveryInfoUrl,
postDeliveryInfoHeaders,
configId,
account
});
Expand All @@ -151,9 +159,14 @@ function bosonWidgetShowRedeem(args) {
const params = buildParams([
{ tag: "exchangeId", value: args.exchangeId },
{ tag: "sellerId", value: args.sellerId },
{ tag: "bypassMode", value: args.bypassMode },
{ tag: "redeemCallbackUrl", value: args.redeemCallbackUrl },
{ tag: "redeemCallbackHeaders", value: args.redeemCallbackHeaders },
{ tag: "exchangeState", value: args.exchangeState },
{
tag: "showRedemptionOverview",
value: args.showRedemptionOverview?.toString() // to allow passing either a real boolean or a string
},
{ tag: "widgetAction", value: args.widgetAction },
{ tag: "postDeliveryInfoUrl", value: args.postDeliveryInfoUrl },
{ tag: "postDeliveryInfoHeaders", value: args.postDeliveryInfoHeaders },
{ tag: "configId", value: args.configId },
{ tag: "account", value: args.account }
]);
Expand Down
93 changes: 68 additions & 25 deletions src/components/widgets/redeem/Redeem.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {
ConfigId,
RedemptionBypassMode,
RedemptionWidget
RedemptionWidget,
RedemptionWidgetAction,
subgraph
} from "@bosonprotocol/react-kit";
import { useSearchParams } from "react-router-dom";

Expand All @@ -11,20 +12,31 @@ export const redeemPath = "/redeem";
export function Redeem() {
const [searchParams] = useSearchParams();
const exchangeId = searchParams.get("exchangeId") || undefined;
const bypassMode: RedemptionBypassMode = checkBypassMode(
searchParams.get("bypassMode") || undefined
const showRedemptionOverviewStr = searchParams.get("showRedemptionOverview");
const showRedemptionOverview = showRedemptionOverviewStr
? /^true$/i.test(showRedemptionOverviewStr)
: true; // default value
const widgetAction: RedemptionWidgetAction = checkWidgetAction(
searchParams.get("widgetAction") || undefined
);
const redeemCallbackUrl = searchParams.get("redeemCallbackUrl") || undefined;
const redeemCallbackHeaders =
searchParams.get("redeemCallbackHeaders") || undefined;
let redeemCallbackHeadersDecoded = undefined;
if (redeemCallbackHeaders) {
const exchangeState: subgraph.ExchangeState = checkExchangeState(
searchParams.get("exchangeState") || undefined
);
const postDeliveryInfoUrl =
searchParams.get("postDeliveryInfoUrl") || undefined;
const postDeliveryInfoHeaders =
searchParams.get("postDeliveryInfoHeaders") || undefined;
let postDeliveryInfoHeadersDecoded = undefined;
if (postDeliveryInfoHeaders) {
try {
redeemCallbackHeadersDecoded = JSON.parse(redeemCallbackHeaders);
console.log("redeemCallbackHeadersDecoded", redeemCallbackHeadersDecoded);
postDeliveryInfoHeadersDecoded = JSON.parse(postDeliveryInfoHeaders);
console.log(
"postDeliveryInfoHeadersDecoded",
postDeliveryInfoHeadersDecoded
);
} catch (e) {
console.error(
`Unable to parse JSON from redeemCallbackHeaders='${redeemCallbackHeaders}': ${e}`
`Unable to parse JSON from postDeliveryInfoHeaders='${postDeliveryInfoHeaders}': ${e}`
);
}
}
Expand All @@ -43,6 +55,8 @@ export function Redeem() {

return (
<RedemptionWidget
showRedemptionOverview={showRedemptionOverview}
exchangeState={exchangeState}
exchangeId={exchangeId}
sellerIds={sellerIds}
configId={configId}
Expand Down Expand Up @@ -77,25 +91,54 @@ export function Redeem() {
}
}}
modalMargin="2%"
bypassMode={bypassMode}
redeemCallbackUrl={redeemCallbackUrl}
redeemCallbackHeaders={redeemCallbackHeadersDecoded}
widgetAction={widgetAction}
postDeliveryInfoUrl={postDeliveryInfoUrl}
postDeliveryInfoHeaders={postDeliveryInfoHeadersDecoded}
></RedemptionWidget>
);
}

function checkBypassMode(
bypassModeStr: string | undefined
): RedemptionBypassMode {
switch (bypassModeStr) {
case RedemptionBypassMode.REDEEM: {
return RedemptionBypassMode.REDEEM;
function checkWidgetAction(
widgetActionStr: string | undefined
): RedemptionWidgetAction {
switch (widgetActionStr?.toLowerCase()) {
case undefined:
case RedemptionWidgetAction.SELECT_EXCHANGE.toLowerCase(): {
return RedemptionWidgetAction.SELECT_EXCHANGE;
}
case RedemptionWidgetAction.EXCHANGE_DETAILS.toLowerCase(): {
return RedemptionWidgetAction.EXCHANGE_DETAILS;
}
case RedemptionWidgetAction.REDEEM_FORM.toLowerCase(): {
return RedemptionWidgetAction.REDEEM_FORM;
}
case RedemptionWidgetAction.CANCEL_FORM.toLowerCase(): {
return RedemptionWidgetAction.CANCEL_FORM;
}
case RedemptionWidgetAction.CONFIRM_REDEEM.toLowerCase(): {
return RedemptionWidgetAction.CONFIRM_REDEEM;
}
}
throw new Error(`Not supported widget action '${widgetActionStr}'`);
}

function checkExchangeState(
exchangeStateStr: string | undefined
): subgraph.ExchangeState {
switch (exchangeStateStr?.toLowerCase()) {
case undefined:
case subgraph.ExchangeState.Committed.toLowerCase(): {
return subgraph.ExchangeState.Committed;
}
case subgraph.ExchangeState.Redeemed.toLowerCase(): {
return subgraph.ExchangeState.Redeemed;
}
case RedemptionBypassMode.CANCEL: {
return RedemptionBypassMode.CANCEL;
case subgraph.ExchangeState.Disputed.toLowerCase(): {
return subgraph.ExchangeState.Disputed;
}
default: {
return RedemptionBypassMode.NORMAL;
case subgraph.ExchangeState.Completed.toLowerCase(): {
return subgraph.ExchangeState.Completed;
}
}
throw new Error(`Not supported exchange state '${exchangeStateStr}'`);
}

0 comments on commit 8d6d392

Please sign in to comment.