diff --git a/backend/database/migrations/20241121_1_WithdrawalsCopyDataToTempSchema.js b/backend/database/migrations/20241121_1_WithdrawalsCopyDataToTempSchema.js new file mode 100644 index 0000000..2a4cd6a --- /dev/null +++ b/backend/database/migrations/20241121_1_WithdrawalsCopyDataToTempSchema.js @@ -0,0 +1,37 @@ +// This script must be run wih first start on old source database +// this is just to copy data to new schema that will not be synced with main schema +module.exports = { + async up(knex) { + try { + let trx = await knex.transaction(); + let result = await trx.raw( `SELECT id, prop_receiving_address, prop_amount + FROM proposal_contents + WHERE prop_receiving_address IS NOT NULL;`); + await trx.raw('CREATE SCHEMA IF NOT EXISTS temp'); + await trx.raw(` + CREATE TABLE IF NOT EXISTS temp.temp_migrate_data ( + id int4 PRIMARY KEY, + prop_receiving_address VARCHAR(255), + prop_amount DECIMAL + ); + `); + result = await trx.raw(` + INSERT INTO temp.temp_migrate_data (id, prop_receiving_address, prop_amount) + SELECT id, prop_receiving_address, prop_amount + FROM proposal_contents + WHERE prop_receiving_address IS NOT NULL; + `); + console.log("Data coppied to temp table temp_migrate_data"); + await trx.raw('ALTER TABLE proposal_contents DROP COLUMN prop_receiving_address'); + console.log("Columns prop_receiving_address dropped successfully"); + await trx.raw('ALTER TABLE proposal_contents DROP COLUMN prop_amount'); + console.log("Columns prop_amount dropped successfully"); + trx.commit(); + } + catch(error) + { + console.error('Error copping data:', error); + } + console.log('Migration 20241121_1 completed!'); + } +} \ No newline at end of file diff --git a/backend/src/api/proposal-content/content-types/proposal-content/schema.json b/backend/src/api/proposal-content/content-types/proposal-content/schema.json index da764da..df36fee 100644 --- a/backend/src/api/proposal-content/content-types/proposal-content/schema.json +++ b/backend/src/api/proposal-content/content-types/proposal-content/schema.json @@ -20,33 +20,24 @@ "default": false }, "prop_abstract": { - "type": "text", - "maxLength": 2500 - }, + "type": "text", + "maxLength": 2500 + }, "prop_motivation": { - "type": "text", - "maxLength": 12000 - }, + "type": "text", + "maxLength": 12000 + }, "prop_rationale": { - "type": "text", - "maxLength": 12000 - }, + "type": "text", + "maxLength": 12000 + }, "gov_action_type_id": { "type": "string" }, "prop_name": { - "type": "string", - "required": true, - "maxLength": 80 - }, - "prop_receiving_address": { "type": "string", - "required": false, - "maxLength": 200 - }, - "prop_amount": { - "type": "float", - "required": false + "required": true, + "maxLength": 80 }, "proposal_links": { "type": "component", @@ -71,6 +62,12 @@ }, "prop_submission_date": { "type": "date" + }, + "proposal_withdrawals": { + "displayName": "proposal_withdrawals", + "type": "component", + "repeatable": true, + "component": "proposal.proposal-withdrawals" } } } diff --git a/backend/src/api/proposal-content/controllers/proposal-content.js b/backend/src/api/proposal-content/controllers/proposal-content.js index ab1aee4..fdfea8a 100644 --- a/backend/src/api/proposal-content/controllers/proposal-content.js +++ b/backend/src/api/proposal-content/controllers/proposal-content.js @@ -22,7 +22,9 @@ module.exports = createCoreController( if (!sanitizedQueryParams?.populate?.includes("proposal_links")) { sanitizedQueryParams.populate.push("proposal_links"); } - + if (!sanitizedQueryParams?.populate?.includes("proposal_withdrawals")) { + sanitizedQueryParams.populate.push("proposal_withdrawals"); + } const { results, pagination } = await strapi .service("api::proposal-content.proposal-content") .find(sanitizedQueryParams); diff --git a/backend/src/components/proposal/proposal-withdrawals.json b/backend/src/components/proposal/proposal-withdrawals.json new file mode 100644 index 0000000..ac10a4d --- /dev/null +++ b/backend/src/components/proposal/proposal-withdrawals.json @@ -0,0 +1,18 @@ +{ + "collectionName": "components_proposal_proposal_withdrawals", + "info": { + "displayName": "proposal_withdrawals", + "description": "" + }, + "options": {}, + "attributes": { + "prop_receiving_address": { + "type": "string", + "maxLength": 200 + }, + "prop_amount": { + "type": "float", + "min": 0 + } + } +} diff --git a/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json b/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json index 0456655..c8fa535 100644 --- a/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json +++ b/backend/src/extensions/documentation/documentation/1.0.0/full_documentation.json @@ -13,7 +13,7 @@ "name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html" }, - "x-generation-date": "2024-05-22T09:15:57.890Z" + "x-generation-date": "2024-11-26T08:48:46.401Z" }, "x-strapi-config": { "plugins": [], @@ -22,7 +22,7 @@ "openapi": "3.0.0", "servers": [ { - "url": "http://localhost:1337/api", + "url": "http://localhost:1338/api", "description": "Development server" } ], @@ -103,9 +103,6 @@ }, "comment_text": { "type": "string" - }, - "comment_has_replays": { - "type": "boolean" } } } @@ -172,9 +169,6 @@ "comment_text": { "type": "string" }, - "comment_has_replays": { - "type": "boolean" - }, "createdAt": { "type": "string", "format": "date-time" @@ -575,6 +569,10 @@ "type": "string", "format": "date-time" }, + "publishedAt": { + "type": "string", + "format": "date-time" + }, "createdBy": { "type": "object", "properties": { @@ -1726,12 +1724,6 @@ "prop_comments_number": { "type": "integer" }, - "prop_submited": { - "type": "boolean" - }, - "prop_status_id": { - "type": "string" - }, "user_id": { "type": "string" } @@ -1800,12 +1792,6 @@ "prop_comments_number": { "type": "integer" }, - "prop_submited": { - "type": "boolean" - }, - "prop_status_id": { - "type": "string" - }, "user_id": { "type": "string" }, @@ -2136,8 +2122,7 @@ "data": { "required": [ "prop_name", - "prop_receiving_address", - "prop_amount" + "user_id" ], "type": "object", "properties": { @@ -2162,17 +2147,32 @@ "prop_name": { "type": "string" }, - "prop_receiving_address": { + "proposal_links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProposalProposalLinkComponent" + } + }, + "is_draft": { + "type": "boolean" + }, + "user_id": { "type": "string" }, - "prop_amount": { - "type": "number", - "format": "float" + "prop_submitted": { + "type": "boolean" }, - "proposal_links": { + "prop_submission_tx_hash": { + "type": "string" + }, + "prop_submission_date": { + "type": "string", + "format": "date" + }, + "proposal_withdrawals": { "type": "array", "items": { - "$ref": "#/components/schemas/ProposalProposalLinkComponent" + "$ref": "#/components/schemas/ProposalProposalWithdrawalsComponent" } } } @@ -2229,8 +2229,7 @@ "type": "object", "required": [ "prop_name", - "prop_receiving_address", - "prop_amount" + "user_id" ], "properties": { "proposal_id": { @@ -2254,17 +2253,32 @@ "prop_name": { "type": "string" }, - "prop_receiving_address": { + "proposal_links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProposalProposalLinkComponent" + } + }, + "is_draft": { + "type": "boolean" + }, + "user_id": { "type": "string" }, - "prop_amount": { - "type": "number", - "format": "float" + "prop_submitted": { + "type": "boolean" }, - "proposal_links": { + "prop_submission_tx_hash": { + "type": "string" + }, + "prop_submission_date": { + "type": "string", + "format": "date" + }, + "proposal_withdrawals": { "type": "array", "items": { - "$ref": "#/components/schemas/ProposalProposalLinkComponent" + "$ref": "#/components/schemas/ProposalProposalWithdrawalsComponent" } }, "createdAt": { @@ -2599,7 +2613,22 @@ } } }, - "ProposalStatusRequest": { + "ProposalProposalWithdrawalsComponent": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "prop_receiving_address": { + "type": "string" + }, + "prop_amount": { + "type": "number", + "format": "float" + } + } + }, + "ProposalSubmitionRequest": { "type": "object", "required": [ "data" @@ -2608,31 +2637,35 @@ "data": { "type": "object", "properties": { - "prop_status_name": { + "proposal_id": { + "type": "string" + }, + "sub_json_path": {}, + "sub_location_url": { "type": "string" } } } } }, - "ProposalStatusListResponseDataItem": { + "ProposalSubmitionListResponseDataItem": { "type": "object", "properties": { "id": { "type": "number" }, "attributes": { - "$ref": "#/components/schemas/ProposalStatus" + "$ref": "#/components/schemas/ProposalSubmition" } } }, - "ProposalStatusListResponse": { + "ProposalSubmitionListResponse": { "type": "object", "properties": { "data": { "type": "array", "items": { - "$ref": "#/components/schemas/ProposalStatusListResponseDataItem" + "$ref": "#/components/schemas/ProposalSubmitionListResponseDataItem" } }, "meta": { @@ -2661,10 +2694,14 @@ } } }, - "ProposalStatus": { + "ProposalSubmition": { "type": "object", "properties": { - "prop_status_name": { + "proposal_id": { + "type": "string" + }, + "sub_json_path": {}, + "sub_location_url": { "type": "string" }, "createdAt": { @@ -2963,66 +3000,72 @@ } } }, - "ProposalStatusResponseDataObject": { + "ProposalSubmitionResponseDataObject": { "type": "object", "properties": { "id": { "type": "number" }, "attributes": { - "$ref": "#/components/schemas/ProposalStatus" + "$ref": "#/components/schemas/ProposalSubmition" } } }, - "ProposalStatusResponse": { + "ProposalSubmitionResponse": { "type": "object", "properties": { "data": { - "$ref": "#/components/schemas/ProposalStatusResponseDataObject" + "$ref": "#/components/schemas/ProposalSubmitionResponseDataObject" }, "meta": { "type": "object" } } }, - "ProposalSubmitionRequest": { + "ProposalVoteRequest": { "type": "object", "required": [ "data" ], "properties": { "data": { + "required": [ + "proposal_id", + "user_id" + ], "type": "object", "properties": { "proposal_id": { "type": "string" }, - "sub_json_path": {}, - "sub_location_url": { + "user_id": { "type": "string" + }, + "vote_result": { + "type": "boolean" } } } } }, - "ProposalSubmitionListResponseDataItem": { + "ProposalVoteListResponseDataItem": { "type": "object", "properties": { "id": { "type": "number" }, "attributes": { - "$ref": "#/components/schemas/ProposalSubmition" + "$ref": "#/components/schemas/ProposalVote" } } }, - "ProposalSubmitionListResponse": { + "ProposalVoteListResponse": { "type": "object", "properties": { "data": { "type": "array", "items": { - "$ref": "#/components/schemas/ProposalSubmitionListResponseDataItem" + "$ref": "#/components/schemas/ProposalVoteListResponseDataItem" } }, "meta": { @@ -3051,16 +3094,22 @@ } } }, - "ProposalSubmition": { + "ProposalVote": { "type": "object", + "required": [ + "proposal_id", + "user_id" + ], "properties": { "proposal_id": { "type": "string" }, - "sub_json_path": {}, - "sub_location_url": { + "user_id": { "type": "string" }, + "vote_result": { + "type": "boolean" + }, "createdAt": { "type": "string", "format": "date-time" @@ -3357,72 +3406,68 @@ } } }, - "ProposalSubmitionResponseDataObject": { + "ProposalVoteResponseDataObject": { "type": "object", "properties": { "id": { "type": "number" }, "attributes": { - "$ref": "#/components/schemas/ProposalSubmition" + "$ref": "#/components/schemas/ProposalVote" } } }, - "ProposalSubmitionResponse": { + "ProposalVoteResponse": { "type": "object", "properties": { "data": { - "$ref": "#/components/schemas/ProposalSubmitionResponseDataObject" + "$ref": "#/components/schemas/ProposalVoteResponseDataObject" }, "meta": { "type": "object" } } }, - "ProposalVoteRequest": { + "WalletTypeRequest": { "type": "object", "required": [ "data" ], "properties": { "data": { - "required": [ - "proposal_id", - "user_id" - ], "type": "object", "properties": { - "proposal_id": { + "wallet_name": { "type": "string" }, - "user_id": { + "wallet_image": { "type": "string" }, - "vote_result": { + "wallet_active": { "type": "boolean" } } } } }, - "ProposalVoteListResponseDataItem": { + "WalletTypeListResponseDataItem": { "type": "object", "properties": { "id": { "type": "number" }, "attributes": { - "$ref": "#/components/schemas/ProposalVote" + "$ref": "#/components/schemas/WalletType" } } }, - "ProposalVoteListResponse": { + "WalletTypeListResponse": { "type": "object", "properties": { "data": { "type": "array", "items": { - "$ref": "#/components/schemas/ProposalVoteListResponseDataItem" + "$ref": "#/components/schemas/WalletTypeListResponseDataItem" } }, "meta": { @@ -3451,20 +3496,16 @@ } } }, - "ProposalVote": { + "WalletType": { "type": "object", - "required": [ - "proposal_id", - "user_id" - ], "properties": { - "proposal_id": { + "wallet_name": { "type": "string" }, - "user_id": { + "wallet_image": { "type": "string" }, - "vote_result": { + "wallet_active": { "type": "boolean" }, "createdAt": { @@ -3763,963 +3804,60 @@ } } }, - "ProposalVoteResponseDataObject": { + "WalletTypeResponseDataObject": { "type": "object", "properties": { "id": { "type": "number" }, "attributes": { - "$ref": "#/components/schemas/ProposalVote" + "$ref": "#/components/schemas/WalletType" } } }, - "ProposalVoteResponse": { + "WalletTypeResponse": { "type": "object", "properties": { "data": { - "$ref": "#/components/schemas/ProposalVoteResponseDataObject" + "$ref": "#/components/schemas/WalletTypeResponseDataObject" }, "meta": { "type": "object" } } - }, - "WalletTypeRequest": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "object", - "properties": { - "wallet_name": { - "type": "string" - }, - "wallet_image": { - "type": "string" - }, - "wallet_active": { - "type": "boolean" + } + } + }, + "paths": { + "/comments": { + "get": { + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommentListResponse" + } } } - } - } - }, - "WalletTypeListResponseDataItem": { - "type": "object", - "properties": { - "id": { - "type": "number" }, - "attributes": { - "$ref": "#/components/schemas/WalletType" - } - } - }, - "WalletTypeListResponse": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WalletTypeListResponseDataItem" + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } } }, - "meta": { - "type": "object", - "properties": { - "pagination": { - "type": "object", - "properties": { - "page": { - "type": "integer" - }, - "pageSize": { - "type": "integer", - "minimum": 25 - }, - "pageCount": { - "type": "integer", - "maximum": 1 - }, - "total": { - "type": "integer" - } - } - } - } - } - } - }, - "WalletType": { - "type": "object", - "properties": { - "wallet_name": { - "type": "string" - }, - "wallet_image": { - "type": "string" - }, - "wallet_active": { - "type": "boolean" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "format": "date-time" - }, - "createdBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": { - "firstname": { - "type": "string" - }, - "lastname": { - "type": "string" - }, - "username": { - "type": "string" - }, - "email": { - "type": "string", - "format": "email" - }, - "resetPasswordToken": { - "type": "string" - }, - "registrationToken": { - "type": "string" - }, - "isActive": { - "type": "boolean" - }, - "roles": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "code": { - "type": "string" - }, - "description": { - "type": "string" - }, - "users": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - } - }, - "permissions": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": { - "action": { - "type": "string" - }, - "actionParameters": {}, - "subject": { - "type": "string" - }, - "properties": {}, - "conditions": {}, - "role": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "format": "date-time" - }, - "createdBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - }, - "updatedBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - } - } - } - } - } - } - } - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "format": "date-time" - }, - "createdBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - }, - "updatedBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - } - } - } - } - } - } - } - }, - "blocked": { - "type": "boolean" - }, - "preferedLanguage": { - "type": "string" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "format": "date-time" - }, - "createdBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - }, - "updatedBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - } - } - } - } - } - } - }, - "updatedBy": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "type": "object", - "properties": {} - } - } - } - } - } - } - }, - "WalletTypeResponseDataObject": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "attributes": { - "$ref": "#/components/schemas/WalletType" - } - } - }, - "WalletTypeResponse": { - "type": "object", - "properties": { - "data": { - "$ref": "#/components/schemas/WalletTypeResponseDataObject" - }, - "meta": { - "type": "object" - } - } - } - } - }, - "paths": { - "/comments": { - "get": { - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommentListResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - }, - "tags": [ - "Comment" - ], - "parameters": [ - { - "name": "sort", - "in": "query", - "description": "Sort by attributes ascending (asc) or descending (desc)", - "deprecated": false, - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "pagination[withCount]", - "in": "query", - "description": "Return page/pageSize (default: true)", - "deprecated": false, - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "pagination[page]", - "in": "query", - "description": "Page number (default: 0)", - "deprecated": false, - "required": false, - "schema": { - "type": "integer" - } - }, - { - "name": "pagination[pageSize]", - "in": "query", - "description": "Page size (default: 25)", - "deprecated": false, - "required": false, - "schema": { - "type": "integer" - } - }, - { - "name": "pagination[start]", - "in": "query", - "description": "Offset value (default: 0)", - "deprecated": false, - "required": false, - "schema": { - "type": "integer" - } - }, - { - "name": "pagination[limit]", - "in": "query", - "description": "Number of entities to return (default: 25)", - "deprecated": false, - "required": false, - "schema": { - "type": "integer" - } - }, - { - "name": "fields", - "in": "query", - "description": "Fields to return (ex: title,author)", - "deprecated": false, - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "populate", - "in": "query", - "description": "Relations to return", - "deprecated": false, - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "filters", - "in": "query", - "description": "Filters to apply", - "deprecated": false, - "required": false, - "schema": { - "type": "object" - }, - "style": "deepObject" - }, - { - "name": "locale", - "in": "query", - "description": "Locale to apply", - "deprecated": false, - "required": false, - "schema": { - "type": "string" - } - } - ], - "operationId": "get/comments" - }, - "post": { - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommentResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - }, - "tags": [ - "Comment" - ], - "parameters": [], - "operationId": "post/comments", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommentRequest" - } - } - } - } - } - }, - "/comments/{id}": { - "get": { - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommentResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - }, - "tags": [ - "Comment" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "description": "", - "deprecated": false, - "required": true, - "schema": { - "type": "number" - } - } - ], - "operationId": "get/comments/{id}" - }, - "put": { - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommentResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - }, - "tags": [ - "Comment" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "description": "", - "deprecated": false, - "required": true, - "schema": { - "type": "number" - } - } - ], - "operationId": "put/comments/{id}", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommentRequest" - } - } - } - } - }, - "delete": { - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "integer", - "format": "int64" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "403": { - "description": "Forbidden", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - }, - "tags": [ - "Comment" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "description": "", - "deprecated": false, - "required": true, - "schema": { - "type": "number" - } - } - ], - "operationId": "delete/comments/{id}" - } - }, - "/governance-action-types": { - "get": { - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GovernanceActionTypeListResponse" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" } } } @@ -4756,7 +3894,7 @@ } }, "tags": [ - "Governance-action-type" + "Comment" ], "parameters": [ { @@ -4861,7 +3999,7 @@ } } ], - "operationId": "get/governance-action-types" + "operationId": "get/comments" }, "post": { "responses": { @@ -4870,7 +4008,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GovernanceActionTypeResponse" + "$ref": "#/components/schemas/CommentResponse" } } } @@ -4927,23 +4065,23 @@ } }, "tags": [ - "Governance-action-type" + "Comment" ], "parameters": [], - "operationId": "post/governance-action-types", + "operationId": "post/comments", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GovernanceActionTypeRequest" + "$ref": "#/components/schemas/CommentRequest" } } } } } }, - "/governance-action-types/{id}": { + "/comments/{id}": { "get": { "responses": { "200": { @@ -4951,7 +4089,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GovernanceActionTypeResponse" + "$ref": "#/components/schemas/CommentResponse" } } } @@ -5008,7 +4146,7 @@ } }, "tags": [ - "Governance-action-type" + "Comment" ], "parameters": [ { @@ -5022,7 +4160,7 @@ } } ], - "operationId": "get/governance-action-types/{id}" + "operationId": "get/comments/{id}" }, "put": { "responses": { @@ -5031,7 +4169,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GovernanceActionTypeResponse" + "$ref": "#/components/schemas/CommentResponse" } } } @@ -5088,7 +4226,7 @@ } }, "tags": [ - "Governance-action-type" + "Comment" ], "parameters": [ { @@ -5102,13 +4240,13 @@ } } ], - "operationId": "put/governance-action-types/{id}", + "operationId": "put/comments/{id}", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GovernanceActionTypeRequest" + "$ref": "#/components/schemas/CommentRequest" } } } @@ -5179,7 +4317,7 @@ } }, "tags": [ - "Governance-action-type" + "Comment" ], "parameters": [ { @@ -5193,10 +4331,10 @@ } } ], - "operationId": "delete/governance-action-types/{id}" + "operationId": "delete/comments/{id}" } }, - "/polls": { + "/governance-action-types": { "get": { "responses": { "200": { @@ -5204,7 +4342,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollListResponse" + "$ref": "#/components/schemas/GovernanceActionTypeListResponse" } } } @@ -5261,7 +4399,7 @@ } }, "tags": [ - "Poll" + "Governance-action-type" ], "parameters": [ { @@ -5366,7 +4504,7 @@ } } ], - "operationId": "get/polls" + "operationId": "get/governance-action-types" }, "post": { "responses": { @@ -5375,7 +4513,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollResponse" + "$ref": "#/components/schemas/GovernanceActionTypeResponse" } } } @@ -5432,23 +4570,23 @@ } }, "tags": [ - "Poll" + "Governance-action-type" ], "parameters": [], - "operationId": "post/polls", + "operationId": "post/governance-action-types", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollRequest" + "$ref": "#/components/schemas/GovernanceActionTypeRequest" } } } } } }, - "/polls/{id}": { + "/governance-action-types/{id}": { "get": { "responses": { "200": { @@ -5456,7 +4594,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollResponse" + "$ref": "#/components/schemas/GovernanceActionTypeResponse" } } } @@ -5513,7 +4651,7 @@ } }, "tags": [ - "Poll" + "Governance-action-type" ], "parameters": [ { @@ -5527,7 +4665,7 @@ } } ], - "operationId": "get/polls/{id}" + "operationId": "get/governance-action-types/{id}" }, "put": { "responses": { @@ -5536,7 +4674,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollResponse" + "$ref": "#/components/schemas/GovernanceActionTypeResponse" } } } @@ -5593,7 +4731,7 @@ } }, "tags": [ - "Poll" + "Governance-action-type" ], "parameters": [ { @@ -5607,13 +4745,13 @@ } } ], - "operationId": "put/polls/{id}", + "operationId": "put/governance-action-types/{id}", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollRequest" + "$ref": "#/components/schemas/GovernanceActionTypeRequest" } } } @@ -5684,7 +4822,7 @@ } }, "tags": [ - "Poll" + "Governance-action-type" ], "parameters": [ { @@ -5698,10 +4836,10 @@ } } ], - "operationId": "delete/polls/{id}" + "operationId": "delete/governance-action-types/{id}" } }, - "/poll-votes": { + "/polls": { "get": { "responses": { "200": { @@ -5709,7 +4847,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollVoteListResponse" + "$ref": "#/components/schemas/PollListResponse" } } } @@ -5766,7 +4904,7 @@ } }, "tags": [ - "Poll-vote" + "Poll" ], "parameters": [ { @@ -5871,7 +5009,7 @@ } } ], - "operationId": "get/poll-votes" + "operationId": "get/polls" }, "post": { "responses": { @@ -5880,7 +5018,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollVoteResponse" + "$ref": "#/components/schemas/PollResponse" } } } @@ -5937,23 +5075,23 @@ } }, "tags": [ - "Poll-vote" + "Poll" ], "parameters": [], - "operationId": "post/poll-votes", + "operationId": "post/polls", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollVoteRequest" + "$ref": "#/components/schemas/PollRequest" } } } } } }, - "/poll-votes/{id}": { + "/polls/{id}": { "get": { "responses": { "200": { @@ -5961,7 +5099,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollVoteResponse" + "$ref": "#/components/schemas/PollResponse" } } } @@ -6018,7 +5156,7 @@ } }, "tags": [ - "Poll-vote" + "Poll" ], "parameters": [ { @@ -6032,7 +5170,7 @@ } } ], - "operationId": "get/poll-votes/{id}" + "operationId": "get/polls/{id}" }, "put": { "responses": { @@ -6041,7 +5179,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollVoteResponse" + "$ref": "#/components/schemas/PollResponse" } } } @@ -6098,7 +5236,7 @@ } }, "tags": [ - "Poll-vote" + "Poll" ], "parameters": [ { @@ -6112,13 +5250,13 @@ } } ], - "operationId": "put/poll-votes/{id}", + "operationId": "put/polls/{id}", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PollVoteRequest" + "$ref": "#/components/schemas/PollRequest" } } } @@ -6189,7 +5327,7 @@ } }, "tags": [ - "Poll-vote" + "Poll" ], "parameters": [ { @@ -6203,10 +5341,10 @@ } } ], - "operationId": "delete/poll-votes/{id}" + "operationId": "delete/polls/{id}" } }, - "/proposals": { + "/poll-votes": { "get": { "responses": { "200": { @@ -6214,7 +5352,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalListResponse" + "$ref": "#/components/schemas/PollVoteListResponse" } } } @@ -6271,7 +5409,7 @@ } }, "tags": [ - "Proposal" + "Poll-vote" ], "parameters": [ { @@ -6376,7 +5514,7 @@ } } ], - "operationId": "get/proposals" + "operationId": "get/poll-votes" }, "post": { "responses": { @@ -6385,7 +5523,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalResponse" + "$ref": "#/components/schemas/PollVoteResponse" } } } @@ -6442,23 +5580,23 @@ } }, "tags": [ - "Proposal" + "Poll-vote" ], "parameters": [], - "operationId": "post/proposals", + "operationId": "post/poll-votes", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalRequest" + "$ref": "#/components/schemas/PollVoteRequest" } } } } } }, - "/proposals/{id}": { + "/poll-votes/{id}": { "get": { "responses": { "200": { @@ -6466,7 +5604,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalResponse" + "$ref": "#/components/schemas/PollVoteResponse" } } } @@ -6523,7 +5661,7 @@ } }, "tags": [ - "Proposal" + "Poll-vote" ], "parameters": [ { @@ -6537,7 +5675,7 @@ } } ], - "operationId": "get/proposals/{id}" + "operationId": "get/poll-votes/{id}" }, "put": { "responses": { @@ -6546,7 +5684,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalResponse" + "$ref": "#/components/schemas/PollVoteResponse" } } } @@ -6603,7 +5741,7 @@ } }, "tags": [ - "Proposal" + "Poll-vote" ], "parameters": [ { @@ -6617,13 +5755,13 @@ } } ], - "operationId": "put/proposals/{id}", + "operationId": "put/poll-votes/{id}", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalRequest" + "$ref": "#/components/schemas/PollVoteRequest" } } } @@ -6694,7 +5832,7 @@ } }, "tags": [ - "Proposal" + "Poll-vote" ], "parameters": [ { @@ -6708,10 +5846,10 @@ } } ], - "operationId": "delete/proposals/{id}" + "operationId": "delete/poll-votes/{id}" } }, - "/proposal-contents": { + "/proposals": { "get": { "responses": { "200": { @@ -6719,7 +5857,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalContentListResponse" + "$ref": "#/components/schemas/ProposalListResponse" } } } @@ -6776,7 +5914,7 @@ } }, "tags": [ - "Proposal-content" + "Proposal" ], "parameters": [ { @@ -6881,7 +6019,7 @@ } } ], - "operationId": "get/proposal-contents" + "operationId": "get/proposals" }, "post": { "responses": { @@ -6890,7 +6028,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalContentResponse" + "$ref": "#/components/schemas/ProposalResponse" } } } @@ -6947,23 +6085,23 @@ } }, "tags": [ - "Proposal-content" + "Proposal" ], "parameters": [], - "operationId": "post/proposal-contents", + "operationId": "post/proposals", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalContentRequest" + "$ref": "#/components/schemas/ProposalRequest" } } } } } }, - "/proposal-contents/{id}": { + "/proposals/{id}": { "get": { "responses": { "200": { @@ -6971,7 +6109,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalContentResponse" + "$ref": "#/components/schemas/ProposalResponse" } } } @@ -7028,7 +6166,7 @@ } }, "tags": [ - "Proposal-content" + "Proposal" ], "parameters": [ { @@ -7042,7 +6180,7 @@ } } ], - "operationId": "get/proposal-contents/{id}" + "operationId": "get/proposals/{id}" }, "put": { "responses": { @@ -7051,7 +6189,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalContentResponse" + "$ref": "#/components/schemas/ProposalResponse" } } } @@ -7108,7 +6246,7 @@ } }, "tags": [ - "Proposal-content" + "Proposal" ], "parameters": [ { @@ -7122,13 +6260,13 @@ } } ], - "operationId": "put/proposal-contents/{id}", + "operationId": "put/proposals/{id}", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalContentRequest" + "$ref": "#/components/schemas/ProposalRequest" } } } @@ -7199,7 +6337,7 @@ } }, "tags": [ - "Proposal-content" + "Proposal" ], "parameters": [ { @@ -7213,10 +6351,10 @@ } } ], - "operationId": "delete/proposal-contents/{id}" + "operationId": "delete/proposals/{id}" } }, - "/proposal-statuses": { + "/proposal-contents": { "get": { "responses": { "200": { @@ -7224,7 +6362,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalStatusListResponse" + "$ref": "#/components/schemas/ProposalContentListResponse" } } } @@ -7281,7 +6419,7 @@ } }, "tags": [ - "Proposal-status" + "Proposal-content" ], "parameters": [ { @@ -7386,7 +6524,7 @@ } } ], - "operationId": "get/proposal-statuses" + "operationId": "get/proposal-contents" }, "post": { "responses": { @@ -7395,7 +6533,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalStatusResponse" + "$ref": "#/components/schemas/ProposalContentResponse" } } } @@ -7452,23 +6590,23 @@ } }, "tags": [ - "Proposal-status" + "Proposal-content" ], "parameters": [], - "operationId": "post/proposal-statuses", + "operationId": "post/proposal-contents", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalStatusRequest" + "$ref": "#/components/schemas/ProposalContentRequest" } } } } } }, - "/proposal-statuses/{id}": { + "/proposal-contents/{id}": { "get": { "responses": { "200": { @@ -7476,7 +6614,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalStatusResponse" + "$ref": "#/components/schemas/ProposalContentResponse" } } } @@ -7533,7 +6671,7 @@ } }, "tags": [ - "Proposal-status" + "Proposal-content" ], "parameters": [ { @@ -7547,7 +6685,7 @@ } } ], - "operationId": "get/proposal-statuses/{id}" + "operationId": "get/proposal-contents/{id}" }, "put": { "responses": { @@ -7556,7 +6694,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalStatusResponse" + "$ref": "#/components/schemas/ProposalContentResponse" } } } @@ -7613,7 +6751,7 @@ } }, "tags": [ - "Proposal-status" + "Proposal-content" ], "parameters": [ { @@ -7627,13 +6765,13 @@ } } ], - "operationId": "put/proposal-statuses/{id}", + "operationId": "put/proposal-contents/{id}", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProposalStatusRequest" + "$ref": "#/components/schemas/ProposalContentRequest" } } } @@ -7704,7 +6842,7 @@ } }, "tags": [ - "Proposal-status" + "Proposal-content" ], "parameters": [ { @@ -7718,7 +6856,7 @@ } } ], - "operationId": "delete/proposal-statuses/{id}" + "operationId": "delete/proposal-contents/{id}" } }, "/proposal-submitions": { diff --git a/backend/types/generated/components.d.ts b/backend/types/generated/components.d.ts index 3ed7ad9..bce6192 100644 --- a/backend/types/generated/components.d.ts +++ b/backend/types/generated/components.d.ts @@ -1,3 +1,4 @@ +import { ProposalProposalLink } from './components.d'; import type { Schema, Attribute } from '@strapi/strapi'; export interface ProposalProposalLink extends Schema.Component { @@ -15,10 +16,25 @@ export interface ProposalProposalLink extends Schema.Component { }; } +export interface ProposalProposalWithdrawals extends Schema.Component { + collectionName: 'components_proposal_proposal_withdrawals'; + info: { + displayName: 'proposal_withdrawals'; + }; + attributes: { + prop_receiving_address: Attribute.String & + Attribute.SetMinMaxLength<{ + maxLength: 200; + }>; + prop_amoount: Attribute.Decimal + }; +} + declare module '@strapi/types' { export module Shared { export interface Components { 'proposal.proposal-link': ProposalProposalLink; + 'proposal.proposal-withdrawals': ProposalProposalWithdrawals; } } } diff --git a/backend/types/generated/contentTypes.d.ts b/backend/types/generated/contentTypes.d.ts index c778698..d3fa6a0 100644 --- a/backend/types/generated/contentTypes.d.ts +++ b/backend/types/generated/contentTypes.d.ts @@ -1025,17 +1025,16 @@ export interface ApiProposalContentProposalContent Attribute.SetMinMaxLength<{ maxLength: 80; }>; - prop_receiving_address: Attribute.String & - Attribute.SetMinMaxLength<{ - maxLength: 200; - }>; - prop_amount: Attribute.Float; proposal_links: Attribute.Component<'proposal.proposal-link', true>; is_draft: Attribute.Boolean & Attribute.DefaultTo; user_id: Attribute.String & Attribute.Required; prop_submitted: Attribute.Boolean & Attribute.DefaultTo; prop_submission_tx_hash: Attribute.String & Attribute.Unique; prop_submission_date: Attribute.Date; + proposal_withdrawals: Attribute.Component< + 'proposal.proposal-withdrawals', + true + >; createdAt: Attribute.DateTime; updatedAt: Attribute.DateTime; createdBy: Attribute.Relation< diff --git a/pdf-ui/package.json b/pdf-ui/package.json index f52ceb4..7952103 100644 --- a/pdf-ui/package.json +++ b/pdf-ui/package.json @@ -1,6 +1,6 @@ { "name": "@intersect.mbo/pdf-ui", - "version": "0.4.1", + "version": "0.5.0", "description": "Proposal discussion ui", "main": "./src/index.js", "exports": { diff --git a/pdf-ui/src/components/CreateGovernanceActionDialog/index.jsx b/pdf-ui/src/components/CreateGovernanceActionDialog/index.jsx index c0db402..7979628 100644 --- a/pdf-ui/src/components/CreateGovernanceActionDialog/index.jsx +++ b/pdf-ui/src/components/CreateGovernanceActionDialog/index.jsx @@ -29,32 +29,31 @@ const CreateGovernanceActionDialog = ({ open = false, onClose = false }) => { const [step, setStep] = useState(1); const [proposalData, setProposalData] = useState({ proposal_links: [], + proposal_withdrawals: [] }); + const [governanceActionTypes, setGovernanceActionTypes] = useState([]); const [isContinueDisabled, setIsContinueDisabled] = useState(true); - const [showDraftSuccessfulModal, setShowDraftSuccessfulModal] = - useState(false); + const [showDraftSuccessfulModal, setShowDraftSuccessfulModal] = useState(false); const [selectedDraftId, setSelectedDraftId] = useState(null); const [errors, setErrors] = useState({ name: false, abstract: false, motivation: false, rationale: false, - address: false, - amount: false, + // address: false, + // amount: false, }); const [helperText, setHelperText] = useState({ name: '', abstract: '', motivation: '', rationale: '', - address: ``, - amount: ``, }); const [linksErrors, setLinksErrors] = useState({}); - + const [withdrawalsErrors, setWithdrawalsErrors ] = useState({}); const isSmallScreen = useMediaQuery((theme) => theme.breakpoints.down('sm') ); @@ -101,15 +100,17 @@ const CreateGovernanceActionDialog = ({ open = false, onClose = false }) => { )?.label; if (selectedLabel === 'Treasury') { - if ( - proposalData?.prop_receiving_address && - !errors?.address && - proposalData?.prop_amount && - !errors?.amount - ) { - setIsContinueDisabled(false); - } else { - setIsContinueDisabled(true); + if (proposalData?.proposal_withdravals) { + if ( + proposalData?.proposal_withdravals?.some( + (proposal_withdraval) => !proposal_withdraval.prop_receiving_address || !proposal_withdraval.prop_amount + ) || + Object.values(withdrawalsErrors).some((error) => error.url) + ) { + return setIsContinueDisabled(true); + } else { + setIsContinueDisabled(false); + } } } else { setIsContinueDisabled(false); @@ -117,7 +118,7 @@ const CreateGovernanceActionDialog = ({ open = false, onClose = false }) => { } else { setIsContinueDisabled(true); } - }, [proposalData, errors, linksErrors]); // proposalData is a dependency + }, [proposalData, errors, linksErrors, withdrawalsErrors]); // proposalData is a dependency const handleCreateProposal = async (isDraft = false) => { setLoading(true); @@ -262,6 +263,8 @@ const CreateGovernanceActionDialog = ({ open = false, onClose = false }) => { setHelperText={setHelperText} linksErrors={linksErrors} setLinksErrors={setLinksErrors} + withdrawalsErrors={withdrawalsErrors} + setWithdrawalsErrors={setWithdrawalsErrors} /> )} diff --git a/pdf-ui/src/components/CreationGoveranceAction/Step2.jsx b/pdf-ui/src/components/CreationGoveranceAction/Step2.jsx index 909417b..8bae74f 100644 --- a/pdf-ui/src/components/CreationGoveranceAction/Step2.jsx +++ b/pdf-ui/src/components/CreationGoveranceAction/Step2.jsx @@ -8,7 +8,7 @@ import { Typography, } from '@mui/material'; import { useEffect, useState } from 'react'; -import { LinkManager } from '.'; +import { LinkManager, WithdrawalsManager } from '.'; import { useAppContext } from '../../context/context'; import { getGovernanceActionTypes } from '../../lib/api'; import { @@ -32,6 +32,8 @@ const Step2 = ({ setHelperText, linksErrors, setLinksErrors, + withdrawalsErrors, + setWithdrawalsErrors, }) => { const titleMaxLength = 80; const abstractMaxLength = 2500; @@ -43,87 +45,87 @@ const Step2 = ({ )?.label || '' ); - const handleAddressChange = async (e) => { - const newAddress = e.target.value?.trim(); - setProposalData((prev) => ({ - ...prev, - prop_receiving_address: newAddress, - })); - - if (newAddress === '') { - setErrors((prev) => ({ - ...prev, - address: false, - })); - setHelperText((prev) => ({ - ...prev, - address: ``, - })); - return; - } - - const validationResult = await isRewardAddress(newAddress); - if (validationResult === true) { - setErrors((prev) => ({ - ...prev, - address: false, - })); - setHelperText((prev) => ({ - ...prev, - address: ``, - })); - } else { - setErrors((prev) => ({ - ...prev, - address: true, - })); - setHelperText((prev) => ({ - ...prev, - address: validationResult, - })); - } - }; - - const handleAmountChange = (e) => { - const newAmount = e.target.value?.trim(); - setProposalData((prev) => ({ - ...prev, - prop_amount: newAmount, - })); - - if (newAmount === '') { - setErrors((prev) => ({ - ...prev, - amount: false, - })); - setHelperText((prev) => ({ - ...prev, - amount: ``, - })); - return; - } - - const validationResult = numberValidation(newAmount); - if (validationResult === true) { - setErrors((prev) => ({ - ...prev, - amount: false, - })); - setHelperText((prev) => ({ - ...prev, - amount: ``, - })); - } else { - setErrors((prev) => ({ - ...prev, - amount: true, - })); - setHelperText((prev) => ({ - ...prev, - amount: validationResult, - })); - } - }; + // const handleAddressChange = async (e) => { + // const newAddress = e.target.value?.trim(); + // setProposalData((prev) => ({ + // ...prev, + // prop_receiving_address: newAddress, + // })); + + // if (newAddress === '') { + // setErrors((prev) => ({ + // ...prev, + // address: false, + // })); + // setHelperText((prev) => ({ + // ...prev, + // address: ``, + // })); + // return; + // } + + // const validationResult = await isRewardAddress(newAddress); + // if (validationResult === true) { + // setErrors((prev) => ({ + // ...prev, + // address: false, + // })); + // setHelperText((prev) => ({ + // ...prev, + // address: ``, + // })); + // } else { + // setErrors((prev) => ({ + // ...prev, + // address: true, + // })); + // setHelperText((prev) => ({ + // ...prev, + // address: validationResult, + // })); + // } + // }; + + // const handleAmountChange = (e) => { + // const newAmount = e.target.value?.trim(); + // setProposalData((prev) => ({ + // ...prev, + // prop_amount: newAmount, + // })); + + // if (newAmount === '') { + // setErrors((prev) => ({ + // ...prev, + // amount: false, + // })); + // setHelperText((prev) => ({ + // ...prev, + // amount: ``, + // })); + // return; + // } + + // const validationResult = numberValidation(newAmount); + // if (validationResult === true) { + // setErrors((prev) => ({ + // ...prev, + // amount: false, + // })); + // setHelperText((prev) => ({ + // ...prev, + // amount: ``, + // })); + // } else { + // setErrors((prev) => ({ + // ...prev, + // amount: true, + // })); + // setHelperText((prev) => ({ + // ...prev, + // amount: validationResult, + // })); + // } + // }; const handleChange = (e) => { const selectedValue = e.target.value; @@ -134,8 +136,7 @@ const Step2 = ({ setProposalData((prev) => ({ ...prev, gov_action_type_id: selectedValue, - prop_receiving_address: null, - prop_amount: null, + proposal_withdrawals:[{ prop_receiving_address: null, prop_amount: null }] })); setSelectedGovActionName(selectedLabel); @@ -449,7 +450,21 @@ const Step2 = ({ {selectedGovActionName === 'Treasury' ? ( <> - + + + {/* + /> */} + + ) : null} { + const theme = useTheme(); + + const handleWithdrawalChange = async (index, field, value) => { + const newWithdrawal = proposalData?.proposal_withdrawals?.map((proposal_withdrawal, i) => { + if (i === index) { + return { ...proposal_withdrawal, [field]: value }; + } + return proposal_withdrawal; + }); + setProposalData({ + ...proposalData, + proposal_withdrawals: newWithdrawal, + }); + // If the prop_receiving_address is empty, remove the error + if (field === 'prop_' && value === '') { + return setWithdrawalsErrors((prev) => { + const { [index]: removed, ...rest } = prev; + return rest; + }); + } + // Validate prop_receiving_address + + if (field === 'prop_receiving_address') { + const validationResult = await isRewardAddress(value); + setWithdrawalsErrors((prev) => ({ + ...prev, + [index]: { + ...prev[index], + prop_receiving_address: validationResult===true ? '' : validationResult, + }, + })); + } + if (field === 'prop_amount') { + const validationResult = numberValidation(value); + setWithdrawalsErrors((prev) => ({ + ...prev, + [index]: { + ...prev[index], + prop_amount: validationResult===true ? '' : validationResult, + }, + })); + } + + }; + + + const handleAddWithdrawal = () => { + if (proposalData?.proposal_withdrawals?.length < maxWithdrawals) { + setProposalData({ + ...proposalData, + proposal_withdrawals: [ + ...proposalData?.proposal_withdrawals, { prop_receiving_address: null, prop_amount: null }, + ], + }); + } + }; + + const handleRemoveWithdrawal = (index) => { + let newWithdrawal = proposalData?.proposal_withdrawals?.filter( + (_, i) => i !== index + ); + setProposalData({ + ...proposalData, + proposal_withdrawals: newWithdrawal, + }); + + // Remove errors for removed link + setWithdrawalsErrors((prev) => { + const { [index]: removed, ...rest } = prev; + return rest; + }); + }; + return ( + + {proposalData?.proposal_withdrawals?.map((withdrawal, index) => ( + 0?(theme) => theme.palette.primary.lightGray:""} + position='relative' + > + + {index === 0 ? null : ( + + handleRemoveWithdrawal(index)} + data-testid='withdrawal-wrapper-remove-address-button' + > + + + + )} + + { + handleWithdrawalChange( + index, + 'prop_receiving_address', + e.target.value + )}} + required + inputProps={{ + 'data-testid': `receiving-address-${index}-input`, + }} + error={!!withdrawalsErrors[index]?.prop_receiving_address} + helperText={withdrawalsErrors[index]?.prop_receiving_address} + FormHelperTextProps={{ + sx: { + backgroundColor: 'transparent', + }, + 'data-testid': `receiving-address-${index}-input`, + }} + /> + + handleWithdrawalChange( + index, + 'prop_amount', + e.target.value + )} + required + inputProps={{ + 'data-testid': `amount-${index}-input`, + }} + error={!!withdrawalsErrors[index]?.prop_amount} + helperText={withdrawalsErrors[index]?.prop_amount} + FormHelperTextProps={{ + sx: { + backgroundColor: 'transparent', + }, + 'data-testid': `amount-${index}-input`, + }} + /> + + + ))} + {proposalData?.proposal_withdrawals?.length < maxWithdrawals && ( + + + + )} + + ); +}; + +export default WithdrawalsManager; diff --git a/pdf-ui/src/components/CreationGoveranceAction/index.js b/pdf-ui/src/components/CreationGoveranceAction/index.js index 8912ecc..bf5d0b4 100644 --- a/pdf-ui/src/components/CreationGoveranceAction/index.js +++ b/pdf-ui/src/components/CreationGoveranceAction/index.js @@ -2,5 +2,6 @@ export { default as Step1 } from './Step1'; export { default as Step2 } from './Step2'; export { default as Step3 } from './Step3'; export { default as LinkManager } from './LinkManager'; +export { default as WithdrawalsManager} from "./WithdrawalsManager"; export { default as Step3Modal } from './Step3Modal'; export { default as DraftSuccessfulModal } from './DraftSuccessfulModal'; diff --git a/pdf-ui/src/components/EditProposalDialog/index.jsx b/pdf-ui/src/components/EditProposalDialog/index.jsx index bcd7dce..d0d81fa 100644 --- a/pdf-ui/src/components/EditProposalDialog/index.jsx +++ b/pdf-ui/src/components/EditProposalDialog/index.jsx @@ -38,6 +38,7 @@ import { numberValidation, } from '../../lib/utils'; import { LinkManager } from '../CreationGoveranceAction'; +import { WithdrawalsManager } from '../CreationGoveranceAction'; import DeleteProposalModal from '../DeleteProposalModal'; import CreateGA2 from '../../assets/svg/CreateGA2.jsx'; @@ -90,19 +91,17 @@ const EditProposalDialog = ({ abstract: false, motivation: false, rationale: false, - address: false, - amount: false, }); const [helperText, setHelperText] = useState({ name: '', abstract: '', motivation: '', rationale: '', - address: ``, - amount: ``, }); const [linksErrors, setLinksErrors] = useState({}); + const [withdrawalsErrors, setWithdrawalsErrors] = useState({}); + const isSmallScreen = useMediaQuery((theme) => theme.breakpoints.down('sm') @@ -132,8 +131,19 @@ const EditProposalDialog = ({ setIsSaveDisabled(false); } } - - const selectedLabel = governanceActionTypes.find( + if (draft?.proposal_withdrawals) { + if ( + draft?.proposal_withdrawals?.some( + (proposal_withdrawal) => !proposal_withdrawal || !proposal_withdrawal.prop_receiving_address + ) || + Object.values(withdrawalsErrors).some((error) => error.prop_receiving_address) + ) { + return setIsSaveDisabled(true); + } else { + setIsSaveDisabled(false); + } + } + const selectedLabel = governanceActionTypes.find( (option) => option?.value === draft?.gov_action_type_id )?.label; @@ -155,7 +165,6 @@ const EditProposalDialog = ({ setIsSaveDisabled(true); } }; - const setDraftData = (proposalData) => { const draft = { proposal_id: proposalData?.id, @@ -164,20 +173,16 @@ const EditProposalDialog = ({ ?.gov_action_type_id, prop_abstract: proposalData?.attributes?.content?.attributes?.prop_abstract, - prop_amount: - proposalData?.attributes?.content?.attributes?.prop_amount, prop_motivation: proposalData?.attributes?.content?.attributes?.prop_motivation, prop_name: proposalData?.attributes?.content?.attributes?.prop_name, prop_rationale: proposalData?.attributes?.content?.attributes?.prop_rationale, - prop_receiving_address: - proposalData?.attributes?.content?.attributes - ?.prop_receiving_address, + proposal_withdrawals: + proposalData?.attributes?.content?.attributes?.proposal_withdrawals, proposal_links: proposalData?.attributes?.content?.attributes?.proposal_links, }; - return draft; }; @@ -196,91 +201,8 @@ const EditProposalDialog = ({ } }; - const handleAddressChange = async (e) => { - const newAddress = e.target.value?.trim(); - setDraft((prev) => ({ - ...prev, - prop_receiving_address: newAddress, - })); - - if (newAddress === '') { - setErrors((prev) => ({ - ...prev, - address: false, - })); - setHelperText((prev) => ({ - ...prev, - address: ``, - })); - return; - } - - const validationResult = await isRewardAddress(newAddress); - if (validationResult === true) { - setErrors((prev) => ({ - ...prev, - address: false, - })); - setHelperText((prev) => ({ - ...prev, - address: ``, - })); - } else { - setErrors((prev) => ({ - ...prev, - address: true, - })); - setHelperText((prev) => ({ - ...prev, - address: validationResult, - })); - } - }; - - const handleAmountChange = (e) => { - const newAmount = e.target.value?.trim(); - setDraft((prev) => ({ - ...prev, - prop_amount: newAmount, - })); - - if (newAmount === '') { - setErrors((prev) => ({ - ...prev, - amount: false, - })); - setHelperText((prev) => ({ - ...prev, - amount: ``, - })); - return; - } - - const validationResult = numberValidation(newAmount); - if (validationResult === true) { - setErrors((prev) => ({ - ...prev, - amount: false, - })); - setHelperText((prev) => ({ - ...prev, - amount: ``, - })); - } else { - setErrors((prev) => ({ - ...prev, - amount: true, - })); - setHelperText((prev) => ({ - ...prev, - amount: validationResult, - })); - } - }; - const handleTextAreaChange = (event, field, errorField) => { const value = event?.target?.value; - setDraft((prev) => ({ ...prev, [field]: value, @@ -398,11 +320,9 @@ const EditProposalDialog = ({ useEffect(() => { fetchGovernanceActionTypes(); }, []); - useEffect(() => { setDraft(setDraftData(proposal)); }, [proposal]); - useEffect(() => { handleIsSaveDisabled(); }, [draft, errors, linksErrors]); @@ -864,7 +784,13 @@ const EditProposalDialog = ({ {selectedGovActionName === 'Treasury' ? ( <> - + {/* + /> */} ) : null} diff --git a/pdf-ui/src/components/ProposalsList/index.jsx b/pdf-ui/src/components/ProposalsList/index.jsx index 650fee5..7c6f365 100644 --- a/pdf-ui/src/components/ProposalsList/index.jsx +++ b/pdf-ui/src/components/ProposalsList/index.jsx @@ -76,10 +76,10 @@ const ProposalsList = ({ let query = ''; if (isDraft) { if (statusList?.length === 0 || statusList?.length === 2) { - query = `filters[$and][2][is_draft]=true&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links`; + query = `filters[$and][2][is_draft]=true&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links&populate[1]=proposal_withdrawals`; } else { const isSubmitted = haveSubmittedFilter ? 'true' : 'false'; - query = `filters[$and][2][is_draft]=true&filters[$and][3][prop_submitted]=${isSubmitted}&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links`; + query = `filters[$and][2][is_draft]=true&filters[$and][3][prop_submitted]=${isSubmitted}&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links&populate[1]=proposal_withdrawals`; } } else { if (statusList?.length === 0 || statusList?.length === 2) { @@ -87,14 +87,14 @@ const ProposalsList = ({ governanceAction?.id }&filters[$and][1][prop_name][$containsi]=${ debouncedSearchValue || '' - }&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links`; + }&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links&populate[1]=proposal_withdrawals`; } else { const isSubmitted = haveSubmittedFilter ? 'true' : 'false'; query = `filters[$and][0][gov_action_type_id]=${ governanceAction?.id }&filters[$and][1][prop_name][$containsi]=${ debouncedSearchValue || '' - }&filters[$and][2][prop_submitted]=${isSubmitted}&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links`; + }&filters[$and][2][prop_submitted]=${isSubmitted}&pagination[page]=${page}&pagination[pageSize]=25&sort[createdAt]=${sortType}&populate[0]=proposal_links&populate[1]=proposal_withdrawals`; } } const { proposals, pgCount } = await getProposals(query); diff --git a/pdf-ui/src/components/ReviewVersions/index.jsx b/pdf-ui/src/components/ReviewVersions/index.jsx index ee51555..438e7d3 100644 --- a/pdf-ui/src/components/ReviewVersions/index.jsx +++ b/pdf-ui/src/components/ReviewVersions/index.jsx @@ -44,7 +44,7 @@ const ReviewVersions = ({ open, onClose, id }) => { const fetchVersions = async () => { try { - let query = `filters[$and][0][prop_id]=${id}&pagination[page]=1&pagination[pageSize]=25&sort[createdAt]=desc&populate[0]=proposal_links`; + let query = `filters[$and][0][prop_id]=${id}&pagination[page]=1&pagination[pageSize]=25&sort[createdAt]=desc&populate[0]=proposal_links&populate[1]=proposal_withdrawals`; const { proposals } = await getProposals(query); if (!proposals) return;