diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..3b7c061d
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,22 @@
+### Issue/Feature
+
+### Reproduce
+Issue exists on version `1.` of sdk-dapp-core-ui.
+
+### Root cause
+
+### Fix
+
+### Additional changes
+
+### Contains breaking changes
+[x] No
+
+[] Yes
+
+### Updated CHANGELOG
+[x] Yes
+
+### Testing
+[x] User testing
+[] Unit tests
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..cb32836d
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,41 @@
+name: Build and test
+
+on:
+ pull_request:
+ branches: [main, development]
+ paths:
+ - 'src/**'
+ - '**.js'
+ - '**.ts'
+ - '**.json'
+ repository_dispatch:
+ types: run-unit-tests
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ build-test:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ packages: write
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v1
+ with:
+ node-version: 18
+ registry-url: https://registry.npmjs.org/
+
+ - name: Setup yarn
+ run: npm install -g yarn
+
+ - name: Install dependencies
+ run: yarn install
+
+ - name: Run tests
+ run: yarn test --silent
+
+ - name: Build project
+ run: yarn build
diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml
new file mode 100644
index 00000000..1b1502a2
--- /dev/null
+++ b/.github/workflows/changelog.yml
@@ -0,0 +1,16 @@
+name: "CHANGELOG entry secretary"
+on:
+ pull_request:
+ branches: [main, development]
+ # The specific activity types are listed here to include "labeled" and "unlabeled"
+ # (which are not included by default for the "pull_request" trigger).
+ # This is needed to allow skipping enforcement of the changelog in PRs with specific labels,
+ # as defined in the (optional) "skipLabels" property.
+ types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
+
+jobs:
+ # Enforces the update of a changelog file on every pull request
+ changelog:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: dangoslen/changelog-enforcer@v3
\ No newline at end of file
diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml
new file mode 100644
index 00000000..5a78eec1
--- /dev/null
+++ b/.github/workflows/npm-publish.yml
@@ -0,0 +1,52 @@
+name: Publish sdk-dapp-core-ui
+
+on:
+ push:
+ branches: [main]
+ repository_dispatch:
+ types: publish-npm
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ publish-npm:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ packages: write
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v1
+ with:
+ node-version: 18
+ registry-url: https://registry.npmjs.org/
+
+ - name: Setup yarn
+ run: npm install -g yarn
+
+ - name: Install dependencies
+ run: yarn install
+
+ - name: Run tests
+ run: yarn test
+
+ - name: Build project
+ run: yarn build
+
+ - name: Get package info
+ id: package
+ uses: andreigiura/action-nodejs-package-info@v1.0.2
+
+ - name: Publish to npmjs next version
+ env:
+ NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
+ if: ${{ steps.package.outputs.is-prerelease == 'true'}}
+ run: echo ${{ steps.package.outputs.is-prerelease}} && npm publish --tag next
+
+ - name: Publish to npmjs
+ env:
+ NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
+ if: ${{ steps.package.outputs.is-prerelease == 'false' }}
+ run: npm publish
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..48e3dd31
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,13 @@
+# Change Log
+
+All notable changes will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [[0.0.0-alpha.1](https://github.com/multiversx/mx-sdk-dapp-core-ui/pull/16)] - 2025-01-20
+
+- [Updated formatAmount component and removed dependencies](https://github.com/multiversx/mx-sdk-dapp-core-ui/pull/17)
+- [Updated formatAmount component](https://github.com/multiversx/mx-sdk-dapp-core-ui/pull/15)
\ No newline at end of file
diff --git a/package.json b/package.json
index b8bd4ec8..0cd7942f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@multiversx/sdk-dapp-core-ui",
- "version": "0.0.0-alpha.0",
+ "version": "0.0.0-alpha.1",
"description": "A library to hold UI components for a dApp on the MultiversX blockchain",
"author": "MultiversX",
"license": "MIT",
@@ -53,8 +53,7 @@
"dependencies": {
"@fortawesome/fontawesome-svg-core": ">= 6.7.2",
"@fortawesome/free-solid-svg-icons": ">= 6.7.2",
- "@multiversx/sdk-dapp-utils": ">= 1.0.2",
- "bignumber.js": ">= 9.1.2",
+ "@multiversx/sdk-dapp-utils": ">= 1.0.4",
"classnames": ">= 2.5.1",
"qrcode": ">= 1.5.4"
},
diff --git a/src/common/generic-modal/generic-modal.css b/src/common/generic-modal/generic-modal.css
index 6603232d..f51d5cb4 100644
--- a/src/common/generic-modal/generic-modal.css
+++ b/src/common/generic-modal/generic-modal.css
@@ -1,33 +1,34 @@
:host {
- display: block;
- }
-
- .modal {
- position: fixed;
- z-index: 1000;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.4);
- }
-
- .modal-content {
- background-color: #ffffff;
- margin: 5% auto;
- padding: 20px;
- border-radius: 12px;
- width: 90%;
- max-width: 600px;
- }
-
- .modal-header {
- text-align: center;
- margin-bottom: 20px;
- }
-
- .close {
- float: right;
- cursor: pointer;
- padding: 5px;
- }
+ display: block;
+}
+
+.modal {
+ position: fixed;
+ z-index: 1000;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.4);
+ overflow: auto;
+}
+
+.modal-content {
+ background-color: #ffffff;
+ margin: 5% auto;
+ padding: 20px;
+ border-radius: 12px;
+ width: 90%;
+ max-width: 600px;
+}
+
+.modal-header {
+ text-align: center;
+ margin-bottom: 20px;
+}
+
+.close {
+ float: right;
+ cursor: pointer;
+ padding: 5px;
+}
diff --git a/src/components.d.ts b/src/components.d.ts
index b8e889e1..5721a2d0 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -28,13 +28,11 @@ export namespace Components {
}
interface FormatAmount {
"class"?: string;
- "decimals"?: number;
- "digits"?: number;
- "egldLabel"?: string;
- "showLabel"?: boolean;
- "showLastNonZeroDecimal"?: boolean;
- "token"?: string;
- "value": string;
+ "isValid": boolean;
+ "label"?: string;
+ "labelClass"?: string;
+ "valueDecimal": string;
+ "valueInteger": string;
}
interface FungibleComponent {
}
@@ -293,13 +291,11 @@ declare namespace LocalJSX {
}
interface FormatAmount {
"class"?: string;
- "decimals"?: number;
- "digits"?: number;
- "egldLabel"?: string;
- "showLabel"?: boolean;
- "showLastNonZeroDecimal"?: boolean;
- "token"?: string;
- "value"?: string;
+ "isValid"?: boolean;
+ "label"?: string;
+ "labelClass"?: string;
+ "valueDecimal"?: string;
+ "valueInteger"?: string;
}
interface FungibleComponent {
}
diff --git a/src/components/format-amount/format-amount.tsx b/src/components/format-amount/format-amount.tsx
index bca38c25..60f2189e 100644
--- a/src/components/format-amount/format-amount.tsx
+++ b/src/components/format-amount/format-amount.tsx
@@ -1,7 +1,4 @@
import { Component, Prop, h } from '@stencil/core';
-import BigNumber from 'bignumber.js';
-import { formatAmount } from '@multiversx/sdk-dapp-utils/out/helpers';
-import { DECIMALS, DIGITS, ZERO } from '@multiversx/sdk-dapp-utils/out/constants';
@Component({
tag: 'format-amount',
@@ -10,13 +7,11 @@ import { DECIMALS, DIGITS, ZERO } from '@multiversx/sdk-dapp-utils/out/constants
})
export class FormatAmount {
@Prop() class?: string;
- @Prop() decimals?: number = DECIMALS;
- @Prop() digits?: number = DIGITS;
- @Prop() egldLabel?: string;
- @Prop() showLabel?: boolean = true;
- @Prop() showLastNonZeroDecimal?: boolean = false;
- @Prop() token?: string;
- @Prop() value: string;
+ @Prop() isValid: boolean;
+ @Prop() label?: string;
+ @Prop() labelClass?: string;
+ @Prop() valueDecimal: string;
+ @Prop() valueInteger: string;
private renderInvalid() {
return (
@@ -29,41 +24,25 @@ export class FormatAmount {
}
private renderValid() {
- const formattedValue = formatAmount({
- input: this.value,
- decimals: this.decimals,
- digits: this.digits,
- showLastNonZeroDecimal: this.showLastNonZeroDecimal,
- addCommas: true
- });
-
- const valueParts = formattedValue.split('.');
- const hasNoDecimals = valueParts.length === 1;
- const isNotZero = formattedValue !== ZERO;
-
- if (this.digits > 0 && hasNoDecimals && isNotZero) {
- valueParts.push(ZERO.repeat(this.digits));
- }
-
return (
- {valueParts[0]}
+ {this.valueInteger}
- {valueParts.length > 1 && (
+ {this.valueDecimal && (
- .{valueParts[1]}
+ .{this.valueDecimal}
)}
- {this.showLabel && (
+ {this.label && (
- {` ${this.token ?? this.egldLabel}`}
+ {this.label}
)}
@@ -71,7 +50,6 @@ export class FormatAmount {
}
render() {
- const isInteger = new BigNumber(this.value).isInteger();
- return !isInteger ? this.renderInvalid() : this.renderValid();
+ return this.isValid ? this.renderValid() : this.renderInvalid();
}
}
diff --git a/src/components/format-amount/readme.md b/src/components/format-amount/readme.md
index b26ccf11..645ff7d9 100644
--- a/src/components/format-amount/readme.md
+++ b/src/components/format-amount/readme.md
@@ -7,16 +7,14 @@
## Properties
-| Property | Attribute | Description | Type | Default |
-| ------------------------ | ---------------------------- | ----------- | --------- | ----------- |
-| `class` | `class` | | `string` | `undefined` |
-| `decimals` | `decimals` | | `number` | `DECIMALS` |
-| `digits` | `digits` | | `number` | `DIGITS` |
-| `egldLabel` | `egld-label` | | `string` | `undefined` |
-| `showLabel` | `show-label` | | `boolean` | `true` |
-| `showLastNonZeroDecimal` | `show-last-non-zero-decimal` | | `boolean` | `false` |
-| `token` | `token` | | `string` | `undefined` |
-| `value` | `value` | | `string` | `undefined` |
+| Property | Attribute | Description | Type | Default |
+| -------------- | --------------- | ----------- | --------- | ----------- |
+| `class` | `class` | | `string` | `undefined` |
+| `isValid` | `is-valid` | | `boolean` | `undefined` |
+| `label` | `label` | | `string` | `undefined` |
+| `labelClass` | `label-class` | | `string` | `undefined` |
+| `valueDecimal` | `value-decimal` | | `string` | `undefined` |
+| `valueInteger` | `value-integer` | | `string` | `undefined` |
----------------------------------------------
diff --git a/src/components/format-amount/tests/format-amount.spec.ts b/src/components/format-amount/tests/format-amount.spec.ts
index a72b28f3..49440fac 100644
--- a/src/components/format-amount/tests/format-amount.spec.ts
+++ b/src/components/format-amount/tests/format-amount.spec.ts
@@ -1,17 +1,16 @@
import { newSpecPage } from '@stencil/core/testing';
import { FormatAmount } from '../format-amount';
-describe('Format amount component when digits = 2', () => {
+describe('FormatAmount component', () => {
const renderComponent = async (props: any) => {
const page = await newSpecPage({
components: [FormatAmount],
html: '',
- supportsShadowDom: true
+ supportsShadowDom: true,
});
const component = page.root;
- // Set each property individually
- Object.keys(props).forEach(key => {
+ Object.keys(props).forEach((key) => {
component[key] = props[key];
});
@@ -31,81 +30,64 @@ describe('Format amount component when digits = 2', () => {
.length;
};
- it('should show 2 non zero decimals', async () => {
+ it('should render valid amount with decimals', async () => {
const props = {
- value: '9999979999800000000000000',
- showLastNonZeroDecimal: false,
- showLabel: true,
- digits: 2,
- egldLabel: 'EGLD'
+ isValid: true,
+ valueInteger: '99999',
+ valueDecimal: '99',
+ label: 'EGLD',
};
const page = await renderComponent(props);
- expect(await decimalsSelector(page)).toBe('.99');
+ expect(page.root.shadowRoot.querySelector('span[data-testid="formatAmountInt"]').textContent).toBe('99999');
+ expect(decimalsSelector(page)).toBe('.99');
});
- it('should show 2 zero decimals', async () => {
+ it('should not render decimals when valueDecimal is empty', async () => {
const props = {
- value: '9000000000000000000000000',
- showLastNonZeroDecimal: false,
- showLabel: true,
- digits: 2,
- egldLabel: 'EGLD'
+ isValid: true,
+ valueInteger: '90000',
+ valueDecimal: '',
+ label: 'EGLD',
};
const page = await renderComponent(props);
- expect(await decimalsSelector(page)).toBe('.00');
+ expect(decimalsSelector(page)).toBe(undefined);
});
- it('should show all non zero decimals when showLastNonZeroDecimal = true', async () => {
+ it('should render invalid state when isValid is false', async () => {
const props = {
- value: '100000000000000',
- showLastNonZeroDecimal: true,
- showLabel: false,
- digits: 2,
- egldLabel: 'EGLD'
+ isValid: false,
+ valueInteger: '',
+ valueDecimal: '',
+ label: '',
};
const page = await renderComponent(props);
- expect(await decimalsSelector(page)).toBe('.0001');
+ expect(page.root.shadowRoot.querySelector('span[data-testid="formatAmountInt"]').textContent).toBe('...');
});
- it('should not show decimals when value is 0', async () => {
+ it('should render symbol when label is provided', async () => {
const props = {
- value: '100000000000000',
- showLastNonZeroDecimal: false,
- showLabel: true,
- digits: 2,
- egldLabel: 'EGLD'
+ isValid: true,
+ valueInteger: '90000',
+ valueDecimal: '00',
+ label: 'EGLD',
};
const page = await renderComponent(props);
- expect(await decimalsSelector(page)).toBe(undefined);
+ expect(symbolSelector(page)).toBe(1);
});
- it('should show symbol', async () => {
+ it('should not render symbol when label is not provided', async () => {
const props = {
- value: '9000000000000000000000000',
- showLastNonZeroDecimal: false,
- showLabel: true,
- digits: 2,
- egldLabel: 'EGLD'
+ isValid: true,
+ valueInteger: '90000',
+ valueDecimal: '00',
+ label: '',
};
const page = await renderComponent(props);
- expect(await symbolSelector(page)).toBe(1);
- });
-
- it('should not show symbol', async () => {
- const props = {
- value: '9000000000000000000000000',
- showLastNonZeroDecimal: false,
- showLabel: false,
- digits: 2,
- egldLabel: 'EGLD'
- };
-
- const page = await renderComponent(props);
- expect(await symbolSelector(page)).toBe(0);
+ expect(symbolSelector(page)).toBe(0);
});
});
diff --git a/src/components/ledger-connect-modal/ledger-connect-modal.css b/src/components/ledger-connect-modal/ledger-connect-modal.css
index 8e42ff47..53438568 100644
--- a/src/components/ledger-connect-modal/ledger-connect-modal.css
+++ b/src/components/ledger-connect-modal/ledger-connect-modal.css
@@ -29,7 +29,9 @@
.account-list {
width: 100%;
min-height: 300px;
+ max-height: 300px;
position: relative;
+ overflow: auto;
}
.account-row {
@@ -147,6 +149,7 @@
padding: 12px;
text-align: center;
border-radius: 8px;
+ word-break: break-word;
}
.ledger-confirm-address-section .ledger-confirm-address-header {
diff --git a/src/components/sign-transactions-modal/components/fungible-component/fungible-component.tsx b/src/components/sign-transactions-modal/components/fungible-component/fungible-component.tsx
index fcee75e2..b1d2f965 100644
--- a/src/components/sign-transactions-modal/components/fungible-component/fungible-component.tsx
+++ b/src/components/sign-transactions-modal/components/fungible-component/fungible-component.tsx
@@ -1,22 +1,26 @@
import { Component, h } from '@stencil/core';
import state from '../../signTransactionsModalStore';
+import { NftEnumType } from 'types/tokens.types';
const LABELS = {
- SemiFungibleESDT: 'SFT',
- NonFungibleESDT: 'NFT',
+ [NftEnumType.SemiFungibleESDT]: 'SFT',
+ [NftEnumType.NonFungibleESDT]: 'NFT'
};
@Component({
tag: 'fungible-component',
styleUrl: 'fungible-component.css',
- shadow: false,
+ shadow: false
})
export class FungibleComponent {
render() {
const { sftTransaction, nftTransaction, commonData } = state;
const { tokenType } = commonData;
- const data = tokenType === 'SemiFungibleESDT' ? sftTransaction : nftTransaction;
+ const data =
+ tokenType === NftEnumType.SemiFungibleESDT
+ ? sftTransaction
+ : nftTransaction;
const { amount = '', identifier = '', imageURL = '' } = data || {};
const label = LABELS[tokenType];
diff --git a/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.css b/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.css
index 82b574b8..140d23b4 100644
--- a/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.css
+++ b/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.css
@@ -7,8 +7,8 @@
.transaction-container {
display: flex;
flex-direction: column;
- padding: 1rem;
- gap: 2rem;
+ padding: 0rem 1rem 0rem 1rem;
+ gap: 1rem;
}
.receiver-container {
@@ -27,12 +27,25 @@
line-height: 1;
}
-.data-content {
+.data-content-container {
+ display: block;
width: 100%;
+ min-height: 100px;
height: 100px;
- resize: none;
- border-radius: 0.5rem;
- padding: 0.5rem;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ padding: 8px;
+ overflow-y: auto;
+ font-family: inherit;
+ font-size: inherit;
+ background-color: #f9f9f9;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ color: #333;
+}
+
+.data-content {
+ opacity: 0.6;
}
.fee-container {
@@ -43,6 +56,39 @@
line-height: 1;
}
+.sign-button-container {
+ display: flex;
+ flex-direction: column;
+}
+
+.sign-back-button {
+ display: inline-block;
+ padding: 8px 12px;
+ background-color: transparent;
+ color: #1a56db;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ text-decoration: none;
+ font-size: 16px;
+
+ &:hover {
+ text-decoration: underline;
+ color: #0033a0;
+ }
+
+ &:active {
+ color: #001f70;
+ }
+
+ &:disabled {
+ color: #a1a1a1;
+ cursor: not-allowed;
+ text-decoration: none;
+ opacity: 0.6;
+ }
+}
+
.sign-button {
display: block;
width: 200px;
@@ -63,3 +109,7 @@
transform: none;
}
}
+
+.highlight {
+ opacity: 1;
+}
diff --git a/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.tsx b/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.tsx
index 16d4175e..d805eac1 100644
--- a/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.tsx
+++ b/src/components/sign-transactions-modal/components/sign-transaction-component/sign-transaction-component.tsx
@@ -6,14 +6,86 @@ import state from '../../signTransactionsModalStore';
@Component({
tag: 'sign-transaction-component',
styleUrl: 'sign-transaction-component.css',
- shadow: false,
+ shadow: false
})
export class SignTransaction {
@Prop() header: VNode;
+ getSignButtonProps() {
+ const { currentIndex, nextUnsignedTxIndex } = state.commonData;
+
+ if (currentIndex === nextUnsignedTxIndex) {
+ return {
+ signText: 'Sign',
+ disabled: state.isWaitingForSignature,
+ 'data-testid': DataTestIdsEnum.signTransactionBtn,
+ onClick: state.onSign
+ };
+ }
+
+ return {
+ signText: 'Next',
+ disabled: false,
+ 'data-testid': DataTestIdsEnum.signNextTransactionBtn,
+ onClick: state.onNext
+ };
+ }
+
+ getBackButtonProps() {
+ const { transactionsCount, currentIndex } = state.commonData;
+ const isMultipleTransactions = transactionsCount > 1;
+
+ if (!isMultipleTransactions) {
+ return {};
+ }
+
+ if (currentIndex === 0) {
+ return {
+ 'data-testid': DataTestIdsEnum.signCancelBtn,
+ backButtonText: 'Cancel',
+ onClick: state.onCancel
+ };
+ }
+
+ return {
+ 'data-testid': DataTestIdsEnum.signBackBtn,
+ backButtonText: 'Back',
+ onClick: state.onPrev,
+ disabled: state.isWaitingForSignature
+ };
+ }
+
+ getHighlightedData() {
+ const { data, highlight } = state.commonData;
+
+ if (!highlight || !data) {
+ return data;
+ }
+
+ const parts = data.split(highlight);
+
+ return (
+
+ {parts.map((part, index) => (
+
+ {part}
+ {index < parts.length - 1 && (
+ {highlight}
+ )}
+
+ ))}
+
+ );
+ }
+
render() {
- const { receiver, egldLabel, data, feeInFiatLimit, feeLimit } = state.commonData;
+ const { receiver, egldLabel, feeInFiatLimit, feeLimit, scCall } =
+ state.commonData;
+ const { signText, ...signButtonProps } = this.getSignButtonProps();
+ const { backButtonText, ...backButtonProps } = this.getBackButtonProps();
+
+ const highlightedData = this.getHighlightedData();
return (
{this.header}
@@ -34,16 +106,29 @@ export class SignTransaction {
≈{feeInFiatLimit}
+ {scCall && (
+
+
Smart Contract Call
+
{scCall}
+
+ )}
+
Data
-
+
{highlightedData}
-
+
+
+
+ {backButtonText && (
+
+ )}
+
);
}
diff --git a/src/components/sign-transactions-modal/readme.md b/src/components/sign-transactions-modal/readme.md
index c39a6cc2..640f6e84 100644
--- a/src/components/sign-transactions-modal/readme.md
+++ b/src/components/sign-transactions-modal/readme.md
@@ -7,9 +7,9 @@
## Properties
-| Property | Attribute | Description | Type | Default |
-| -------- | --------- | ----------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `data` | -- | | `ISignTransactionsModalData` | `{ commonData: { egldLabel: '', feeLimit: '', feeInFiatLimit: '', transactionsCount: 0, currentIndex: 0 }, tokenTransaction: null, nftTransaction: null, sftTransaction: null, }` |
+| Property | Attribute | Description | Type | Default |
+| -------- | --------- | ----------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `data` | -- | | `ISignTransactionsModalData` | `{ commonData: { egldLabel: '', feeLimit: '', feeInFiatLimit: '', transactionsCount: 0, currentIndex: 0 }, tokenTransaction: null, nftTransaction: null, sftTransaction: null }` |
## Methods
diff --git a/src/components/sign-transactions-modal/sign-transactions-modal.tsx b/src/components/sign-transactions-modal/sign-transactions-modal.tsx
index ce7ca441..aa147ac8 100644
--- a/src/components/sign-transactions-modal/sign-transactions-modal.tsx
+++ b/src/components/sign-transactions-modal/sign-transactions-modal.tsx
@@ -1,28 +1,46 @@
-import { Component, Prop, h, Element, Method, forceUpdate, Watch } from '@stencil/core';
+import {
+ Component,
+ Prop,
+ h,
+ Element,
+ Method,
+ forceUpdate,
+ Watch
+} from '@stencil/core';
import { EventBus, IEventBus } from 'utils/EventBus';
-import { ISignTransactionsModalData, SignEventsEnum } from './sign-transactions-modal.types';
+import {
+ ISignTransactionsModalData,
+ SignEventsEnum
+} from './sign-transactions-modal.types';
import state, { resetState } from './signTransactionsModalStore';
const signScreens = {
FungibleESDT: 'token-component',
SemiFungibleESDT: 'fungible-component',
NonFungibleESDT: 'fungible-component',
+ MetaESDT: 'token-component'
};
@Component({
tag: 'sign-transactions-modal',
styleUrl: 'sign-transactions-modal.css',
- shadow: true,
+ shadow: true
})
export class SignTransactionsModal {
@Element() hostElement: HTMLElement;
private eventBus: IEventBus = new EventBus();
@Prop() data: ISignTransactionsModalData = {
- commonData: { egldLabel: '', feeLimit: '', feeInFiatLimit: '', transactionsCount: 0, currentIndex: 0 },
+ commonData: {
+ egldLabel: '',
+ feeLimit: '',
+ feeInFiatLimit: '',
+ transactionsCount: 0,
+ currentIndex: 0
+ },
tokenTransaction: null,
nftTransaction: null,
- sftTransaction: null,
+ sftTransaction: null
};
@Method() async getEventBus() {
@@ -46,6 +64,18 @@ export class SignTransactionsModal {
state.isWaitingForSignature = true;
this.eventBus.publish(SignEventsEnum.SIGN_TRANSACTION);
};
+
+ state.onPrev = () => {
+ this.eventBus.publish(SignEventsEnum.PREV_TRANSACTION);
+ };
+
+ state.onNext = () => {
+ this.eventBus.publish(SignEventsEnum.NEXT_TRANSACTION);
+ };
+
+ state.onCancel = () => {
+ this.eventBus.publish(SignEventsEnum.CLOSE);
+ };
}
render() {
@@ -71,14 +101,6 @@ export class SignTransactionsModal {
);
}
- async nextPage() {
- this.eventBus.publish(SignEventsEnum.NEXT_PAGE);
- }
-
- async prevPage() {
- this.eventBus.publish(SignEventsEnum.PREV_PAGE);
- }
-
close(props = { isUserClick: true }) {
resetState();
@@ -97,11 +119,17 @@ export class SignTransactionsModal {
}
componentDidLoad() {
- this.eventBus.subscribe(SignEventsEnum.DATA_UPDATE, this.dataUpdate.bind(this));
+ this.eventBus.subscribe(
+ SignEventsEnum.DATA_UPDATE,
+ this.dataUpdate.bind(this)
+ );
}
disconnectedCallback() {
resetState();
- this.eventBus.unsubscribe(SignEventsEnum.DATA_UPDATE, this.dataUpdate.bind(this));
+ this.eventBus.unsubscribe(
+ SignEventsEnum.DATA_UPDATE,
+ this.dataUpdate.bind(this)
+ );
}
}
diff --git a/src/components/sign-transactions-modal/sign-transactions-modal.types.ts b/src/components/sign-transactions-modal/sign-transactions-modal.types.ts
index 1c328ac5..38ffea7a 100644
--- a/src/components/sign-transactions-modal/sign-transactions-modal.types.ts
+++ b/src/components/sign-transactions-modal/sign-transactions-modal.types.ts
@@ -1,3 +1,6 @@
+// types here need to be synced with the types in sdk-dapp-core signTransactionsModal.types.ts
+import { EsdtEnumType, NftEnumType } from 'types/tokens.types';
+
export interface ITransactionData {
receiver?: string;
data?: string;
@@ -10,7 +13,7 @@ export type FungibleTransactionType = {
imageURL: string;
};
-export type TokenType = 'SemiFungibleESDT' | 'NonFungibleESDT' | 'FungibleESDT' | null;
+export type TokenType = EsdtEnumType | NftEnumType;
export interface ISignTransactionsModalData {
shouldClose?: true;
@@ -18,15 +21,17 @@ export interface ISignTransactionsModalData {
receiver?: string;
data?: string;
transactionsCount: number;
- /**
- * Token type of the transaction.
- * @param {string} `null` - if is EGLD or MultiEsdt transaction.
- */
tokenType?: TokenType;
egldLabel: string;
feeLimit?: string;
feeInFiatLimit?: string | null;
currentIndex: number;
+ /**
+ * Tracks the index of the next unsigned transaction to be processed.
+ */
+ nextUnsignedTxIndex?: number;
+ highlight?: string;
+ scCall?: string;
};
tokenTransaction: {
identifier?: string;
@@ -39,8 +44,8 @@ export interface ISignTransactionsModalData {
export enum SignEventsEnum {
'SIGN_TRANSACTION' = 'SIGN_TRANSACTION',
- 'NEXT_PAGE' = 'NEXT_PAGE',
- 'PREV_PAGE' = 'PREV_PAGE',
+ 'NEXT_TRANSACTION' = 'NEXT_TRANSACTION',
+ 'PREV_TRANSACTION' = 'PREV_TRANSACTION',
'CLOSE' = 'CLOSE',
- 'DATA_UPDATE' = 'DATA_UPDATE',
+ 'DATA_UPDATE' = 'DATA_UPDATE'
}
diff --git a/src/components/sign-transactions-modal/signTransactionsModalStore.ts b/src/components/sign-transactions-modal/signTransactionsModalStore.ts
index 48f6ba86..d7a37c0a 100644
--- a/src/components/sign-transactions-modal/signTransactionsModalStore.ts
+++ b/src/components/sign-transactions-modal/signTransactionsModalStore.ts
@@ -5,6 +5,9 @@ type ITransactionState = ISignTransactionsModalData & {
isLoading: boolean;
isWaitingForSignature: boolean;
onSign: () => void;
+ onCancel: () => void;
+ onPrev: () => void;
+ onNext: () => void;
};
const initialState: ITransactionState = {
@@ -18,20 +21,24 @@ const initialState: ITransactionState = {
feeInFiatLimit: '',
currentIndex: 0,
receiver: '',
+ nextUnsignedTxIndex: 0
},
nftTransaction: null,
sftTransaction: null,
tokenTransaction: null,
onSign: null,
+ onCancel: null,
+ onPrev: null,
+ onNext: null
};
const { state } = createStore({
- ...initialState,
+ ...initialState
});
export const resetState = () => ({
...state,
- ...initialState,
+ ...initialState
});
export default state;
diff --git a/src/constants/dataTestIds.enum.ts b/src/constants/dataTestIds.enum.ts
index 5f35fd7d..fb3bfc30 100644
--- a/src/constants/dataTestIds.enum.ts
+++ b/src/constants/dataTestIds.enum.ts
@@ -17,4 +17,7 @@ export enum DataTestIdsEnum {
transactionToastTitle = 'transactionToastTitle',
transactionDetailsToastBody = 'transactionDetailsToastBody',
signTransactionBtn = 'signTransactionBtn',
+ signNextTransactionBtn = 'signNextTransactionBtn',
+ signCancelBtn = 'signCancelBtn',
+ signBackBtn = 'signBackBtn'
}
diff --git a/src/index.html b/src/index.html
index 8015d4e4..4b5d1151 100644
--- a/src/index.html
+++ b/src/index.html
@@ -11,11 +11,21 @@
+
+