diff --git a/.changeset/afraid-views-post.md b/.changeset/afraid-views-post.md new file mode 100644 index 000000000..f524e9f4a --- /dev/null +++ b/.changeset/afraid-views-post.md @@ -0,0 +1,5 @@ +--- +"@hashgraph/asset-tokenization-dapp": minor +--- + +Add getCouponAmountFor info (numerator, denominator, recordDateReached) to see coupon view diff --git a/apps/ats/web/package.json b/apps/ats/web/package.json index 1d8dab3e5..34538725e 100644 --- a/apps/ats/web/package.json +++ b/apps/ats/web/package.json @@ -29,7 +29,7 @@ "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "@rollup/plugin-commonjs": "^28.0.6", "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^14.2.0", "@testing-library/user-event": "^14.4.3", "@types/format-util": "^1.0.2", "@types/jest": "^29.5.1", diff --git a/apps/ats/web/src/hooks/queries/useCoupons.ts b/apps/ats/web/src/hooks/queries/useCoupons.ts index 449f35f54..20b34fe33 100644 --- a/apps/ats/web/src/hooks/queries/useCoupons.ts +++ b/apps/ats/web/src/hooks/queries/useCoupons.ts @@ -1,212 +1,9 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +// SPDX-License-Identifier: Apache-2.0 - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -import { UseQueryOptions, useMutation, useQuery } from '@tanstack/react-query'; -import { SDKService } from '../../services/SDKService'; -import { useToast } from 'io-bricks-ui'; -import { useTranslation } from 'react-i18next'; +import { UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query"; +import { SDKService } from "../../services/SDKService"; +import { useToast } from "io-bricks-ui"; +import { useTranslation } from "react-i18next"; import { CouponForViewModel, CouponViewModel, @@ -216,61 +13,53 @@ import { GetCouponRequest, GetTotalCouponHoldersRequest, SetCouponRequest, -} from '@hashgraph/asset-tokenization-sdk'; + CouponAmountForViewModel, +} from "@hashgraph/asset-tokenization-sdk"; -export const GET_SECURITY_COUPONS_FOR = ( - securityId: string, - couponId: number, - targetId: string, -) => `GET_SECURITY_COUPONS_FOR_${securityId}_${couponId}_${targetId}`; +export const GET_SECURITY_COUPONS_FOR = (securityId: string, couponId: number, targetId: string) => + `GET_SECURITY_COUPONS_FOR_${securityId}_${couponId}_${targetId}`; export const GET_SECURITY_COUPONS = (securityId: string, couponId: number) => `GET_SECURITY_COUPONS_${securityId}_${couponId}`; -export const GET_SECURITY_ALL_COUPONS = (securityId: string) => - `GET_SECURITY_ALL_COUPONS_${securityId}`; +export const GET_SECURITY_ALL_COUPONS = (securityId: string) => `GET_SECURITY_ALL_COUPONS_${securityId}`; + +export const GET_SECURITY_COUPONS_HOLDERS = (securityId: string, couponId: number) => + `GET_SECURITY_COUPONS_HOLDERS_${securityId}_${couponId}`; -export const GET_SECURITY_COUPONS_HOLDERS = ( - securityId: string, - couponId: number, -) => `GET_SECURITY_COUPONS_HOLDERS_${securityId}_${couponId}`; +export const GET_SECURITY_COUPONS_TOTAL_HOLDERS = (securityId: string, couponId: number) => + `GET_SECURITY_COUPONS_TOTAL_HOLDERS_${securityId}_${couponId}`; -export const GET_SECURITY_COUPONS_TOTAL_HOLDERS = ( - securityId: string, - couponId: number, -) => `GET_SECURITY_COUPONS_TOTAL_HOLDERS_${securityId}_${couponId}`; +export const GET_SECURITY_AMOUNT_COUPONS_FOR = (securityId: string, couponId: number, targetId: string) => + `GET_SECURITY_AMOUNT_COUPONS_FOR_${securityId}_${couponId}_${targetId}`; export const useCoupons = () => { const toast = useToast(); - const { t } = useTranslation('security', { keyPrefix: 'details.coupons' }); + const { t } = useTranslation("security", { keyPrefix: "details.coupons" }); - return useMutation( - (setCouponRequest: SetCouponRequest) => - SDKService.setCoupon(setCouponRequest), - { - onSuccess: (data) => { - console.log('SDK message --> Coupon creation success: ', data); + return useMutation((setCouponRequest: SetCouponRequest) => SDKService.setCoupon(setCouponRequest), { + onSuccess: (data) => { + console.log("SDK message --> Coupon creation success: ", data); - if (!data) return; + if (!data) return; - toast.show({ - title: t('messages.success'), - description: t('messages.creationSuccessful'), - variant: 'subtle', - status: 'success', - }); - }, - onError: (error) => { - console.log('SDK message --> Coupon creation error: ', error); - toast.show({ - title: t('messages.error'), - description: t('messages.creationFailed'), - variant: 'subtle', - status: 'error', - }); - }, + toast.show({ + title: t("messages.success"), + description: t("messages.creationSuccessful"), + variant: "subtle", + status: "success", + }); }, - ); + onError: (error) => { + console.log("SDK message --> Coupon creation error: ", error); + toast.show({ + title: t("messages.error"), + description: t("messages.creationFailed"), + variant: "subtle", + status: "error", + }); + }, + }); }; export const useGetCouponsFor = ( @@ -278,13 +67,7 @@ export const useGetCouponsFor = ( options: UseQueryOptions, ) => { return useQuery( - [ - GET_SECURITY_COUPONS_FOR( - params.securityId, - params.couponId, - params.targetId, - ), - ], + [GET_SECURITY_COUPONS_FOR(params.securityId, params.couponId, params.targetId)], () => SDKService.getCouponFor(params), options, ); @@ -305,11 +88,7 @@ export const useGetAllCoupons = ( params: GetAllCouponsRequest, options: UseQueryOptions = {}, ) => { - return useQuery( - [GET_SECURITY_ALL_COUPONS(params.securityId)], - () => SDKService.getAllCoupons(params), - options, - ); + return useQuery([GET_SECURITY_ALL_COUPONS(params.securityId)], () => SDKService.getAllCoupons(params), options); }; export const useGetCouponsHolders = ( @@ -333,3 +112,14 @@ export const useGetCouponsTotalHolders = ( options, ); }; + +export const useGetCouponsAmountFor = ( + params: GetCouponForRequest, + options: UseQueryOptions, +) => { + return useQuery( + [GET_SECURITY_AMOUNT_COUPONS_FOR(params.securityId, params.couponId, params.targetId)], + () => SDKService.getCouponAmountFor(params), + options, + ); +}; diff --git a/apps/ats/web/src/i18n/en/security/coupons.ts b/apps/ats/web/src/i18n/en/security/coupons.ts index e733b165b..bbe67890d 100644 --- a/apps/ats/web/src/i18n/en/security/coupons.ts +++ b/apps/ats/web/src/i18n/en/security/coupons.ts @@ -1,256 +1,51 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ +// SPDX-License-Identifier: Apache-2.0 export default { tabs: { - program: 'Program coupon', - see: 'See coupon', - holders: 'Holders', - list: 'List', + program: "Program coupon", + see: "See coupon", + holders: "Holders", + list: "List", }, list: { columns: { - id: 'ID', - recordDate: 'Record Date', - executionDate: 'Execution Date', - rate: 'Coupon Rate', - period: 'Period', - snapshotId: 'Snapshot', + id: "ID", + recordDate: "Record Date", + executionDate: "Execution Date", + rate: "Coupon Rate", + period: "Period", + snapshotId: "Snapshot", }, - emptyTable: 'No coupons found', + emptyTable: "No coupons found", }, program: { input: { - expired: 'You cannot program a coupon since the bond is expired.', + expired: "You cannot program a coupon since the bond is expired.", recordDate: { - label: 'Record date', - placeholder: 'Select record date', - tooltip: - 'Coupon’s record date. A snapshot of Bond holder’s balances will be triggered on this date.', + label: "Record date", + placeholder: "Select record date", + tooltip: "Coupon’s record date. A snapshot of Bond holder’s balances will be triggered on this date.", }, paymentDate: { - label: 'Payment date', - placeholder: 'Select payment date', - tooltip: 'Coupon’s execution date, must occur after the record date.', + label: "Payment date", + placeholder: "Select payment date", + tooltip: "Coupon’s execution date, must occur after the record date.", }, rate: { - label: 'Coupon rate', - placeholder: '0,123%', - tooltip: 'Interest rate for the coupon.', + label: "Coupon rate", + placeholder: "0,123%", + tooltip: "Interest rate for the coupon.", }, period: { - label: 'Coupon period', - placeholder: 'Select coupon period', - tooltip: - 'The period between coupon payments. This field is required for all coupon operations.', + label: "Coupon period", + placeholder: "Select coupon period", + tooltip: "The period between coupon payments. This field is required for all coupon operations.", options: { - day: '1 Day', - week: '1 Week', - month: '1 Month', - quarter: '3 Months', - year: '1 Year', + day: "1 Day", + week: "1 Week", + month: "1 Month", + quarter: "3 Months", + year: "1 Year", }, }, }, @@ -258,45 +53,47 @@ export default { see: { input: { coupon: { - label: 'Coupon ID', - placeholder: 'Add ID', - tooltip: 'ID of the coupon to display.', + label: "Coupon ID", + placeholder: "Add ID", + tooltip: "ID of the coupon to display.", }, account: { - label: 'Account ID', - placeholder: 'Add ID', - tooltip: 'ID of the account to display the coupon for.', + label: "Account ID", + placeholder: "Add ID", + tooltip: "ID of the account to display the coupon for.", }, }, error: { - general: - 'Sorry, there was an error. Please check data and try again, please', + general: "Sorry, there was an error. Please check data and try again, please", }, details: { - title: 'Detail', - paymentDay: 'Payment day', - period: 'Period', - amount: 'Amount', + title: "Detail", + paymentDay: "Payment day", + period: "Period", + amount: "Amount", + numerator: "Numerator", + denominator: "Denominator", + recordDateReached: "Record Date Reached", }, }, holders: { - title: 'Holders', + title: "Holders", couponIdInput: { - label: 'Coupon ID', - placeholder: '1', - tooltip: 'ID of the coupon to display.', + label: "Coupon ID", + placeholder: "1", + tooltip: "ID of the coupon to display.", }, - searchButton: 'Search', - emptyTable: 'No data', + searchButton: "Search", + emptyTable: "No data", table: { - couponId: 'Coupon ID', - holderAddress: 'Holder address', + couponId: "Coupon ID", + holderAddress: "Holder address", }, }, messages: { - success: 'Success: ', - creationSuccessful: 'coupon creation was successful', - error: 'Error: ', - creationFailed: 'coupon creation failed', + success: "Success: ", + creationSuccessful: "coupon creation was successful", + error: "Error: ", + creationFailed: "coupon creation failed", }, }; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/SeeCoupon.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/SeeCoupon.tsx index 9261320c2..35e7f168e 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/SeeCoupon.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/SeeCoupon.tsx @@ -1,209 +1,6 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +// SPDX-License-Identifier: Apache-2.0 - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -import { Button, Center, HStack, Stack, VStack } from '@chakra-ui/react'; +import { Button, Center, HStack, Stack, VStack } from "@chakra-ui/react"; import { InputController, InputNumberController, @@ -212,23 +9,17 @@ import { PhosphorIcon, Text, Tooltip, -} from 'io-bricks-ui'; -import { isValidHederaId, min, required } from '../../../../utils/rules'; -import { useForm } from 'react-hook-form'; -import { Info } from '@phosphor-icons/react'; -import { useTranslation } from 'react-i18next'; -import { - GetCouponForRequest, - GetCouponRequest, -} from '@hashgraph/asset-tokenization-sdk'; -import { useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; -import { - useGetCoupons, - useGetCouponsFor, -} from '../../../../hooks/queries/useCoupons'; -import { formatDate, formatCouponPeriod } from '../../../../utils/format'; -import { DATE_TIME_FORMAT } from '../../../../utils/constants'; +} from "io-bricks-ui"; +import { isValidHederaId, min, required } from "../../../../utils/rules"; +import { useForm } from "react-hook-form"; +import { Info } from "@phosphor-icons/react"; +import { useTranslation } from "react-i18next"; +import { GetCouponForRequest, GetCouponRequest } from "@hashgraph/asset-tokenization-sdk"; +import { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import { useGetCoupons, useGetCouponsFor, useGetCouponsAmountFor } from "../../../../hooks/queries/useCoupons"; +import { formatDate, formatCouponPeriod } from "../../../../utils/format"; +import { DATE_TIME_FORMAT } from "../../../../utils/constants"; interface SeeCouponFormValues { couponId: number; @@ -236,41 +27,47 @@ interface SeeCouponFormValues { } const defaultCouponForRequest = new GetCouponForRequest({ - securityId: '', + securityId: "", couponId: 0, - targetId: '', + targetId: "", }); const defaultCouponRequest = new GetCouponRequest({ - securityId: '', + securityId: "", couponId: 0, }); +const defaultCouponAmountForRequest = new GetCouponForRequest({ + securityId: "", + couponId: 0, + targetId: "", +}); + export const SeeCoupon = () => { const { control, handleSubmit, formState: { isValid }, } = useForm({ - mode: 'all', + mode: "all", }); - const { t: tForm } = useTranslation('security', { - keyPrefix: 'details.coupons.see.input', + const { t: tForm } = useTranslation("security", { + keyPrefix: "details.coupons.see.input", }); - const { t: tDetail } = useTranslation('security', { - keyPrefix: 'details.coupons.see.details', + const { t: tDetail } = useTranslation("security", { + keyPrefix: "details.coupons.see.details", }); - const { t: tGlobal } = useTranslation('globals'); - const { id: securityId = '' } = useParams(); + const { t: tGlobal } = useTranslation("globals"); + const { id: securityId = "" } = useParams(); const [couponsRequest, setCouponsRequest] = useState(); - const [couponForRequest, setCouponsForRequest] = - useState(); - const [isCouponsForLoading, setIsCouponsForLoading] = - useState(false); + const [couponForRequest, setCouponsForRequest] = useState(); + const [couponAmountForRequest, setCouponAmountForRequest] = useState(); + const [isCouponsForLoading, setIsCouponsForLoading] = useState(false); const [isCouponsLoading, setIsCouponsLoading] = useState(false); + const [isCouponsAmountForLoading, setIsCouponsAmountForLoading] = useState(false); const toast = useToast(); - const { t: tError } = useTranslation('security', { - keyPrefix: 'details.Coupons.see.error', + const { t: tError } = useTranslation("security", { + keyPrefix: "details.Coupons.see.error", }); const { data: couponsFor, refetch: refetchCouponsFor } = useGetCouponsFor( @@ -283,25 +80,39 @@ export const SeeCoupon = () => { onError: () => { setIsCouponsForLoading(false); toast.show({ - title: tError('general'), - status: 'error', + title: tError("general"), + status: "error", }); }, }, ); - const { data: coupons, refetch: refetchCoupons } = useGetCoupons( - couponsRequest ?? defaultCouponRequest, + const { data: coupons, refetch: refetchCoupons } = useGetCoupons(couponsRequest ?? defaultCouponRequest, { + enabled: false, + onSuccess: () => { + setIsCouponsLoading(false); + }, + onError: () => { + setIsCouponsLoading(false); + toast.show({ + title: tError("general"), + status: "error", + }); + }, + }); + + const { data: couponsAmountFor, refetch: refetchCouponsAmountFor } = useGetCouponsAmountFor( + couponAmountForRequest ?? defaultCouponAmountForRequest, { enabled: false, onSuccess: () => { - setIsCouponsLoading(false); + setIsCouponsAmountForLoading(false); }, onError: () => { - setIsCouponsLoading(false); + setIsCouponsAmountForLoading(false); toast.show({ - title: tError('general'), - status: 'error', + title: tError("general"), + status: "error", }); }, }, @@ -321,9 +132,17 @@ export const SeeCoupon = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [couponsRequest]); + useEffect(() => { + if (couponAmountForRequest) { + refetchCouponsAmountFor(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [couponForRequest]); + const submitForm = ({ couponId, targetId }: SeeCouponFormValues) => { setIsCouponsForLoading(true); setIsCouponsLoading(true); + setIsCouponsAmountForLoading(true); const couponsForReq = new GetCouponForRequest({ couponId, @@ -337,25 +156,23 @@ export const SeeCoupon = () => { securityId, }); setCouponsRequest(couponsReq); + + const couponsAmountForReq = new GetCouponForRequest({ + couponId, + targetId, + securityId, + }); + setCouponAmountForRequest(couponsAmountForReq); }; return (
- + - - {tForm('coupon.label')}* - - + {tForm("coupon.label")}* + @@ -364,15 +181,13 @@ export const SeeCoupon = () => { control={control} id="couponId" rules={{ required, min: min(0) }} - placeholder={tForm('coupon.placeholder')} + placeholder={tForm("coupon.placeholder")} /> - - {tForm('account.label')}* - - + {tForm("account.label")}* + @@ -380,45 +195,60 @@ export const SeeCoupon = () => { control={control} id="targetId" rules={{ required, isValidHederaId: isValidHederaId }} - placeholder={tForm('account.placeholder')} + placeholder={tForm("account.placeholder")} /> - {couponsFor && coupons && ( + {couponsFor && coupons && couponsAmountFor && ( )} diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx index 3cc804421..c800aac95 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx @@ -1,216 +1,264 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -import { SeeCoupon } from '../SeeCoupon'; -import { render } from '../../../../../test-utils'; - -// TODO Improve tests when it is connected to SDK +// SPDX-License-Identifier: Apache-2.0 + +import { SeeCoupon } from "../SeeCoupon"; +import { render } from "../../../../../test-utils"; +import { screen, fireEvent, waitFor } from "@testing-library/react"; +import { useGetCoupons, useGetCouponsFor, useGetCouponsAmountFor } from "../../../../../hooks/queries/useCoupons"; + +jest.mock("../../../../../hooks/queries/useCoupons"); +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useParams: () => ({ id: "0.0.12345" }), +})); + +const mockUseGetCouponsFor = useGetCouponsFor as jest.Mock; +const mockUseGetCoupons = useGetCoupons as jest.Mock; +const mockUseGetCouponsAmountFor = useGetCouponsAmountFor as jest.Mock; + +const mockRefetchCouponsFor = jest.fn(); +const mockRefetchCoupons = jest.fn(); +const mockRefetchCouponsAmountFor = jest.fn(); + +const defaultHookResponse = { + data: undefined, + refetch: jest.fn(), + isLoading: false, + isError: false, +}; + +const mockCouponsForData = { + value: "100.50", +}; + +const mockCouponsData = { + executionDate: new Date("2024-06-15T10:00:00Z"), + period: 30, +}; + +const mockCouponsAmountForData = { + numerator: "150", + denominator: "1000", + recordDateReached: true, +}; + +const getFormInputsByName = () => { + const couponInput = document.querySelector('input[name="couponId"]') as HTMLInputElement; + const accountInput = document.querySelector('input[name="targetId"]') as HTMLInputElement; + return { couponInput, accountInput }; +}; + describe(`${SeeCoupon.name}`, () => { - test('should render correctly', () => { - const component = render(); + beforeEach(() => { + jest.clearAllMocks(); + + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchCouponsAmountFor, + }); + }); + test("should render correctly", () => { + const component = render(); expect(component.asFragment()).toMatchSnapshot(); }); + + test("should render form inputs", () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + expect(couponInput).toBeInTheDocument(); + expect(accountInput).toBeInTheDocument(); + }); + + test("should disable submit button when form is invalid", () => { + render(); + + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + + test("should enable submit button when form is valid", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).not.toBeDisabled(); + }); + }); + + test("should call refetch functions on form submit", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).not.toBeDisabled(); + }); + + const submitButton = screen.getByRole("button"); + fireEvent.click(submitButton); + + await waitFor(() => { + expect(mockRefetchCouponsFor).toHaveBeenCalled(); + expect(mockRefetchCoupons).toHaveBeenCalled(); + expect(mockRefetchCouponsAmountFor).toHaveBeenCalled(); + }); + }); + + test("should display coupon details when all data is loaded", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsAmountForData, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // Verify amount from couponsFor + expect(screen.getByText("100.50")).toBeInTheDocument(); + + // Verify numerator from couponsAmountFor + expect(screen.getByText("150")).toBeInTheDocument(); + + // Verify denominator from couponsAmountFor + expect(screen.getByText("1000")).toBeInTheDocument(); + + // Verify recordDateReached from couponsAmountFor + expect(screen.getByText("true")).toBeInTheDocument(); + }); + }); + + test("should display default values when couponsAmountFor fields are undefined", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: undefined, + denominator: undefined, + recordDateReached: undefined, + }, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // Verify default values are displayed + const zeroElements = screen.getAllByText("0"); + expect(zeroElements.length).toBeGreaterThanOrEqual(2); + + expect(screen.getByText("false")).toBeInTheDocument(); + }); + }); + + test("should display recordDateReached as false when it is false", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "50", + denominator: "500", + recordDateReached: false, + }, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + expect(screen.getByText("50")).toBeInTheDocument(); + expect(screen.getByText("500")).toBeInTheDocument(); + expect(screen.getByText("false")).toBeInTheDocument(); + }); + }); + + test("should not display details when data is not loaded", () => { + render(); + + expect(screen.queryByText(/numerator/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/denominator/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/recordDateReached/i)).not.toBeInTheDocument(); + }); + + test("should validate couponId with min value of 0", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "-1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + }); + + test("should validate targetId as valid Hedera ID", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "invalid-id" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + }); }); diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx index b7119ae85..e37d898ed 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React from "react"; import { HStack, Modal, @@ -10,33 +10,33 @@ import { ModalOverlay, ModalProps, VStack, -} from '@chakra-ui/react'; -import { Button, InputController, PhosphorIcon, Text } from 'io-bricks-ui'; -import { useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { useGrantKYC } from '../../../../hooks/mutations/useKYC'; -import { GrantKycRequest } from '@hashgraph/asset-tokenization-sdk'; -import { useParams } from 'react-router-dom'; -import { FileArchive } from '@phosphor-icons/react'; -import { useRef, useState } from 'react'; -import { isValidHederaId, required } from '../../../../utils/rules'; +} from "@chakra-ui/react"; +import { Button, InputController, PhosphorIcon, Text } from "io-bricks-ui"; +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { useGrantKYC } from "../../../../hooks/mutations/useKYC"; +import { GrantKycRequest } from "@hashgraph/asset-tokenization-sdk"; +import { useParams } from "react-router-dom"; +import { FileArchive } from "@phosphor-icons/react"; +import { useRef, useState } from "react"; +import { isValidHederaId, required } from "../../../../utils/rules"; interface FormValues { accountId: string; vcFile: string; } -interface KYCModalProps extends Omit {} +interface KYCModalProps extends Omit {} export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { const fileInputRef = useRef(null); - const [fileName, setFileName] = useState(''); + const [fileName, setFileName] = useState(""); const [isLoading, setIsLoading] = useState(false); - const { id: securityId = '' } = useParams(); + const { id: securityId = "" } = useParams(); - const { t: tCreate } = useTranslation('security', { - keyPrefix: 'details.kyc.create', + const { t: tCreate } = useTranslation("security", { + keyPrefix: "details.kyc.create", }); const { @@ -47,7 +47,7 @@ export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { reset, watch, } = useForm({ - mode: 'onChange', + mode: "onChange", }); const { mutate } = useGrantKYC(); @@ -59,10 +59,10 @@ export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { - if (typeof reader.result === 'string') { - const base64Data = reader.result.split(',')[1]; + if (typeof reader.result === "string") { + const base64Data = reader.result.split(",")[1]; if (base64Data) { - setValue('vcFile', base64Data, { shouldValidate: true }); + setValue("vcFile", base64Data, { shouldValidate: true }); } } }; @@ -88,62 +88,57 @@ export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { }); }; - const isDisable = !isValid || !watch('vcFile'); + const isDisable = !isValid || !watch("vcFile"); return ( { - setFileName(''); + setFileName(""); reset(); onClose(); }} > - - {tCreate('title')} + + {tCreate("title")} - + - {fileName} + {fileName} - diff --git a/package-lock.json b/package-lock.json index 55954c494..3018cafa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,7 @@ "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "@rollup/plugin-commonjs": "^28.0.6", "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^14.2.0", "@testing-library/user-event": "^14.4.3", "@types/format-util": "^1.0.2", "@types/jest": "^29.5.1",